From 59c92077977fefb2a421e76fbb5b065c84c9730d Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sat, 2 Jul 2016 17:17:17 -0400 Subject: [PATCH 1/6] Implement restart-policy handling. Closes #1734 Applications without a restart-policy will have their policies set to `on-failure:10`. Users can completely unset the restart-policy using the `docker-options` plugin, though this will be equivalent to setting it explicitly to `no`. Restart policies must be explicitly set, and the following are all valid: - no - unless-stopped - always - on-failure - on-failure:NUMBER --- plugins/ps/commands | 2 ++ plugins/ps/functions | 12 +++++++++ plugins/ps/install | 21 +++++++++++++++ plugins/ps/post-create | 14 ++++++++++ plugins/ps/subcommands/restart-policy | 18 +++++++++++++ plugins/ps/subcommands/set-restart-policy | 31 +++++++++++++++++++++++ 6 files changed, 98 insertions(+) create mode 100755 plugins/ps/install create mode 100755 plugins/ps/post-create create mode 100755 plugins/ps/subcommands/restart-policy create mode 100755 plugins/ps/subcommands/set-restart-policy diff --git a/plugins/ps/commands b/plugins/ps/commands index 1d46d500f..696ef63d4 100755 --- a/plugins/ps/commands +++ b/plugins/ps/commands @@ -16,6 +16,8 @@ case "$1" in ps:restart , Restart app container(s) ps:restartall, Restart all deployed app containers ps:restore, Start previously running apps e.g. after reboot + ps:restart-policy , Shows the restart-policy for an app + ps:set-restart-policy , Sets app restart-policy help_content } diff --git a/plugins/ps/functions b/plugins/ps/functions index 5a9949431..9b4fb5b11 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -165,3 +165,15 @@ ps_scale() { release_and_deploy "$APP" "$IMAGE_TAG" fi } + +get_restart_policies() { + declare desc="strips docker options and prints restart policies" + local -r phase_file_path=$1 + [[ -r "$phase_file_path" ]] && sed -e '/^--restart=/!d' -e 's/^--restart=/ /' < "$phase_file_path" +} + +get_raw_restart_policies() { + declare desc="strips docker options and prints raw restart policies" + local -r phase_file_path=$1 + [[ -r "$phase_file_path" ]] && sed -e '/^--restart=/!d' < "$phase_file_path" +} diff --git a/plugins/ps/install b/plugins/ps/install new file mode 100755 index 000000000..51195449d --- /dev/null +++ b/plugins/ps/install @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/docker-options/functions" +source "$PLUGIN_AVAILABLE_PATH/ps/functions" + +set_default_restart_policies() { + declare desc="set the default restart policy for all applications if there is not one already set" + local APPS="$(dokku_apps)" + local APP + + for APP in $APPS; do + local RESTART_POLICIES=$(get_restart_policies "$(get_phase_file_path "deploy")") + if [[ -z "$RESTART_POLICIES" ]]; then + local passed_phases=(deploy) + add_passed_docker_option passed_phases[@] "--restart=on-failure:10" + fi + done +} + +set_default_restart_policies "$@" diff --git a/plugins/ps/post-create b/plugins/ps/post-create new file mode 100755 index 000000000..948ecf919 --- /dev/null +++ b/plugins/ps/post-create @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/docker-options/functions" +source "$PLUGIN_AVAILABLE_PATH/ps/functions" + +ps_post_create() { + declare desc="ps post-stop plugin trigger" + local trigger="ps_post_stop" + local APP="$1" + + local passed_phases=(deploy) + add_passed_docker_option passed_phases[@] "--restart=on-failure:10" +} diff --git a/plugins/ps/subcommands/restart-policy b/plugins/ps/subcommands/restart-policy new file mode 100755 index 000000000..9ee8c434b --- /dev/null +++ b/plugins/ps/subcommands/restart-policy @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/docker-options/functions" +source "$PLUGIN_AVAILABLE_PATH/ps/functions" + +ps_restart_policy_cmd() { + declare desc="shows the restart-policy for an app" + local cmd="ps:restart-policy" + local passed_phases="deploy" + [[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on" + verify_app_name "$2" && local APP="$2" + + echo "$APP restart-policy:" + get_restart_policies "$(get_phase_file_path "$passed_phases")" +} + +ps_restart_policy_cmd "$@" diff --git a/plugins/ps/subcommands/set-restart-policy b/plugins/ps/subcommands/set-restart-policy new file mode 100755 index 000000000..ab836edea --- /dev/null +++ b/plugins/ps/subcommands/set-restart-policy @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x +source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" +source "$PLUGIN_AVAILABLE_PATH/docker-options/functions" +source "$PLUGIN_AVAILABLE_PATH/ps/functions" + +ps_set_restart_policy_cmd() { + declare desc="sets app restart-policy" + local cmd="ps:set-restart-policy" + [[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on" + verify_app_name "$2" && local APP="$2" + local RESTART_POLICY="$3" + local RE_RESTART_POLICY="^(no|unless-stopped|always|on-failure(:[1-9][0-9]*)?)$" + + if [[ ! "$RESTART_POLICY" =~ $RE_RESTART_POLICY ]]; then + dokku_log_fail "Please specify an valid restart policy matching the following regex: ${RE_RESTART_POLICY}" + fi + + local RESTART_POLICIES=$(get_raw_restart_policies "$(get_phase_file_path "deploy")") + local passed_phases=(deploy) + + for policy in $RESTART_POLICIES; do + remove_passed_docker_option passed_phases[@] "$policy" + done + + dokku_log_info1_quiet "Setting restart policy: ${RESTART_POLICY}" + local passed_phases=(deploy) + add_passed_docker_option passed_phases[@] "--restart=${RESTART_POLICY}" +} + +ps_set_restart_policy_cmd "$@" From 514ebf4d84d3c4d14abc11fdbae4f46c1e0d4fab Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sun, 17 Jul 2016 15:55:14 -0700 Subject: [PATCH 2/6] fix copypasta and actually call trigger --- plugins/ps/post-create | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/ps/post-create b/plugins/ps/post-create index 948ecf919..78e08b1c5 100755 --- a/plugins/ps/post-create +++ b/plugins/ps/post-create @@ -5,10 +5,12 @@ source "$PLUGIN_AVAILABLE_PATH/docker-options/functions" source "$PLUGIN_AVAILABLE_PATH/ps/functions" ps_post_create() { - declare desc="ps post-stop plugin trigger" - local trigger="ps_post_stop" + declare desc="ps post-create plugin trigger" + local trigger="ps_post_create" local APP="$1" local passed_phases=(deploy) add_passed_docker_option passed_phases[@] "--restart=on-failure:10" } + +ps_post_create "$@" From a269f8e003d5e4e620b57780eb0fc1bc092a01f3 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sun, 17 Jul 2016 15:56:11 -0700 Subject: [PATCH 3/6] support --quiet and split up data access from presentation --- plugins/ps/functions | 12 ++++++------ plugins/ps/subcommands/restart-policy | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/ps/functions b/plugins/ps/functions index 9b4fb5b11..a1c0479ab 100755 --- a/plugins/ps/functions +++ b/plugins/ps/functions @@ -166,14 +166,14 @@ ps_scale() { fi } -get_restart_policies() { - declare desc="strips docker options and prints restart policies" - local -r phase_file_path=$1 - [[ -r "$phase_file_path" ]] && sed -e '/^--restart=/!d' -e 's/^--restart=/ /' < "$phase_file_path" -} - get_raw_restart_policies() { declare desc="strips docker options and prints raw restart policies" local -r phase_file_path=$1 [[ -r "$phase_file_path" ]] && sed -e '/^--restart=/!d' < "$phase_file_path" } + +get_restart_policies() { + declare desc="strips docker options and prints restart policies" + local -r phase_file_path=$1 + get_raw_restart_policies "$phase_file_path" | sed -e 's/^--restart=//g' +} diff --git a/plugins/ps/subcommands/restart-policy b/plugins/ps/subcommands/restart-policy index 9ee8c434b..c73ed72ab 100755 --- a/plugins/ps/subcommands/restart-policy +++ b/plugins/ps/subcommands/restart-policy @@ -11,7 +11,7 @@ ps_restart_policy_cmd() { [[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on" verify_app_name "$2" && local APP="$2" - echo "$APP restart-policy:" + dokku_log_info2_quiet "$APP restart-policy:" get_restart_policies "$(get_phase_file_path "$passed_phases")" } From 81f444c8072d854263ec57d3f05baccb22223192 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sun, 17 Jul 2016 15:56:37 -0700 Subject: [PATCH 4/6] pull node:4 image ahead of time as we use it in many tests --- tests/ci/parallel_runner.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/ci/parallel_runner.sh b/tests/ci/parallel_runner.sh index 823ac13e5..3d11995ef 100755 --- a/tests/ci/parallel_runner.sh +++ b/tests/ci/parallel_runner.sh @@ -28,6 +28,8 @@ setup_circle() { sudo -E mkdir -p /home/dokku/.dokkurc sudo -E chown dokku:ubuntu /home/dokku/.dokkurc sudo -E chmod 775 /home/dokku/.dokkurc + # pull node:4 image for testing + sudo docker pull node:4 } if [[ -n "$CIRCLE_NODE_INDEX" ]] && [[ "$MODE" == "setup" ]]; then From 9d387fd66696935dd89f2a2a49fc755f037a7352 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sun, 17 Jul 2016 15:56:55 -0700 Subject: [PATCH 5/6] add ps:restart-policy tests --- tests/unit/10_ps-dockerfile.bats | 17 -------- tests/unit/10_ps-general.bats | 72 ++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 tests/unit/10_ps-general.bats diff --git a/tests/unit/10_ps-dockerfile.bats b/tests/unit/10_ps-dockerfile.bats index 8d158e3d8..7627b7e75 100644 --- a/tests/unit/10_ps-dockerfile.bats +++ b/tests/unit/10_ps-dockerfile.bats @@ -224,20 +224,3 @@ teardown() { done } -@test "(ps:scale) procfile commands extraction" { - source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" - source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions" - cat < "$DOKKU_ROOT/$TEST_APP/DOKKU_PROCFILE" -web: node web.js -worker: node worker.js -EOF - run get_cmd_from_procfile "$TEST_APP" web - echo "output: "$output - echo "status: "$status - assert_output "node web.js" - - run get_cmd_from_procfile "$TEST_APP" worker - echo "output: "$output - echo "status: "$status - assert_output "node worker.js" -} diff --git a/tests/unit/10_ps-general.bats b/tests/unit/10_ps-general.bats new file mode 100644 index 000000000..251882dc5 --- /dev/null +++ b/tests/unit/10_ps-general.bats @@ -0,0 +1,72 @@ +#!/usr/bin/env bats + +load test_helper + +setup() { + create_app +} + +teardown() { + destroy_app +} + +@test "(ps:scale) procfile commands extraction" { + source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" + source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions" + cat < "$DOKKU_ROOT/$TEST_APP/DOKKU_PROCFILE" +web: node web.js +worker: node worker.js +EOF + run get_cmd_from_procfile "$TEST_APP" web + echo "output: "$output + echo "status: "$status + assert_output "node web.js" + + run get_cmd_from_procfile "$TEST_APP" worker + echo "output: "$output + echo "status: "$status + assert_output "node worker.js" +} + +@test "(ps:restart-policy) default policy" { + run bash -c "dokku --quiet ps:restart-policy $TEST_APP" + echo "output: "$output + echo "status: "$status + assert_output "on-failure:10" +} + + +@test "(ps:restart-policy) ps:set-restart-policy, ps:restart-policy" { + for policy in no unless-stopped always on-failure on-failure:20; do + run bash -c "dokku ps:set-restart-policy $TEST_APP $policy" + echo "output: "$output + echo "status: "$status + assert_success + + run bash -c "dokku --quiet ps:restart-policy $TEST_APP" + echo "output: "$output + echo "status: "$status + assert_output "$policy" + done +} + +@test "(ps:restart-policy) deployed policy" { + test_restart_policy="on-failure:20" + run bash -c "dokku ps:set-restart-policy $TEST_APP $test_restart_policy" + echo "output: "$output + echo "status: "$status + assert_success + + run bash -c "dokku --quiet ps:restart-policy $TEST_APP" + echo "output: "$output + echo "status: "$status + assert_output "$test_restart_policy" + + deploy_app dockerfile + + CID=$(< $DOKKU_ROOT/$TEST_APP/CONTAINER.web.1) + run bash -c "docker inspect -f '{{ .HostConfig.RestartPolicy.Name }}:{{ .HostConfig.RestartPolicy.MaximumRetryCount }}' $CID" + echo "output: "$output + echo "status: "$status + assert_output "$test_restart_policy" +} From 909382742421cae98cd1be4ec1b0f88f396d4c21 Mon Sep 17 00:00:00 2001 From: Michael Hobbs Date: Sun, 17 Jul 2016 19:26:56 -0700 Subject: [PATCH 6/6] fix docker-options tests --- tests/unit/20_docker-options.bats | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/20_docker-options.bats b/tests/unit/20_docker-options.bats index bd31481a4..da40a4ea0 100644 --- a/tests/unit/20_docker-options.bats +++ b/tests/unit/20_docker-options.bats @@ -67,10 +67,10 @@ teardown() { echo "output: "$output echo "status: "$status assert_success - run /bin/bash -c "dokku docker-options $TEST_APP | wc -l | grep -q 0" + run /bin/bash -c "dokku docker-options $TEST_APP | xargs" echo "output: "$output echo "status: "$status - assert_success + assert_output "Deploy options: --restart=on-failure:10" } @test "(docker-options) docker-options:remove (build phase)" { @@ -105,10 +105,10 @@ teardown() { echo "output: "$output echo "status: "$status assert_success - run /bin/bash -c "dokku docker-options $TEST_APP deploy" + run /bin/bash -c "dokku docker-options $TEST_APP deploy | xargs" echo "output: "$output echo "status: "$status - assert_output "Deploy options: none" + assert_output "Deploy options: --restart=on-failure:10" } @test "(docker-options) docker-options:remove (run phase)" {