diff --git a/Dockerfile b/Dockerfile index a2adebd..6f5385f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,11 @@ -ARG GO_BASE=golang:1.25-alpine +# The Go it builds with, pinned here because genesis builds this file with no arguments (novox/hq +# issue 223) — the Makefile passes the same digest. A tag older than go.mod asks for is how +# `make image` broke once before (issue 146). +ARG GO_BASE=golang@sha256:8ac98ca534ac3f51e1f420a1dd2c15e74c75cfa0f23f3ad27eb5d7236c349a0c # The control plane's image — for genesis and the lab only. The mesh runs the controller as a Go # bundle the host starts as a process (module.json; novox/hq issue 213), and builds no image of it. +# Genesis builds this file and raises it as the container the process replaces on the first push +# (mesh-host internal/bootstrap, novox/hq issue 223). # # novox/hq ADR 0006: this image is pinned by digest in the bundle the host carries, fetched on a # machine where no mesh exists yet, and run before there is anything to check it against. So it diff --git a/internal/catalogue/genesis_image_test.go b/internal/catalogue/genesis_image_test.go new file mode 100644 index 0000000..ad3f0f1 --- /dev/null +++ b/internal/catalogue/genesis_image_test.go @@ -0,0 +1,29 @@ +package catalogue + +import ( + "os" + "regexp" + "testing" +) + +// novox/hq issue 223: genesis raises the controller as a container built from this repository's own +// Dockerfile, with no build arguments — the manifest no longer builds an image, so nothing passes a +// base in. The Dockerfile's own default must therefore be a Go that builds this module, pinned by +// digest, and the replacement the manifest's process names must be the container genesis raises. +func TestGenesisCanBuildTheControllersImageAsItStands(t *testing.T) { + raw, err := os.ReadFile("../../Dockerfile") + if err != nil { + t.Fatal(err) + } + if !regexp.MustCompile(`(?m)^ARG GO_BASE=golang@sha256:[0-9a-f]{64}$`).Match(raw) { + t.Fatal("the Dockerfile's default Go base is not pinned by digest; genesis builds it with no arguments") + } + makefile, err := os.ReadFile("../../Makefile") + if err != nil { + t.Fatal(err) + } + pin := regexp.MustCompile(`golang@sha256:[0-9a-f]{64}`) + if string(pin.Find(raw)) != string(pin.Find(makefile)) { + t.Errorf("the Dockerfile and the Makefile build on different Go: %s, %s", pin.Find(raw), pin.Find(makefile)) + } +}