diff --git a/docs/deployment/application-management.md b/docs/deployment/application-management.md index bfbacd755..4162c1f90 100644 --- a/docs/deployment/application-management.md +++ b/docs/deployment/application-management.md @@ -8,8 +8,10 @@ apps:create # Create a new app apps:destroy # Permanently destroy an app apps:exists # Checks if an app exists apps:list # List your apps +apps:lock # Creates a '.deploy.lock' file in an application's repo apps:rename # Rename an app apps:report [] [] # Display report about an app +apps:unlock # Removes the '.deploy.lock' file from an application's repo ``` ## Usage @@ -134,7 +136,7 @@ This will copy all of your app's contents into a new app directory with the name ### Cloning an existing app -> New as of 0.8.1 +> New as of 0.11.5 You can clone an existing app using the `apps:clone` command. Note that the application *must* have been deployed at least once, or cloning will not complete successfully: @@ -156,6 +158,39 @@ By default, Dokku will deploy this new application, though you can skip the depl dokku apps:clone --skip-deploy node-js-app io-js-app ``` +### Locking app deploys + +> New as of 0.11.6 + +If you wish to disable deploying for a period of time, this can be done via deploy locks. Normally, deploy locks exist only for the duration of a deploy so as to avoid deploys from colliding, but a deploy lock can be created by running the `apps:lock` subcommand. + + +```shell +dokku apps:lock node-js-app +``` + +``` +-----> Deploy lock created +``` + +### Unlocking app deploys + +> New as of 0.11.6 + +In some cases, it may be necessary to remove an existing deploy lock. This can be performed via the `apps:unlock` subcommand. + +> Warning: Removing the deploy lock _will not_ stop in progress deploys. At this time, in progress deploys will need to be manually terminated by someone with server access. + +```shell +dokku apps:unlock node-js-app +``` + +``` + ! A deploy may be in progress. + ! Removing the application lock will not stop in progress deploys. +-----> Deploy lock removed. +``` + ### Displaying reports about an app > New as of 0.8.1 @@ -171,12 +206,14 @@ dokku apps:report App dir: /home/dokku/node-js-app Git sha: dbddc3f Deploy method: git + Locked: false =====> python-sample not deployed =====> ruby-sample App dir: /home/dokku/ruby-sample Git sha: a2d477c Deploy method: git + Locked: false ``` You can run the command for a specific app also. @@ -188,7 +225,9 @@ dokku apps:report node-js-app ``` =====> node-js-app App dir: /home/dokku/node-js-app - Git sha: dbddc3f + Git sha: dbddc3f + Deploy method: git + Locked: false ``` You can pass flags which will output only the value of the specific information you want. For example: diff --git a/plugins/apps/internal-functions b/plugins/apps/internal-functions index 4de6de77e..252d68a5d 100755 --- a/plugins/apps/internal-functions +++ b/plugins/apps/internal-functions @@ -10,8 +10,10 @@ apps_help_content_func() { apps:create , Create a new app apps:destroy , Permanently destroy an app apps:list, List your apps + apps:lock , Creates a '.deploy.lock' file in an application's repo apps:rename , Rename an app apps:report [] [], Display report about an app + apps:unlock , Removes the '.deploy.lock' file from an application's repo help_content } @@ -49,3 +51,15 @@ apps_list_cmd() { echo "$app" done } + +apps_is_locked() { + declare desc="check if an app is locked" + declare APP="$1" + local LOCKED=false + + if [[ -f "$DOKKU_ROOT/$APP/.deploy.lock" ]]; then + LOCKED=true + fi + + echo "$LOCKED" +} \ No newline at end of file diff --git a/plugins/apps/subcommands/lock b/plugins/apps/subcommands/lock new file mode 100755 index 000000000..bbe6f017a --- /dev/null +++ b/plugins/apps/subcommands/lock @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/apps/internal-functions" + +apps_lock_cmd() { + declare desc="creates a '.deploy.lock' file in an application's repo" + declare cmd="apps:lock" + [[ "$1" == "$cmd" ]] && shift 1 + declare APP="$1"; verify_app_name "$APP" + + touch "$DOKKU_ROOT/$APP/.deploy.lock" || dokku_log_fail "Unable to create deploy lock" + + dokku_log_info1 "Deploy lock created" +} + +apps_lock_cmd "$@" diff --git a/plugins/apps/subcommands/report b/plugins/apps/subcommands/report index 39e848665..bb3484987 100755 --- a/plugins/apps/subcommands/report +++ b/plugins/apps/subcommands/report @@ -2,6 +2,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_AVAILABLE_PATH/apps/functions" +source "$PLUGIN_AVAILABLE_PATH/apps/internal-functions" report_single_app() { declare APP="$1" INFO_FLAG="$2" @@ -16,6 +17,7 @@ report_single_app() { "--app-dir: $APP_DIR" "--git-sha: $(GIT_DIR="$APP_DIR" git rev-parse --short HEAD 2> /dev/null || false)" "--deploy-source: $(: | plugn trigger deploy-source "$APP")" + "--locked: $(apps_is_locked "$APP")" ) if [[ -z "$INFO_FLAG" ]]; then diff --git a/plugins/apps/subcommands/unlock b/plugins/apps/subcommands/unlock new file mode 100755 index 000000000..4eac17eb3 --- /dev/null +++ b/plugins/apps/subcommands/unlock @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/apps/internal-functions" + +apps_unlock_cmd() { + declare desc="removes the '.deploy.lock' file from an application's repo" + declare cmd="apps:unlock" + [[ "$1" == "$cmd" ]] && shift 1 + declare APP="$1"; verify_app_name "$APP" + + if [[ -f "$DOKKU_ROOT/$APP/.deploy.lock" ]]; then + dokku_log_warn "A deploy may be in progress." + dokku_log_warn "Removing the application lock will not stop in progress deploys." + fi + + rm -f "$DOKKU_ROOT/$APP/.deploy.lock" || dokku_log_fail "Unable to remove deploy lock" + + dokku_log_info1 "Deploy lock removed." +} + +apps_unlock_cmd "$@" diff --git a/plugins/common/functions b/plugins/common/functions index 9b220ab5a..82f82f077 100755 --- a/plugins/common/functions +++ b/plugins/common/functions @@ -1160,8 +1160,8 @@ acquire_app_deploy_lock() { local LOCK_TYPE="${2:-waiting}" local APP_DEPLOY_LOCK_FD="200" local APP_DEPLOY_LOCK_FILE="$DOKKU_ROOT/$APP/.deploy.lock" - local LOCK_WAITING_MSG="$APP is currently being deployed. Waiting..." - local LOCK_FAILED_MSG="$APP is currently being deployed. Exiting..." + local LOCK_WAITING_MSG="$APP currently has a deploy lock in place. Waiting..." + local LOCK_FAILED_MSG="$APP currently has a deploy lock in place. Exiting..." local SHOW_MSG=true eval "exec $APP_DEPLOY_LOCK_FD>$APP_DEPLOY_LOCK_FILE" diff --git a/tests/unit/10_apps.bats b/tests/unit/10_apps.bats index d0ff646f2..5fb722f6b 100644 --- a/tests/unit/10_apps.bats +++ b/tests/unit/10_apps.bats @@ -150,4 +150,35 @@ teardown () { echo "status: "$status assert_success +} + +@test "(apps) apps:lock/unlock" { + create_app + + run bash -c "dokku apps:report $TEST_APP --locked" + echo "output: "$output + echo "status: "$status + assert_output "false" + + run bash -c "dokku apps:lock $TEST_APP" + echo "output: "$output + echo "status: "$status + assert_success + + run bash -c "dokku apps:report $TEST_APP --locked" + echo "output: "$output + echo "status: "$status + assert_output "true" + + run bash -c "dokku apps:unlock $TEST_APP" + echo "output: "$output + echo "status: "$status + assert_success + + run bash -c "dokku apps:report $TEST_APP --locked" + echo "output: "$output + echo "status: "$status + assert_output "false" + + destroy_app } \ No newline at end of file