#!/usr/bin/env bash # Row 233 (I3, #1735): root's upgrade and rollback for a stack whose units are root's system units # (stack-release.sh --units external, row 232). r6's activate A1-A5, A2f, R1-R4 and rollback # (agents/darkwing/work/queue-195/DESIGN.md), as the I3 brief changes them # (docs/plans/2026-10-20_installer-rows.md). Deviations and decisions: # agents/darkwing/work/queue-233/BUILD.md. # # stack-upgrade.sh upgrade --instance dev --bundle FILE --sha SHA [--migrate] [--no-rehearsal] # [--rehearse-port N] [--timeout S] # stack-upgrade.sh rollback --instance dev --to ID [--restore ACT [--events N]] [--timeout S] # # Root runs it from a root-owned checkout of the reviewed commit, never from a copy, because the # stack's user can write the copies. The unit values come from /etc/mosaic-stack/.args, # which I2's install writes: one case2-unit.sh argument per line, the serve flags after `--`. Only # --copy changes, and the file changes only after confirm passes. The stack's user runs its steps # from its own clone, /src/mosaic-stack, through sudo. Root reads none of that user's output # but exit codes and the rehearsal's BACKUP_STORE line (sage-1653), which it copies into its step # log after a match against a fixed pattern and decides nothing on. # # --no-rehearsal is for a stack whose log records no backup. The rehearsal runs either way: exit 3 # from it (no-backup) goes on only with the flag, and exit 0 with the flag refuses # rehearsal-required (sage-1650, sage-1652). # # The lock /run/mosaic-stack/upgrade-.lock is held from before A1 to the end of the run, # rollback included; every child runs with the lock's descriptor closed. The step log # /var/log/mosaic-stack/upgrade-.log gets one line per step, `