From 653f3086234169a8a96884ef17b4cf11eb57fc95 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 5 Aug 2026 15:07:22 -0700 Subject: [PATCH] cutover: add full-session logging (writes to same dir as backup) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Persists the ENTIRE multi-phase transcript (Pre-Phase-0 through Phase 11, including Phase 0's preflight.sh output and any automatically triggered rollback.sh output) to a single timestamped cutover-session-.log in BACKUP_DIR (/volume1/SMB-docker/backup) — the same directory the pg_dumpall backup lands in. Exports CUTOVER_SESSION_LOG so child preflight.sh/rollback.sh invocations append to the same file instead of opening their own. Adds an EXIT trap that always announces final exit code + log path, specifically so the one scenario RUNBOOK.md flags as needing manual intervention (rollback.sh itself failing partway) is still fully investigable after the fact even without a live terminal. Console/SSH output is unchanged (tee mirrors to both). See ADR-0001 note, Session Update 9. --- postgresql/cutover/cutover.sh | 61 +++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/postgresql/cutover/cutover.sh b/postgresql/cutover/cutover.sh index 0573072..f631cf6 100644 --- a/postgresql/cutover/cutover.sh +++ b/postgresql/cutover/cutover.sh @@ -176,6 +176,24 @@ # for the exact detection logic, the prompt itself, and the # AUTO_CLEANUP=yes escape hatch for unattended re-runs where the operator # has already decided cleanup is always wanted. +# +# 2026 run #6 (addition, no new run yet) — SESSION LOGGING added. Every +# prior investigation into a failed run depended entirely on someone +# having a live terminal open and scrolled back far enough, or on the +# operator's own memory. This is fragile, especially for the one +# genuinely dangerous scenario every phase above is built to avoid ever +# reaching manually: rollback.sh itself failing partway (see +# trigger_rollback() below — this is the one case RUNBOOK.md section 4 +# says requires manual intervention). Without a persisted transcript, +# investigating THAT scenario after the fact means reconstructing what +# happened from partial memory of a scrollback buffer that may already be +# gone. FIXED: this script now writes its ENTIRE stdout/stderr transcript +# (all 11 phases, plus Pre-Phase-0 and Phase 0's preflight.sh output, plus +# any triggered rollback.sh output) to a single timestamped file in +# BACKUP_DIR — the SAME directory the pg_dumpall backup itself lands in, +# so the backup and the transcript of the run that produced/needed it are +# always sitting right next to each other. See "SESSION LOGGING" comment +# below for implementation detail. See ADR-0001 note, Session Update 9. set -uo pipefail # NOTE: deliberately not -e — every phase below checks # its own command's exit status explicitly so we can @@ -192,6 +210,41 @@ NETWORK_NAME="postgresql_db-backend" PATRONI_SCOPE="postgres-ha" BACKUP_DIR="/volume1/SMB-docker/backup" +# ── SESSION LOGGING (added — see ADR-0001 note, Session Update 9) ──────── +# Persists this run's ENTIRE multi-phase stdout/stderr transcript to a +# single timestamped file in BACKUP_DIR — the SAME location preflight.sh +# writes the pg_dumpall backup to, per explicit operator request: the +# backup and the transcript of the run that needed it always end up +# sitting right next to each other. CUTOVER_SESSION_LOG is exported so +# preflight.sh and rollback.sh (both invoked below as plain +# `bash