diff --git a/docs/deployment/schedulers/docker-local.md b/docs/deployment/schedulers/docker-local.md index 869f937ad..aeb96cf97 100644 --- a/docs/deployment/schedulers/docker-local.md +++ b/docs/deployment/schedulers/docker-local.md @@ -5,7 +5,7 @@ ``` scheduler-docker-local:report [] [] # Displays a scheduler-docker-local report for one or more apps -scheduler-docker-local:set () # Set or clear a scheduler-docker-local property for an app +scheduler-docker-local:set [|--global] () # Set or clear a scheduler-docker-local property for an app or globally ``` > [!IMPORTANT] @@ -46,7 +46,19 @@ Once set, you may re-enable it by setting a blank value for `init-process`: dokku scheduler-docker-local:set node-js-app init-process ``` -All image containers with the label `org.opencontainers.image.vendor=linuxserver.io` will have the automatic init process injection force-disabled without further intervention. +The default value may also be configured globally with the `--global` flag. Per-app values take precedence over the global value when set. + +```shell +dokku scheduler-docker-local:set --global init-process false +``` + +The global value may also be unset by setting a blank value. + +```shell +dokku scheduler-docker-local:set --global init-process +``` + +All image containers with the label `org.opencontainers.image.vendor=linuxserver.io` will have the automatic init process injection force-disabled without further intervention when neither an app-level nor a global value is set. ### Deploying Process Types in Parallel @@ -66,6 +78,18 @@ Once set, you may reset it by setting a blank value for `parallel-schedule-count dokku scheduler-docker-local:set node-js-app parallel-schedule-count ``` +The default value may also be configured globally with the `--global` flag. Per-app values take precedence over the global value when set. + +```shell +dokku scheduler-docker-local:set --global parallel-schedule-count 4 +``` + +The global value may also be unset by setting a blank value. + +```shell +dokku scheduler-docker-local:set --global parallel-schedule-count +``` + If the value of `parallel-schedule-count` is increased and a given process type fails to schedule successfully, then any in-flight process types will continue to be processed, while all process types that have not been scheduled will be skipped before the deployment finally fails. Container scheduling output is shown in the order it is received, and thus may be out of order in case of output to stderr. @@ -100,6 +124,57 @@ Note that increasing the value of `max_parallel` may significantly impact CPU ut See the [app.json location documentation](/docs/advanced-usage/deployment-tasks.md#changing-the-appjson-location) for more information on where to place your `app.json` file. +### Displaying scheduler-docker-local reports for an app + +You can get a report about the app's scheduler-docker-local configuration using the `scheduler-docker-local:report` command: + +```shell +dokku scheduler-docker-local:report +``` + +``` +=====> node-js-app scheduler-docker-local information + Scheduler docker local computed init process: true + Scheduler docker local computed parallel schedule count:1 + Scheduler docker local global init process: true + Scheduler docker local global parallel schedule count: 1 + Scheduler docker local init process: + Scheduler docker local parallel schedule count: +``` + +You can run the command for a specific app also. + +```shell +dokku scheduler-docker-local:report node-js-app +``` + +You can pass flags which will output only the value of the specific information you want. For example: + +```shell +dokku scheduler-docker-local:report node-js-app --scheduler-docker-local-computed-init-process +``` + +When run against `--global`, only the global keys are reported. + +```shell +dokku scheduler-docker-local:report --global +``` + +The available keys are: + +- `--scheduler-docker-local-init-process`: the raw per-app init-process value (empty when unset). +- `--scheduler-docker-local-computed-init-process`: the effective init-process value, computed as the per-app value if set, otherwise the global value, otherwise `true`. +- `--scheduler-docker-local-global-init-process`: the global init-process value (defaults to `true`). +- `--scheduler-docker-local-parallel-schedule-count`: the raw per-app parallel-schedule-count value (empty when unset). +- `--scheduler-docker-local-computed-parallel-schedule-count`: the effective parallel-schedule-count value, computed as the per-app value if set, otherwise the global value, otherwise `1`. +- `--scheduler-docker-local-global-parallel-schedule-count`: the global parallel-schedule-count value (defaults to `1`). + +The report may also be emitted as JSON using `--format json`, which is useful for external tooling that needs to distinguish a value set on the app from one that is defaulting. + +```shell +dokku scheduler-docker-local:report node-js-app --format json +``` + ## Scheduler Interface The following sections describe implemented scheduler functionality for the `docker-local` scheduler. diff --git a/plugins/scheduler-docker-local/bin/scheduler-deploy-process b/plugins/scheduler-docker-local/bin/scheduler-deploy-process index bc567deb9..aeb6a60d1 100755 --- a/plugins/scheduler-docker-local/bin/scheduler-deploy-process +++ b/plugins/scheduler-docker-local/bin/scheduler-deploy-process @@ -4,6 +4,7 @@ set -eo pipefail source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions" source "$PLUGIN_AVAILABLE_PATH/checks/functions" +source "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/internal-functions" fn-scheduler-deploy-process() { declare APP="$1" IMAGE_SOURCE_TYPE="$2" IMAGE="$3" IMAGE_TAG="$4" PROC_TYPE="$5" PROC_COUNT="$6" @@ -36,7 +37,10 @@ fn-scheduler-deploy-process() { CONTAINER_INDEX=$((CONTAINER_INDEX + 1)) done - INJECT_INIT_FLAG="$(fn-plugin-property-get "scheduler-docker-local" "$APP" "init-process" "")" + INJECT_INIT_FLAG="$(fn-scheduler-docker-local-init-process "$APP")" + if [[ -z "$INJECT_INIT_FLAG" ]]; then + INJECT_INIT_FLAG="$(fn-plugin-property-get-default "scheduler-docker-local" "--global" "init-process" "")" + fi if [[ -z "$INJECT_INIT_FLAG" ]]; then # special-case linuxserver.io images as those always use an s6-overlay image_vendor="$("$DOCKER_BIN" image inspect --format '{{ index .Config.Labels "org.opencontainers.image.vendor" }}' "$IMAGE")" diff --git a/plugins/scheduler-docker-local/help-functions b/plugins/scheduler-docker-local/help-functions index 97f67800d..63444e048 100755 --- a/plugins/scheduler-docker-local/help-functions +++ b/plugins/scheduler-docker-local/help-functions @@ -28,6 +28,6 @@ fn-help-content() { declare desc="return help content" cat <] [], Displays a scheduler-docker-local report for one or more apps - scheduler-docker-local:set (), Set or clear a scheduler-docker-local property for an app + scheduler-docker-local:set [|--global] (), Set or clear a scheduler-docker-local property for an app or globally help_content } diff --git a/plugins/scheduler-docker-local/internal-functions b/plugins/scheduler-docker-local/internal-functions index e947d782a..921678500 100755 --- a/plugins/scheduler-docker-local/internal-functions +++ b/plugins/scheduler-docker-local/internal-functions @@ -42,13 +42,23 @@ cmd-scheduler-docker-local-report-single() { if [[ "$INFO_FLAG" == "true" ]]; then INFO_FLAG="" fi - if [[ "$APP" != "--global" ]]; then + local flag_map=() + if [[ "$APP" == "--global" ]]; then + flag_map=( + "--scheduler-docker-local-global-init-process: $(fn-scheduler-docker-local-global-init-process "$APP")" + "--scheduler-docker-local-global-parallel-schedule-count: $(fn-scheduler-docker-local-global-parallel-schedule-count "$APP")" + ) + else verify_app_name "$APP" + flag_map=( + "--scheduler-docker-local-computed-init-process: $(fn-scheduler-docker-local-computed-init-process "$APP")" + "--scheduler-docker-local-computed-parallel-schedule-count: $(fn-scheduler-docker-local-computed-parallel-schedule-count "$APP")" + "--scheduler-docker-local-global-init-process: $(fn-scheduler-docker-local-global-init-process "$APP")" + "--scheduler-docker-local-global-parallel-schedule-count: $(fn-scheduler-docker-local-global-parallel-schedule-count "$APP")" + "--scheduler-docker-local-init-process: $(fn-scheduler-docker-local-init-process "$APP")" + "--scheduler-docker-local-parallel-schedule-count: $(fn-scheduler-docker-local-parallel-schedule-count "$APP")" + ) fi - local flag_map=( - "--scheduler-docker-local-init-process: $(fn-plugin-property-get "scheduler-docker-local" "$APP" "init-process" "true")" - "--scheduler-docker-local-parallel-schedule-count: $(fn-plugin-property-get "scheduler-docker-local" "$APP" "parallel-schedule-count" "")" - ) fn-report-validate-format "$FORMAT" "$INFO_FLAG" @@ -85,6 +95,46 @@ cmd-scheduler-docker-local-report-single() { fi } +fn-scheduler-docker-local-init-process() { + declare APP="$1" + fn-plugin-property-get-default "scheduler-docker-local" "$APP" "init-process" "" +} + +fn-scheduler-docker-local-computed-init-process() { + declare APP="$1" + local value + value="$(fn-scheduler-docker-local-init-process "$APP")" + if [[ -z "$value" ]]; then + value="$(fn-scheduler-docker-local-global-init-process "$APP")" + fi + echo "$value" +} + +fn-scheduler-docker-local-global-init-process() { + declare APP="$1" + fn-plugin-property-get-default "scheduler-docker-local" "--global" "init-process" "true" +} + +fn-scheduler-docker-local-parallel-schedule-count() { + declare APP="$1" + fn-plugin-property-get-default "scheduler-docker-local" "$APP" "parallel-schedule-count" "" +} + +fn-scheduler-docker-local-computed-parallel-schedule-count() { + declare APP="$1" + local value + value="$(fn-scheduler-docker-local-parallel-schedule-count "$APP")" + if [[ -z "$value" ]]; then + value="$(fn-scheduler-docker-local-global-parallel-schedule-count "$APP")" + fi + echo "$value" +} + +fn-scheduler-docker-local-global-parallel-schedule-count() { + declare APP="$1" + fn-plugin-property-get-default "scheduler-docker-local" "--global" "parallel-schedule-count" "1" +} + fn-scheduler-docker-local-get-checks-file-path() { declare APP="$1" diff --git a/plugins/scheduler-docker-local/scheduler-deploy b/plugins/scheduler-docker-local/scheduler-deploy index 16c3370be..dfb0cc572 100755 --- a/plugins/scheduler-docker-local/scheduler-deploy +++ b/plugins/scheduler-docker-local/scheduler-deploy @@ -74,7 +74,7 @@ trigger-scheduler-docker-local-scheduler-deploy() { DOKKU_NETWORK_BIND_ALL="$DOKKU_NETWORK_BIND_ALL" DOKKU_HEROKUISH="$DOKKU_HEROKUISH" DOKKU_CNB="$DOKKU_CNB" DOCKER_RUN_LABEL_ARGS="$DOCKER_RUN_LABEL_ARGS" DOKKU_START_CMD="$DOKKU_START_CMD" DOCKER_STOP_TIME_ARG="$DOCKER_STOP_TIME_ARG" "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/bin/scheduler-deploy-process" "$APP" "$IMAGE_SOURCE_TYPE" "$IMAGE" "$IMAGE_TAG" "$PROC_TYPE" "$PROC_COUNT" done < <(plugn trigger ps-current-scale "$APP") - PARALLEL_DEPLOY_COUNT="$(fn-plugin-property-get "scheduler-docker-local" "$APP" "parallel-schedule-count" "1")" + PARALLEL_DEPLOY_COUNT="$(fn-scheduler-docker-local-computed-parallel-schedule-count "$APP")" DOKKU_NETWORK_BIND_ALL="$DOKKU_NETWORK_BIND_ALL" DOKKU_HEROKUISH="$DOKKU_HEROKUISH" DOKKU_CNB="$DOKKU_CNB" DOCKER_RUN_LABEL_ARGS="$DOCKER_RUN_LABEL_ARGS" DOKKU_START_CMD="$DOKKU_START_CMD" DOCKER_STOP_TIME_ARG="$DOCKER_STOP_TIME_ARG" parallel --will-cite --halt soon,fail=1 --jobs "$PARALLEL_DEPLOY_COUNT" --ungroup <"$TMP_FILE" diff --git a/plugins/scheduler-docker-local/subcommands/set b/plugins/scheduler-docker-local/subcommands/set index eade01b3a..26abf238f 100755 --- a/plugins/scheduler-docker-local/subcommands/set +++ b/plugins/scheduler-docker-local/subcommands/set @@ -5,12 +5,12 @@ set -eo pipefail [[ $DOKKU_TRACE ]] && set -x cmd-scheduler-docker-local-set() { - declare desc="set or clear a scheduler-docker-local property for an app" + declare desc="set or clear a scheduler-docker-local property for an app or globally" declare cmd="scheduler-docker-local:set" [[ "$1" == "$cmd" ]] && shift 1 declare APP="$1" KEY="$2" VALUE="$3" local VALID_KEYS=("init-process" "parallel-schedule-count") - verify_app_name "$APP" + [[ "$APP" == "--global" ]] || verify_app_name "$APP" [[ -z "$KEY" ]] && dokku_log_fail "No key specified" diff --git a/tests/unit/scheduler-docker-local.bats b/tests/unit/scheduler-docker-local.bats index 2dc5a677f..f5ef9ec5d 100644 --- a/tests/unit/scheduler-docker-local.bats +++ b/tests/unit/scheduler-docker-local.bats @@ -10,12 +10,18 @@ teardown() { global_teardown } -@test "(scheduler-docker-local:report) --global --scheduler-docker-local-init-process" { - run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-init-process" +@test "(scheduler-docker-local:report) --global --scheduler-docker-local-global-init-process" { + run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-global-init-process" echo "output: $output" echo "status: $status" assert_success assert_output "true" + + run /bin/bash -c "dokku scheduler-docker-local:report --global --scheduler-docker-local-global-parallel-schedule-count" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "1" } @test "(scheduler-docker-local:report) info-flag works before deploy" { @@ -28,11 +34,36 @@ teardown() { echo "output: $output" echo "status: $status" assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-computed-parallel-schedule-count" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "1" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-global-parallel-schedule-count" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "1" run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-init-process" echo "output: $output" echo "status: $status" assert_success + assert_output "" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-computed-init-process" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "true" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-global-init-process" + echo "output: $output" + echo "status: $status" + assert_success assert_output "true" run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --scheduler-docker-local-invalid-flag" @@ -44,6 +75,104 @@ teardown() { destroy_app } +@test "(scheduler-docker-local:report) --format json" { + run create_app + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -e ." + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"init-process\"'" + echo "output: $output" + echo "status: $status" + assert_output "" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"computed-init-process\"'" + echo "output: $output" + echo "status: $status" + assert_output "true" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"global-init-process\"'" + echo "output: $output" + echo "status: $status" + assert_output "true" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"parallel-schedule-count\"'" + echo "output: $output" + echo "status: $status" + assert_output "" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"computed-parallel-schedule-count\"'" + echo "output: $output" + echo "status: $status" + assert_output "1" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"global-parallel-schedule-count\"'" + echo "output: $output" + echo "status: $status" + assert_output "1" + + run /bin/bash -c "dokku scheduler-docker-local:set $TEST_APP init-process false" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"init-process\"'" + echo "output: $output" + echo "status: $status" + assert_output "false" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"computed-init-process\"'" + echo "output: $output" + echo "status: $status" + assert_output "false" + + destroy_app +} + +@test "(scheduler-docker-local:set) --global" { + run /bin/bash -c "dokku scheduler-docker-local:set --global parallel-schedule-count 4" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku scheduler-docker-local:report --global --format json | jq -r '.\"global-parallel-schedule-count\"'" + echo "output: $output" + echo "status: $status" + assert_output "4" + + run create_app + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"parallel-schedule-count\"'" + echo "output: $output" + echo "status: $status" + assert_output "" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"computed-parallel-schedule-count\"'" + echo "output: $output" + echo "status: $status" + assert_output "4" + + run /bin/bash -c "dokku scheduler-docker-local:report $TEST_APP --format json | jq -r '.\"global-parallel-schedule-count\"'" + echo "output: $output" + echo "status: $status" + assert_output "4" + + run /bin/bash -c "dokku scheduler-docker-local:set --global parallel-schedule-count" + echo "output: $output" + echo "status: $status" + assert_success + + destroy_app +} + @test "(scheduler-docker-local) scheduler-docker-local:help" { run /bin/bash -c "dokku scheduler-docker-local" echo "output: $output"