From 8369fe22b8733a155ef128b2d906d3382aec657d Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 25 Sep 2026 17:54:46 +0200 Subject: [PATCH] builder is a real built module now, not handed over MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Its own image ('mesh-builder@sha256:0000...0000', later manually pinned to a real digest tonight when the placeholder blocked a push) was never produced by anything the mesh tracks — cmd/mesh-builder lives in mesh-controller's own repository, and nothing declared how to build an image from it. Uses the same context mechanism route-proxy does (mesh- controller#62): the Dockerfile compiles ./cmd/mesh-builder from a clone of mesh-controller's repository, not a vendored copy. Unlike mesh-controller's own FROM scratch (ADR 0006 — nothing to audit but one binary), the build machine's whole job is shelling out to git and docker, so its runtime is Alpine with both installed from the base's own packages, not fetched on their own. Bootstrapped live tonight: a manual build got the new image running long enough to build itself properly through the pipeline it had just gained, and mesh-controller itself needed the same upgrade first (it parses manifests too, and rejected the new context field with the old binary) — genesis's own kind of ordering problem, solved by hand exactly once. --- modules/builder/Dockerfile | 25 +++++++++++++++++++++++++ modules/builder/module.json | 27 +++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 modules/builder/Dockerfile diff --git a/modules/builder/Dockerfile b/modules/builder/Dockerfile new file mode 100644 index 0000000..5b2f18f --- /dev/null +++ b/modules/builder/Dockerfile @@ -0,0 +1,25 @@ +ARG GO_BASE +ARG ALPINE_BASE +# builder's own image: the build machine itself, compiled into a container. +# +# **The source is not vendored here.** builder's actual code — cmd/mesh-builder, internal/builder, +# internal/catalogue — lives in the mesh-controller repository, the same control plane it is one +# half of. This module ships the packaging, not a second copy of the source, so the build context +# is the mesh-controller repository root (declared under build.artifacts[].context), and this +# Dockerfile compiles ./cmd/mesh-builder from it — the same shape route-proxy already uses for the +# same reason. +FROM ${GO_BASE} AS build +WORKDIR /src +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -trimpath -o /mesh-builder ./cmd/mesh-builder + +# Unlike mesh-controller's own FROM scratch (ADR 0006: nothing to audit but one binary), the build +# machine's whole job is shelling out to git and docker — it needs a real userland to do that in, +# not a second copy of either tool vendored into this image. apk installs both from the base's own +# packages, not fetched on its own at build time. +FROM ${ALPINE_BASE} +RUN apk add --no-cache docker-cli git +COPY --from=build /mesh-builder /usr/local/bin/mesh-builder +ENTRYPOINT ["/usr/local/bin/mesh-builder"] diff --git a/modules/builder/module.json b/modules/builder/module.json index 229ca97..325dbe6 100644 --- a/modules/builder/module.json +++ b/modules/builder/module.json @@ -50,7 +50,7 @@ "id": "server", "type": "container", "name": "mesh-builder", - "image": "novox.internal:5100/mesh-builder@sha256:42f5203a6838776447790d9e7d27f22a56e9462bdd25401645f22d188da56704", + "artifact": "server", "env-file": [ "/var/lib/mesh/builder/builder.env" ], @@ -64,5 +64,28 @@ ], "network": "host" } - ] + ], + "build": { + "artifacts": [ + { + "name": "server", + "kind": "image", + "from": "Dockerfile", + "context": { + "repository": "https://git.novox.be/novox/mesh-controller.git", + "ref": "main" + } + } + ], + "on": [ + { + "arg": "GO_BASE", + "image": "golang@sha256:1ae0735f00daffa3aaf1363a5184c0d2dc55c78e3db4ec70241cdac97bf84b59" + }, + { + "arg": "ALPINE_BASE", + "image": "alpine@sha256:d9e853e87e55526f6b2917df91a2115c36dd7c696a35be12163d44e6e2a4b6bc" + } + ] + } }