diff --git a/test/integration/genesis.ts b/test/integration/genesis.ts index 0f25fba..191101e 100644 --- a/test/integration/genesis.ts +++ b/test/integration/genesis.ts @@ -12,6 +12,7 @@ * description of genesis, and both the single-node bed and the four-node bed call it. */ import { existsSync, writeFileSync } from "node:fs"; +import { execFileSync } from "node:child_process"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; import { exec, instanceNameOf, push } from "../../src/lifecycle/operate.ts"; @@ -110,13 +111,27 @@ export async function genesis(o: GenesisOptions): Promise { // The catalogue. `mesh-bootstrap --catalog` reads manifests from a CHECKOUT on the machine, // because at this moment the mesh has no forge, no build machine and — until the registry step // finishes — no registry. A manifest is a file, and somebody has to have put it there. - await must(`mkdir -p ${modules.map((m) => `${catalogueOnMachine}/modules/${m}`).join(" ")}`); + // + // **The WHOLE checkout, not the three genesis names.** `--catalog` is documented as a checkout + // of the catalogue repository, and phase two reads more from it than genesis does — postgres, + // mesh-catalog, the packet filter, whatever extras. Stocking only the bootstrap three left + // phase two unable to read a manifest that was never put there (novox/hq installer step 14). The + // production equivalent is an operator with a full checkout, or the installer cloning the repo; + // the lab stands in for that by copying the whole tree once. + const bundleTar = join(tmpdir(), `mesh-lab-catalogue-${process.pid}-${node}.tar`); + execFileSync("tar", ["-cf", bundleTar, "-C", o.catalogDir, "."]); + await must(`mkdir -p ${catalogueOnMachine}/modules`); + await push(o.instanceId, node, bundleTar, "/tmp/catalogue.tar"); + await must(`tar -xf /tmp/catalogue.tar -C ${catalogueOnMachine}/modules`); + // The three genesis itself needs must be present, or the pivot cannot even begin — checked here + // rather than discovered at step 8, where the message is about a missing file. for (const module of modules) { - const from = resolve(o.catalogDir, module, "module.json"); - if (!existsSync(from)) return stop("preparing the catalogue", `the catalogue has no ${module}/module.json at ${from}`); - await push(o.instanceId, node, from, `${catalogueOnMachine}/modules/${module}/module.json`); + const at = `${catalogueOnMachine}/modules/${module}/module.json`; + if (!(await on(`test -f ${at}`)).ok) { + return stop("preparing the catalogue", `the catalogue has no ${module}/module.json`); + } } - report.push(` catalogue ${modules.join(", ")} at ${catalogueOnMachine}`); + report.push(` catalogue full checkout at ${catalogueOnMachine} (${modules.join(", ")} + phase two)`); const local = join(tmpdir(), `mesh-lab-substrate-${process.pid}-${node}.lock`); writeFileSync(local, o.bundleTemplate);