The no-fake multi-node gate: built-store-cross-node #34

Merged
jschoubben merged 12 commits from bed/built-store-cross-node into main 2026-09-17 23:00:49 +00:00
Showing only changes of commit ca263d2a8b - Show all commits
@@ -236,6 +236,24 @@ test("a joined node's consumers open the store and broker the mesh built and ado
await mesh(`assign ${CONTROL} networking`); await mesh(`assign ${CONTROL} networking`);
await mesh(`assign ${NODE} networking`); await mesh(`assign ${NODE} networking`);
// The networking module carries the registry trust (ADR 0082): a merged daemon.json naming the
// store's internal name, and a docker restart when it first lands. It must be ON both machines
// before anything builds or pulls — the builder pushes to anchor.internal:5000 the moment the
// first build finishes. Pushed and WAITED for, because the restart bounces the runtime and an
// apply in flight retries.
for (const machine of [CONTROL, NODE]) {
await mesh(`push ${machine}`, 600_000);
const deadline = Date.now() + 300_000;
let trusted = false;
while (Date.now() < deadline) {
const got = await on(machine, `grep -s "anchor.internal:5000" /etc/docker/daemon.json && docker info --format '{{json .RegistryConfig.IndexConfigs}}' 2>/dev/null | grep -q "anchor.internal:5000" && echo TRUSTED`);
if (/TRUSTED/.test(got.out)) { trusted = true; break; }
await new Promise((r) => setTimeout(r, 5_000));
}
assert.ok(trusted, `${machine}'s runtime never learned the registry trust:\n` +
(await on(machine, `cat /etc/docker/daemon.json 2>&1; docker info 2>&1 | tail -20`)).out);
}
// The shared base first — every module with code of its own stands on it. // The shared base first — every module with code of its own stands on it.
await registerModule(BASE.module, baseManifest); await registerModule(BASE.module, baseManifest);
const base = await mesh(`build ${forgeUrl(BASE.repo)} --ref ${refFor(BASE.repo)} --wait 1200s`, 1_500_000); const base = await mesh(`build ${forgeUrl(BASE.repo)} --ref ${refFor(BASE.repo)} --wait 1200s`, 1_500_000);