From 1bdbf47ffa83f96fe65b5c5dc217d95e3a28e520 Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 25 Oct 2026 14:29:06 +0100 Subject: [PATCH] Leave out the node's own copy only by kind and id, never by a shared target (issue 1945, review) A unit or container of the node's own that shares only its name with a module's resource is not the module's: dropped, its record became an orphan the apply removes, stopping the module's unit (1945/AC17). --- cmd/mesh-host/nodeagent.go | 12 ++++-------- cmd/mesh-host/whatruns_test.go | 12 ++++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/cmd/mesh-host/nodeagent.go b/cmd/mesh-host/nodeagent.go index a8b59a9..63bb2f1 100644 --- a/cmd/mesh-host/nodeagent.go +++ b/cmd/mesh-host/nodeagent.go @@ -204,9 +204,11 @@ func declarationOf(cs ...delivery.Composed) (*declaration.Declaration, error) { } // ownWithout is the node's own composition without the resources a module's composition among modules also declares: -// the same kind and id, or the same kind and target (a file at one path). It answers what it left out, as " ()". +// the same kind and id. A resource that shares only its target (a unit or container of the same name, another id) is +// not the module's, and stays: dropped, its record would be an orphan the apply removes, stopping the module's unit. It +// answers what it left out, as " ()". func ownWithout(own delivery.Composed, modules []delivery.Composed) (delivery.Composed, []string) { - byID, byTarget := map[string]string{}, map[string]string{} + byID := map[string]string{} for _, c := range modules { if c.Module == "" { continue @@ -217,9 +219,6 @@ func ownWithout(own delivery.Composed, modules []delivery.Composed) (delivery.Co continue } byID[string(r.Kind())+"\x00"+r.Identity()] = c.Module - if t := r.Target(); t != "" { - byTarget[string(r.Kind())+"\x00"+t] = c.Module - } } } if len(byID) == 0 { @@ -234,9 +233,6 @@ func ownWithout(own delivery.Composed, modules []delivery.Composed) (delivery.Co continue } module, dup := byID[string(r.Kind())+"\x00"+r.Identity()] - if !dup && r.Target() != "" { - module, dup = byTarget[string(r.Kind())+"\x00"+r.Target()] - } if dup { dropped = append(dropped, fmt.Sprintf("%s (%s)", r.Identity(), module)) continue diff --git a/cmd/mesh-host/whatruns_test.go b/cmd/mesh-host/whatruns_test.go index d443cda..2ffd7c6 100644 --- a/cmd/mesh-host/whatruns_test.go +++ b/cmd/mesh-host/whatruns_test.go @@ -125,3 +125,15 @@ func TestTheKeptDeclarationsFilledPathsGoToTheirModules(t *testing.T) { t.Errorf("a kept declaration that does not read split into %v", splitBy) } } + +// 1945/AC17 (unit, review): a resource of the node's own that shares only its target with a module's (another id: a +// unit or a container of the same name) is not the module's, and is neither dropped nor left to be removed. +func TestASharedTargetWithAnotherIDIsNotDropped(t *testing.T) { + ownFile, _ := json.Marshal(map[string]any{"id": "host.zshrc", "type": "file", "path": "/tmp/r6/zsh/rc", "content": "x"}) + own := delivery.Composed{Node: "n1", Resources: []json.RawMessage{ownFile}} + zsh := delivery.Composed{Node: "n1", Module: "zsh", FP: "src2:aa", Resources: []json.RawMessage{aFileOf("zsh", "rc")}} + trimmed, dropped := ownWithout(own, []delivery.Composed{zsh}) + if len(dropped) != 0 || len(trimmed.Resources) != 1 { + t.Errorf("a resource sharing only its target was dropped: %v", dropped) + } +}