hizrianraz's picture
SAQS freeze card sync from 617c08a30546 (parent 7525c28aecc6; role Preview; gitignore-aware)
e40f52e verified
Raw
History Blame Contribute Delete
18.5 kB
#!/bin/bash -p
{ builtin set +x; } 2>/dev/null
# Guarded Preview launcher for the exact official FP8 snapshot and pinned vLLM
# arm64 image. A successful process start is not a measured/runnable receipt.
if [[ "$-" != *p* || "${BASH_SOURCE[0]}" != "$0" ]]; then
/usr/bin/printf '%s\n' 'FAIL-CLOSED: execute this file directly; sourcing/plain bash is unsupported' >&2
exit 126
fi
builtin unset POSIXLY_CORRECT POSIX_PEDANTIC BASH_COMPAT GLOBIGNORE
builtin set +o posix
builtin set -euo pipefail
IFS=$' \t\n'
PS4='+ '
builtin umask 077
builtin ulimit -c 0
if (( EUID == 0 || EUID != UID )); then
/usr/bin/printf '%s\n' 'FAIL-CLOSED: launch as one unprivileged user with matching real/effective IDs' >&2
exit 126
fi
readonly CLEAN_PATH="/usr/local/cuda/bin:/usr/bin:/bin"
builtin export PATH="${CLEAN_PATH}"
builtin unset LD_PRELOAD LD_AUDIT LD_LIBRARY_PATH CDPATH ENV BASH_ENV TMPDIR TMP TEMP \
PYTHONPATH PYTHONHOME PYTHONSTARTUP PYTHONINSPECT PYTHONWARNINGS PYTHONUSERBASE \
DOCKER_HOST DOCKER_CONTEXT DOCKER_TLS_VERIFY DOCKER_CERT_PATH DOCKER_CONFIG \
HTTP_PROXY HTTPS_PROXY ALL_PROXY http_proxy https_proxy all_proxy NO_PROXY no_proxy
for inherited_function in awk basename cat cd chmod command curl date dirname docker echo env export find git grep jq kill mkdir nvidia-smi pgrep printf pwd python3 readlink rmdir sed set sha256sum sleep ss stat tr uname unset wc; do
builtin unset -f "${inherited_function}" 2>/dev/null || true
done
API_KEY="${VLLM_API_KEY:-}"
EXPECTED_PACK_REVISION="${QWEN_EXPECT_PACK_REVISION:-}"
EXPECTED_PACK_ROOT="${QWEN_ALLOWED_PACK_ROOT:-}"
ALLOWED_MODEL_ROOT_INPUT="${QWEN_ALLOWED_MODEL_ROOT:-}"
MODEL_INPUT="${QWEN_FP8_DIR:-}"
HOST="${HOST:-127.0.0.1}"
PORT="${PORT:-8001}"
CTX="${CTX:-32768}"
GPU_MEM_UTIL="${GPU_MEM_UTIL:-0.80}"
CONTAINER_NAME="${QWEN_CONTAINER_NAME:-qwen3-coder-next-fp8-vllm}"
MEASURE_OWNER="${SAQS_MEASURE_OWNER:-}"
builtin export -n API_KEY EXPECTED_PACK_REVISION EXPECTED_PACK_ROOT ALLOWED_MODEL_ROOT_INPUT MODEL_INPUT 2>/dev/null || true
builtin unset VLLM_API_KEY QWEN_EXPECT_PACK_REVISION QWEN_ALLOWED_PACK_ROOT QWEN_ALLOWED_MODEL_ROOT \
QWEN_FP8_DIR MODEL TP MAX_NUM_SEQS QWEN_MIN_AVAILABLE_GIB VLLM_IMAGE VLLM_IMAGE_DIGEST \
TRUST_REMOTE_CODE EXPOSE_LAN MEASURE_WINDOW SAQS_MEASURE_OWNER
readonly ROOT="$(builtin cd "$(/usr/bin/dirname -- "${BASH_SOURCE[0]}")/.." && builtin pwd -P)"
readonly EXPECTED_ORIGIN="https://github.com/hizrianraz/Qwen3-Coder-Next-Spark-Agentic.git"
readonly EXPECTED_REPO="Qwen/Qwen3-Coder-Next-FP8"
readonly EXPECTED_REVISION="da6e2ed27304dd39abadd9c82ef50e8de67bdd4c"
readonly EXPECTED_VERIFIED_REVISION="${EXPECTED_REPO}@${EXPECTED_REVISION}"
readonly EXPECTED_MANIFEST_SHA256="d7269c078ec614ae57792ec63da00b3e13cf88e61f421ef4bcf4bdaac54b0190"
readonly EXPECTED_VERIFIED_FILES=52
readonly EXPECTED_SHARDS=40
readonly VLLM_IMAGE="vllm/vllm-openai@sha256:e4f88a835143cd22aee2397a26ec6bb80b3a4a6fe0c882bcbc63822904766089"
readonly VLLM_OCI_INDEX_DIGEST="sha256:e4f88a835143cd22aee2397a26ec6bb80b3a4a6fe0c882bcbc63822904766089"
readonly VLLM_ARM64_MANIFEST_DIGEST="sha256:2cc49b81319f7a66a33dd8bd63a7bfddae079122b33ce51989b6828a1f038c37"
readonly VLLM_CONFIG_DIGEST="sha256:30a38a1d74a17365eca400e83ffd885b250e0c8c0d3c5b508afa8c412d2ddf95"
readonly VLLM_VERSION="0.25.1"
readonly VLLM_COMMIT="752a3a504485790a2e8491cacbb35c137339ad34"
readonly MANIFEST="${ROOT}/results/SHA256SUMS.fp8"
readonly DOCKER_BIN="/usr/bin/docker"
readonly DOCKER_SOCKET="/var/run/docker.sock"
readonly DOCKER_ENDPOINT="unix:///var/run/docker.sock"
readonly MIN_AVAILABLE_KIB=$((96 * 1024 * 1024))
readonly MIN_TOTAL_KIB=$((115 * 1024 * 1024))
early_die() { /usr/bin/printf 'FAIL-CLOSED: %s\n' "$*" >&2; exit 3; }
git_clean() {
/usr/bin/env -i PATH="${CLEAN_PATH}" LC_ALL=C GIT_CONFIG_NOSYSTEM=1 HOME=/nonexistent \
/usr/bin/git -c core.fsmonitor=false -c core.hooksPath=/dev/null "$@"
}
# The commit/root values must come from an independently reviewed release
# record. Deriving them from this checkout would not be an immutable source pin.
[[ "${EXPECTED_PACK_REVISION}" =~ ^[0-9a-f]{40}$ ]] || early_die \
"set QWEN_EXPECT_PACK_REVISION to the authorized published 40-hex commit"
[[ -n "${EXPECTED_PACK_ROOT}" && "${EXPECTED_PACK_ROOT}" == /* ]] || early_die \
"set QWEN_ALLOWED_PACK_ROOT to the canonical absolute checkout root"
[[ "${EXPECTED_PACK_ROOT%/}" == "${ROOT}" ]] || early_die "executed pack root differs from QWEN_ALLOWED_PACK_ROOT"
actual_head="$(git_clean -C "${ROOT}" rev-parse --verify HEAD 2>/dev/null)" || early_die "pack is not a trusted Git checkout"
[[ "${actual_head}" == "${EXPECTED_PACK_REVISION}" ]] || early_die "pack commit does not match the authorized revision"
actual_origin="$(git_clean -C "${ROOT}" remote get-url origin 2>/dev/null)" || early_die "pack has no canonical origin"
[[ "${actual_origin}" == "${EXPECTED_ORIGIN}" ]] || early_die "pack origin must equal ${EXPECTED_ORIGIN}"
git_clean -C "${ROOT}" diff --quiet --ignore-submodules -- || early_die "pack has unstaged tracked changes"
git_clean -C "${ROOT}" diff --cached --quiet --ignore-submodules -- || early_die "pack has staged tracked changes"
tracked_status="$(git_clean -C "${ROOT}" status --porcelain=v1 --untracked-files=no --ignore-submodules=none)"
[[ -z "${tracked_status}" ]] || early_die "pack tracked tree is not clean at the authorized commit"
for required_tracked_path in scripts/serve_vllm_fp8.sh scripts/_qwen_runtime_common.sh results/SHA256SUMS.fp8; do
git_clean -C "${ROOT}" ls-files --error-unmatch -- "${required_tracked_path}" >/dev/null 2>&1 || early_die \
"critical runtime path is not tracked by the authorized commit: ${required_tracked_path}"
done
readonly QWEN_PACK_ROOT="${ROOT}"
QWEN_COMMON_IMPORT_TOKEN="qwen-common-after-git-bind-v1"
builtin source "${ROOT}/scripts/_qwen_runtime_common.sh"
qwen_validate_trusted_directory_chain "${ROOT}" "pack root"
qwen_validate_regular_file "${ROOT}/scripts/serve_vllm_fp8.sh" "Qwen launcher"
qwen_validate_regular_file "${ROOT}/scripts/_qwen_runtime_common.sh" "Qwen runtime library"
qwen_validate_regular_file "${MANIFEST}" "FP8 checksum manifest"
[[ "$(qwen_hash_file "${MANIFEST}")" == "${EXPECTED_MANIFEST_SHA256}" ]] || qwen_die "pack FP8 manifest digest mismatch"
[[ -n "${ALLOWED_MODEL_ROOT_INPUT}" ]] || qwen_die "set QWEN_ALLOWED_MODEL_ROOT to a pre-created private model root"
ALLOWED_MODEL_ROOT="$(qwen_lexical_abs "${ALLOWED_MODEL_ROOT_INPUT}")"
qwen_validate_allowed_model_root "${ALLOWED_MODEL_ROOT}"
MODEL="${MODEL_INPUT:-${ALLOWED_MODEL_ROOT}/${QWEN_MODEL_BASENAME}}"
MODEL="$(qwen_lexical_abs "${MODEL}")"
[[ "${MODEL}" == "${ALLOWED_MODEL_ROOT}/${QWEN_MODEL_BASENAME}" ]] || qwen_die \
"model must equal <QWEN_ALLOWED_MODEL_ROOT>/${QWEN_MODEL_BASENAME}"
qwen_validate_model_tree_security "${MODEL}"
if (( ${#API_KEY} < 32 || ${#API_KEY} > 256 )) || [[ ! "${API_KEY}" =~ ^[A-Za-z0-9._~-]+$ ]]; then
qwen_die "set VLLM_API_KEY to 32..256 random URL-safe characters"
fi
case "${HOST}" in 127.0.0.1|localhost) HOST="127.0.0.1" ;; *) qwen_die "host publication is fixed to 127.0.0.1" ;; esac
[[ "${PORT}" == "8001" ]] || qwen_die "Preview profile requires port 8001"
[[ "${CTX}" =~ ^[0-9]+$ ]] || qwen_die "CTX must be an integer"
(( CTX >= 2048 && CTX <= 32768 )) || qwen_die "CTX must be 2048..32768"
if ! /usr/bin/awk -v value="${GPU_MEM_UTIL}" 'BEGIN {exit !(value ~ /^[0-9]+([.][0-9]+)?$/ && value >= 0.50 && value <= 0.80)}'; then
qwen_die "GPU_MEM_UTIL must be 0.50..0.80"
fi
[[ "${CONTAINER_NAME}" =~ ^qwen3-coder-next-fp8-vllm(-[A-Za-z0-9][A-Za-z0-9_.-]{0,80})?$ ]] || qwen_die "invalid Qwen container name"
[[ -z "${MEASURE_OWNER}" || "${MEASURE_OWNER}" =~ ^[0-9a-f]{64}$ ]] || qwen_die "invalid SAQS_MEASURE_OWNER"
marker_value() {
local key="$1" marker="$2" count
count="$(/usr/bin/awk -F= -v key="${key}" '$1 == key {n++} END {print n+0}' "${marker}")"
[[ "${count}" == "1" ]] || qwen_die "marker must contain exactly one ${key}= entry"
/usr/bin/awk -F= -v key="${key}" '$1 == key {sub(/^[^=]*=/, ""); print}' "${marker}"
}
qwen_verify_snapshot() {
local required marker tree_entries top_files snapshot_files verified_files=0 verified_shards=0 expected name verified_at
qwen_validate_model_tree_security "${MODEL}"
for required in config.json generation_config.json model.safetensors.index.json PULL_COMPLETE .verified-revision; do
qwen_validate_regular_file "${MODEL}/${required}" "model ${required}"
done
[[ "$(/usr/bin/cat -- "${MODEL}/.verified-revision")" == "${EXPECTED_VERIFIED_REVISION}" ]] || qwen_die "verified revision mismatch"
marker="${MODEL}/PULL_COMPLETE"
[[ "$(marker_value schema "${marker}")" == "saqs.fp8_verification/v2" ]] || qwen_die "unsupported marker schema"
[[ "$(marker_value repo "${marker}")" == "${EXPECTED_REPO}" ]] || qwen_die "marker repository mismatch"
[[ "$(marker_value revision "${marker}")" == "${EXPECTED_REVISION}" ]] || qwen_die "marker revision mismatch"
[[ "$(marker_value verified_revision "${marker}")" == "${EXPECTED_VERIFIED_REVISION}" ]] || qwen_die "marker verified-revision mismatch"
[[ "$(marker_value manifest_sha256 "${marker}")" == "${EXPECTED_MANIFEST_SHA256}" ]] || qwen_die "marker manifest mismatch"
[[ "$(marker_value verified_files "${marker}")" == "${EXPECTED_VERIFIED_FILES}" ]] || qwen_die "marker file-count mismatch"
[[ "$(marker_value verified_shards "${marker}")" == "${EXPECTED_SHARDS}" ]] || qwen_die "marker shard-count mismatch"
[[ "$(marker_value status "${marker}")" == "verified" ]] || qwen_die "marker is not verified"
[[ "$(marker_value diy_gguf "${marker}")" == "false" ]] || qwen_die "marker must identify official FP8, not DIY GGUF"
verified_at="$(marker_value verified_at "${marker}")"
[[ "${verified_at}" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[^[:space:]]+$ ]] || qwen_die "marker verified_at is malformed"
tree_entries="$(/usr/bin/find "${MODEL}" -mindepth 1 | /usr/bin/wc -l | /usr/bin/tr -d '[:space:]')"
top_files="$(/usr/bin/find "${MODEL}" -mindepth 1 -maxdepth 1 -type f | /usr/bin/wc -l | /usr/bin/tr -d '[:space:]')"
[[ "${tree_entries}" == "54" && "${top_files}" == "54" ]] || qwen_die \
"model tree must contain only 52 upstream files and two verification markers"
snapshot_files="$(/usr/bin/find "${MODEL}" -maxdepth 1 -type f ! -name PULL_COMPLETE ! -name .verified-revision | /usr/bin/wc -l | /usr/bin/tr -d '[:space:]')"
[[ "${snapshot_files}" == "${EXPECTED_VERIFIED_FILES}" ]] || qwen_die "model tree must contain exactly 52 upstream files"
while read -r expected name; do
[[ "${expected}" =~ ^[0-9a-f]{64}$ ]] || continue
case "${name}" in /*|../*|*/../*|*/..) qwen_die "unsafe manifest path: ${name}" ;; esac
qwen_validate_regular_file "${MODEL}/${name}" "snapshot ${name}"
[[ "$(qwen_hash_file "${MODEL}/${name}")" == "${expected}" ]] || qwen_die "SHA-256 mismatch for ${name}"
verified_files=$((verified_files + 1))
[[ "${name}" == model-*-of-00040.safetensors ]] && verified_shards=$((verified_shards + 1))
done < <(/usr/bin/awk 'NF >= 2 && $1 ~ /^[0-9a-fA-F]{64}$/ {print tolower($1), $NF}' "${MANIFEST}")
[[ "${verified_files}" == "52" && "${verified_shards}" == "40" ]] || qwen_die "snapshot verification incomplete"
}
qwen_verify_snapshot
# Pin the target machine before any container action.
arch="$(/usr/bin/uname -m)"
[[ "${arch}" == "aarch64" || "${arch}" == "arm64" ]] || qwen_die "DGX Spark target must be arm64/aarch64"
gpu_names="$(/usr/bin/nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null)" || qwen_die "cannot query GPU identity"
[[ "$(/usr/bin/printf '%s\n' "${gpu_names}" | /usr/bin/awk 'NF {n++} END {print n+0}')" == "1" ]] || qwen_die "DGX Spark target must expose one GPU"
[[ "${gpu_names}" == *GB10* ]] || qwen_die "DGX Spark target must expose GB10"
mem_total_kib="$(/usr/bin/awk '/^MemTotal:/ {print $2; found=1} END {if (!found) exit 1}' /proc/meminfo)" || qwen_die "cannot read MemTotal"
(( mem_total_kib >= MIN_TOTAL_KIB )) || qwen_die "target must expose at least 115 GiB MemTotal"
docker_clean() {
/usr/bin/env -i PATH="${CLEAN_PATH}" HOME=/nonexistent LC_ALL=C \
"${DOCKER_BIN}" "$@"
}
docker_local() {
/usr/bin/env -i PATH="${CLEAN_PATH}" HOME=/nonexistent LC_ALL=C DOCKER_HOST="${DOCKER_ENDPOINT}" \
"${DOCKER_BIN}" "$@"
}
image_id=""
verify_docker_boundary() {
local socket_real socket_mode docker_context context_host image_arch image_os
qwen_validate_regular_file "${DOCKER_BIN}" "Docker client"
[[ -S "${DOCKER_SOCKET}" && ! -L "${DOCKER_SOCKET}" ]] || qwen_die "local Docker Unix socket is unavailable"
socket_real="$(/usr/bin/readlink -f -- "${DOCKER_SOCKET}")" || qwen_die "cannot resolve Docker socket"
[[ "${socket_real}" == "/run/docker.sock" || "${socket_real}" == "/var/run/docker.sock" ]] || qwen_die "Docker socket resolves outside the local system socket"
[[ "$(qwen_stat_owner "${DOCKER_SOCKET}")" == "0" ]] || qwen_die "Docker socket must be root-owned"
socket_mode="$(qwen_stat_mode "${DOCKER_SOCKET}")"
(( (8#${socket_mode} & 0002) == 0 )) || qwen_die "Docker socket must not be world writable"
docker_context="$(docker_clean context show 2>/dev/null)" || qwen_die "cannot query Docker context"
[[ "${docker_context}" == "default" ]] || qwen_die "Docker context must be default"
context_host="$(docker_clean context inspect default --format '{{ (index .Endpoints "docker").Host }}' 2>/dev/null)" || qwen_die "cannot inspect Docker context"
[[ "${context_host}" == "unix:///var/run/docker.sock" || "${context_host}" == "unix:///run/docker.sock" ]] || qwen_die "Docker context is not the local Unix daemon"
[[ -n "$(docker_local info --format '{{.Name}}' 2>/dev/null)" ]] || qwen_die "local Docker daemon is unavailable"
image_id="$(docker_local image inspect --format '{{.Id}}' "${VLLM_IMAGE}" 2>/dev/null)" || qwen_die \
"pinned image is absent; pull the exact digest for linux/arm64 before launch"
image_arch="$(docker_local image inspect --format '{{.Architecture}}' "${VLLM_IMAGE}")"
image_os="$(docker_local image inspect --format '{{.Os}}' "${VLLM_IMAGE}")"
[[ "${image_id}" == "${VLLM_CONFIG_DIGEST}" && "${image_arch}" == "arm64" && "${image_os}" == "linux" ]] || qwen_die \
"local image ID/platform does not match the audited arm64 descriptor chain"
}
verify_docker_boundary
check_residency() {
local processes containers available total free used port_rows gpu_rows
processes="$(/usr/bin/pgrep -af '(llama-server|pulsar-server|ds4-server|vllm[[:space:]]+serve|vllm[.]entrypoints|sglang[.]launch_server|ollama[[:space:]]+serve|text-generation-launcher|tritonserver)' 2>/dev/null || true)"
[[ -z "${processes}" ]] || qwen_die "known model runtime already resident: ${processes//$'\n'/; }"
containers="$(docker_local ps --format '{{.ID}} {{.Names}} {{.Image}}' 2>/dev/null)" || qwen_die "cannot inventory Docker containers"
containers="$(/usr/bin/printf '%s\n' "${containers}" | /usr/bin/grep -Ei 'laguna|deepseek|qwen|vllm|sglang|llama|pulsar|ds4|ollama|text-generation|triton' || true)"
[[ -z "${containers}" ]] || qwen_die "model-serving container already resident: ${containers//$'\n'/; }"
gpu_rows="$(/usr/bin/nvidia-smi --query-compute-apps=pid,process_name --format=csv,noheader,nounits 2>/dev/null)" || qwen_die "cannot inventory GPU compute processes"
[[ -z "${gpu_rows}" ]] || qwen_die "GPU compute process already resident: ${gpu_rows//$'\n'/; }"
available="$(/usr/bin/awk '/^MemAvailable:/ {print $2; found=1} END {if (!found) exit 1}' /proc/meminfo)" || qwen_die "cannot refresh MemAvailable"
total="$(/usr/bin/awk '/^SwapTotal:/ {print $2; found=1} END {if (!found) print 0}' /proc/meminfo)"
free="$(/usr/bin/awk '/^SwapFree:/ {print $2; found=1} END {if (!found) print 0}' /proc/meminfo)"
used=$((total - free))
(( available >= MIN_AVAILABLE_KIB )) || qwen_die "single-model gate requires at least 96 GiB MemAvailable"
(( used == 0 )) || qwen_die "active swap is forbidden at launch"
port_rows="$(/usr/bin/ss -H -ltn "sport = :${PORT}" 2>/dev/null)" || qwen_die "cannot inventory TCP port ${PORT}"
[[ -z "${port_rows}" ]] || qwen_die "TCP port ${PORT} is already listening"
}
qwen_acquire_operation_lock
trap 'qwen_release_locks' EXIT
trap 'qwen_release_locks; exit 130' INT
trap 'qwen_release_locks; exit 143' TERM
trap 'qwen_release_locks; exit 129' HUP
check_residency
qwen_acquire_host_residency_lock
# Refresh every mutable boundary after both locks are held and immediately
# before docker run. This remains point-in-time protection against same-UID or
# privileged actors; the card does not call loopback or the API key a sandbox.
qwen_verify_snapshot
[[ "$(qwen_hash_file "${MANIFEST}")" == "${EXPECTED_MANIFEST_SHA256}" ]] || qwen_die "manifest changed after preflight"
verify_docker_boundary
check_residency
/usr/bin/printf '%s\n' "[qwen-preview] snapshot=${EXPECTED_VERIFIED_REVISION} files=52 shards=40"
/usr/bin/printf '%s\n' "[qwen-preview] image=${VLLM_IMAGE} arm64_manifest=${VLLM_ARM64_MANIFEST_DIGEST} image_id=${image_id}"
/usr/bin/printf '%s\n' '[qwen-preview] network=trusted-single-user-loopback; VLLM_API_KEY protects /v1,/v2,/inference prefixes and does not protect every vLLM endpoint'
/usr/bin/printf '%s\n' '[qwen-preview] evidence=unverified exact model load; no runnable, tool, throughput, hero, or SAQS claim'
DOCKER_ARGS=(
run --rm --pull never --gpus all --platform linux/arm64
--name "${CONTAINER_NAME}"
--label "saqs.pack=Qwen3-Coder-Next-Spark-Agentic"
--security-opt no-new-privileges:true
--cap-drop ALL
--pids-limit 4096
--ulimit core=0
--shm-size=16g
--publish "${HOST}:${PORT}:8000"
--volume "${MODEL}:/model:ro"
--env VLLM_API_KEY
--env VLLM_PLUGINS=
--env VLLM_DEBUG_LOG_API_SERVER_RESPONSE=0
)
if [[ -n "${MEASURE_OWNER}" ]]; then DOCKER_ARGS+=(--label "saqs.measure_owner=${MEASURE_OWNER}"); fi
DOCKER_ARGS+=(
"${VLLM_IMAGE}"
--model /model
--served-model-name local-qwen3-coder-next
--host 0.0.0.0
--port 8000
--tensor-parallel-size 1
--max-model-len "${CTX}"
--gpu-memory-utilization "${GPU_MEM_UTIL}"
--max-num-seqs 1
--cpu-offload-gb 0
--generation-config vllm
--disable-fastapi-docs
--enable-auto-tool-choice
--tool-call-parser qwen3_coder
)
set +e
/usr/bin/env -i PATH="${CLEAN_PATH}" HOME=/nonexistent LC_ALL=C DOCKER_HOST="${DOCKER_ENDPOINT}" \
VLLM_API_KEY="${API_KEY}" "${DOCKER_BIN}" "${DOCKER_ARGS[@]}"
docker_rc=$?
set -e
builtin unset API_KEY
qwen_release_locks
trap - EXIT INT TERM HUP
exit "${docker_rc}"