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:
2026-10-25 09:38:28 +01:00
parent b680db85cb
commit 2d71270858
16 changed files with 404 additions and 3 deletions
+5
View File
@@ -243,6 +243,11 @@ type Manager struct {
restorePutBackNotify func(stack string, replayErr error)
// restoreNotStartedNotify (R-1270) is called once when a restore's data is back but its app did not start in time.
restoreNotStartedNotify func(stack, kind string, cause error)
// D48: the restore's image probe and pull (nil → docker; tests set them, TestMain makes every image present), and
// the operator notice of a restore refused because an image could not be downloaded.
imagePresentFn func(ref string) bool
imagePullFn func(ctx context.Context, ref string) (string, error)
restorePullRefusedNotify func(stack, ref string, cause error)
// R-403 unit-REHYDRATE seam — the copy that refills the primary unit from the Tier-2 mirror after
// a restore, overridable so the "only when hollow" condition and the byte-identical non-effect are