mesh-bootstrap: the first-node procedure, as a program rather than a test

The only complete written-down copy of how a mesh is stood up was an integration
test in the lab. That is why every bootstrap gap kept being found late: an install
procedure that lives as a test fixture is exercised by whoever writes tests, never
by whoever installs. This is that procedure.

A separate binary, not a mesh-host subcommand. mesh-host says of itself that it
connects to nothing and listens on nothing and that what it applies comes from a
file, and that sentence is what makes an always-running root daemon auditable. An
installer loads images and interrogates a control plane. Same tier, different
program.

The control plane's image is carried, not built and not fetched. The forge that
holds its source runs on the mesh, so a bootstrap that had to fetch it would need
a mesh in order to raise one. Embedding breaks that cycle the way the carried
bundle breaks "copy it onto a machine and run it". The image id is read out of the
saved tar before the runtime is asked anything, which is what makes the load
idempotent: the installer can ask whether the machine already holds exactly this.

Five steps, each idempotent and each saying whether it found or changed something,
because this is run over and over by somebody getting a machine working. It stops
at a running substrate with a control plane that replies — enrolment, the module
catalogue and assignment are the next stage and are deliberately absent.

Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
This commit is contained in:
2026-09-10 23:17:30 +02:00
parent 4af9483219
commit b82ab95f74
18 changed files with 2620 additions and 2 deletions
+223
View File
@@ -0,0 +1,223 @@
package bootstrap
import (
"os"
"strings"
"testing"
)
// Each test names the decision it defends (novox/hq ADR 0017).
const (
held = "sha256:1111111111111111111111111111111111111111111111111111111111111111"
otherHeld = "sha256:2222222222222222222222222222222222222222222222222222222222222222"
)
// theRealBundle is this repository's own substrate example, used rather than a fixture.
//
// A fixture would agree with whatever this code does. The example is what an installer is actually
// pointed at, it names the control plane twice, and it is the file that changes when the substrate
// changes — so a rewrite that stops working on it is a rewrite that has stopped working.
func theRealBundle(t *testing.T) []byte {
t.Helper()
raw, err := os.ReadFile("../../examples/substrate-first-node.lock")
if err != nil {
t.Fatalf("reading the substrate example: %v", err)
}
return raw
}
func TestTheControlPlaneIsNamedByTheImageThisMachineHolds(t *testing.T) {
out, err := Rewrite(theRealBundle(t), held)
if err != nil {
t.Fatal(err)
}
if !out.Changed {
t.Error("the rewrite reported nothing changed, and the template named a registry image")
}
control, err := controlPlaneIn(out.Declaration)
if err != nil {
t.Fatal(err)
}
if control.Image != held {
t.Errorf("the control plane is %q, want %q", control.Image, held)
}
}
// **Every place the bundle names that image, not only the container.**
//
// The substrate names the control plane's image twice: the container that runs `serve`, and the
// action that runs `migrate` to create the contexts' schemas. Rewriting only the container leaves
// the migration pointing at an image no registry serves, and the apply dies in the middle — after
// the store is up and before the broker. This is the test that would have caught that.
func TestEveryPlaceTheBundleNamesTheControlPlaneIsRewritten(t *testing.T) {
template := theRealBundle(t)
out, err := Rewrite(template, held)
if err != nil {
t.Fatal(err)
}
if out.Places < 2 {
t.Fatalf("the control plane's image was found in %d place(s); the substrate names it in "+
"the container AND in the migration action", out.Places)
}
if remaining := strings.Count(string(out.Bundle), out.Was); remaining != 0 {
t.Errorf("the produced bundle still names %q in %d place(s)", out.Was, remaining)
}
if got := strings.Count(string(out.Bundle), held); got != out.Places {
t.Errorf("the produced bundle names the held image %d time(s), and %d were replaced",
got, out.Places)
}
}
// Third-party images are somebody else's, at somebody else's registry, and the installer has no
// business touching them (novox/hq ADR 0006).
func TestPostgresAndTheBrokerAreLeftExactlyAsTheyWere(t *testing.T) {
template := theRealBundle(t)
out, err := Rewrite(template, held)
if err != nil {
t.Fatal(err)
}
produced := containerImages(out.Declaration)
for _, id := range []string{"store", "broker"} {
image, named := produced[id]
if !named {
t.Fatalf("the substrate example no longer declares a %q container", id)
}
// Compared against the template's own text rather than against an expectation written
// here: what is being defended is "unchanged", and the template is the only thing that
// knows what it said.
if !strings.Contains(string(template), `"image": "`+image+`"`) {
t.Errorf("%s is now %q, which the template does not say", id, image)
}
if strings.HasPrefix(image, "sha256:") {
t.Errorf("%s was rewritten to an image this machine holds, and nothing holds it", id)
}
}
// And the claim in the report is the same claim, so a person reading it is reading evidence.
if len(out.Kept) != 2 {
t.Errorf("the rewrite reports %d untouched image(s): %v", len(out.Kept), out.Kept)
}
}
// A bundle with no control plane raises a store and a broker and no mesh. Refused, because
// applying it would succeed and leave a machine that looks bootstrapped.
func TestABundleThatNamesNoControlPlaneIsRefused(t *testing.T) {
template := []byte(`{"declaration":1,"resources":[
{"id":"store","type":"container","name":"mesh-store","image":"postgres@sha256:` +
strings.Repeat("7", 64) + `"}
]}`)
_, err := Rewrite(template, held)
if err == nil {
t.Fatal("a bundle with no control plane was rewritten and would have been applied")
}
// The refusal has to be actionable: it says what the bundle DID declare, so somebody can see
// they pointed it at the wrong file or misspelled the id.
if !strings.Contains(err.Error(), ControlPlaneID) || !strings.Contains(err.Error(), "store") {
t.Errorf("the refusal names neither what was wanted nor what was there: %v", err)
}
}
func TestAControlPlaneThatIsNotAContainerIsRefused(t *testing.T) {
template := []byte(`{"declaration":1,"resources":[
{"id":"control-plane","type":"package","package":"mesh-control"}
]}`)
if _, err := Rewrite(template, held); err == nil {
t.Fatal("a control plane declared as a package was accepted, and a package has no image")
}
}
// Idempotence. This program is run over and over while somebody gets a machine working, and the
// second run must be able to say the bundle already names this image rather than reporting a
// rewrite it did not perform.
func TestRewritingABundleThatAlreadyNamesTheImageChangesNothing(t *testing.T) {
first, err := Rewrite(theRealBundle(t), held)
if err != nil {
t.Fatal(err)
}
second, err := Rewrite(first.Bundle, held)
if err != nil {
t.Fatal(err)
}
if second.Changed {
t.Error("re-running the rewrite reported a change, and the image was already the one held")
}
if string(second.Bundle) != string(first.Bundle) {
t.Error("re-running the rewrite produced different bytes")
}
if second.Was != held {
t.Errorf("the second run reports it replaced %q; it replaced nothing", second.Was)
}
}
// A DIFFERENT image, though, must move — the ordinary case of a new control plane being installed
// over an old one. "Already correct" must not be the same code path as "already ran".
func TestANewImageReplacesAnOlderHeldOne(t *testing.T) {
first, err := Rewrite(theRealBundle(t), held)
if err != nil {
t.Fatal(err)
}
second, err := Rewrite(first.Bundle, otherHeld)
if err != nil {
t.Fatal(err)
}
if !second.Changed || second.Was != held || second.Now != otherHeld {
t.Errorf("a new image did not replace the old one: changed=%v was=%q now=%q",
second.Changed, second.Was, second.Now)
}
}
// The produced bundle is meant to be READ. Re-serialising a parsed declaration would drop every
// comment in the template, and the substrate example is mostly comments — each one recording why a
// resource is the way it is, several of them paid for in the lab.
func TestTheProducedBundleKeepsTheTemplatesComments(t *testing.T) {
template := theRealBundle(t)
out, err := Rewrite(template, held)
if err != nil {
t.Fatal(err)
}
const remembered = "NAMED VOLUME"
if !strings.Contains(string(out.Bundle), remembered) {
t.Errorf("the produced bundle lost the template's comments; %q is gone", remembered)
}
}
// The installer must refuse its own bad input in its own words, rather than writing a bundle and
// letting the host refuse a declaration somebody did not write.
func TestSomethingThatIsNotAnImageIdIsRefused(t *testing.T) {
for _, bad := range []string{
"",
"mesh-control:latest",
"sha256:abc",
"sha256:" + strings.Repeat("1", 63),
"sha256:" + strings.Repeat("g", 64),
"mesh-control@sha256:" + strings.Repeat("1", 64),
} {
if _, err := Rewrite(theRealBundle(t), bad); err == nil {
t.Errorf("image id %q was accepted", bad)
}
}
}
// The address every enrolment token will carry is reported and never invented. It differs per
// machine and it is silently fatal when wrong: a node enrols against a dead address and nothing
// says so until it fails to come back.
func TestTheAddressNodesWillDialIsReportedAndNotRewritten(t *testing.T) {
template := theRealBundle(t)
out, err := Rewrite(template, held)
if err != nil {
t.Fatal(err)
}
if out.BrokerAddress == "" {
t.Fatal("the substrate example no longer says what address enrolling nodes will dial")
}
if !strings.Contains(string(out.Bundle), out.BrokerAddress) {
t.Errorf("the produced bundle no longer carries %q — it was rewritten, and nothing here "+
"knows this machine's address", out.BrokerAddress)
}
}