Files
computer-playbook/scripts/tests/deploy/local/deploy/main.sh
T
kevinveenbirkenbachandClaude Opus 5 7254227b1b fix(deploy): refuse an update against a stack the drill left torn down
The restore cycle stops every subject of the host, replays into the database
services alone, and starts the rest again at the very end. Any exit in
between skips that last step, so the host keeps its subjects down - and
nothing recorded it.

The next deploy then failed on a symptom of the teardown rather than on
whatever ended the drill. It cost two runs: once 'rake db:migrate' against a
database the cycle had emptied but not yet replayed, once
Redis::CannotConnectError because the cycle never restarted redis. Both times
the message pointed away from the cause, and fixing what it named would have
fixed nothing.

A trap armed before the teardown now records the teardown and the exit code,
and mode=update refuses to run while that record stands. purge=true and
mode=reinstall pass, because both rebuild the state the drill destroyed; a
completed cycle clears the record itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 10:54:47 +02:00

107 lines
3.3 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Single entry point for every local deploy flow.
#
# Routing environment variables (set them via `make compose-deploy<short>=<value>`;
# `make compose-deploy` maps the short Make variables to the INFINITO_* env vars):
# mode initialize (default) | reinstall | update
# Short Make alias: mode
# bundles optional. Comma-separated bundle names. When
# set, routes to bundles/fresh.sh (initialize
# or reinstall) or bundles/update.sh (update).
# apps is ignored in this case (it
# gets resolved from the bundles).
# apps optional. Comma-separated app ids. When set
# (and bundles is not), routes to the
# selection.sh of the chosen verb.
# Short Make alias: apps
# purge true | false (default: false). When true and
# apps is set, runs the entity purge
# before the deploy.
# Short Make alias: purge
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../../../../.." && pwd)"
cd "${REPO_ROOT}"
MODE="${mode:-initialize}" # nocheck: deploy router knob; routes to apps/<verb>/ subscripts
PURGE="${purge:-false}" # nocheck: deploy router knob; gates entity pre-purge
case "${MODE}" in
initialize | reinstall | update) ;;
*)
echo "ERROR: invalid mode='${MODE}' (must be initialize|reinstall|update)" >&2
exit 2
;;
esac
TORN_DOWN_MARKER="${REPO_ROOT}/.stack-torn-down"
if [[ "${MODE}" == "update" ]] && [[ "${PURGE}" != "true" ]] &&
[[ -f "${TORN_DOWN_MARKER}" ]]; then
cat >&2 <<-EOF
ERROR: refusing mode=update against a torn-down stack.
$(cat "${TORN_DOWN_MARKER}")
An update deploys onto whatever is running. With the subjects down it
fails on a symptom of the teardown - a missing redis, an empty database
- and not on whatever broke the run that left them down. Fixing that
symptom fixes nothing.
Re-run with purge=true to clear the entity state first, or with
mode=reinstall for a fresh baseline. Both remove ${TORN_DOWN_MARKER}.
EOF
exit 1
fi
rm -f "${TORN_DOWN_MARKER}"
run_pre_purge() {
if [[ "${PURGE}" == "true" ]]; then
echo ">>> Pre-purging entities for apps=${apps}"
bash scripts/tests/deploy/local/purge/entity.sh
fi
}
if [[ -n "${bundles:-}" ]]; then
case "${MODE}" in
initialize | reinstall)
target="${SCRIPT_DIR}/bundles/fresh.sh"
;;
update)
target="${SCRIPT_DIR}/bundles/update.sh"
;;
esac
elif [[ -n "${apps:-}" ]]; then
case "${MODE}" in
initialize)
run_pre_purge
exec bash "${SCRIPT_DIR}/apps/initialize/selection.sh" "${apps}"
;;
reinstall)
run_pre_purge
target="${SCRIPT_DIR}/apps/reinstall/selection.sh"
;;
update)
run_pre_purge
target="${SCRIPT_DIR}/apps/update/selection.sh"
;;
esac
else
case "${MODE}" in
initialize)
echo "=== local full deploy (distro=${INFINITO_DISTRO}) ==="
target="${SCRIPT_DIR}/apps/initialize/all.sh"
;;
reinstall)
echo "ERROR: mode=reinstall requires apps= or bundles=" >&2
exit 2
;;
update)
target="${SCRIPT_DIR}/apps/update/all.sh"
;;
esac
fi
exec bash "${target}"