D47 follow-up: a set-aside tells the operator once (backup_run_failures, leg unit-set-aside, both identities, own run id). Red-proved. Commit only.
gates / gates (push) Successful in 1m33s
gates / gates (push) Successful in 1m33s
This commit is contained in:
@@ -248,6 +248,9 @@ type Manager struct {
|
||||
imagePresentFn func(ref string) bool
|
||||
imagePullFn func(ctx context.Context, ref string) (string, error)
|
||||
restorePullRefusedNotify func(stack, ref string, cause error)
|
||||
// unitSetAsideNotify (D47 follow-up, brief 2026-10-26 Part 5.2): one operator line when a box sets an earlier
|
||||
// install's unit aside — so a household's set-aside after the floor is visible to the operator.
|
||||
unitSetAsideNotify func(stack, unitID, liveID, dest string)
|
||||
|
||||
// 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
|
||||
|
||||
@@ -181,9 +181,17 @@ func (m *Manager) guardUnitDir(stack, unitDir, setAsideNs, what string) error {
|
||||
}
|
||||
m.logger.Printf("[INFO] [backup] %s: the recovery unit of an earlier install (%s; %s) is SET ASIDE whole → %s; this install (%s) gets its own unit from its first backup (D47)",
|
||||
stack, orUnknown(unitID), why, dest, orUnknown(liveID))
|
||||
if m.unitSetAsideNotify != nil {
|
||||
m.unitSetAsideNotify(stack, orUnknown(unitID), orUnknown(liveID), dest)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetUnitSetAsideNotify wires the operator line for a set-aside unit (main.go).
|
||||
func (m *Manager) SetUnitSetAsideNotify(fn func(stack, unitID, liveID, dest string)) {
|
||||
m.unitSetAsideNotify = fn
|
||||
}
|
||||
|
||||
func orUnknown(id string) string {
|
||||
if id == "" {
|
||||
return "unrecorded"
|
||||
|
||||
@@ -302,3 +302,21 @@ func TestD47_OwnerVerdict(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// D47 follow-up (brief 2026-10-26 Part 5.2): a set-aside tells the operator once — the box's own households must not
|
||||
// set units aside silently after the floor. COMPANION RED-PROOF: drop the notify call → this fails.
|
||||
func TestD47_ASetAsideTellsTheOperatorOnce(t *testing.T) {
|
||||
r := d47Setup(t, "aaaa000000000001")
|
||||
var got []string
|
||||
r.m.SetUnitSetAsideNotify(func(stack, unitID, liveID, dest string) { got = append(got, stack+" "+unitID+" "+liveID) })
|
||||
r.reinstall("bbbb000000000002")
|
||||
if err := r.m.captureRecoveryUnit("tandoor", false); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := r.m.captureRecoveryUnit("tandoor", false); err != nil { // the next refresh: nothing more to set aside
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(got) != 1 || got[0] != "tandoor aaaa000000000001 bbbb000000000002" {
|
||||
t.Fatalf("the operator hears once, with both identities: %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user