Adoption mode: a node in use is adopted before it is converged (hq ADR 0100–0103) #20

Merged
jschoubben merged 52 commits from feat/adoption-mode into main 2026-09-22 19:01:47 +00:00
2 changed files with 8 additions and 2 deletions
Showing only changes of commit 272e1a65ea - Show all commits
+4 -1
View File
@@ -87,8 +87,11 @@ func guardResources(ports []int) []map[string]any {
return []map[string]any{ return []map[string]any{
{"id": guardID, "type": "file", "path": guardPath, "content": AsGuard(ports), "mode": "0644"}, {"id": guardID, "type": "file", "path": guardPath, "content": AsGuard(ports), "mode": "0644"},
{"id": guardUnitID, "type": "file", "path": guardUnitPath, "content": guardUnitText(), "mode": "0644"}, {"id": guardUnitID, "type": "file", "path": guardUnitPath, "content": guardUnitText(), "mode": "0644"},
// A changed table is reloaded — the unit's ExecReload loads it in one transaction, so the
// ports are never unguarded — and only a changed unit restarts it. As the controller
// declares it, so the first push finds nothing different.
{"id": guardRunningID, "type": "service", "unit": guardUnit, "state": "running", {"id": guardRunningID, "type": "service", "unit": guardUnit, "state": "running",
"boot": "enabled", "restart-on": []any{guardID, guardUnitID}}, "boot": "enabled", "reload-on": []any{guardID}, "restart-on": []any{guardUnitID}},
} }
} }
+4 -1
View File
@@ -121,7 +121,10 @@ func TestAnAdoptedBundleLoadsNoDroppingTableAndExactlyTheGuard(t *testing.T) {
t.Error("nft, which loads the guard, is no longer installed") t.Error("nft, which loads the guard, is no longer installed")
} }
unit := r.Declaration.Resources[at[guardRunningID]].(*declaration.Service) unit := r.Declaration.Resources[at[guardRunningID]].(*declaration.Service)
if unit.Unit != guardUnit || unit.State != "running" || strings.Join(unit.RestartOn, ",") != guardID+","+guardUnitID { // A changed table is reloaded, never restarted: a restart deletes the table before loading
// it again, leaving the ports unguarded in between.
if unit.Unit != guardUnit || unit.State != "running" || strings.Join(unit.RestartOn, ",") != guardUnitID ||
strings.Join(unit.ReloadOn, ",") != guardID {
t.Errorf("the guard's service: %+v", unit) t.Errorf("the guard's service: %+v", unit)
} }
stop := r.Declaration.Resources[at[guardUnitID]].(*declaration.File).Content stop := r.Declaration.Resources[at[guardUnitID]].(*declaration.File).Content