cutover: add full-session logging to preflight.sh (writes to same dir as backup)
ci/woodpecker/push/deploy Pipeline was successful

Persists this run's entire stdout/stderr transcript to BACKUP_DIR
(/volume1/SMB-docker/backup), the SAME location as the pg_dumpall
backup file itself, so a failed run can be investigated later even
without a live terminal attached. Appends to an already-open
CUTOVER_SESSION_LOG if invoked as a child of cutover.sh (one merged
multi-phase transcript per session); opens its own
preflight-standalone-<TS>.log if run directly. Also logs the repo's
git HEAD at cutover/ for traceability, per the ADR-0001 note's
local-checkout-drift lesson (Session Update 8).

See ADR-0001 note, Session Update 9.
This commit is contained in:
2026-08-05 15:03:14 -07:00
parent 82a8414ffa
commit fcbaa2cba3
+35
View File
@@ -33,6 +33,18 @@
# risks either false-positive halts or false-confidence passes. This # risks either false-positive halts or false-confidence passes. This
# check exists to surface anomalies for review, not to silently gate # check exists to surface anomalies for review, not to silently gate
# cutover on an imperfect heuristic. # cutover on an imperfect heuristic.
#
# ── SESSION LOGGING (added — see ADR-0001 note, Session Update 9) ─────────
# Every run's full stdout/stderr transcript is persisted to a timestamped
# .log file in BACKUP_DIR — the SAME directory the pg_dumpall backup file
# itself lands in — so a failed run (or, worse, a failed automatic
# rollback.sh invoked afterward by cutover.sh) can still be investigated
# later even if nobody was watching a live terminal at the time. This
# script either appends to an already-open session log
# (CUTOVER_SESSION_LOG, exported by a parent cutover.sh so all phases land
# in ONE merged transcript) or opens its own timestamped log if run
# standalone. Console/SSH output is unchanged either way — tee mirrors to
# both the file and the real stdout/stderr.
set -euo pipefail set -euo pipefail
@@ -64,7 +76,30 @@ log() { echo "[preflight $(date +%H:%M:%S)] $*"; }
warn() { echo "[preflight WARN $(date +%H:%M:%S)] $*" >&2; } warn() { echo "[preflight WARN $(date +%H:%M:%S)] $*" >&2; }
fail() { echo "[preflight FAIL $(date +%H:%M:%S)] $*" >&2; exit 1; } fail() { echo "[preflight FAIL $(date +%H:%M:%S)] $*" >&2; exit 1; }
# ── Session logging setup — MUST happen before any other output so the
# very first log lines are captured too. Deliberately uses the SAME
# BACKUP_DIR as the pg_dumpall backup file itself (not a separate log
# location), per explicit operator request: whoever goes looking for "the
# backup from that failed run" finds the matching transcript sitting
# right next to it.
mkdir -p "$BACKUP_DIR"
if [ -z "${CUTOVER_SESSION_LOG:-}" ]; then
# No parent cutover.sh session log already open — standalone invocation,
# open our own.
CUTOVER_SESSION_LOG="${BACKUP_DIR}/preflight-standalone-${TS}.log"
export CUTOVER_SESSION_LOG
fi
# Append (not truncate) — if a parent cutover.sh already wrote earlier
# output to this same file, we must not clobber it. tee mirrors to the
# real stdout/stderr too, so console/SSH-visible output is unchanged.
exec > >(tee -a "$CUTOVER_SESSION_LOG") 2>&1
log "=== ADR-0001 Phase 3 cutover preflight starting ===" log "=== ADR-0001 Phase 3 cutover preflight starting ==="
log "Full session transcript: ${CUTOVER_SESSION_LOG}"
if [ -d "${REPO_ROOT}/.git" ]; then
GIT_HEAD="$(git -C "$REPO_ROOT" rev-parse HEAD 2>/dev/null || echo unknown)"
log "Repo HEAD at ${REPO_ROOT}: ${GIT_HEAD} (confirm this matches origin/main — see ADR-0001 note's local-checkout-drift lesson, Session Update 8, if unsure)"
fi
# ── Gate 1: Disk space (checked BEFORE backup; halts before anything is written) ── # ── Gate 1: Disk space (checked BEFORE backup; halts before anything is written) ──
log "Checking free space on ${PG_DATA_ROOT} (resolves through symlinks to real backing filesystem)..." log "Checking free space on ${PG_DATA_ROOT} (resolves through symlinks to real backing filesystem)..."