diff --git a/bin/heroku-hhvm-apache2 b/bin/heroku-hhvm-apache2 index 80b718164..44d072fb8 100755 --- a/bin/heroku-hhvm-apache2 +++ b/bin/heroku-hhvm-apache2 @@ -4,8 +4,10 @@ set -o pipefail # fail harder set -eu -# for patterns further down +# for ${DOCUMENT_ROOT%%*(/)} pattern further down shopt -s extglob +# for detecting when -l 'logs/*.log' matches nothing +shopt -s nullglob php_passthrough() { local dir=$(dirname "$1") @@ -30,6 +32,10 @@ check_exists() { fi } +touch_log() { + mkdir -p $(dirname "$1") && touch "$1" +} + print_help() { echo "\ Boots HHVM together with Apache2 on Heroku and for local development. @@ -55,12 +61,18 @@ Options: -h Display this help screen and exit. -i The path to the php.ini file to use. [default: $COMPOSER_VENDOR_DIR/heroku/heroku-buildpack-php/conf/hhvm/php.ini] + -l Path to additional log file to tail to STDERR so its + contents appear in 'heroku logs'. If the file does not + exist, it will be created. Wildcards are allowed, but + must be quoted and must match already existing files. + Note: this option can be repeated multiple times. + +All file paths must be relative to '$HEROKU_APP_DIR'. Any file name that ends in '.php' will be run through the PHP interpreter first. You may use this for templating although this is less useful than e.g. for Nginx where unlike in Apache2, you cannot reference environment variables in config files using a '\${VARNAME}' syntax. -All file paths must be relative to '$HEROKU_APP_DIR'. If you would like to use the -C and -c options together, make sure you retain the appropriate include mechanisms (see default configs for details). @@ -75,7 +87,10 @@ export PORT=${PORT:-$(( $RANDOM+1024 ))} export COMPOSER_VENDOR_DIR=$(composer config vendor-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT export COMPOSER_BIN_DIR=$(composer config bin-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT -while getopts ":C:c:i:h" opt; do +# our standard logs +logs=( "/tmp/heroku.apache2_error.$PORT.log" "/tmp/heroku.apache2_access.$PORT.log" ) + +while getopts ":C:c:i:l:h" opt; do case $opt in C) httpd_config_include=$(check_exists "$OPTARG" "C") @@ -86,6 +101,21 @@ while getopts ":C:c:i:h" opt; do i) php_config=$(check_exists "$OPTARG" "i") ;; + l) + logarg=( $OPTARG ) # must not quote this or wildcards won't get expanded into individual values + if [[ ${#logarg[@]} -eq 0 ]]; then # we set nullglob to detect if a pattern matched nothing (then the array is empty) + echo "Pattern '$OPTARG' passed to option -l matched no files" >&2 + exit 1 + fi + for logfile in "${logarg[@]}"; do + if [[ -d "$logfile" ]]; then + echo "-l '$logfile': is a directory" >&2 + exit 1 + fi + touch_log "$logfile" || { echo "Could not touch '$logfile'; permissions problem?" >&2; exit 1; } + logs+=("$logfile") # must quote here in case a wildcard matched a file with a space in the name + done + ;; h) print_help 2>&1 exit @@ -120,7 +150,7 @@ if [[ "$#" == "1" ]]; then exit 1 else # strip trailing slashes if present - DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} + DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} # powered by extglob echo "DOCUMENT_ROOT changed to '$DOCUMENT_ROOT'" >&2 fi fi @@ -157,7 +187,7 @@ trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs - # redirect logs to STDERR; write "tail ..." to the shared pipe if it exits echo "Starting log redirection..." >&2 -( touch "/tmp/heroku.apache2_error.$PORT.log" "/tmp/heroku.apache2_access.$PORT.log"; tail -qF -n 0 /tmp/heroku.*.$PORT.log 1>&2 || true; echo "tail heroku.*.$PORT.log" >&3; ) 3> $wait_pipe & +( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe & # start HHVM; write "hhvm" to the shared pipe if it exits echo "Starting hhvm..." >&2 ( hhvm --mode server -vServer.Type=fastcgi -vServer.FileSocket=/tmp/heroku.fcgi.$PORT.sock -c "$php_config" || true; echo "hhvm" >&3; ) 3> $wait_pipe & diff --git a/bin/heroku-hhvm-nginx b/bin/heroku-hhvm-nginx index f01f71f47..50e256b0d 100755 --- a/bin/heroku-hhvm-nginx +++ b/bin/heroku-hhvm-nginx @@ -4,8 +4,10 @@ set -o pipefail # fail harder set -eu -# for patterns further down +# for ${DOCUMENT_ROOT%%*(/)} pattern further down shopt -s extglob +# for detecting when -l 'logs/*.log' matches nothing +shopt -s nullglob php_passthrough() { local dir=$(dirname "$1") @@ -30,6 +32,10 @@ check_exists() { fi } +touch_log() { + mkdir -p $(dirname "$1") && touch "$1" +} + print_help() { echo "\ Boots HHVM together with Nginx on Heroku and for local development. @@ -57,11 +63,17 @@ Options: -h Display this help screen and exit. -i The path to the php.ini file to use. [default: $COMPOSER_VENDOR_DIR/heroku/heroku-buildpack-php/conf/hhvm/php.ini] + -l Path to additional log file to tail to STDERR so its + contents appear in 'heroku logs'. If the file does not + exist, it will be created. Wildcards are allowed, but + must be quoted and must match already existing files. + Note: this option can be repeated multiple times. + +All file paths must be relative to '$HEROKU_APP_DIR'. Any file name that ends in '.php' will be run through the PHP interpreter first. You may use this for templating; this is, for instance, necessary for Nginx, where environment variables cannot be referenced in configuration files. -All file paths must be relative to '$HEROKU_APP_DIR'. If you would like to use the -C and -c options together, make sure you retain the appropriate include mechanisms (see default configs for details). @@ -76,7 +88,10 @@ export PORT=${PORT:-$(( $RANDOM+1024 ))} export COMPOSER_VENDOR_DIR=$(composer config vendor-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT export COMPOSER_BIN_DIR=$(composer config bin-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT -while getopts ":C:c:i:h" opt; do +# our standard logs +logs=( "/tmp/heroku.nginx_access.$PORT.log" ) + +while getopts ":C:c:i:l:h" opt; do case $opt in C) nginx_config_include=$(check_exists "$OPTARG" "C") @@ -87,6 +102,21 @@ while getopts ":C:c:i:h" opt; do i) php_config=$(check_exists "$OPTARG" "i") ;; + l) + logarg=( $OPTARG ) # must not quote this or wildcards won't get expanded into individual values + if [[ ${#logarg[@]} -eq 0 ]]; then # we set nullglob to detect if a pattern matched nothing (then the array is empty) + echo "Pattern '$OPTARG' passed to option -l matched no files" >&2 + exit 1 + fi + for logfile in "${logarg[@]}"; do + if [[ -d "$logfile" ]]; then + echo "-l '$logfile': is a directory" >&2 + exit 1 + fi + touch_log "$logfile" || { echo "Could not touch '$logfile'; permissions problem?" >&2; exit 1; } + logs+=("$logfile") # must quote here in case a wildcard matched a file with a space in the name + done + ;; h) print_help 2>&1 exit @@ -120,7 +150,7 @@ if [[ "$#" == "1" ]]; then exit 1 else # strip trailing slashes if present - DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} + DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} # powered by extglob echo "DOCUMENT_ROOT changed to '$DOCUMENT_ROOT'" >&2 fi fi @@ -157,7 +187,7 @@ trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs - # redirect logs to STDERR; write "tail ..." to the shared pipe if it exits echo "Starting log redirection..." >&2 -( touch "/tmp/heroku.nginx_access.$PORT.log"; tail -qF -n 0 /tmp/heroku.*.$PORT.log 1>&2 || true; echo "tail heroku.*.$PORT.log" >&3; ) 3> $wait_pipe & +( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe & # start HHVM; write "hhvm" to the shared pipe if it exits echo "Starting hhvm..." >&2 ( hhvm --mode server -vServer.Type=fastcgi -vServer.FileSocket=/tmp/heroku.fcgi.$PORT.sock -c "$php_config" || true; echo "hhvm" >&3; ) 3> $wait_pipe & diff --git a/bin/heroku-php-apache2 b/bin/heroku-php-apache2 index a47a75782..1b8ddf513 100755 --- a/bin/heroku-php-apache2 +++ b/bin/heroku-php-apache2 @@ -4,8 +4,10 @@ set -o pipefail # fail harder set -eu -# for patterns further down +# for ${DOCUMENT_ROOT%%*(/)} pattern further down shopt -s extglob +# for detecting when -l 'logs/*.log' matches nothing +shopt -s nullglob php_passthrough() { local dir=$(dirname "$1") @@ -30,6 +32,10 @@ check_exists() { fi } +touch_log() { + mkdir -p $(dirname "$1") && touch "$1" +} + print_help() { echo "\ Boots PHP-FPM together with Apache2 on Heroku and for local development. @@ -62,12 +68,18 @@ Options: -h Display this help screen and exit. -i The path to the php.ini file to use. [default: $COMPOSER_VENDOR_DIR/heroku/heroku-buildpack-php/conf/php/php.ini] + -l Path to additional log file to tail to STDERR so its + contents appear in 'heroku logs'. If the file does not + exist, it will be created. Wildcards are allowed, but + must be quoted and must match already existing files. + Note: this option can be repeated multiple times. + +All file paths must be relative to '$HEROKU_APP_DIR'. Any file name that ends in '.php' will be run through the PHP interpreter first. You may use this for templating although this is less useful than e.g. for Nginx where unlike in Apache2, you cannot reference environment variables in config files using a '\${VARNAME}' syntax. -All file paths must be relative to '$HEROKU_APP_DIR'. If you would like to use the -C and -c or -F and -f options together, make sure you retain the appropriate include mechanisms (see default configs for details). @@ -82,7 +94,10 @@ export PORT=${PORT:-$(( $RANDOM+1024 ))} export COMPOSER_VENDOR_DIR=$(composer config vendor-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT export COMPOSER_BIN_DIR=$(composer config bin-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT -while getopts ":C:c:F:f:i:h" opt; do +# our standard logs +logs=( "/tmp/heroku.php-fpm.$PORT.log" "/tmp/heroku.apache2_error.$PORT.log" "/tmp/heroku.apache2_access.$PORT.log" ) + +while getopts ":C:c:F:f:i:l:h" opt; do case $opt in C) httpd_config_include=$(check_exists "$OPTARG" "C") @@ -99,6 +114,21 @@ while getopts ":C:c:F:f:i:h" opt; do i) php_config=$(check_exists "$OPTARG" "i") ;; + l) + logarg=( $OPTARG ) # must not quote this or wildcards won't get expanded into individual values + if [[ ${#logarg[@]} -eq 0 ]]; then # we set nullglob to detect if a pattern matched nothing (then the array is empty) + echo "Pattern '$OPTARG' passed to option -l matched no files" >&2 + exit 1 + fi + for logfile in "${logarg[@]}"; do + if [[ -d "$logfile" ]]; then + echo "-l '$logfile': is a directory" >&2 + exit 1 + fi + touch_log "$logfile" || { echo "Could not touch '$logfile'; permissions problem?" >&2; exit 1; } + logs+=("$logfile") # must quote here in case a wildcard matched a file with a space in the name + done + ;; h) print_help 2>&1 exit @@ -134,7 +164,7 @@ if [[ "$#" == "1" ]]; then exit 1 else # strip trailing slashes if present - DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} + DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} # powered by extglob echo "DOCUMENT_ROOT changed to '$DOCUMENT_ROOT'" >&2 fi fi @@ -182,7 +212,7 @@ trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs - # redirect logs to STDERR; write "tail ..." to the shared pipe if it exits echo "Starting log redirection..." >&2 -( touch "/tmp/heroku.php-fpm.$PORT.log" "/tmp/heroku.apache2_error.$PORT.log" "/tmp/heroku.apache2_access.$PORT.log"; tail -qF -n 0 /tmp/heroku.*.$PORT.log 1>&2 || true; echo "tail heroku.*.$PORT.log" >&3; ) 3> $wait_pipe & +( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe & # start FPM; write "php-fpm" to the shared pipe if it exits echo "Starting php-fpm..." >&2 ( php-fpm --nodaemonize -y "$fpm_config" -c "$php_config" || true; echo "php-fpm" >&3; ) 3> $wait_pipe & diff --git a/bin/heroku-php-nginx b/bin/heroku-php-nginx index 9753cd4a9..aa61bc54d 100755 --- a/bin/heroku-php-nginx +++ b/bin/heroku-php-nginx @@ -4,8 +4,10 @@ set -o pipefail # fail harder set -eu -# for patterns further down +# for ${DOCUMENT_ROOT%%*(/)} pattern further down shopt -s extglob +# for detecting when -l 'logs/*.log' matches nothing +shopt -s nullglob php_passthrough() { local dir=$(dirname "$1") @@ -30,6 +32,10 @@ check_exists() { fi } +touch_log() { + mkdir -p $(dirname "$1") && touch "$1" +} + print_help() { echo "\ Boots PHP-FPM together with Nginx on Heroku and for local development. @@ -64,11 +70,17 @@ Options: -h Display this help screen and exit. -i The path to the php.ini file to use. [default: $COMPOSER_VENDOR_DIR/heroku/heroku-buildpack-php/conf/php/php.ini] + -l Path to additional log file to tail to STDERR so its + contents appear in 'heroku logs'. If the file does not + exist, it will be created. Wildcards are allowed, but + must be quoted and must match already existing files. + Note: this option can be repeated multiple times. + +All file paths must be relative to '$HEROKU_APP_DIR'. Any file name that ends in '.php' will be run through the PHP interpreter first. You may use this for templating; this is, for instance, necessary for Nginx, where environment variables cannot be referenced in configuration files. -All file paths must be relative to '$HEROKU_APP_DIR'. If you would like to use the -C and -c or -F and -f options together, make sure you retain the appropriate include mechanisms (see default configs for details). @@ -83,7 +95,10 @@ export PORT=${PORT:-$(( $RANDOM+1024 ))} export COMPOSER_VENDOR_DIR=$(composer config vendor-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT export COMPOSER_BIN_DIR=$(composer config bin-dir 2> /dev/null | tail -n 1) # tail, as composer echos outdated version warnings to STDOUT -while getopts ":C:c:F:f:i:h" opt; do +# our standard logs +logs=( "/tmp/heroku.php-fpm.$PORT.log" "/tmp/heroku.nginx_access.$PORT.log" ) + +while getopts ":C:c:F:f:i:l:h" opt; do case $opt in C) nginx_config_include=$(check_exists "$OPTARG" "C") @@ -100,6 +115,21 @@ while getopts ":C:c:F:f:i:h" opt; do i) php_config=$(check_exists "$OPTARG" "i") ;; + l) + logarg=( $OPTARG ) # must not quote this or wildcards won't get expanded into individual values + if [[ ${#logarg[@]} -eq 0 ]]; then # we set nullglob to detect if a pattern matched nothing (then the array is empty) + echo "Pattern '$OPTARG' passed to option -l matched no files" >&2 + exit 1 + fi + for logfile in "${logarg[@]}"; do + if [[ -d "$logfile" ]]; then + echo "-l '$logfile': is a directory" >&2 + exit 1 + fi + touch_log "$logfile" || { echo "Could not touch '$logfile'; permissions problem?" >&2; exit 1; } + logs+=("$logfile") # must quote here in case a wildcard matched a file with a space in the name + done + ;; h) print_help 2>&1 exit @@ -134,7 +164,7 @@ if [[ "$#" == "1" ]]; then exit 1 else # strip trailing slashes if present - DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} + DOCUMENT_ROOT=${DOCUMENT_ROOT%%*(/)} # powered by extglob echo "DOCUMENT_ROOT changed to '$DOCUMENT_ROOT'" >&2 fi fi @@ -182,7 +212,7 @@ trap 'trap - EXIT; echo "Going down, terminating child processes..." >&2; jobs - # redirect logs to STDERR; write "tail ..." to the shared pipe if it exits echo "Starting log redirection..." >&2 -( touch "/tmp/heroku.php-fpm.$PORT.log" "/tmp/heroku.nginx_access.$PORT.log"; tail -qF -n 0 /tmp/heroku.*.$PORT.log 1>&2 || true; echo "tail heroku.*.$PORT.log" >&3; ) 3> $wait_pipe & +( touch "${logs[@]}"; tail -qF -n 0 "${logs[@]}" 1>&2 || true; echo 'tail "${logs[@]}"' >&3; ) 3> $wait_pipe & # start FPM; write "php-fpm" to the shared pipe if it exits echo "Starting php-fpm..." >&2 ( php-fpm --nodaemonize -y "$fpm_config" -c "$php_config" || true; echo "php-fpm" >&3; ) 3> $wait_pipe &