feat: split scheduler-docker-local report into raw, computed, and global

The bare `init-process` and `parallel-schedule-count` keys previously returned the computed value, so external tooling could not tell whether a property had been set on the app or was merely defaulting. Both properties are now also configurable with `--global`, the report exposes `computed-*` and `global-*` keys alongside the bare raw keys, and the deploy path honors the global value before falling back to the linuxserver.io vendor heuristic.
This commit is contained in:
Jose Diaz-Gonzalez
2026-05-11 22:29:28 -04:00
parent db2cbd802f
commit 7d73cf78c4
7 changed files with 272 additions and 14 deletions

View File

@@ -5,7 +5,7 @@
```
scheduler-docker-local:report [<app>] [<flag>] # Displays a scheduler-docker-local report for one or more apps
scheduler-docker-local:set <app> <key> (<value>) # Set or clear a scheduler-docker-local property for an app
scheduler-docker-local:set [<app>|--global] <key> (<value>) # 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.

View File

@@ -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")"

View File

@@ -28,6 +28,6 @@ fn-help-content() {
declare desc="return help content"
cat <<help_content
scheduler-docker-local:report [<app>] [<flag>], Displays a scheduler-docker-local report for one or more apps
scheduler-docker-local:set <app> <property> (<value>), Set or clear a scheduler-docker-local property for an app
scheduler-docker-local:set [<app>|--global] <property> (<value>), Set or clear a scheduler-docker-local property for an app or globally
help_content
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"