R-1251 (P1): a pending put-back blocks every start — a cut restore's copy on an unbound drive waits (a restore hold), is poured back when the drive binds before any start; a failed put-back holds the app (H2); Stop during a restore still puts back (H7). Commit only, unreleased.
gates / gates (push) Successful in 1m18s
gates / gates (push) Successful in 1m18s
This commit is contained in:
@@ -493,3 +493,19 @@ func assignedIdentsIn(body *ast.BlockStmt) []string {
|
||||
})
|
||||
return names
|
||||
}
|
||||
|
||||
// R-1251: the guard's hold store and drive question are wired BEFORE Recover (a waiting put-back would otherwise be
|
||||
// read as „gone" and nothing would hold the app), and the waiting put-backs are resumed after it. COMPANION
|
||||
// RED-PROOF (2026-10-24): delete SetHolds or SetUndoReachable, or move either below Recover → this fails.
|
||||
func TestR1251_MainWiresThePutBackWait(t *testing.T) {
|
||||
names := callsInMain(t, mainBody(t))
|
||||
rec := indexOfCall(names, "Recover")
|
||||
for _, n := range []string{"SetHolds", "SetUndoReachable"} {
|
||||
if i := indexOfCall(names, n); i < 0 || i > rec {
|
||||
t.Errorf("func main() must call appStopGuard.%s before Recover (at %d, Recover at %d)", n, i, rec)
|
||||
}
|
||||
}
|
||||
if i := indexOfCall(names, "ResumeWaitingPutBacks"); i < rec {
|
||||
t.Errorf("func main() must resume the waiting put-backs after Recover (at %d, Recover at %d)", i, rec)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +466,26 @@ func main() {
|
||||
}
|
||||
return (&stackAdapter{mgr: stackMgr, encKey: encKey}).RecreateStackDefinitionFromUnit(name, defDir, cfg.Env)
|
||||
}, logger))
|
||||
// R-1251: a cut restore's copy on a drive that is not bound yet WAITS (a restore hold every start path honours),
|
||||
// it is never „gone" — and is poured back before anything starts the app. The drive question is the app's own:
|
||||
// a copy under its HDD_PATH is reachable only while that path is a live mountpoint.
|
||||
appStopGuard.SetHolds(sett)
|
||||
appStopGuard.SetUndoReachable(func(name, dir string) bool {
|
||||
cfg := stackMgr.LoadAppConfigByName(name)
|
||||
if cfg == nil {
|
||||
return false // cannot determine — the safe side is „waiting"
|
||||
}
|
||||
hdd := cfg.Env["HDD_PATH"]
|
||||
if hdd == "" || !strings.HasPrefix(filepath.Clean(dir), filepath.Clean(hdd)+string(filepath.Separator)) {
|
||||
return true
|
||||
}
|
||||
return stackMgr.DriveLive(hdd)
|
||||
})
|
||||
appStopRecovery := appStopGuard.Recover()
|
||||
// R-1251: a put-back that waited for its drive (a hold from an earlier start) runs now if that drive is bound.
|
||||
if started := appStopGuard.ResumeWaitingPutBacks(); len(started) > 0 {
|
||||
logger.Printf("[WARN] [appstop] %d app(s) whose interrupted restore waited for its drive are put back and started: %v", len(started), started)
|
||||
}
|
||||
|
||||
// --- R-166: desired-state backfill (running-only) ---
|
||||
// Converge the apps whose intent is unambiguous — deployed and observed UP — so the fleet stops
|
||||
|
||||
Reference in New Issue
Block a user