D48: a restore downloads first — every restore path resolves and pulls every image of the definition that will run before the stop, under the image-work lock held until the restore returns; a failed pull refuses with the app untouched (a deleted version and a busy registry read differently), one operator line. Red-proved. Commit only.
gates / gates (push) Successful in 1m26s

This commit is contained in:
admin committed 2026-10-25 09:38:28 +01:00
1 parent b680db85cb
commit 2d71270858
16 files changed
+404 -3

No files matched your search

+24
View File
@@ -22,6 +22,30 @@ brief 2026-10-24, Part 4 (commit only; the release rides the next normal train).
`…OnlyWhenTheAgentWaitsAndAnAppRuns`, `…QBLimitRuleSkipsAHeldLimit`, `…TheTwoAppsReadAndWriteTheirLimit`,
`TestLineTestRunOutlastsTheClientTimeout`, `TestStartUpwatchRecoversTheHoldFirst`, `TestUpwatchHoldGetsBothAgentCalls`.
### A restore downloads first (D48) — 2026-10-25, commit only
Operator ruling D48 (2026-10-25 08:38, `09` §3 decision 257): every restore path resolves and pulls every image its
definition names before the first change to the app; a failed pull is a refusal with the app untouched. Design:
felhom.eu `07` §6.6.
- **Before (`e1613ae`):** the order was checks → stop → copy → volumes → definition → DB-only start (the FIRST pull) →
replay → start; a version that could not be downloaded ended in the D22 put-back, the app down meanwhile.
- **Now (`internal/backup/restore_pull.go`, `prepareRestoreImages`):** after the existing refusals and before the stop,
each image of the definition that will RUN is present or pulled now, under the image-work lock held SHARED until the
restore returns (`dockerexec.HoldImageWork`, R-863 — the clean-up's TryLock cannot run in between; nesting is safe
because nothing takes the lock exclusively and waits, pinned). Paths (each at its own line): the local unit restore
— so the second drive's unit restore, the whole restore (its `CheckOnly` pass carries the pull; the whole restore
holds the lock across its file half), a kept load (local and off-site) and a set-aside unit — the off-site restore,
the second drive's file restore and the no-unit fallback.
- **A failed pull:** the household reads „Ennek a mentésnek a verzióját (%s) nem lehet letölteni: a készítője már nem
kínálja…" when Docker says the version does not exist (`manifest unknown`, `not found`, `pull access denied`,
`repository does not exist`), „…most nem lehet letölteni… Próbáld újra később…" for anything else; the operator gets
one `backup_run_failures` line (leg `restore-image-unavailable`). Not covered: the `.fab` import (its own row).
- Tests (each seen failing with the pull switched off): `TestD48_AnUnpullablePinIsRefusedBeforeTheStop`,
`…AnUnreachableRegistryReadsDifferently`, `…APullablePinIsPulledFirstAndTheRestoreRuns`,
`…TheCheckOnlyPassCarriesThePull`, `…TheOffsiteRestoreToo`, `…PullGone`; dockerexec
`TestD48_HoldImageWorkBlocksCleanupAndNests`, `…TheOnlyExclusiveTakerNeverWaits`.
### A restore whose app does not start is never „success" (R-1270, P2) — 2026-10-25, commit only
- **Measured before (9202, 0.342.0 = `e1613ae` for these files; `audits/restore-truth-2026-10-25/before/`):** the