From 61449249a8fc9d6c08eb2fd850bb59a2c7401d86 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 22 Oct 2026 21:08:47 +0200 Subject: [PATCH] =?UTF-8?q?Name=20build-agent's=20own=20as=20the=20builder?= =?UTF-8?q?'s=20module,=20build-agent=20and=20mesh-tools=20(ADR=200520=20?= =?UTF-8?q?=C2=A71,=20issue=201851)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADR 0520 narrowed after its review: mesh-tools-go builds from its own directory on a pinned base and has its key from mesh-build-image, and mesh-tools-python is no module, so the set is named, not derived from the toolchain bases. --- cmd/mesh-controller/builders_own_test.go | 26 +++++++++++++++--------- cmd/mesh-controller/plan_keys.go | 17 ++++++---------- internal/builder/toolchain.go | 15 -------------- 3 files changed, 22 insertions(+), 36 deletions(-) diff --git a/cmd/mesh-controller/builders_own_test.go b/cmd/mesh-controller/builders_own_test.go index 05b7589c..55aabaa9 100644 --- a/cmd/mesh-controller/builders_own_test.go +++ b/cmd/mesh-controller/builders_own_test.go @@ -60,11 +60,12 @@ func TestAWalkAsksBuildAgentForTheBuildersOwnModuleAlone(t *testing.T) { } } -// ADR 0520 (issue 1851): until R4g build-agent and the toolchain images its builds stand on are build-agent's own, as the -// builder's module is: the builder writes no key of them, so a walk asks build-agent for them and reads no key; any other -// module of the same tier is still taken from its key. -func TestAWalkAsksBuildAgentForItselfAndItsToolchainsAndReadsNoKeyOfThem(t *testing.T) { - own := []string{"build-agent", "mesh-tools", "mesh-tools-go", "mesh-tools-python"} +// ADR 0520 §1 (issue 1851): until R4g build-agent and mesh-tools, the toolchain image its builds stand on, are build-agent's +// own, as the builder's module is: the builder writes no key of them, so a walk asks build-agent for them and reads no key; +// mesh-tools-go (its key from mesh-build-image) and any other module of the same tier are still taken from their keys. +func TestAWalkAsksBuildAgentForItselfAndMeshToolsAndReadsNoKeyOfThem(t *testing.T) { + own := []string{"build-agent", "mesh-tools"} + keyed := []string{"mesh-tools-go", "sudo"} wasModule := askedModuleOf askedModuleOf = func(_ context.Context, _ buildSource, path string) (string, error) { return strings.TrimPrefix(path, "modules/"), nil @@ -75,6 +76,9 @@ func TestAWalkAsksBuildAgentForItselfAndItsToolchainsAndReadsNoKeyOfThem(t *test t.Fatalf("an ask of %s is refused: %v", m, err) } } + if err := onlyTheBuildersOwn(t.Context(), buildSource{Repository: "novox/x", Seat: "git"}, "modules/mesh-tools-go"); !errors.Is(err, errNotTheBuildersOwn) { + t.Fatalf("an ask of mesh-tools-go went on: %v", err) + } var asked []string was := askABuild askABuild = func(_ context.Context, _ buildSource, path, _ string) (string, error) { @@ -83,8 +87,8 @@ func TestAWalkAsksBuildAgentForItselfAndItsToolchainsAndReadsNoKeyOfThem(t *test } t.Cleanup(func() { askABuild = was }) p, byName := aWalkOfOne("sudo") - p.Tiers = [][]string{append(append([]string{}, own...), "sudo")} - for _, m := range own { + p.Tiers = [][]string{append(append([]string{}, own...), keyed...)} + for _, m := range append(append([]string{}, own...), keyed...) { e := byName["sudo"] e.Source.Path = "modules/" + m byName[m] = e @@ -92,7 +96,7 @@ func TestAWalkAsksBuildAgentForItselfAndItsToolchainsAndReadsNoKeyOfThem(t *test for _, m := range p.Tiers[0] { askModule(t.Context(), p, m, byName) } - if strings.Join(asked, " ") != "modules/build-agent modules/mesh-tools modules/mesh-tools-go modules/mesh-tools-python" { + if strings.Join(asked, " ") != "modules/build-agent modules/mesh-tools" { t.Fatalf("build-agent was asked for %v", asked) } for _, m := range own { @@ -100,7 +104,9 @@ func TestAWalkAsksBuildAgentForItselfAndItsToolchainsAndReadsNoKeyOfThem(t *test t.Fatalf("%s is not asked of build-agent, or is read from a key: %+v", m, s) } } - if s := p.Modules["sudo"]; !s.Key || s.Build != "" { - t.Fatalf("the other module is not taken from its key: %+v", s) + for _, m := range keyed { + if s := p.Modules[m]; !s.Key || s.Build != "" { + t.Fatalf("%s is not taken from its key: %+v", m, s) + } } } diff --git a/cmd/mesh-controller/plan_keys.go b/cmd/mesh-controller/plan_keys.go index cf8f6a30..453bcbc2 100644 --- a/cmd/mesh-controller/plan_keys.go +++ b/cmd/mesh-controller/plan_keys.go @@ -25,19 +25,14 @@ import ( // **No timer**: the builder's and the indexer's writes wake the look (builderkeys.Watch, watchNewModules). // isBuildersOwn says a module is build-agent's own: asked of build-agent on a merge and taken from its build record, never -// from the builder's key, until R4g (ADR 0453 §5, ADR 0498 §7, ADR 0520). They are the builder's module, build-agent itself -// (its image's context is another repository's) and the toolchain images build-agent's builds stand on -// (builder.Bases): the builder writes no key of any of them, and a walk waiting for one would hold its tier for ever. +// from the builder's key, until R4g (ADR 0453 §5, ADR 0498 §7, ADR 0520 §1). func isBuildersOwn(module string) bool { return buildersOwn(module) } -// buildAgentsOwn are those modules: the builder's, build-agent's and every toolchain's base, read from the toolchains. -var buildAgentsOwn = func() map[string]bool { - own := map[string]bool{sdkdelivery.BuilderModule: true, builder.AgentModule: true} - for _, b := range builder.Bases() { - own[b] = true - } - return own -}() +// buildAgentsOwn are those modules, named (ADR 0520 §1): the builder's; build-agent itself, whose image's context is another +// repository's; and mesh-tools, the toolchain image build-agent's builds stand on. The builder writes no key of any of them, +// and a walk waiting for one would hold its tier for ever. mesh-tools-go is not among them: it builds from a Dockerfile in +// its own directory on a pinned base, and has its key from mesh-build-image. +var buildAgentsOwn = map[string]bool{sdkdelivery.BuilderModule: true, builder.AgentModule: true, "mesh-tools": true} // buildersOwn is isBuildersOwn's rule: a variable only so a test of the asks left (their bus waits, their plan key) may // name modules of its own as build-agent's. diff --git a/internal/builder/toolchain.go b/internal/builder/toolchain.go index 1cb0a381..2b77567e 100644 --- a/internal/builder/toolchain.go +++ b/internal/builder/toolchain.go @@ -237,21 +237,6 @@ func spoken() string { // AgentModule is build-agent's own module: the machine's builder, whose image is built from another repository's context. const AgentModule = "build-agent" -// Bases are the modules whose artifacts provide the toolchains' compilers (Toolchain.Base), each once, sorted: images -// build-agent's builds stand on. -func Bases() []string { - seen := map[string]bool{} - var out []string - for _, t := range toolchains { - if t.Base != "" && !seen[t.Base] { - seen[t.Base] = true - out = append(out, t.Base) - } - } - sort.Strings(out) - return out -} - func Languages() []string { names := make([]string, 0, len(toolchains)) for _, t := range toolchains {