The registry is added, not built

A mesh that has just bootstrapped cannot build the module that gives it
an artifact store: building publishes to the store, and the builder will
not start without one (novox/hq 04-ISSUES/029).

This test built it and passed, because the scenario's registry was
already standing to receive the push — which is precisely why a real
first mesh would have hit this and the lab never did. A stand-in for
Docker Hub was quietly also standing in for the thing under test.

So the module now names its image by digest, the way the bundle names
the three a first node starts from, and is added as a manifest rather
than built. That is the only path open to a real first mesh, so it is
the path this walks.

Its skip on MESH_LAB_BUILDER goes with it. Nothing in the test needs a
builder any more, and a skip that names a thing the test does not use
sends the next person to look in the wrong place.
This commit is contained in:
2026-09-01 21:17:59 +02:00
parent 2b3a30619b
commit f85dbb0713
+16 -12
View File
@@ -586,30 +586,34 @@ test("a machine that fell behind catches up without being named", { skip, timeou
assert.match(await mesh("push --behind"), /every machine is doing what it was told/);
});
test("the mesh runs its own artifact store", {
skip: skip || (!builder ? "set MESH_LAB_BUILDER to a built mesh-builder" : false),
timeout: 900_000,
}, async () => {
test("the mesh runs its own artifact store", { skip, timeout: 900_000 }, async () => {
// Artifacts go to a registry, and the only registries that existed were raised by the lab or by
// the bootstrap bundle. A mesh had no way to run its own.
//
// Chicken and egg, resolved the way the bootstrap's is: the scenario's registry serves the image
// the module mirrors, and the module then runs a registry of the mesh's own.
// **Named, not mirrored** (novox/hq 04-ISSUES/029). Mirroring publishes to the artifact store,
// and the builder will not start without one — so a module that provides the store and builds
// its own image asks the mesh to put an artifact into the thing that artifact is needed to
// create. It worked here only because the scenario's registry was already standing to receive
// the push, which is exactly why a real first mesh would have found this and the lab did not.
//
// So the image is named by digest, the way the bundle names the three a first node starts from.
// A registry is the one module that cannot be delivered by the mesh's own delivery.
await must("anchor", `mkdir -p /root/registry && printf %s '{"module":"registry","version":"1",` +
`"provides":[{"name":"artifact-store","scope":"mesh"}],` +
`"capabilities":["container-runtime"],` +
`"claims":[{"name":"the-artifact-store","scope":"node"}],` +
`"serves":{"artifact-store":{"port":5000}},` +
`"build":{"artifacts":[{"name":"registry","kind":"upstream","from":"${pinned("registry")}"}]},` +
`"resources":[` +
`{"id":"state","type":"directory","path":"/var/lib/mesh/registry","mode":"0700"},` +
`{"id":"store","type":"container","name":"mesh-registry","artifact":"registry",` +
`{"id":"store","type":"container","name":"mesh-registry","image":"${pinned("registry")}",` +
`"ports":["5000:5000"],"volumes":["mesh-registry-data:/var/lib/registry"]}]}' ` +
`> /root/registry/module.json`);
await must("anchor", `cd /root/registry && git init -q . && git add -A && ` +
`git -c user.email=lab -c user.name=lab commit -qm registry`);
await mesh("build /root/registry --wait 300s", 420_000);
// **Added, not built** — and this is the half that proves the fix. Building needs a builder,
// and a builder will not start without an artifact store to publish to, so a mesh that has just
// bootstrapped cannot build the module that gives it one. Adding the manifest directly is the
// path a real first mesh has to take, so it is the path this walks.
await must("anchor", `docker cp /root/registry/module.json mesh-control:/registry.json`);
await mesh("module add /registry.json");
await mesh("assign anchor registry");
await mesh("push anchor");
await new Promise((r) => setTimeout(r, 12_000));