diff --git a/.editorconfig b/.editorconfig index 74df3a01e..4794bb74b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,3 +9,6 @@ indent_size = 2 insert_final_newline = true indent_style = tab indent_size = 4 + +[*.mk] +indent_style = tab diff --git a/Makefile b/Makefile index a458414de..842539b68 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,8 @@ endif .PHONY: all install copyfiles version plugins dependencies sshcommand pluginhook docker aufs stack count dokku-installer vagrant-acl-add vagrant-dokku +include tests.mk + all: # Type "make install" to install. @@ -27,10 +29,10 @@ copyfiles: addman mkdir -p ${PLUGINS_PATH} find ${PLUGINS_PATH} -mindepth 2 -maxdepth 2 -name '.core' -printf '%h\0' | xargs -0 rm -Rf find plugins/ -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | while read plugin; do \ - rm -Rf ${PLUGINS_PATH}/$$plugin && \ - cp -R plugins/$$plugin ${PLUGINS_PATH} && \ - touch ${PLUGINS_PATH}/$$plugin/.core; \ - done + rm -Rf ${PLUGINS_PATH}/$$plugin && \ + cp -R plugins/$$plugin ${PLUGINS_PATH} && \ + touch ${PLUGINS_PATH}/$$plugin/.core; \ + done addman: mkdir -p /usr/local/share/man/man1 @@ -72,7 +74,9 @@ endif sleep 2 # give docker a moment i guess aufs: +ifndef CI lsmod | grep aufs || modprobe aufs || apt-get install -qq -y linux-image-extra-`uname -r` > /dev/null +endif stack: @echo "Start building buildstep" @@ -106,3 +110,4 @@ vagrant-acl-add: vagrant-dokku: vagrant ssh -- "sudo -H -u root bash -c 'dokku $(RUN_ARGS)'" + diff --git a/bootstrap.sh b/bootstrap.sh index 3950ef3fc..8c7b79b18 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -16,9 +16,10 @@ fi apt-get update apt-get install -qq -y git make curl software-properties-common man-db -[[ `lsb_release -sr` == "12.04" ]] && apt-get install -qq -y python-software-properties +[[ $(lsb_release -sr) == "12.04" ]] && apt-get install -qq -y python-software-properties -cd ~ && test -d dokku || git clone $DOKKU_REPO +cd ~ +test -d dokku || git clone $DOKKU_REPO cd dokku git fetch origin diff --git a/dokku b/dokku index 9680a8588..a5a9e1013 100755 --- a/dokku +++ b/dokku @@ -44,13 +44,13 @@ case "$1" in build) APP="$2"; IMAGE="dokku/$APP"; CACHE_DIR="$DOKKU_ROOT/$APP/cache" id=$(cat | docker run -i -a stdin $DOKKU_IMAGE /bin/bash -c "mkdir -p /app && tar -xC /app") - test $(docker wait $id) -eq 0 + test "$(docker wait $id)" -eq 0 docker commit $id $IMAGE > /dev/null [[ -d $CACHE_DIR ]] || mkdir $CACHE_DIR pluginhook pre-build $APP id=$(docker run -d -v $CACHE_DIR:/cache $IMAGE /build/builder) docker attach $id - test $(docker wait $id) -eq 0 + test "$(docker wait $id)" -eq 0 docker commit $id $IMAGE > /dev/null pluginhook post-build $APP ;; @@ -59,8 +59,8 @@ case "$1" in APP="$2"; IMAGE="dokku/$APP" pluginhook pre-release $APP if [[ -f "$DOKKU_ROOT/$APP/ENV" ]]; then - id=$(cat "$DOKKU_ROOT/$APP/ENV" | docker run -i -a stdin $IMAGE /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/app-env.sh") - test $(docker wait $id) -eq 0 + id=$(docker run -i -a stdin $IMAGE /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/app-env.sh" < "$DOKKU_ROOT/$APP/ENV") + test "$(docker wait $id)" -eq 0 docker commit $id $IMAGE > /dev/null fi pluginhook post-release $APP @@ -143,8 +143,8 @@ case "$1" in # temporary hack for https://github.com/progrium/dokku/issues/82 deploy:all) - for app in $(ls -d $DOKKU_ROOT/*/CONTAINER); do - APP=$(basename $(dirname $app)); + for app in $DOKKU_ROOT/*/CONTAINER; do + APP=$(basename "$(dirname $app)"); dokku deploy $APP done ;; @@ -163,7 +163,7 @@ EOF *) implemented=0 - for script in $(ls -d $PLUGIN_PATH/*/commands); do + for script in $PLUGIN_PATH/*/commands; do set +e; $script "$@" ; exit_code=$? ; set -e if [ "$exit_code" -eq "$DOKKU_NOT_IMPLEMENTED_EXIT" ]; then continue diff --git a/plugins/00_dokku-standard/backup-import b/plugins/00_dokku-standard/backup-import index eca5228b3..47ec23314 100755 --- a/plugins/00_dokku-standard/backup-import +++ b/plugins/00_dokku-standard/backup-import @@ -8,7 +8,7 @@ TARGET_DIR="$3" [[ -f $IMPORT_DIR/.sshcommand ]] && mv $IMPORT_DIR/.sshcommand $TARGET_DIR/.sshcommand if [[ -f $IMPORT_DIR/.ssh/authorized_keys ]]; then mkdir -p $TARGET_DIR/.ssh - cat $IMPORT_DIR/.ssh/authorized_keys $TARGET_DIR/.ssh/authorized_keys | uniq > $TARGET_DIR/.ssh/authorized_keys + cat $IMPORT_DIR/.ssh/authorized_keys $TARGET_DIR/.ssh/authorized_keys | uniq > tmpfile && mv tmpfile $TARGET_DIR/.ssh/authorized_keys chmod 0700 $TARGET_DIR/.ssh chmod 0600 $TARGET_DIR/.ssh/* fi diff --git a/plugins/00_dokku-standard/install b/plugins/00_dokku-standard/install index 765d258a3..518519f36 100755 --- a/plugins/00_dokku-standard/install +++ b/plugins/00_dokku-standard/install @@ -2,7 +2,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x if [[ ! -f "$DOKKU_ROOT/HOSTNAME" ]]; then - echo $(hostname -f) > $DOKKU_ROOT/HOSTNAME + hostname -f > $DOKKU_ROOT/HOSTNAME fi if [[ ! -f "$DOKKU_ROOT/VHOST" ]]; then diff --git a/plugins/backup/commands b/plugins/backup/commands index 959fa3200..3eacdde2a 100755 --- a/plugins/backup/commands +++ b/plugins/backup/commands @@ -14,7 +14,7 @@ case "$1" in : | pluginhook backup-export 1 $BACKUP_DIR | tar -cf $BACKUP_TMP_FILE --files-from - pushd $BACKUP_DIR > /dev/null - ls -d */ | grep -oE '[^/]+' > "$BACKUP_TMP_DIR/.dokku_backup_apps" + find . -maxdepth 1 -type d -not -name . | sed 's:./::g' > "$BACKUP_TMP_DIR/.dokku_backup_apps" popd > /dev/null # we want to insert the files in the root of the tar diff --git a/plugins/checks/check-deploy b/plugins/checks/check-deploy index 00346af5b..35b333ce4 100755 --- a/plugins/checks/check-deploy +++ b/plugins/checks/check-deploy @@ -56,15 +56,15 @@ sleep $WAIT # --location Follow redirects CURL_OPTIONS="-q --compressed --fail --location --max-time 30" -cat "$FILENAME" | while read PATHNAME EXPECTED ; do +while read PATHNAME EXPECTED < "$FILENAME"; do # Ignore empty lines and lines starting with # - [[ -z "$PATHNAME" || "$PATHNAME" =~ ^\# ]] && continue + [[ -z "$PATHNAME" || "$PATHNAME" =~ ^# ]] && continue URL="http://$HOSTNAME:$PORT$PATHNAME" echo "checking with: curl $CURL_OPTIONS $URL" HTML=$(curl $CURL_OPTIONS $URL) - if [[ -n "$EXPECTED" && ! "$HTML" =~ "$EXPECTED" ]] ; then + if [[ -n "$EXPECTED" && ! "$HTML" =~ $EXPECTED ]] ; then echo -e "\033[31m\033[1m$URL: expected to but did not find: \"$EXPECTED\"\033[0m" exit 1 else diff --git a/plugins/config/commands b/plugins/config/commands index 5eaa20c8c..bb46313e2 100755 --- a/plugins/config/commands +++ b/plugins/config/commands @@ -15,21 +15,21 @@ config_styled_hash () { longest="" while read -r word; do - KEY=`echo $word | cut -d"=" -f1` + KEY=$(echo $word | cut -d"=" -f1) if [ ${#KEY} -gt ${#longest} ]; then longest=$KEY fi done <<< "$vars" while read -r word; do - KEY=`echo $word | cut -d"=" -f1` - VALUE=`echo $word | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//"` + KEY=$(echo $word | cut -d"=" -f1) + VALUE=$(echo $word | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//") num_zeros=$((${#longest} - ${#KEY})) zeros=" " while [ $num_zeros -gt 0 ]; do zeros="$zeros " - num_zeros=$(($num_zeros - 1)) + num_zeros=$((num_zeros - 1)) done echo "$prefix$KEY:$zeros$VALUE" done <<< "$vars" @@ -68,7 +68,7 @@ case "$1" in config_create [[ ! -s $ENV_FILE ]] && echo "$APP has no config vars" && exit 1 - VARS=`cat $ENV_FILE | grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" | cut -d" " -f2-` + VARS=$(grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | cut -d" " -f2-) for var in "$@"; do if [[ "$var" == "--shell" ]]; then @@ -99,7 +99,7 @@ case "$1" in KEY="$3" - cat $ENV_FILE | grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" | grep "^export $KEY=" | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//" + grep -Eo "export ([a-zA-Z_][a-zA-Z0-9_]*=.*)" $ENV_FILE | grep "^export $KEY=" | cut -d"=" -f2- | sed -e "s/^'//" -e "s/'$//" ;; config:set) @@ -115,7 +115,7 @@ case "$1" in config_create ENV_ADD="" - ENV_TEMP=`cat "${ENV_FILE}"` + ENV_TEMP=$(cat "${ENV_FILE}") RESTART_APP=false shift 2 @@ -128,8 +128,8 @@ case "$1" in done for var; do - KEY=`echo ${var} | cut -d"=" -f1` - VALUE=`echo ${var} | cut -d"=" -f2-` + KEY=$(echo ${var} | cut -d"=" -f1) + VALUE=$(echo ${var} | cut -d"=" -f2-) if [[ $KEY =~ [a-zA-Z_][a-zA-Z0-9_]* ]]; then RESTART_APP=true @@ -162,7 +162,7 @@ ${var}" fi config_create - ENV_TEMP=`cat "${ENV_FILE}"` + ENV_TEMP=$(cat "${ENV_FILE}") VARS="${*:3}" for var in $VARS; do diff --git a/plugins/git/commands b/plugins/git/commands index 9ddbd2855..ec5a452be 100755 --- a/plugins/git/commands +++ b/plugins/git/commands @@ -57,7 +57,7 @@ EOF chmod +x $PRERECEIVE_HOOK fi - args=$@ + args=$* git-shell -c "$args" ;; diff --git a/plugins/nginx-vhosts/backup-import b/plugins/nginx-vhosts/backup-import index 232b2a4eb..7b6b4b77e 100755 --- a/plugins/nginx-vhosts/backup-import +++ b/plugins/nginx-vhosts/backup-import @@ -9,6 +9,6 @@ TARGET_DIR="$3" cd $IMPORT_DIR for file in */tls/server.*; do - mkdir -p $(dirname $TARGET_DIR$file) + mkdir -p "$(dirname $TARGET_DIR$file)" cp $file $TARGET_DIR$file done diff --git a/plugins/nginx-vhosts/commands b/plugins/nginx-vhosts/commands index eed58c1e7..231abf487 100755 --- a/plugins/nginx-vhosts/commands +++ b/plugins/nginx-vhosts/commands @@ -95,7 +95,7 @@ EOF [[ -t 0 ]] && echo "Tar archive containing server.crt and server.key expected on stdin" && exit 1 APP="$2" - TEMP_DIR=`mktemp -d` + TEMP_DIR=$(mktemp -d) cd $TEMP_DIR tar xvf - <&0 [[ ! -f "$TEMP_DIR/server.crt" ]] && echo "Tar archive missing server.crt" && exit 1 diff --git a/tests.mk b/tests.mk new file mode 100644 index 000000000..5138311b1 --- /dev/null +++ b/tests.mk @@ -0,0 +1,63 @@ +shellcheck: +ifeq ($(shell shellcheck > /dev/null 2>&1 ; echo $$?),127) +ifeq ($(shell uname),Darwin) + brew install shellcheck +else + sudo add-apt-repository 'deb http://archive.ubuntu.com/ubuntu trusty-backports main restricted universe multiverse' + sudo apt-get update && sudo apt-get install -y shellcheck +endif +endif + +ci-dependencies: shellcheck bats + +setup-deploy-tests: + # echo "-----> Enabling tracing" + # mkdir -p /home/dokku + # echo "export DOKKU_TRACE=1" >> /home/dokku/dokkurc + @echo "Setting dokku.me in /etc/hosts" + sudo /bin/bash -c "[[ `ping -c1 dokku.me > /dev/null 2>&1; echo $$?` -eq 0 ]] || echo \"127.0.0.1 dokku.me *.dokku.me\" >> /etc/hosts" + + @echo "-----> Generating keypair..." + mkdir -p /root/.ssh + rm -f /root/.ssh/dokku_test_rsa* + echo -e "y\n" | ssh-keygen -f /root/.ssh/dokku_test_rsa -t rsa -N '' + chmod 600 /root/.ssh/dokku_test_rsa* + + @echo "-----> Setting up ssh config..." +ifeq ($(shell ls /root/.ssh/config > /dev/null 2>&1 ; echo $$?),0) +ifeq ($(shell grep dokku.me /root/.ssh/config),) + echo "Host dokku.me \\r\\n RequestTTY yes \\r\\n IdentityFile /root/.ssh/dokku_test_rsa" >> /root/.ssh/config +endif +else + echo "Host dokku.me \\r\\n RequestTTY yes \\r\\n IdentityFile /root/.ssh/dokku_test_rsa" >> /root/.ssh/config +endif + + @echo "-----> Installing SSH public key..." + sudo sshcommand acl-remove dokku test + cat /root/.ssh/dokku_test_rsa.pub | sudo sshcommand acl-add dokku test + + @echo "-----> Intitial SSH connection to populate known_hosts..." + ssh -o StrictHostKeyChecking=no dokku@dokku.me help > /dev/null + +bats: + git clone https://github.com/sstephenson/bats.git /tmp/bats + cd /tmp/bats && sudo ./install.sh /usr/local + rm -rf /tmp/bats + +lint: + # these are disabled due to their expansive existence in the codebase. we should clean it up though + # SC2034: VAR appears unused - https://github.com/koalaman/shellcheck/wiki/SC2034 + # SC2086: Double quote to prevent globbing and word splitting - https://github.com/koalaman/shellcheck/wiki/SC2086 + @echo linting... + @$(QUIET) find . -not -path '*/\.*' | xargs file | egrep "shell|bash" | awk '{ print $$1 }' | sed 's/://g' | xargs shellcheck -e SC2034,SC2086 + +unit-tests: + @echo running unit tests... + @$(QUIET) bats tests/unit + +deploy-tests: + @echo running deploy tests... + # @$(QUIET) bats tests/deploy + cd tests && ./test_deploy ./apps/go dokku.me + +test: lint setup-deploy-tests unit-tests deploy-tests diff --git a/tests/apps/config/check_deploy b/tests/apps/config/check_deploy index 57e2a697a..6dbfb7c2d 100755 --- a/tests/apps/config/check_deploy +++ b/tests/apps/config/check_deploy @@ -9,7 +9,7 @@ test_url () { path="$1" expected_output="$2" url="$base_url$path" - output="$(curl -s $url)" - echo $output + output="$(curl -s "$url")" + echo "$output" test "$output" == "$expected_output" -} \ No newline at end of file +} diff --git a/tests/apps/config/post-deploy b/tests/apps/config/post-deploy index 440051a2c..a886db06b 100755 --- a/tests/apps/config/post-deploy +++ b/tests/apps/config/post-deploy @@ -4,5 +4,5 @@ set -ex; REMOTE=$1 REPO=$2 -ssh $REMOTE config:set $REPO CONFTEST=config-test HELLO=\"Hello world\" +ssh "$REMOTE" config:set "$REPO" CONFTEST=config-test HELLO=\"Hello world\" diff --git a/tests/apps/gitsubmodules/Procfile b/tests/apps/gitsubmodules/Procfile index ef9bb41c0..b2773f7ab 100644 --- a/tests/apps/gitsubmodules/Procfile +++ b/tests/apps/gitsubmodules/Procfile @@ -1 +1 @@ -web: node node-js-sample/web.js +web: node node-js-sample/index.js diff --git a/tests/apps/gitsubmodules/check_deploy b/tests/apps/gitsubmodules/check_deploy index 2fdc00cf6..9df50a1dd 100755 --- a/tests/apps/gitsubmodules/check_deploy +++ b/tests/apps/gitsubmodules/check_deploy @@ -1,2 +1,5 @@ #!/bin/bash -set -e; output="$(curl -s $1)"; echo $output; test "$output" == "Hello World!" \ No newline at end of file +set -ex +echo "curl -s $1" +curl -s -S $1 +output="$(curl -s $1)"; echo $output; test "$output" == "Hello World!" diff --git a/tests/apps/go/check_deploy b/tests/apps/go/check_deploy index b75487a8e..ec2a725de 100755 --- a/tests/apps/go/check_deploy +++ b/tests/apps/go/check_deploy @@ -1,2 +1,2 @@ #!/bin/bash -set -e; test "$(curl -s $1)" == "go" \ No newline at end of file +set -e; test "$(curl -s "$1")" == "go" diff --git a/tests/apps/multi/check_deploy b/tests/apps/multi/check_deploy index 2a595019c..c07594a6d 100755 --- a/tests/apps/multi/check_deploy +++ b/tests/apps/multi/check_deploy @@ -1,2 +1,2 @@ #!/bin/bash -set -e; curl -s $1 | grep -q "Heroku Multi Buildpack on Dokku" +set -e; curl -s "$1" | grep -q "Heroku Multi Buildpack on Dokku" diff --git a/tests/apps/nodejs-express/check_deploy b/tests/apps/nodejs-express/check_deploy index d0bbf9c84..ef07f38a9 100755 --- a/tests/apps/nodejs-express/check_deploy +++ b/tests/apps/nodejs-express/check_deploy @@ -1,2 +1,2 @@ #!/bin/bash -set -e; output="$(curl -s $1)"; echo $output; test "$output" == "nodejs/express" \ No newline at end of file +set -e; output="$(curl -s "$1")"; echo "$output"; test "$output" == "nodejs/express" diff --git a/tests/apps/php/check_deploy b/tests/apps/php/check_deploy index c3fdb6bf5..049d32714 100755 --- a/tests/apps/php/check_deploy +++ b/tests/apps/php/check_deploy @@ -1,2 +1,2 @@ #!/bin/bash -set -e; output="$(curl -s $1)"; echo $output; test "$output" == "