feat(stack-deploy): accept -e/--emergency and -f/--force flags, pass through to git-guard.sh

Flags may appear before or after the stack name (stack-deploy.sh traefik -e
and stack-deploy.sh -e traefik both work) — the stack name is whatever
argument isn't a recognized flag. No change to the render/mount-guard/deploy
logic; this only changes how the git-guard.sh pre-flight is invoked. See
deploy/git-guard.sh header for what each flag actually does.
This commit is contained in:
Bot
2026-09-12 00:04:42 -07:00
parent 8fa085ebde
commit 9ec1b1811b
+28 -2
View File
@@ -38,10 +38,36 @@
# pre-escaping) or values get doubled twice. Getting this wrong # pre-escaping) or values get doubled twice. Getting this wrong
# silently corrupts any secret/hash containing '$' (confirmed impact: # silently corrupts any secret/hash containing '$' (confirmed impact:
# LITELLM keys truncated, IMMICH_KIOSK_BASICAUTH bcrypt hash mismatched). # LITELLM keys truncated, IMMICH_KIOSK_BASICAUTH bcrypt hash mismatched).
#
# Usage: stack-deploy.sh [-e|--emergency] [-f|--force] <stack-name>
# Flags may appear before or after the stack name, e.g. both
# `stack-deploy.sh traefik -e` and `stack-deploy.sh -e traefik` work.
#
# -e/--emergency and -f/--force (added 2026-09-12, circular-dependency
# bootstrap incident — see deploy/git-guard.sh header for full detail):
# Both are passed straight through to git-guard.sh unchanged; this script
# does not interpret them itself beyond stripping them from the stack-name
# argument list. -e tries alternate Gitea endpoints (VIP, then each node's
# direct IP) before falling back to normal sync logic against whichever
# one responds. -f skips the sync check entirely — last resort only, read
# the warning banner it prints. Neither flag changes anything about the
# render/mount-guard/deploy steps below; they only affect whether and how
# git-guard.sh's pre-flight check runs.
set -euo pipefail set -euo pipefail
STACK="${1:?Usage: stack-deploy.sh <stack-name>}" # ── Flag parsing (stack name is whatever's left after flags are stripped) ──
GUARD_FLAGS=()
STACK=""
for arg in "$@"; do
case "$arg" in
-e|--emergency) GUARD_FLAGS+=(-e) ;;
-f|--force) GUARD_FLAGS+=(-f) ;;
*) STACK="$arg" ;;
esac
done
: "${STACK:?Usage: stack-deploy.sh [-e|--emergency] [-f|--force] <stack-name>}"
DIR="/volume1/docker/compose-files" DIR="/volume1/docker/compose-files"
PY="$DIR/deploy/envparse.py" PY="$DIR/deploy/envparse.py"
MOUNT_GUARD="$DIR/deploy/mount-guard.py" MOUNT_GUARD="$DIR/deploy/mount-guard.py"
@@ -50,7 +76,7 @@ GLOBAL_ENV="$DIR/deploy/global.env"
# ── Pre-flight: ensure local checkout is in sync with Gitea ───────────────── # ── Pre-flight: ensure local checkout is in sync with Gitea ─────────────────
# Prevents deploying from a stale/diverged local tree (see incident 2026-08-26). # Prevents deploying from a stale/diverged local tree (see incident 2026-08-26).
# Invoked via `bash` explicitly so the tracked file's exec bit doesn't matter. # Invoked via `bash` explicitly so the tracked file's exec bit doesn't matter.
bash "$DIR/deploy/git-guard.sh" || { echo "ERROR: git-guard check failed. Deploy aborted."; exit 1; } bash "$DIR/deploy/git-guard.sh" "${GUARD_FLAGS[@]:-}" || { echo "ERROR: git-guard check failed. Deploy aborted."; exit 1; }
# ── Locate compose file(s) ────────────────────────────────────────────────── # ── Locate compose file(s) ──────────────────────────────────────────────────