From 946756bd437c4ab029b427de2c56e15a938fa848 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 12 Jun 2016 19:58:38 -0400 Subject: [PATCH 01/12] Move git functions into sourceable functions file --- plugins/git/commands | 126 +---------------------------------------- plugins/git/functions | 127 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 125 deletions(-) create mode 100755 plugins/git/functions diff --git a/plugins/git/commands b/plugins/git/commands index f7f409b02..25502b961 100755 --- a/plugins/git/commands +++ b/plugins/git/commands @@ -1,130 +1,6 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -source "$PLUGIN_AVAILABLE_PATH/apps/functions" -source "$PLUGIN_AVAILABLE_PATH/config/functions" - -git_build_app_repo() { - declare desc="builds local git app repo for app" - verify_app_name "$1" - local APP="$1"; local REV="$2" - - # clean up after ourselves - local GIT_BUILD_APP_REPO_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_git.XXXX") - trap 'rm -rf "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" > /dev/null' RETURN INT TERM EXIT - - - # git clone - this method creates a new git repository and adds the primary - # repo as a remote, then does a fetch depth=1 to avoid cloning - # the entire repo - local TMP_TAG="dokku/$REV" - chmod 755 "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" - unset GIT_DIR GIT_WORK_TREE - pushd "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" > /dev/null - [[ ! -d "$DOKKU_ROOT/$APP" ]] && apps_create "$APP" - GIT_DIR="$DOKKU_ROOT/$APP" git tag -d "$TMP_TAG" &> /dev/null || true - GIT_DIR="$DOKKU_ROOT/$APP" git tag "$TMP_TAG" "$REV" &> /dev/null - git init &> /dev/null - git config advice.detachedHead false - git remote add origin "$DOKKU_ROOT/$APP" &> /dev/null - git fetch --depth=1 origin "refs/tags/$TMP_TAG" &> /dev/null - git reset --hard FETCH_HEAD &> /dev/null - git submodule update --init --recursive &> /dev/null - GIT_DIR="$DOKKU_ROOT/$APP" git tag -d "$TMP_TAG" &> /dev/null || true - find -name .git -prune -exec rm -rf {} \; > /dev/null - - if [[ -f Dockerfile ]] && [[ "$([[ -f .env ]] && grep -q BUILDPACK_URL .env; echo $?)" != "0" ]] && [[ ! -f ".buildpacks" ]] && [[ -z $(config_get "$APP" BUILDPACK_URL || true) ]]; then - plugn trigger pre-receive-app "$APP" "dockerfile" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV" - dokku receive "$APP" "dockerfile" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" - else - plugn trigger pre-receive-app "$APP" "herokuish" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV" - dokku receive "$APP" "herokuish" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" - fi -} - -git_hook_cmd() { - declare desc="kick off receive-app trigger from git prereceive hook" - local cmd="git-hook" - local APP="$2" - - local oldrev newrev refname - while read -r oldrev newrev refname; do - # Only run this script for the master branch. You can remove this - # if block if you wish to run it for others as well. - if [[ $refname = "refs/heads/master" ]]; then - # broken out into plugin so we might support other methods to receive an app - # shellcheck disable=SC2086 - plugn trigger receive-app $APP $newrev - else - if [[ $(find "$PLUGIN_PATH"/enabled/*/receive-branch 2>/dev/null | wc -l) != 0 ]]; then - # shellcheck disable=SC2086 - plugn trigger receive-branch $APP $newrev $refname - else - echo $'\e[1G\e[K'"-----> WARNING: deploy did not complete, you must push to master." - echo $'\e[1G\e[K'"-----> for example, try 'git push ${refname/refs\/heads\/}:master'" - fi - fi - done -} - -git_upload_pack_cmd() { - declare desc="executes git-upload-pack" - local cmd="git-upload-pack" - local APP="$(echo "$2" | perl -pe 's/(?/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG" - - shift 1 - flock -o "$APP_BUILD_LOCK" dokku git-build-locked "$@" -} - -git_build_locked_cmd() { - declare desc="setup and call git_build_app_repo" - local cmd="git-build-locked" - local APP="$2" - if [[ $# -ge 3 ]]; then - local REF="$3" - else - local REF=$(< "$DOKKU_ROOT/$APP/refs/heads/master") - fi - # shellcheck disable=SC2086 - git_build_app_repo $APP $REF -} - -git_glob_cmd() { - declare desc="catch-all for any other git-* commands" - local cmd="git-*" - local APP="$(echo "$2" | perl -pe 's/(? /dev/null - local PRERECEIVE_HOOK="$APP_PATH/hooks/pre-receive" - cat > "$PRERECEIVE_HOOK" < /dev/null' RETURN INT TERM EXIT + + + # git clone - this method creates a new git repository and adds the primary + # repo as a remote, then does a fetch depth=1 to avoid cloning + # the entire repo + local TMP_TAG="dokku/$REV" + chmod 755 "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" + unset GIT_DIR GIT_WORK_TREE + pushd "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" > /dev/null + [[ ! -d "$DOKKU_ROOT/$APP" ]] && apps_create "$APP" + GIT_DIR="$DOKKU_ROOT/$APP" git tag -d "$TMP_TAG" &> /dev/null || true + GIT_DIR="$DOKKU_ROOT/$APP" git tag "$TMP_TAG" "$REV" &> /dev/null + git init &> /dev/null + git config advice.detachedHead false + git remote add origin "$DOKKU_ROOT/$APP" &> /dev/null + git fetch --depth=1 origin "refs/tags/$TMP_TAG" &> /dev/null + git reset --hard FETCH_HEAD &> /dev/null + git submodule update --init --recursive &> /dev/null + GIT_DIR="$DOKKU_ROOT/$APP" git tag -d "$TMP_TAG" &> /dev/null || true + find -name .git -prune -exec rm -rf {} \; > /dev/null + + if [[ -f Dockerfile ]] && [[ "$([[ -f .env ]] && grep -q BUILDPACK_URL .env; echo $?)" != "0" ]] && [[ ! -f ".buildpacks" ]] && [[ -z $(config_get "$APP" BUILDPACK_URL || true) ]]; then + plugn trigger pre-receive-app "$APP" "dockerfile" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV" + dokku receive "$APP" "dockerfile" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" + else + plugn trigger pre-receive-app "$APP" "herokuish" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV" + dokku receive "$APP" "herokuish" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" + fi +} + +git_hook_cmd() { + declare desc="kick off receive-app trigger from git prereceive hook" + local cmd="git-hook" + local APP="$2" + + local oldrev newrev refname + while read -r oldrev newrev refname; do + # Only run this script for the master branch. You can remove this + # if block if you wish to run it for others as well. + if [[ $refname = "refs/heads/master" ]]; then + # broken out into plugin so we might support other methods to receive an app + # shellcheck disable=SC2086 + plugn trigger receive-app $APP $newrev + else + if [[ $(find "$PLUGIN_PATH"/enabled/*/receive-branch 2>/dev/null | wc -l) != 0 ]]; then + # shellcheck disable=SC2086 + plugn trigger receive-branch $APP $newrev $refname + else + echo $'\e[1G\e[K'"-----> WARNING: deploy did not complete, you must push to master." + echo $'\e[1G\e[K'"-----> for example, try 'git push ${refname/refs\/heads\/}:master'" + fi + fi + done +} + +git_upload_pack_cmd() { + declare desc="executes git-upload-pack" + local cmd="git-upload-pack" + local APP="$(echo "$2" | perl -pe 's/(?/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG" + + shift 1 + flock -o "$APP_BUILD_LOCK" dokku git-build-locked "$@" +} + +git_build_locked_cmd() { + declare desc="setup and call git_build_app_repo" + local cmd="git-build-locked" + local APP="$2" + if [[ $# -ge 3 ]]; then + local REF="$3" + else + local REF=$(< "$DOKKU_ROOT/$APP/refs/heads/master") + fi + # shellcheck disable=SC2086 + git_build_app_repo $APP $REF +} + +git_glob_cmd() { + declare desc="catch-all for any other git-* commands" + local cmd="git-*" + local APP="$(echo "$2" | perl -pe 's/(? /dev/null + local PRERECEIVE_HOOK="$APP_PATH/hooks/pre-receive" + cat > "$PRERECEIVE_HOOK" < Date: Sun, 12 Jun 2016 20:18:07 -0400 Subject: [PATCH 02/12] Remove use of dokku binary from git plugin --- plugins/git/receive-app | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/git/receive-app b/plugins/git/receive-app index 162fe5172..1af0457d2 100755 --- a/plugins/git/receive-app +++ b/plugins/git/receive-app @@ -1,18 +1,20 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/git/functions" -git_receive_app(){ +git_receive_app() { declare desc="git receive-app plugin trigger" local trigger="git_receive_app" local APP="$1"; local REV="$2" + local cmd="git-build" # Don't trigger git build if there is no git repository. if [[ ! -d "$DOKKU_ROOT/$APP/refs" ]]; then true else # shellcheck disable=SC2086 - dokku git-build $APP $REV + git_build_cmd $cmd $APP $REV fi } From aca2540651a256dc5bcc887fb1a72f592e2010e0 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 12 Jun 2016 20:22:53 -0400 Subject: [PATCH 03/12] Move tar functions into sourceable functions file --- plugins/tar/functions | 70 ++++++++++++++++++++++++++++ plugins/tar/subcommands/build | 15 +----- plugins/tar/subcommands/build-locked | 36 +------------- plugins/tar/subcommands/from | 12 +---- plugins/tar/subcommands/in | 12 +---- 5 files changed, 74 insertions(+), 71 deletions(-) create mode 100755 plugins/tar/functions diff --git a/plugins/tar/functions b/plugins/tar/functions new file mode 100755 index 000000000..10a935ed4 --- /dev/null +++ b/plugins/tar/functions @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" + +tar_build_cmd() { + declare desc="calls tar:build-locked via command line" + local cmd="tar:build" + + verify_app_name "$2" + local APP="$2"; local APP_BUILD_LOCK="$DOKKU_ROOT/$APP/.build.lock" + local APP_BUILD_LOCK_MSG="$APP is currently being deployed or locked. Waiting..." + [[ $(flock -n "$APP_BUILD_LOCK" true &>/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG" + + shift 1 + flock -o "$APP_BUILD_LOCK" dokku tar:build-locked "$@" +} + +tar_build_locked_cmd() { + declare desc="builds apps from tarball via command line" + local cmd="tar:build-locked" + local APP="$2" + + verify_app_name "$2" + shift 2 + + # clean up after ourselves + local TAR_BUILD_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_tar.XXXX") + trap 'rm -rf "$TAR_BUILD_TMP_WORK_DIR" > /dev/null' RETURN INT TERM EXIT + + # extract tar file + chmod 755 "$TAR_BUILD_TMP_WORK_DIR" + pushd "$TAR_BUILD_TMP_WORK_DIR" > /dev/null + + # Detect a common prefix that all files in the tar have, and strip off each directory found in it + local COMMON_PREFIX=$(tar -tf "$DOKKU_ROOT/$APP/src.tar" | sed -e 'N;s/^\(.*\).*\n\1.*$/\1\n\1/;D') + local BOGUS_PARTS=$(echo "$COMMON_PREFIX " | awk 'BEGIN{FS="/"} {print NF-1}') + + dokku_log_info1_quiet "Striping $BOGUS_PARTS worth of directories from tarball" + + tar -x -C "$TAR_BUILD_TMP_WORK_DIR" -f "$DOKKU_ROOT/$APP/src.tar" --strip-components="$BOGUS_PARTS" + chmod -R u+r "$TAR_BUILD_TMP_WORK_DIR" + + if [[ -f Dockerfile ]] && [[ "$([[ -f .env ]] && grep -q BUILDPACK_URL .env; echo $?)" != "0" ]] && [[ ! -f ".buildpacks" ]]; then + plugn trigger pre-receive-app "$APP" "dockerfile" "$TAR_BUILD_TMP_WORK_DIR" + dokku receive "$APP" "dockerfile" "$TAR_BUILD_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" + else + plugn trigger pre-receive-app "$APP" "herokuish" "$TAR_BUILD_TMP_WORK_DIR" + dokku receive "$APP" "herokuish" "$TAR_BUILD_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" + fi +} + +tar_from_cmd() { + declare desc="deploys app from tarball at URL via command line" + local cmd="tar:from" + verify_app_name "$2" + local APP=$2 + local URL=$3 + shift 3 + curl -# --insecure -L "$URL" | dokku tar:in "$APP" "$@" +} + +tar_in_cmd() { + declare desc="deploys app from tarball on STDIN via command line" + local cmd="tar:in" + local APP="$2" + + verify_app_name "$2" + tee "$DOKKU_ROOT/$APP/src.tar" | wc -c + plugn trigger receive-app "$APP" +} diff --git a/plugins/tar/subcommands/build b/plugins/tar/subcommands/build index ecb0b96e0..2fbab85a0 100755 --- a/plugins/tar/subcommands/build +++ b/plugins/tar/subcommands/build @@ -1,18 +1,5 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" - -tar_build_cmd() { - declare desc="calls tar:build-locked via command line" - local cmd="tar:build" - - verify_app_name "$2" - local APP="$2"; local APP_BUILD_LOCK="$DOKKU_ROOT/$APP/.build.lock" - local APP_BUILD_LOCK_MSG="$APP is currently being deployed or locked. Waiting..." - [[ $(flock -n "$APP_BUILD_LOCK" true &>/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG" - - shift 1 - flock -o "$APP_BUILD_LOCK" dokku tar:build-locked "$@" -} +source "$PLUGIN_AVAILABLE_PATH/tar/functions" tar_build_cmd "$@" diff --git a/plugins/tar/subcommands/build-locked b/plugins/tar/subcommands/build-locked index ace52fe92..e660d95f1 100755 --- a/plugins/tar/subcommands/build-locked +++ b/plugins/tar/subcommands/build-locked @@ -1,39 +1,5 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" - -tar_build_locked_cmd() { - declare desc="builds apps from tarball via command line" - local cmd="tar:build-locked" - local APP="$2" - - verify_app_name "$2" - shift 2 - - # clean up after ourselves - local TAR_BUILD_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_tar.XXXX") - trap 'rm -rf "$TAR_BUILD_TMP_WORK_DIR" > /dev/null' RETURN INT TERM EXIT - - # extract tar file - chmod 755 "$TAR_BUILD_TMP_WORK_DIR" - pushd "$TAR_BUILD_TMP_WORK_DIR" > /dev/null - - # Detect a common prefix that all files in the tar have, and strip off each directory found in it - local COMMON_PREFIX=$(tar -tf "$DOKKU_ROOT/$APP/src.tar" | sed -e 'N;s/^\(.*\).*\n\1.*$/\1\n\1/;D') - local BOGUS_PARTS=$(echo "$COMMON_PREFIX " | awk 'BEGIN{FS="/"} {print NF-1}') - - dokku_log_info1_quiet "Striping $BOGUS_PARTS worth of directories from tarball" - - tar -x -C "$TAR_BUILD_TMP_WORK_DIR" -f "$DOKKU_ROOT/$APP/src.tar" --strip-components="$BOGUS_PARTS" - chmod -R u+r "$TAR_BUILD_TMP_WORK_DIR" - - if [[ -f Dockerfile ]] && [[ "$([[ -f .env ]] && grep -q BUILDPACK_URL .env; echo $?)" != "0" ]] && [[ ! -f ".buildpacks" ]]; then - plugn trigger pre-receive-app "$APP" "dockerfile" "$TAR_BUILD_TMP_WORK_DIR" - dokku receive "$APP" "dockerfile" "$TAR_BUILD_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" - else - plugn trigger pre-receive-app "$APP" "herokuish" "$TAR_BUILD_TMP_WORK_DIR" - dokku receive "$APP" "herokuish" "$TAR_BUILD_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" - fi -} +source "$PLUGIN_AVAILABLE_PATH/tar/functions" tar_build_locked_cmd "$@" diff --git a/plugins/tar/subcommands/from b/plugins/tar/subcommands/from index c51b74fbf..9e66df76a 100755 --- a/plugins/tar/subcommands/from +++ b/plugins/tar/subcommands/from @@ -1,15 +1,5 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" - -tar_from_cmd() { - declare desc="deploys app from tarball at URL via command line" - local cmd="tar:from" - verify_app_name "$2" - local APP=$2 - local URL=$3 - shift 3 - curl -# --insecure -L "$URL" | dokku tar:in "$APP" "$@" -} +source "$PLUGIN_AVAILABLE_PATH/tar/functions" tar_from_cmd "$@" diff --git a/plugins/tar/subcommands/in b/plugins/tar/subcommands/in index 7bbdb5f87..d39277d75 100755 --- a/plugins/tar/subcommands/in +++ b/plugins/tar/subcommands/in @@ -1,15 +1,5 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" - -tar_in_cmd() { - declare desc="deploys app from tarball on STDIN via command line" - local cmd="tar:in" - local APP="$2" - - verify_app_name "$2" - tee "$DOKKU_ROOT/$APP/src.tar" | wc -c - plugn trigger receive-app "$APP" -} +source "$PLUGIN_AVAILABLE_PATH/tar/functions" tar_in_cmd "$@" From 1216a5e65aeccc896fc1b8d445422ef1c500df91 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 12 Jun 2016 20:24:10 -0400 Subject: [PATCH 04/12] Remove use of dokku binary from tar plugin --- plugins/tar/functions | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/tar/functions b/plugins/tar/functions index 10a935ed4..44effc01a 100755 --- a/plugins/tar/functions +++ b/plugins/tar/functions @@ -12,7 +12,7 @@ tar_build_cmd() { [[ $(flock -n "$APP_BUILD_LOCK" true &>/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG" shift 1 - flock -o "$APP_BUILD_LOCK" dokku tar:build-locked "$@" + flock -o "$APP_BUILD_LOCK" tar_build_locked_cmd "tar:build-locked" "$@" } tar_build_locked_cmd() { @@ -56,7 +56,7 @@ tar_from_cmd() { local APP=$2 local URL=$3 shift 3 - curl -# --insecure -L "$URL" | dokku tar:in "$APP" "$@" + curl -# --insecure -L "$URL" | tar_in_cmd "tar:in" "$APP" "$@" } tar_in_cmd() { From 2ece0e1bf808511ec05b7e8d8da1f8467233b5da Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Jun 2016 15:25:09 -0700 Subject: [PATCH 05/12] move DOKKU_NGINX_SSL_PORT setting to correct logic block --- plugins/nginx-vhosts/functions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/nginx-vhosts/functions b/plugins/nginx-vhosts/functions index 1964b45b9..11dba3d0a 100755 --- a/plugins/nginx-vhosts/functions +++ b/plugins/nginx-vhosts/functions @@ -88,8 +88,8 @@ configure_nginx_ports() { else local NGINX_SSL_PORT=443 fi - fi config_set --no-restart "$APP" DOKKU_NGINX_SSL_PORT="$NGINX_SSL_PORT" + fi fi if [[ -z "$DOKKU_PROXY_PORT_MAP" ]]; then if [[ -n "$RAW_TCP_PORTS" ]]; then From 4f8c1b64c9483a08077cd6cc7fbf621922710b96 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Jun 2016 15:25:46 -0700 Subject: [PATCH 06/12] implement central deploy lock and use in tar plugin --- plugins/common/functions | 27 ++++++++++++++++++ plugins/tar/functions | 42 +++++++++------------------- plugins/tar/receive-app | 6 +++- plugins/tar/subcommands/build | 5 ---- plugins/tar/subcommands/build-locked | 5 ---- 5 files changed, 45 insertions(+), 40 deletions(-) delete mode 100755 plugins/tar/subcommands/build delete mode 100755 plugins/tar/subcommands/build-locked diff --git a/plugins/common/functions b/plugins/common/functions index 9fb90c6d1..e59ac6d4a 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -820,3 +820,30 @@ merge_dedupe_list() { local merged_list="$(tr "$delimiter" $'\n' <<< "$input_lists" | sort | uniq | xargs)" echo "$merged_list" } + +acquire_app_deploy_lock() { + declare desc="acquire advisory lock for use in git/tar deploys" + local APP="$1"; verify_app_name "$APP" + local APP_DEPLOY_LOCK_FD="200" + local APP_DEPLOY_LOCK_FILE="$DOKKU_ROOT/$APP/.deploy.lock" + local APP_DEPLOY_LOCK_MSG="$APP is currently being deployed. Waiting..." + local SHOW_MSG=true + + eval "exec $APP_DEPLOY_LOCK_FD>$APP_DEPLOY_LOCK_FILE" + while [[ $(flock -n "$APP_DEPLOY_LOCK_FD" &>/dev/null ; echo $?) -ne 0 ]]; do + if [[ "$SHOW_MSG" == "true" ]]; then + echo "$APP_DEPLOY_LOCK_MSG" + SHOW_MSG=false + fi + sleep 1 + done +} + +release_app_deploy_lock() { + declare desc="release advisory lock used in git/tar deploys" + local APP="$1"; verify_app_name "$APP" + local APP_DEPLOY_LOCK_FD="200" + local APP_DEPLOY_LOCK_FILE="$DOKKU_ROOT/$APP/.deploy.lock" + + flock -u "$APP_DEPLOY_LOCK_FD" && rm -f "$APP_DEPLOY_LOCK_FILE" &> /dev/null +} diff --git a/plugins/tar/functions b/plugins/tar/functions index 44effc01a..4581677aa 100755 --- a/plugins/tar/functions +++ b/plugins/tar/functions @@ -2,26 +2,10 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -tar_build_cmd() { - declare desc="calls tar:build-locked via command line" - local cmd="tar:build" - - verify_app_name "$2" - local APP="$2"; local APP_BUILD_LOCK="$DOKKU_ROOT/$APP/.build.lock" - local APP_BUILD_LOCK_MSG="$APP is currently being deployed or locked. Waiting..." - [[ $(flock -n "$APP_BUILD_LOCK" true &>/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG" - - shift 1 - flock -o "$APP_BUILD_LOCK" tar_build_locked_cmd "tar:build-locked" "$@" -} - -tar_build_locked_cmd() { +tar_build() { declare desc="builds apps from tarball via command line" - local cmd="tar:build-locked" - local APP="$2" - - verify_app_name "$2" - shift 2 + local APP="$1"; verify_app_name "$APP" + shift 1 # clean up after ourselves local TAR_BUILD_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_tar.XXXX") @@ -49,16 +33,6 @@ tar_build_locked_cmd() { fi } -tar_from_cmd() { - declare desc="deploys app from tarball at URL via command line" - local cmd="tar:from" - verify_app_name "$2" - local APP=$2 - local URL=$3 - shift 3 - curl -# --insecure -L "$URL" | tar_in_cmd "tar:in" "$APP" "$@" -} - tar_in_cmd() { declare desc="deploys app from tarball on STDIN via command line" local cmd="tar:in" @@ -68,3 +42,13 @@ tar_in_cmd() { tee "$DOKKU_ROOT/$APP/src.tar" | wc -c plugn trigger receive-app "$APP" } + +tar_from_cmd() { + declare desc="deploys app from tarball at URL via command line" + local cmd="tar:from" + verify_app_name "$2" + local APP=$2 + local URL=$3 + shift 3 + curl -# --insecure -L "$URL" | tar_in_cmd "tar:in" "$APP" "$@" +} diff --git a/plugins/tar/receive-app b/plugins/tar/receive-app index 16f6dd5ca..4ff75f293 100755 --- a/plugins/tar/receive-app +++ b/plugins/tar/receive-app @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/tar/functions" tar_receive_app() { declare desc="tar receive-app plugin trigger" @@ -11,7 +12,10 @@ tar_receive_app() { if [[ ! -f "$DOKKU_ROOT/$APP/src.tar" ]]; then true else - dokku tar:build "$APP" + acquire_app_deploy_lock "$APP" + # shellcheck disable=SC2086 + tar_build "$@" + release_app_deploy_lock "$APP" fi } diff --git a/plugins/tar/subcommands/build b/plugins/tar/subcommands/build deleted file mode 100755 index 2fbab85a0..000000000 --- a/plugins/tar/subcommands/build +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_AVAILABLE_PATH/tar/functions" - -tar_build_cmd "$@" diff --git a/plugins/tar/subcommands/build-locked b/plugins/tar/subcommands/build-locked deleted file mode 100755 index e660d95f1..000000000 --- a/plugins/tar/subcommands/build-locked +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_AVAILABLE_PATH/tar/functions" - -tar_build_locked_cmd "$@" From fcefd4a29b1dd0fad9e320eb14a8c0174abec659 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Jun 2016 16:10:51 -0700 Subject: [PATCH 07/12] use central deploy lock in git plugin --- plugins/common/functions | 22 ++++++++++++++-------- plugins/git/commands | 8 -------- plugins/git/functions | 38 +++++++++++++------------------------- plugins/git/receive-app | 5 +++-- 4 files changed, 30 insertions(+), 43 deletions(-) diff --git a/plugins/common/functions b/plugins/common/functions index e59ac6d4a..97279f404 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -824,19 +824,25 @@ merge_dedupe_list() { acquire_app_deploy_lock() { declare desc="acquire advisory lock for use in git/tar deploys" local APP="$1"; verify_app_name "$APP" + local LOCK_TYPE="${2:-waiting}" local APP_DEPLOY_LOCK_FD="200" local APP_DEPLOY_LOCK_FILE="$DOKKU_ROOT/$APP/.deploy.lock" - local APP_DEPLOY_LOCK_MSG="$APP is currently being deployed. Waiting..." + local LOCK_WAITING_MSG="$APP is currently being deployed. Waiting..." + local LOCK_FAILED_MSG="$APP is currently being deployed. Exiting..." local SHOW_MSG=true eval "exec $APP_DEPLOY_LOCK_FD>$APP_DEPLOY_LOCK_FILE" - while [[ $(flock -n "$APP_DEPLOY_LOCK_FD" &>/dev/null ; echo $?) -ne 0 ]]; do - if [[ "$SHOW_MSG" == "true" ]]; then - echo "$APP_DEPLOY_LOCK_MSG" - SHOW_MSG=false - fi - sleep 1 - done + if [[ "$LOCK_TYPE" == "waiting" ]]; then + while [[ $(flock -n "$APP_DEPLOY_LOCK_FD" &>/dev/null ; echo $?) -ne 0 ]]; do + if [[ "$SHOW_MSG" == "true" ]]; then + echo "$LOCK_WAITING_MSG" + SHOW_MSG=false + fi + sleep 1 + done + else + flock -n "$APP_DEPLOY_LOCK_FD" &>/dev/null || dokku_log_fail "$LOCK_FAILED_MSG" + fi } release_app_deploy_lock() { diff --git a/plugins/git/commands b/plugins/git/commands index 25502b961..7df19a867 100755 --- a/plugins/git/commands +++ b/plugins/git/commands @@ -11,14 +11,6 @@ case "$1" in git_upload_pack_cmd "$@" ;; - git-build) - git_build_cmd "$@" - ;; - - git-build-locked) - git_build_locked_cmd "$@" - ;; - git-*) git_glob_cmd "$@" ;; diff --git a/plugins/git/functions b/plugins/git/functions index bd779661e..a20f8414e 100755 --- a/plugins/git/functions +++ b/plugins/git/functions @@ -13,7 +13,6 @@ git_build_app_repo() { local GIT_BUILD_APP_REPO_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_git.XXXX") trap 'rm -rf "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" > /dev/null' RETURN INT TERM EXIT - # git clone - this method creates a new git repository and adds the primary # repo as a remote, then does a fetch depth=1 to avoid cloning # the entire repo @@ -67,6 +66,19 @@ git_hook_cmd() { done } +git_build() { + declare desc="setup and call git_build_app_repo" + local APP="$1" + if [[ $# -ge 2 ]]; then + local REF="$2" + else + local REF=$(< "$DOKKU_ROOT/$APP/refs/heads/master") + fi + + # shellcheck disable=SC2086 + git_build_app_repo $APP $REF +} + git_upload_pack_cmd() { declare desc="executes git-upload-pack" local cmd="git-upload-pack" @@ -76,30 +88,6 @@ git_upload_pack_cmd() { plugn trigger git-post-pull "$APP" } -git_build_cmd() { - declare desc="lock git-build" - local cmd="git-build" - local APP="$2"; local APP_BUILD_LOCK="$DOKKU_ROOT/$APP/.build.lock" - local APP_BUILD_LOCK_MSG="$APP is currently being deployed or locked. Waiting..." - [[ $(flock -n "$APP_BUILD_LOCK" true &>/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG" - - shift 1 - flock -o "$APP_BUILD_LOCK" dokku git-build-locked "$@" -} - -git_build_locked_cmd() { - declare desc="setup and call git_build_app_repo" - local cmd="git-build-locked" - local APP="$2" - if [[ $# -ge 3 ]]; then - local REF="$3" - else - local REF=$(< "$DOKKU_ROOT/$APP/refs/heads/master") - fi - # shellcheck disable=SC2086 - git_build_app_repo $APP $REF -} - git_glob_cmd() { declare desc="catch-all for any other git-* commands" local cmd="git-*" diff --git a/plugins/git/receive-app b/plugins/git/receive-app index 1af0457d2..652bc15b2 100755 --- a/plugins/git/receive-app +++ b/plugins/git/receive-app @@ -7,14 +7,15 @@ git_receive_app() { declare desc="git receive-app plugin trigger" local trigger="git_receive_app" local APP="$1"; local REV="$2" - local cmd="git-build" # Don't trigger git build if there is no git repository. if [[ ! -d "$DOKKU_ROOT/$APP/refs" ]]; then true else + acquire_app_deploy_lock "$APP" "exclusive" # shellcheck disable=SC2086 - git_build_cmd $cmd $APP $REV + git_build $APP $REV + release_app_deploy_lock "$APP" fi } From ce3aa4b93edcf4ba786a17515ddfd2db32e1a175 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Jun 2016 16:40:35 -0700 Subject: [PATCH 08/12] remove calls to dokku binary for build/receive/release --- docs/development/plugin-triggers.md | 18 +- dokku | 7 +- plugins/00_dokku-standard/subcommands/build | 65 ---- plugins/00_dokku-standard/subcommands/deploy | 171 +---------- plugins/00_dokku-standard/subcommands/receive | 22 -- plugins/00_dokku-standard/subcommands/release | 40 --- plugins/common/functions | 287 +++++++++++++++++- plugins/config/functions | 8 +- plugins/git/functions | 4 +- plugins/tar/functions | 4 +- 10 files changed, 307 insertions(+), 319 deletions(-) delete mode 100755 plugins/00_dokku-standard/subcommands/build delete mode 100755 plugins/00_dokku-standard/subcommands/receive delete mode 100755 plugins/00_dokku-standard/subcommands/release diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md index 4b2933f44..44bb1cbcb 100644 --- a/docs/development/plugin-triggers.md +++ b/docs/development/plugin-triggers.md @@ -164,7 +164,7 @@ esac ### `docker-args-build` - Description: -- Invoked by: `dokku build` +- Invoked by: `dokku_build` - Arguments: `$APP $IMAGE_SOURCE_TYPE` - Example: @@ -300,7 +300,7 @@ nginx -t ### `post-build-buildpack` - Description: Allows you to run commands after the build image is create for a given app. Only applies to applications using buildpacks. -- Invoked by: `dokku build` +- Invoked by: `dokku_build` - Arguments: `$APP` - Example: @@ -315,7 +315,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x ### `post-build-dockerfile` - Description: Allows you to run commands after the build image is create for a given app. Only applies to applications using a dockerfile. -- Invoked by: `dokku build` +- Invoked by: `dokku_build` - Arguments: `$APP` - Example: @@ -423,7 +423,7 @@ haproxy-build-config "$APP" ### `post-release-buildpack` - Description: Allows you to run commands after environment variables are set for the release step of the deploy. Only applies to applications using buildpacks. -- Invoked by: `dokku release` +- Invoked by: `dokku_release` - Arguments: `$APP $IMAGE_TAG` - Example: @@ -450,7 +450,7 @@ docker commit $ID $IMAGE > /dev/null ### `post-release-dockerfile` - Description: Allows you to run commands after environment variables are set for the release step of the deploy. Only applies to applications using a dockerfile. -- Invoked by: `dokku release` +- Invoked by: `dokku_release` - Arguments: `$APP $IMAGE_TAG` - Example: @@ -486,7 +486,7 @@ dokku config:set --no-restart $APP MANUALLY_STOPPED=1 ### `pre-build-buildpack` - Description: Allows you to run commands before the build image is created for a given app. For instance, this can be useful to add env vars to your container. Only applies to applications using buildpacks. -- Invoked by: `dokku build` +- Invoked by: `dokku_build` - Arguments: `$APP` - Example: @@ -501,7 +501,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x ### `pre-build-dockerfile` - Description: Allows you to run commands before the build image is created for a given app. For instance, this can be useful to add env vars to your container. Only applies to applications using a dockerfile. -- Invoked by: `dokku build` +- Invoked by: `dokku_build` - Arguments: `$APP` - Example: @@ -580,7 +580,7 @@ echo "$APP" > "$TMP_WORK_DIR/dokku-is-awesome" ### `pre-release-buildpack` - Description: Allows you to run commands before environment variables are set for the release step of the deploy. Only applies to applications using buildpacks. -- Invoked by: `dokku release` +- Invoked by: `dokku_release` - Arguments: `$APP $IMAGE_TAG` - Example: @@ -607,7 +607,7 @@ docker commit $ID $IMAGE > /dev/null ### `pre-release-dockerfile` - Description: Allows you to run commands before environment variables are set for the release step of the deploy. Only applies to applications using a dockerfile. -- Invoked by: `dokku release` +- Invoked by: `dokku_release` - Arguments: `$APP $IMAGE_TAG` - Example: diff --git a/dokku b/dokku index b80742acc..4238b4f10 100755 --- a/dokku +++ b/dokku @@ -100,13 +100,10 @@ execute_dokku_cmd() { nginx|nginx:*) local PLUGIN_NAME=${PLUGIN_NAME/nginx/nginx-vhosts} ;; - receive|deploy|build|release) + deploy|delete|ls|run|cleanup) local PLUGIN_NAME="00_dokku-standard" ;; - trace|delete|ls|run|cleanup) - local PLUGIN_NAME="00_dokku-standard" - ;; - url|urls|report|version) + trace|url|urls|report|version) local PLUGIN_NAME="00_dokku-standard" ;; esac diff --git a/plugins/00_dokku-standard/subcommands/build b/plugins/00_dokku-standard/subcommands/build deleted file mode 100755 index 4df74e26b..000000000 --- a/plugins/00_dokku-standard/subcommands/build +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -source "$PLUGIN_AVAILABLE_PATH/config/functions" - -dokku_build_cmd() { - declare desc="build phase" - local cmd="build" - local APP="$2"; local IMAGE_SOURCE_TYPE="$3"; local TMP_WORK_DIR="$4"; local IMAGE=$(get_app_image_name "$APP") - verify_app_name "$APP" - - local CACHE_DIR="$DOKKU_ROOT/$APP/cache" - - eval "$(config_export app "$APP")" - pushd "$TMP_WORK_DIR" &> /dev/null - - case "$IMAGE_SOURCE_TYPE" in - herokuish) - local id=$(tar -c . | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /app && tar -xC /app") - test "$(docker wait "$id")" -eq 0 - docker commit "$id" "$IMAGE" > /dev/null - [[ -d $CACHE_DIR ]] || mkdir -p "$CACHE_DIR" - plugn trigger pre-build-buildpack "$APP" - - local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$IMAGE_SOURCE_TYPE") - [[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true " - # shellcheck disable=SC2086 - local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -v $CACHE_DIR:/cache -e CACHE_PATH=/cache $DOCKER_ARGS $IMAGE /build) - docker attach "$id" - test "$(docker wait "$id")" -eq 0 - docker commit "$id" "$IMAGE" > /dev/null - - plugn trigger post-build-buildpack "$APP" - ;; - - dockerfile) - # extract first port from Dockerfile - local DOCKERFILE_PORTS=$(get_dockerfile_exposed_ports Dockerfile) - [[ -n "$DOCKERFILE_PORTS" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_PORTS="$DOCKERFILE_PORTS" - - # extract ENTRYPOINT/CMD from Dockerfile - local DOCKERFILE_ENTRYPOINT=$(extract_directive_from_dockerfile Dockerfile ENTRYPOINT) - [[ -n "$DOCKERFILE_ENTRYPOINT" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_ENTRYPOINT="$DOCKERFILE_ENTRYPOINT" - local DOCKERFILE_CMD=$(extract_directive_from_dockerfile Dockerfile CMD) - [[ -n "$DOCKERFILE_CMD" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_CMD="$DOCKERFILE_CMD" - plugn trigger pre-build-dockerfile "$APP" - - [[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache" - local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$IMAGE_SOURCE_TYPE") - # strip --volume and -v args from DOCKER_ARGS - local DOCKER_ARGS=$(sed -e "s/--volume=[[:graph:]]\+[[:blank:]]\?//g" -e "s/-v[[:blank:]]\?[[:graph:]]\+[[:blank:]]\?//g" <<< "$DOCKER_ARGS") - - # shellcheck disable=SC2086 - docker build $DOCKER_ARGS $DOKKU_DOCKER_BUILD_OPTS -t $IMAGE . - - plugn trigger post-build-dockerfile "$APP" - ;; - - *) - dokku_log_fail "Building image source type $IMAGE_SOURCE_TYPE not supported!" - ;; - esac -} - -dokku_build_cmd "$@" diff --git a/plugins/00_dokku-standard/subcommands/deploy b/plugins/00_dokku-standard/subcommands/deploy index 68f1a2252..888165a4c 100755 --- a/plugins/00_dokku-standard/subcommands/deploy +++ b/plugins/00_dokku-standard/subcommands/deploy @@ -1,175 +1,6 @@ #!/usr/bin/env bash set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -source "$PLUGIN_AVAILABLE_PATH/checks/functions" -source "$PLUGIN_AVAILABLE_PATH/config/functions" -source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" - -dokku_deploy_cmd() { - declare desc="deploy phase" - local cmd="deploy" - [[ -z $2 ]] && dokku_log_fail "Please specify an app to deploy" - local APP="$2"; local IMAGE_TAG="$3"; local IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG") - verify_app_name "$APP" - plugn trigger pre-deploy "$APP" "$IMAGE_TAG" - - is_image_herokuish_based "$IMAGE" && local DOKKU_HEROKUISH=true - local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" - local oldids=$(get_app_container_ids "$APP") - - local DOKKU_DEFAULT_DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG") - local DOKKU_IS_APP_PROXY_ENABLED="$(is_app_proxy_enabled "$APP")" - local DOKKU_DOCKER_STOP_TIMEOUT="$(config_get "$APP" DOKKU_DOCKER_STOP_TIMEOUT || true)" - [[ $DOKKU_DOCKER_STOP_TIMEOUT ]] && DOCKER_STOP_TIME_ARG="--time=${DOKKU_DOCKER_STOP_TIMEOUT}" - - local line; local PROC_TYPE; local PROC_COUNT; local CONTAINER_INDEX - while read -r line || [[ -n "$line" ]]; do - [[ "$line" =~ ^#.* ]] && continue - line="$(strip_inline_comments "$line")" - PROC_TYPE=${line%%=*} - PROC_COUNT=${line#*=} - CONTAINER_INDEX=1 - - if [[ "$(is_app_proctype_checks_disabled "$APP" "$PROC_TYPE")" == "true" ]]; then - dokku_log_info1 "zero downtime is disabled for app ($APP.$PROC_TYPE). stopping currently running containers" - local cid proctype_oldids="$(get_app_container_ids "$APP" "$PROC_TYPE")" - for cid in $proctype_oldids; do - dokku_log_info2 "stopping $APP.$PROC_TYPE ($cid)" - # shellcheck disable=SC2086 - docker stop $DOCKER_STOP_TIME_ARG "$cid" &> /dev/null - done - fi - - while [[ $CONTAINER_INDEX -le $PROC_COUNT ]]; do - local id=""; local port=""; local ipaddr="" - local DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_TYPE.$CONTAINER_INDEX" - local DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_TYPE.$CONTAINER_INDEX" - local DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_TYPE.$CONTAINER_INDEX" - - # start the app - local DOCKER_ARGS="$DOKKU_DEFAULT_DOCKER_ARGS" - local DOCKER_ARGS+=" -e DYNO='$PROC_TYPE.$CONTAINER_INDEX' " - [[ "$DOKKU_TRACE" ]] && local DOCKER_ARGS+=" -e TRACE=true " - - [[ -n "$DOKKU_HEROKUISH" ]] && local START_CMD="/start $PROC_TYPE" - - if [[ -z "$DOKKU_HEROKUISH" ]]; then - local DOKKU_DOCKERFILE_PORTS=($(config_get "$APP" DOKKU_DOCKERFILE_PORTS || true)) - local DOKKU_DOCKERFILE_START_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_START_CMD || true) - local DOKKU_PROCFILE_START_CMD=$(get_cmd_from_procfile "$APP" "$PROC_TYPE") - local START_CMD=${DOKKU_DOCKERFILE_START_CMD:-$DOKKU_PROCFILE_START_CMD} - fi - - if [[ "$PROC_TYPE" == "web" ]]; then - if [[ -z "${DOKKU_DOCKERFILE_PORTS[*]}" ]]; then - local port=5000 - local DOKKU_DOCKER_PORT_ARGS+="-p $port" - else - local p - for p in ${DOKKU_DOCKERFILE_PORTS[*]};do - if [[ ! "$p" =~ .*udp.* ]]; then - # set port to first non-udp port - local p=${p//\/tcp} - local port=${port:="$p"} - fi - local DOKKU_DOCKER_PORT_ARGS+=" -p $p " - done - fi - if [[ "$DOKKU_IS_APP_PROXY_ENABLED" == "true" ]]; then - # shellcheck disable=SC2086 - local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD) - local ipaddr=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$id") - # Docker < 1.9 compatibility - if [[ -z $ipaddr ]]; then - local ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$id") - fi - else - # shellcheck disable=SC2086 - local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD) - local port=$(docker port "$id" "$port" | sed 's/[0-9.]*://') - local ipaddr=127.0.0.1 - fi - else - # shellcheck disable=SC2086 - local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOCKER_ARGS $IMAGE $START_CMD) - fi - - kill_new() { - declare desc="wrapper function to kill newly started app container" - local id="$1" - docker inspect "$id" &> /dev/null && docker stop "$id" > /dev/null && docker kill "$id" &> /dev/null - trap - INT TERM EXIT - kill -9 $$ - } - - # run checks first, then post-deploy hooks, which switches proxy traffic - trap 'kill_new $id' INT TERM EXIT - if [[ "$(is_app_proctype_checks_disabled "$APP" "$PROC_TYPE")" == "false" ]]; then - dokku_log_info1 "Attempting pre-flight checks" - plugn trigger check-deploy "$APP" "$id" "$PROC_TYPE" "$port" "$ipaddr" - fi - trap - INT TERM EXIT - - # now using the new container - [[ -n "$id" ]] && echo "$id" > "$DOKKU_CONTAINER_ID_FILE" - [[ -n "$ipaddr" ]] && echo "$ipaddr" > "$DOKKU_IP_FILE" - [[ -n "$port" ]] && echo "$port" > "$DOKKU_PORT_FILE" - - # cleanup pre-migration files - rm -f "$DOKKU_ROOT/$APP/CONTAINER" "$DOKKU_ROOT/$APP/IP" "$DOKKU_ROOT/$APP/PORT" - - local CONTAINER_INDEX=$(( CONTAINER_INDEX + 1 )) - done - # cleanup when we scale down - if [[ "$PROC_COUNT" == 0 ]]; then - local CONTAINER_IDX_OFFSET=0 - else - local CONTAINER_IDX_OFFSET=$((PROC_COUNT + 1)) - fi - local container_state_filetype - for container_state_filetype in CONTAINER IP PORT; do - cd "$DOKKU_ROOT/$APP" - find . -maxdepth 1 -name "$container_state_filetype.$PROC_TYPE.*" -printf "%f\n" | sort -t . -k 3 -n | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f - done - done < "$DOKKU_SCALE_FILE" - - dokku_log_info1 "Running post-deploy" - plugn trigger post-deploy "$APP" "$port" "$ipaddr" "$IMAGE_TAG" - - # kill the old container - if [[ -n "$oldids" ]]; then - - if [[ -z "$DOKKU_WAIT_TO_RETIRE" ]]; then - local DOKKU_APP_DOKKU_WAIT_TO_RETIRE=$(config_get "$APP" DOKKU_WAIT_TO_RETIRE || true) - local DOKKU_GLOBAL_DOKKU_WAIT_TO_RETIRE=$(config_get --global DOKKU_WAIT_TO_RETIRE || true) - local DOKKU_WAIT_TO_RETIRE=${DOKKU_APP_DOKKU_WAIT_TO_RETIRE:="$DOKKU_GLOBAL_DOKKU_WAIT_TO_RETIRE"} - fi - - # Let the old container finish processing requests, before terminating it - local WAIT="${DOKKU_WAIT_TO_RETIRE:-60}" - dokku_log_info1 "Shutting down old containers in $WAIT seconds" - local oldid - for oldid in $oldids; do - dokku_log_info2 "$oldid" - done - ( - exec >/dev/null 2>/dev/null /dev/null - dokku build "$APP" "$IMAGE_SOURCE_TYPE" "$TMP_WORK_DIR" - release_and_deploy "$APP" -} - -dokku_receive_cmd "$@" diff --git a/plugins/00_dokku-standard/subcommands/release b/plugins/00_dokku-standard/subcommands/release deleted file mode 100755 index 7dc148014..000000000 --- a/plugins/00_dokku-standard/subcommands/release +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x -source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" -source "$PLUGIN_AVAILABLE_PATH/config/functions" - -dokku_release_cmd() { - declare desc="release phase" - local cmd="release" - local APP="$2"; local IMAGE_SOURCE_TYPE="$3"; local IMAGE_TAG="$4"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG") - verify_app_name "$APP" - - case "$IMAGE_SOURCE_TYPE" in - herokuish) - plugn trigger pre-release-buildpack "$APP" "$IMAGE_TAG" - if [[ -n $(config_export global) ]]; then - local id=$(config_export global | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh") - test "$(docker wait "$id")" -eq 0 - docker commit "$id" "$IMAGE" > /dev/null - fi - if [[ -n $(config_export app "$APP") ]]; then - local id=$(config_export app "$APP" | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh") - test "$(docker wait "$id")" -eq 0 - docker commit "$id" "$IMAGE" > /dev/null - fi - plugn trigger post-release-buildpack "$APP" "$IMAGE_TAG" - ;; - - dockerfile) - # buildstep plugins don't necessarily make sense for dockerfiles. call the new breed!!! - plugn trigger pre-release-dockerfile "$APP" "$IMAGE_TAG" - plugn trigger post-release-dockerfile "$APP" "$IMAGE_TAG" - ;; - - *) - dokku_log_fail "Releasing image source type $IMAGE_SOURCE_TYPE not supported!" - ;; - esac -} - -dokku_release_cmd "$@" diff --git a/plugins/common/functions b/plugins/common/functions index 97279f404..c495e8af1 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -414,6 +414,272 @@ is_app_running() { fi } +dokku_build() { + declare desc="build phase" + source "$PLUGIN_AVAILABLE_PATH/config/functions" + + local APP="$1"; local IMAGE_SOURCE_TYPE="$2"; local TMP_WORK_DIR="$3"; local IMAGE=$(get_app_image_name "$APP") + verify_app_name "$APP" + + local CACHE_DIR="$DOKKU_ROOT/$APP/cache" + + eval "$(config_export app "$APP")" + pushd "$TMP_WORK_DIR" &> /dev/null + + case "$IMAGE_SOURCE_TYPE" in + herokuish) + local id=$(tar -c . | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /app && tar -xC /app") + test "$(docker wait "$id")" -eq 0 + docker commit "$id" "$IMAGE" > /dev/null + [[ -d $CACHE_DIR ]] || mkdir -p "$CACHE_DIR" + plugn trigger pre-build-buildpack "$APP" + + local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$IMAGE_SOURCE_TYPE") + [[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true " + # shellcheck disable=SC2086 + local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -v $CACHE_DIR:/cache -e CACHE_PATH=/cache $DOCKER_ARGS $IMAGE /build) + docker attach "$id" + test "$(docker wait "$id")" -eq 0 + docker commit "$id" "$IMAGE" > /dev/null + + plugn trigger post-build-buildpack "$APP" + ;; + + dockerfile) + # extract first port from Dockerfile + local DOCKERFILE_PORTS=$(get_dockerfile_exposed_ports Dockerfile) + [[ -n "$DOCKERFILE_PORTS" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_PORTS="$DOCKERFILE_PORTS" + + # extract ENTRYPOINT/CMD from Dockerfile + local DOCKERFILE_ENTRYPOINT=$(extract_directive_from_dockerfile Dockerfile ENTRYPOINT) + [[ -n "$DOCKERFILE_ENTRYPOINT" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_ENTRYPOINT="$DOCKERFILE_ENTRYPOINT" + local DOCKERFILE_CMD=$(extract_directive_from_dockerfile Dockerfile CMD) + [[ -n "$DOCKERFILE_CMD" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_CMD="$DOCKERFILE_CMD" + plugn trigger pre-build-dockerfile "$APP" + + [[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache" + local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$IMAGE_SOURCE_TYPE") + # strip --volume and -v args from DOCKER_ARGS + local DOCKER_ARGS=$(sed -e "s/--volume=[[:graph:]]\+[[:blank:]]\?//g" -e "s/-v[[:blank:]]\?[[:graph:]]\+[[:blank:]]\?//g" <<< "$DOCKER_ARGS") + + # shellcheck disable=SC2086 + docker build $DOCKER_ARGS $DOKKU_DOCKER_BUILD_OPTS -t $IMAGE . + + plugn trigger post-build-dockerfile "$APP" + ;; + + *) + dokku_log_fail "Building image source type $IMAGE_SOURCE_TYPE not supported!" + ;; + esac +} + +dokku_release() { + declare desc="release phase" + source "$PLUGIN_AVAILABLE_PATH/config/functions" + + local APP="$1"; local IMAGE_SOURCE_TYPE="$2"; local IMAGE_TAG="$3"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG") + verify_app_name "$APP" + + case "$IMAGE_SOURCE_TYPE" in + herokuish) + plugn trigger pre-release-buildpack "$APP" "$IMAGE_TAG" + if [[ -n $(config_export global) ]]; then + local id=$(config_export global | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh") + test "$(docker wait "$id")" -eq 0 + docker commit "$id" "$IMAGE" > /dev/null + fi + if [[ -n $(config_export app "$APP") ]]; then + local id=$(config_export app "$APP" | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh") + test "$(docker wait "$id")" -eq 0 + docker commit "$id" "$IMAGE" > /dev/null + fi + plugn trigger post-release-buildpack "$APP" "$IMAGE_TAG" + ;; + + dockerfile) + # buildstep plugins don't necessarily make sense for dockerfiles. call the new breed!!! + plugn trigger pre-release-dockerfile "$APP" "$IMAGE_TAG" + plugn trigger post-release-dockerfile "$APP" "$IMAGE_TAG" + ;; + + *) + dokku_log_fail "Releasing image source type $IMAGE_SOURCE_TYPE not supported!" + ;; + esac +} + +dokku_deploy_cmd() { + declare desc="deploy phase" + local cmd="deploy" + source "$PLUGIN_AVAILABLE_PATH/checks/functions" + source "$PLUGIN_AVAILABLE_PATH/config/functions" + source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" + + [[ -z $1 ]] && dokku_log_fail "Please specify an app to deploy" + local APP="$1"; local IMAGE_TAG="$2"; local IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG") + verify_app_name "$APP" + plugn trigger pre-deploy "$APP" "$IMAGE_TAG" + + is_image_herokuish_based "$IMAGE" && local DOKKU_HEROKUISH=true + local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE" + local oldids=$(get_app_container_ids "$APP") + + local DOKKU_DEFAULT_DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG") + local DOKKU_IS_APP_PROXY_ENABLED="$(is_app_proxy_enabled "$APP")" + local DOKKU_DOCKER_STOP_TIMEOUT="$(config_get "$APP" DOKKU_DOCKER_STOP_TIMEOUT || true)" + [[ $DOKKU_DOCKER_STOP_TIMEOUT ]] && DOCKER_STOP_TIME_ARG="--time=${DOKKU_DOCKER_STOP_TIMEOUT}" + + local line; local PROC_TYPE; local PROC_COUNT; local CONTAINER_INDEX + while read -r line || [[ -n "$line" ]]; do + [[ "$line" =~ ^#.* ]] && continue + line="$(strip_inline_comments "$line")" + PROC_TYPE=${line%%=*} + PROC_COUNT=${line#*=} + CONTAINER_INDEX=1 + + if [[ "$(is_app_proctype_checks_disabled "$APP" "$PROC_TYPE")" == "true" ]]; then + dokku_log_info1 "zero downtime is disabled for app ($APP.$PROC_TYPE). stopping currently running containers" + local cid proctype_oldids="$(get_app_container_ids "$APP" "$PROC_TYPE")" + for cid in $proctype_oldids; do + dokku_log_info2 "stopping $APP.$PROC_TYPE ($cid)" + # shellcheck disable=SC2086 + docker stop $DOCKER_STOP_TIME_ARG "$cid" &> /dev/null + done + fi + + while [[ $CONTAINER_INDEX -le $PROC_COUNT ]]; do + local id=""; local port=""; local ipaddr="" + local DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_TYPE.$CONTAINER_INDEX" + local DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_TYPE.$CONTAINER_INDEX" + local DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_TYPE.$CONTAINER_INDEX" + + # start the app + local DOCKER_ARGS="$DOKKU_DEFAULT_DOCKER_ARGS" + local DOCKER_ARGS+=" -e DYNO='$PROC_TYPE.$CONTAINER_INDEX' " + [[ "$DOKKU_TRACE" ]] && local DOCKER_ARGS+=" -e TRACE=true " + + [[ -n "$DOKKU_HEROKUISH" ]] && local START_CMD="/start $PROC_TYPE" + + if [[ -z "$DOKKU_HEROKUISH" ]]; then + local DOKKU_DOCKERFILE_PORTS=($(config_get "$APP" DOKKU_DOCKERFILE_PORTS || true)) + local DOKKU_DOCKERFILE_START_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_START_CMD || true) + local DOKKU_PROCFILE_START_CMD=$(get_cmd_from_procfile "$APP" "$PROC_TYPE") + local START_CMD=${DOKKU_DOCKERFILE_START_CMD:-$DOKKU_PROCFILE_START_CMD} + fi + + if [[ "$PROC_TYPE" == "web" ]]; then + if [[ -z "${DOKKU_DOCKERFILE_PORTS[*]}" ]]; then + local port=5000 + local DOKKU_DOCKER_PORT_ARGS+="-p $port" + else + local p + for p in ${DOKKU_DOCKERFILE_PORTS[*]};do + if [[ ! "$p" =~ .*udp.* ]]; then + # set port to first non-udp port + local p=${p//\/tcp} + local port=${port:="$p"} + fi + local DOKKU_DOCKER_PORT_ARGS+=" -p $p " + done + fi + if [[ "$DOKKU_IS_APP_PROXY_ENABLED" == "true" ]]; then + # shellcheck disable=SC2086 + local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD) + local ipaddr=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$id") + # Docker < 1.9 compatibility + if [[ -z $ipaddr ]]; then + local ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$id") + fi + else + # shellcheck disable=SC2086 + local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD) + local port=$(docker port "$id" "$port" | sed 's/[0-9.]*://') + local ipaddr=127.0.0.1 + fi + else + # shellcheck disable=SC2086 + local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOCKER_ARGS $IMAGE $START_CMD) + fi + + kill_new() { + declare desc="wrapper function to kill newly started app container" + local id="$1" + docker inspect "$id" &> /dev/null && docker stop "$id" > /dev/null && docker kill "$id" &> /dev/null + trap - INT TERM EXIT + kill -9 $$ + } + + # run checks first, then post-deploy hooks, which switches proxy traffic + trap 'kill_new $id' INT TERM EXIT + if [[ "$(is_app_proctype_checks_disabled "$APP" "$PROC_TYPE")" == "false" ]]; then + dokku_log_info1 "Attempting pre-flight checks" + plugn trigger check-deploy "$APP" "$id" "$PROC_TYPE" "$port" "$ipaddr" + fi + trap - INT TERM EXIT + + # now using the new container + [[ -n "$id" ]] && echo "$id" > "$DOKKU_CONTAINER_ID_FILE" + [[ -n "$ipaddr" ]] && echo "$ipaddr" > "$DOKKU_IP_FILE" + [[ -n "$port" ]] && echo "$port" > "$DOKKU_PORT_FILE" + + # cleanup pre-migration files + rm -f "$DOKKU_ROOT/$APP/CONTAINER" "$DOKKU_ROOT/$APP/IP" "$DOKKU_ROOT/$APP/PORT" + + local CONTAINER_INDEX=$(( CONTAINER_INDEX + 1 )) + done + # cleanup when we scale down + if [[ "$PROC_COUNT" == 0 ]]; then + local CONTAINER_IDX_OFFSET=0 + else + local CONTAINER_IDX_OFFSET=$((PROC_COUNT + 1)) + fi + local container_state_filetype + for container_state_filetype in CONTAINER IP PORT; do + cd "$DOKKU_ROOT/$APP" + find . -maxdepth 1 -name "$container_state_filetype.$PROC_TYPE.*" -printf "%f\n" | sort -t . -k 3 -n | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f + done + done < "$DOKKU_SCALE_FILE" + + dokku_log_info1 "Running post-deploy" + plugn trigger post-deploy "$APP" "$port" "$ipaddr" "$IMAGE_TAG" + + # kill the old container + if [[ -n "$oldids" ]]; then + + if [[ -z "$DOKKU_WAIT_TO_RETIRE" ]]; then + local DOKKU_APP_DOKKU_WAIT_TO_RETIRE=$(config_get "$APP" DOKKU_WAIT_TO_RETIRE || true) + local DOKKU_GLOBAL_DOKKU_WAIT_TO_RETIRE=$(config_get --global DOKKU_WAIT_TO_RETIRE || true) + local DOKKU_WAIT_TO_RETIRE=${DOKKU_APP_DOKKU_WAIT_TO_RETIRE:="$DOKKU_GLOBAL_DOKKU_WAIT_TO_RETIRE"} + fi + + # Let the old container finish processing requests, before terminating it + local WAIT="${DOKKU_WAIT_TO_RETIRE:-60}" + dokku_log_info1 "Shutting down old containers in $WAIT seconds" + local oldid + for oldid in $oldids; do + dokku_log_info2 "$oldid" + done + ( + exec >/dev/null 2>/dev/null /dev/null + dokku_build "$APP" "$IMAGE_SOURCE_TYPE" "$TMP_WORK_DIR" + release_and_deploy "$APP" +} + docker_cleanup() { declare desc="cleans up all exited/dead containers and removes all dangling images" # delete all non-running containers diff --git a/plugins/config/functions b/plugins/config/functions index b2a1e8365..c97ff7c57 100755 --- a/plugins/config/functions +++ b/plugins/config/functions @@ -160,6 +160,8 @@ config_get() { config_set() { declare desc="set value of given config var" + source "$PLUGIN_AVAILABLE_PATH/ps/functions" + [[ "$1" == "config:set" ]] || set -- "config:set" "$@" config_parse_args "$@" @@ -214,12 +216,14 @@ ${var}" [[ $APP ]] && local DOKKU_APP_RESTORE=$(config_get "$APP" DOKKU_APP_RESTORE || true) if [[ "$DOKKU_CONFIG_RESTART" == "true" ]] && [[ "$DOKKU_APP_RESTORE" != 0 ]]; then dokku_log_info1 "Restarting app $APP" - dokku ps:restart "$APP" + ps_restart "$APP" fi } config_unset() { declare desc="unset given config var" + source "$PLUGIN_AVAILABLE_PATH/ps/functions" + [[ "$1" == "config:unset" ]] || set -- "config:unset" "$@" config_parse_args "$@" local SANITIZED_ARGS=($(get_sanitized_config_args "$@")) @@ -247,6 +251,6 @@ config_unset() { [[ $APP ]] && local DOKKU_APP_RESTORE=$(config_get "$APP" DOKKU_APP_RESTORE || true) if [[ "$DOKKU_CONFIG_RESTART" == "true" ]] && [[ "$DOKKU_APP_RESTORE" != 0 ]]; then dokku_log_info1 "Restarting app $APP" - dokku ps:restart "$APP" + ps_restart "$APP" fi } diff --git a/plugins/git/functions b/plugins/git/functions index a20f8414e..33158d646 100755 --- a/plugins/git/functions +++ b/plugins/git/functions @@ -34,10 +34,10 @@ git_build_app_repo() { if [[ -f Dockerfile ]] && [[ "$([[ -f .env ]] && grep -q BUILDPACK_URL .env; echo $?)" != "0" ]] && [[ ! -f ".buildpacks" ]] && [[ -z $(config_get "$APP" BUILDPACK_URL || true) ]]; then plugn trigger pre-receive-app "$APP" "dockerfile" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV" - dokku receive "$APP" "dockerfile" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" + dokku_receive "$APP" "dockerfile" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" else plugn trigger pre-receive-app "$APP" "herokuish" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" "$REV" - dokku receive "$APP" "herokuish" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" + dokku_receive "$APP" "herokuish" "$GIT_BUILD_APP_REPO_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" fi } diff --git a/plugins/tar/functions b/plugins/tar/functions index 4581677aa..93b024645 100755 --- a/plugins/tar/functions +++ b/plugins/tar/functions @@ -26,10 +26,10 @@ tar_build() { if [[ -f Dockerfile ]] && [[ "$([[ -f .env ]] && grep -q BUILDPACK_URL .env; echo $?)" != "0" ]] && [[ ! -f ".buildpacks" ]]; then plugn trigger pre-receive-app "$APP" "dockerfile" "$TAR_BUILD_TMP_WORK_DIR" - dokku receive "$APP" "dockerfile" "$TAR_BUILD_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" + dokku_receive "$APP" "dockerfile" "$TAR_BUILD_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" else plugn trigger pre-receive-app "$APP" "herokuish" "$TAR_BUILD_TMP_WORK_DIR" - dokku receive "$APP" "herokuish" "$TAR_BUILD_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" + dokku_receive "$APP" "herokuish" "$TAR_BUILD_TMP_WORK_DIR" | sed -u "s/^/"$'\e[1G'"/" fi } From c1ae280a78048d0175dde3d6db664073ec98d74c Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Jun 2016 19:30:25 -0700 Subject: [PATCH 09/12] [ci skip] clarify triggers being called by internal functions --- docs/development/plugin-triggers.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/development/plugin-triggers.md b/docs/development/plugin-triggers.md index 44bb1cbcb..c39de89d1 100644 --- a/docs/development/plugin-triggers.md +++ b/docs/development/plugin-triggers.md @@ -164,7 +164,7 @@ esac ### `docker-args-build` - Description: -- Invoked by: `dokku_build` +- Invoked by: `internal function dokku_build() (build phase)` - Arguments: `$APP $IMAGE_SOURCE_TYPE` - Example: @@ -300,7 +300,7 @@ nginx -t ### `post-build-buildpack` - Description: Allows you to run commands after the build image is create for a given app. Only applies to applications using buildpacks. -- Invoked by: `dokku_build` +- Invoked by: `internal function dokku_build() (build phase)` - Arguments: `$APP` - Example: @@ -315,7 +315,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x ### `post-build-dockerfile` - Description: Allows you to run commands after the build image is create for a given app. Only applies to applications using a dockerfile. -- Invoked by: `dokku_build` +- Invoked by: `internal function dokku_build() (build phase)` - Arguments: `$APP` - Example: @@ -423,7 +423,7 @@ haproxy-build-config "$APP" ### `post-release-buildpack` - Description: Allows you to run commands after environment variables are set for the release step of the deploy. Only applies to applications using buildpacks. -- Invoked by: `dokku_release` +- Invoked by: `internal function dokku_release() (release phase)` - Arguments: `$APP $IMAGE_TAG` - Example: @@ -450,7 +450,7 @@ docker commit $ID $IMAGE > /dev/null ### `post-release-dockerfile` - Description: Allows you to run commands after environment variables are set for the release step of the deploy. Only applies to applications using a dockerfile. -- Invoked by: `dokku_release` +- Invoked by: `internal function dokku_release() (release phase)` - Arguments: `$APP $IMAGE_TAG` - Example: @@ -486,7 +486,7 @@ dokku config:set --no-restart $APP MANUALLY_STOPPED=1 ### `pre-build-buildpack` - Description: Allows you to run commands before the build image is created for a given app. For instance, this can be useful to add env vars to your container. Only applies to applications using buildpacks. -- Invoked by: `dokku_build` +- Invoked by: `internal function dokku_build() (build phase)` - Arguments: `$APP` - Example: @@ -501,7 +501,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x ### `pre-build-dockerfile` - Description: Allows you to run commands before the build image is created for a given app. For instance, this can be useful to add env vars to your container. Only applies to applications using a dockerfile. -- Invoked by: `dokku_build` +- Invoked by: `internal function dokku_build() (build phase)` - Arguments: `$APP` - Example: @@ -580,7 +580,7 @@ echo "$APP" > "$TMP_WORK_DIR/dokku-is-awesome" ### `pre-release-buildpack` - Description: Allows you to run commands before environment variables are set for the release step of the deploy. Only applies to applications using buildpacks. -- Invoked by: `dokku_release` +- Invoked by: `internal function dokku_release() (release phase)` - Arguments: `$APP $IMAGE_TAG` - Example: @@ -607,7 +607,7 @@ docker commit $ID $IMAGE > /dev/null ### `pre-release-dockerfile` - Description: Allows you to run commands before environment variables are set for the release step of the deploy. Only applies to applications using a dockerfile. -- Invoked by: `dokku_release` +- Invoked by: `internal function dokku_release() (release phase)` - Arguments: `$APP $IMAGE_TAG` - Example: From 9effe275bdab653040817470518676978bc1c45c Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Fri, 17 Jun 2016 19:49:15 -0700 Subject: [PATCH 10/12] don't call dokku binary in checks/install. fix variable typo --- plugins/checks/install | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/checks/install b/plugins/checks/install index be3feb8d3..28185822a 100755 --- a/plugins/checks/install +++ b/plugins/checks/install @@ -6,8 +6,8 @@ source "$PLUGIN_AVAILABLE_PATH/config/functions" migrate_checks_vars_0_5_0() { declare desc="migrates deprecated CHECKS config variables to simplified counter part introduced in 0.5.x" local APPS="$(dokku_apps)" - local GLOBAL_SKIP_ALL_CHECKS=$(dokku config:get --global DOKKU_SKIP_ALL_CHECKS || true) - local GLOBAL_SKIP_DEFAULT_CHECKS=$(dokku config:get --global DOKKU_SKIP_DEFAULT_CHECKS || true) + local GLOBAL_SKIP_ALL_CHECKS=$(config_get --global DOKKU_SKIP_ALL_CHECKS || true) + local GLOBAL_SKIP_DEFAULT_CHECKS=$(config_get --global DOKKU_SKIP_DEFAULT_CHECKS || true) local app @@ -16,8 +16,8 @@ migrate_checks_vars_0_5_0() { dokku_log_info2 "Please use dokku checks:[disable|enable] to control zero downtime functionality" for app in $APPS; do - local APP_SKIP_ALL_CHECKS=$(dokku config:get "$app" DOKKU_SKIP_ALL_CHECKS || true) - local APP_SKIP_DEFAULT_CHECKS=$(dokku config:get "$app" DOKKU_SKIP_DEFAULT_CHECKS || true) + local APP_SKIP_ALL_CHECKS=$(config_get "$app" DOKKU_SKIP_ALL_CHECKS || true) + local APP_SKIP_DEFAULT_CHECKS=$(config_get "$app" DOKKU_SKIP_DEFAULT_CHECKS || true) if [[ "$APP_SKIP_ALL_CHECKS" == "true" ]] || [[ "$APP_SKIP_DEFAULT_CHECKS" == "true" ]] || [[ "$GLOBAL_SKIP_ALL_CHECKS" == "true" ]] || [[ "$GLOBAL_SKIP_DEFAULT_CHECKS" == "true" ]]; then dokku_log_info2 "" @@ -48,9 +48,9 @@ migrate_checks_vars_0_6_0() { dokku_log_info1 "Migrating zero downtime env variables to 0.6.x. The following variables will be migrated" dokku_log_info2 "DOKKU_CHECKS_ENABLED -> DOKKU_CHECKS_SKIPPED" for app in $APPS; do - local APP_DOKKU_CHECKS_ENABLED=$(dokku config:get "$app" DOKKU_CHECKS_ENABLED || true) + local APP_DOKKU_CHECKS_ENABLED=$(config_get "$app" DOKKU_CHECKS_ENABLED || true) if [[ $APP_DOKKU_CHECKS_ENABLED ]]; then - if [[ "$DOKKU_CHECKS_ENABLED" == "0" ]]; then + if [[ "$APP_DOKKU_CHECKS_ENABLED" == "0" ]]; then dokku_log_info2 "" dokku_log_info2 "zero downtime checks disabled for app ($app)" config_set --no-restart "$app" DOKKU_CHECKS_SKIPPED="_all_" From 8f8ee9c5da373c8fadee338cdce05d3a2754d3b2 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 17 Jun 2016 23:00:43 -0400 Subject: [PATCH 11/12] Add a section on how calling the dokku binary should work [ci skip] --- docs/appendices/0.6.0-migration-guide.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/appendices/0.6.0-migration-guide.md b/docs/appendices/0.6.0-migration-guide.md index ed5871238..d5d773577 100644 --- a/docs/appendices/0.6.0-migration-guide.md +++ b/docs/appendices/0.6.0-migration-guide.md @@ -1,6 +1,7 @@ # 0.6.0 Migration Guide ## zero-downtime deployment + - You can now **actually** disable zero-downtime deployments per-app and per-process-type - Some config variables have been moved around - `DOKKU_CHECKS_ENABLED` has been migrated to `DOKKU_CHECKS_SKIPPED` @@ -9,5 +10,17 @@ - See the [updated `checks`](/dokku/checks-examples/) docs for more info ## proxy port mapping + - You can now configure host -> container proxy port mappings - The UI is handled by the [proxy](/dokku/proxy/) interface plugin by setting the `DOKKU_PROXY_PORT_MAP` config variable in the format of `scheme:host-port:container-port`. The default `nginx-vhosts` proxy plugin supports both the `http` and `https` schemes. + +## calling the dokku binary + +- Plugins should *not* call the dokku binary directly. Clients using the `--app` argument are potentially broken, amongst others, when doing so. Instead, please source the `functions` file for a given plugin when attempting to call dokku internal functions. As a result, the following dokku commands are no longer publicly exposed: + - dokku build + - dokku receive + - dokku release + - dokku tar:build + - dokku tar:build-locked + - dokku git:build + - dokku git:build-locked From b6f9672d400223f749ee96c1daf89659fd072784 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Fri, 17 Jun 2016 23:12:11 -0400 Subject: [PATCH 12/12] Add note to plugin creation regarding calling the binary directly [ci skip] --- docs/development/plugin-creation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/development/plugin-creation.md b/docs/development/plugin-creation.md index c08749d90..26c717f70 100644 --- a/docs/development/plugin-creation.md +++ b/docs/development/plugin-creation.md @@ -155,3 +155,4 @@ A few notes: - From time to time you may want to allow other plugins access to (some of) your plugin's functionality. You can expose this by including a `functions` file in your plugin for others to source. Consider all functions in that file to be publicly accessible by other plugins. Any functions not wished to be made "public" should reside within your plugin trigger or commands files. - As of 0.4.0, we allow image tagging and deployment of said tagged images. Therefore, hard-coding of `$IMAGE` as `dokku/$APP` is no longer sufficient. Instead, for non `pre/post-build-*` plugins, use `get_running_image_tag()` & `get_app_image_name()` as sourced from common/functions. See the [plugin triggers](/dokku/development/plugin-triggers) doc for examples. - As of 0.5.0, we use container labels to help cleanup intermediate containers with `dokku cleanup`. If manually calling `docker run`, include `$DOKKU_GLOBAL_RUN_ARGS`. This will ensure you intermediate containers labeled correctly. +- As of 0.6.0, we advise you to *not* call the dokku binary directly from within plugins. Clients using the `--app` argument are potentially broken, amongst other issues, when doing so. Instead, please source the `functions` file for a given plugin when attempting to call dokku internal functions