From b4f3eaf11b4829bfff1aa31538909a387a963cad Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 22 Sep 2026 18:33:45 +0200 Subject: [PATCH] Release a whole-file hold once the file is declared written into (hq ADR 0102) --- internal/apply/hold.go | 9 +++++++++ internal/apply/into_test.go | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/internal/apply/hold.go b/internal/apply/hold.go index 818ecc4..f763dac 100644 --- a/internal/apply/hold.go +++ b/internal/apply/hold.go @@ -235,6 +235,15 @@ func holdOnAdopted(ctx context.Context, sys system.System, r declaration.Resourc } } + // A file written into replaces nothing that was found, so it is never held (novox/hq ADR + // 0102) — and a hold from when it was declared whole must not keep the mesh's keys out. + if f, ok := r.(*declaration.File); ok && f.Into != "" { + if already { + known.Release(r.Identity()) + } + return false, false, out, nil + } + module, untaken := d.Adoption.UntakenModuleOf(r.Identity()) if !untaken { return false, false, out, nil diff --git a/internal/apply/into_test.go b/internal/apply/into_test.go index 09deb25..58a7962 100644 --- a/internal/apply/into_test.go +++ b/internal/apply/into_test.go @@ -281,3 +281,24 @@ func TestAListTheMeshCreatedGoesWhenEmptied(t *testing.T) { t.Errorf("the key the mesh created was not removed: %v", o) } } + +func TestAHoldFromAWholeFileDoesNotKeepOutAnIntoWrite(t *testing.T) { + // Declared whole before, the runtime's file was held; declared into now, it is written into. + path := filepath.Join(t.TempDir(), "daemon.json") + _ = os.WriteFile(path, []byte(machinesOwn), 0o644) + known := store.State{Held: []store.Held{{ID: "networking.registry-trust", Module: "networking", + Kind: "file", Target: path}}} + d := adopted(t, `{"taken":[],"untaken":{"networking":["networking.registry-trust"]}}`, + fmt.Sprintf(`{"id":"networking.registry-trust","type":"file","path":%q,"into":"json","content":%q}`, + path, `{"insecure-registries":["10.42.0.1:5000"]}`)) + report, state := applyAdopted(t, d, known, &machine{}, t.TempDir()) + if got := outcomeOf(report, "networking.registry-trust").Action; got != "updated" { + t.Errorf("the file was %q, not written into", got) + } + if len(state.Held) != 0 { + t.Errorf("the old hold outlived the into declaration: %+v", state.Held) + } + if fmt.Sprint(readObject(t, path)["insecure-registries"]) != "[192.0.2.7:5000 10.42.0.1:5000]" { + t.Errorf("the mesh's member was not written in: %v", readObject(t, path)) + } +}