Emitting the restart policy as a `--restart` argument from a `docker-args-process-deploy` trigger exposed a latent gluing bug: proxy and builder triggers concatenated `$STDIN$output` with no separator, and the scheduler and builders appended `docker-args-process-*` output directly onto the older `docker-args-*` output, so adjacent arguments could merge into values like `--restart=on-failure:10--label`. A space is now inserted at both the trigger echo and the concatenation so arguments always stay separated.
114 lines
5.0 KiB
Bash
Executable File
114 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -eo pipefail
|
|
[[ $DOKKU_TRACE ]] && set -x
|
|
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"
|
|
local CONTAINER_INDEX=1
|
|
local image_vendor
|
|
|
|
dokku_log_info1 "Deploying $PROC_TYPE (count=$PROC_COUNT)"
|
|
DOKKU_CHECKS_DISABLED="$(is_app_proctype_checks_disabled "$APP" "$PROC_TYPE")"
|
|
if [[ "$DOKKU_CHECKS_DISABLED" == "true" ]]; then
|
|
dokku_log_verbose "Zero downtime is disabled, stopping currently running containers ($PROC_TYPE)"
|
|
local cid proctype_oldids="$(get_app_running_container_ids "$APP" "$PROC_TYPE" 2>/dev/null)"
|
|
for cid in $proctype_oldids; do
|
|
dokku_log_verbose "Stopping $cid ($PROC_TYPE)"
|
|
|
|
# Retire the containers to ensure they get removed
|
|
plugn trigger scheduler-register-retired "$APP" "$cid" "$DOKKU_WAIT_TO_RETIRE"
|
|
|
|
# Disable the container restart policy
|
|
"$DOCKER_BIN" container update --restart=no "$cid" &>/dev/null || true
|
|
|
|
"$DOCKER_BIN" container stop $DOCKER_STOP_TIME_ARG "$cid" &>/dev/null
|
|
done
|
|
fi
|
|
|
|
local PROCESS_TMP_FILE=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
|
|
trap "rm -rf '$PROCESS_TMP_FILE' >/dev/null" RETURN INT TERM EXIT
|
|
|
|
while [[ $CONTAINER_INDEX -le $PROC_COUNT ]]; do
|
|
echo "$PLUGIN_AVAILABLE_PATH/scheduler-docker-local/bin/scheduler-deploy-process-container $APP $IMAGE_SOURCE_TYPE $IMAGE $IMAGE_TAG $PROC_TYPE $PROC_COUNT $CONTAINER_INDEX" >>"$PROCESS_TMP_FILE"
|
|
CONTAINER_INDEX=$((CONTAINER_INDEX + 1))
|
|
done
|
|
|
|
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")"
|
|
if [[ "$image_vendor" == "linuxserver.io" ]]; then
|
|
INJECT_INIT_FLAG="false"
|
|
else
|
|
INJECT_INIT_FLAG="true"
|
|
fi
|
|
fi
|
|
|
|
local DOCKER_ARGS
|
|
DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG" "$PROC_TYPE")
|
|
DOCKER_ARGS+=" $(: | plugn trigger docker-args-process-deploy "$APP" "$IMAGE_SOURCE_TYPE" "$IMAGE_TAG" "$PROC_TYPE")"
|
|
DOCKER_ARGS=" $DOCKER_ARGS "
|
|
declare -a ARG_ARRAY
|
|
eval "ARG_ARRAY=($DOCKER_ARGS)"
|
|
|
|
local port_published=false
|
|
for arg in "${ARG_ARRAY[@]}"; do
|
|
if [[ "$arg" == "-p "* ]] || [[ "$arg" =~ "--publish "* ]] || [[ "$arg" == "-P" ]] || [[ "$arg" =~ "--publish-all"* ]]; then
|
|
port_published=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ "$port_published" == "true" ]]; then
|
|
local warned_on_publish=false
|
|
if [[ "$PROC_COUNT" -gt 1 ]]; then
|
|
warned_on_publish=true
|
|
dokku_log_warn "Deploys may fail when publishing ports and scaling to multiple containers. Consider scaling process type $PROC_TYPE to 1."
|
|
fi
|
|
if [[ "$DOKKU_CHECKS_DISABLED" != "true" ]] && [[ "$warned_on_publish" == "false" ]]; then
|
|
warned_on_publish=true
|
|
dokku_log_warn "Deploys may fail when publishing ports and enabling zero downtime. Consider disabling zero downtime for process type $PROC_TYPE."
|
|
fi
|
|
fi
|
|
|
|
PARALLEL_DEPLOY_COUNT="$(plugn trigger "app-json-process-deploy-parallelism" "$APP" "$PROC_TYPE")"
|
|
DOKKU_CHECKS_DISABLED="$DOKKU_CHECKS_DISABLED" INJECT_INIT_FLAG="$INJECT_INIT_FLAG" parallel --will-cite --halt soon,fail=1 --jobs "$PARALLEL_DEPLOY_COUNT" --ungroup <"$PROCESS_TMP_FILE"
|
|
|
|
plugn trigger scheduler-post-deploy-process "$APP" "$PROC_TYPE"
|
|
|
|
# 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 orphaned_container_file orphaned_cid
|
|
pushd "$DOKKU_ROOT/$APP" >/dev/null
|
|
for orphaned_container_file in $(find . -maxdepth 1 -name "CONTAINER.$PROC_TYPE.*" -printf "%f\n" | sort -t . -k 3 -n | tail -n +$CONTAINER_IDX_OFFSET); do
|
|
[[ -s "$orphaned_container_file" ]] || continue
|
|
orphaned_cid="$(<"$orphaned_container_file")"
|
|
[[ -z "$orphaned_cid" ]] && continue
|
|
dokku_log_verbose "Scheduling orphaned container shutdown in $DOKKU_WAIT_TO_RETIRE seconds (${orphaned_container_file#CONTAINER.})"
|
|
plugn trigger scheduler-register-retired "$APP" "$orphaned_cid" "$DOKKU_WAIT_TO_RETIRE"
|
|
done
|
|
for container_state_filetype in CONTAINER IP PORT; do
|
|
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
|
|
popd &>/dev/null || pushd "/tmp" >/dev/null
|
|
}
|
|
|
|
main() {
|
|
declare desc="wrapper function to ensure tmp files are properly annotated"
|
|
|
|
fn-scheduler-deploy-process "$@"
|
|
}
|
|
|
|
main "$@"
|