R-893 option A (operator D20): a failed off-site restore puts the app's live volumes and definition back exactly and starts it; fit check before the stop; the held sentence made true (R-1169)
gates / gates (push) Successful in 1m11s

This commit is contained in:
2026-10-20 09:17:00 +02:00
parent ae2bfb2f7a
commit 93fb251ea9
13 changed files with 752 additions and 55 deletions
+10 -7
View File
@@ -1008,13 +1008,16 @@ Each app can define rich metadata in `.felhom.yml`:
`--clear-restore-hold <app>`, **which requires a controller restart**. `--single-transaction` on
the Postgres import is a belt only; MariaDB DDL is not transactional, which is why the rollback
is the fix.
- **Off-site restore of one app: a failed replay after a moved definition or a replaced volume HOLDS the app
(R-893 option C, `09` §3 decision 192).** The rollback puts back the database rows only; the snapshot's files,
volumes and older definition would stay. So when the snapshot's definition was written or a named volume was
replaced, the live definition is written back, the app is held stopped (`restore_mixed`, operator-cleared like
a restore hold), the household reads that it needs our help, and the operator gets a `backup_run_failures`
line (leg `restore-hold-mixed`). Otherwise the ladder above is unchanged. „Put back exactly as it was" is the
next slice.
- **Off-site restore of one app: a failed restore puts the app back EXACTLY as it was and starts it (v0.336.0,
R-893 option A, operator D20 = A; `09` §3 decision 192).** Every named volume the snapshot will replace is copied
right after the stop (tars under `<namespace>/backups/restore-undo/<app>/`), after a fit check BEFORE the stop
(the copy is added to the restore's own free-space need; too little room or an unmeasurable volume refuses with
nothing stopped). On any failure after a volume or the definition moved, the copies are poured back, a volume the
snapshot added is removed, the live definition is written back and the app starts; the household reads that the
restore failed and nothing changed (or, with placed files, that its database and volumes are back and the copied
files stay); the operator gets `backup_run_failures` leg `restore-put-back`. Only a put-back that fails — or a
replay AND rollback that both fail — still HOLDS the app (`restore_mixed` / the restore hold, operator-cleared),
and then the copy is kept for support. On success the copy is removed. `offbox_restore_undo.go`.
- **Where an off-site restore puts the data (v0.219.0, R-356).** `ReconstituteFromOffsite` and
`PlaceOffsiteRestore` resolve the destination with `Manager.GetAppDrivePath` — **the same
resolver `CaptureRecoveryUnit` wrote the snapshot with**: the app's `HDD_PATH` if it declares