D49 = A follow-ups: (A) the undo copy is released only after a stable start — 3 min of running, healthy, no restart, one rule for the first verdict and the late-start watch; a watch ends only for a restore begun after it; (B, R-1279) the .fab import downloads first with the restores' D48 helper, before it removes anything. Red-proved. Commit only.
gates / gates (push) Successful in 1m26s

This commit is contained in:
2026-10-25 12:45:33 +01:00
parent e8d2151a77
commit 7720439440
16 changed files with 549 additions and 27 deletions
@@ -40,6 +40,9 @@ type liveVolumeCopy struct {
copied []string // volumes that existed and were copied (each <dir>/<vol>.tar)
absent []string // volumes the snapshot adds that did not exist before (removed on a put-back)
keep bool // set when a put-back could not be done: the copy is the support path back, never removed
// deferred (R-1270 follow-up): a restore that succeeded hands the copy to releaseAfterStableStart — it is removed
// only after the app ran stably for stableStartWindow, so the restore's own drop leaves it alone.
deferred bool
}
// RestoreUndoDir is restoreUndoDir for the app's remove with „delete its backups too" (a kept copy goes with it).
@@ -170,7 +173,7 @@ func (m *Manager) copyLiveVolumes(stack, nsRoot string, vols []string, exists ma
// drop removes the copy (deferred by the restore). A kept copy (a put-back that failed) stays for support.
func (c *liveVolumeCopy) drop(m *Manager, stack string) {
if c == nil || c.dir == "" {
if c == nil || c.dir == "" || c.deferred {
return
}
if c.keep {