The beds raise a mesh through an installer that carries a builder #22
@@ -38,6 +38,16 @@ TSC="$MESH_SDK/node_modules/.bin/tsc"; ( cd "$MOD" && "$TSC" "${SRCS[@]}" --modu
|
|||||||
STAGE="$(mktemp -d)"; trap 'rm -rf "$STAGE"' EXIT
|
STAGE="$(mktemp -d)"; trap 'rm -rf "$STAGE"' EXIT
|
||||||
cp -r "$MESH_TOOLS/dist" "$STAGE/dist"
|
cp -r "$MESH_TOOLS/dist" "$STAGE/dist"
|
||||||
cp -rL "$MESH_TOOLS/node_modules" "$STAGE/node_modules"
|
cp -rL "$MESH_TOOLS/node_modules" "$STAGE/node_modules"
|
||||||
|
# And the sdk, from the sibling this script just built, whatever form the installed tree holds it
|
||||||
|
# in. It used to be relied on being a symlink into that sibling, which `-L` above materialised —
|
||||||
|
# true only on a workstation where somebody had linked them, and false the moment the runtime's
|
||||||
|
# dependencies are installed the ordinary way, which now fetches the sdk as sources with nothing
|
||||||
|
# compiled in it. The image built then looked fine and every entry point inside it pointed at
|
||||||
|
# nothing.
|
||||||
|
rm -rf "$STAGE/node_modules/@novox/mesh-sdk"
|
||||||
|
mkdir -p "$STAGE/node_modules/@novox"
|
||||||
|
cp -rL "$MESH_SDK" "$STAGE/node_modules/@novox/mesh-sdk"
|
||||||
|
rm -rf "$STAGE/node_modules/@novox/mesh-sdk/node_modules"
|
||||||
mkdir -p "$STAGE/modules/$MODULE"; cp -r "$MOD/dist" "$STAGE/modules/$MODULE/dist"
|
mkdir -p "$STAGE/modules/$MODULE"; cp -r "$MOD/dist" "$STAGE/modules/$MODULE/dist"
|
||||||
cp "$MESH_TOOLS/package.json" "$STAGE/package.json"
|
cp "$MESH_TOOLS/package.json" "$STAGE/package.json"
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,17 @@ echo " module $AUDIT"
|
|||||||
STAGE="$(mktemp -d)"
|
STAGE="$(mktemp -d)"
|
||||||
trap 'rm -rf "$STAGE"' EXIT
|
trap 'rm -rf "$STAGE"' EXIT
|
||||||
cp -r "$MESH_TOOLS/dist" "$STAGE/dist"
|
cp -r "$MESH_TOOLS/dist" "$STAGE/dist"
|
||||||
cp -rL "$MESH_TOOLS/node_modules" "$STAGE/node_modules" # -L materialises the @novox/mesh-sdk symlink
|
cp -rL "$MESH_TOOLS/node_modules" "$STAGE/node_modules"
|
||||||
|
# And the sdk, from the sibling this script just built, whatever form the installed tree holds it
|
||||||
|
# in. It used to be relied on being a symlink into that sibling, which `-L` above materialised —
|
||||||
|
# true only on a workstation where somebody had linked them, and false the moment the runtime's
|
||||||
|
# dependencies are installed the ordinary way, which now fetches the sdk as sources with nothing
|
||||||
|
# compiled in it. The image built then looked fine and every entry point inside it pointed at
|
||||||
|
# nothing.
|
||||||
|
rm -rf "$STAGE/node_modules/@novox/mesh-sdk"
|
||||||
|
mkdir -p "$STAGE/node_modules/@novox"
|
||||||
|
cp -rL "$MESH_SDK" "$STAGE/node_modules/@novox/mesh-sdk"
|
||||||
|
rm -rf "$STAGE/node_modules/@novox/mesh-sdk/node_modules" # -L materialises the @novox/mesh-sdk symlink
|
||||||
mkdir -p "$STAGE/modules/audit-logger"
|
mkdir -p "$STAGE/modules/audit-logger"
|
||||||
cp -r "$AUDIT/dist" "$STAGE/modules/audit-logger/dist"
|
cp -r "$AUDIT/dist" "$STAGE/modules/audit-logger/dist"
|
||||||
cp "$MESH_TOOLS/package.json" "$STAGE/package.json"
|
cp "$MESH_TOOLS/package.json" "$STAGE/package.json"
|
||||||
|
|||||||
+11
-7
@@ -91,21 +91,25 @@ export function planned(env: NodeJS.ProcessEnv = process.env): Build[] {
|
|||||||
builds.push({
|
builds.push({
|
||||||
what: "installer",
|
what: "installer",
|
||||||
in: where["mesh-host"],
|
in: where["mesh-host"],
|
||||||
argv: ["make", "bootstrap", `IMAGE=${controlPlaneImage(env)}`, `BOOTSTRAP_OUT=${installer}`],
|
argv: ["make", "bootstrap", `IMAGE=${carriedImage(env)}`, `BOOTSTRAP_OUT=${installer}`],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return builds;
|
return builds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The control-plane image the installer carries.
|
* The image the installer carries.
|
||||||
*
|
*
|
||||||
* `mesh-control:development` is what mesh-control's `make image` tags, and what the scenarios name
|
* **It is the builder, not the control plane** (novox/hq ADR 0073). The installer used to carry the
|
||||||
* — one tag, said in one place. It is overridable because a release installer carries a release
|
* thing it was going to run and now carries the thing that makes it, so a raised mesh holds a
|
||||||
* image, and nothing about that is the lab's business.
|
* control plane it built from a repository and a commit rather than one it was handed.
|
||||||
|
*
|
||||||
|
* `mesh-builder:development` is what mesh-control's `make builder-image` tags — one tag, said in
|
||||||
|
* one place. Overridable because a release installer carries a release image, and nothing about
|
||||||
|
* that is the lab's business.
|
||||||
*/
|
*/
|
||||||
export function controlPlaneImage(env: NodeJS.ProcessEnv = process.env): string {
|
export function carriedImage(env: NodeJS.ProcessEnv = process.env): string {
|
||||||
return env["MESH_LAB_CONTROL_IMAGE"] ?? "mesh-control:development";
|
return env["MESH_LAB_CARRIED_IMAGE"] ?? "mesh-builder:development";
|
||||||
}
|
}
|
||||||
|
|
||||||
/** rebuild runs the plan, and throws on the first failure rather than testing a stale artifact. */
|
/** rebuild runs the plan, and throws on the first failure rather than testing a stale artifact. */
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ const binary = hostBinaryPath();
|
|||||||
const installer = bootstrapBinaryPath();
|
const installer = bootstrapBinaryPath();
|
||||||
const bundle = process.env["MESH_LAB_BUNDLE"] ?? "";
|
const bundle = process.env["MESH_LAB_BUNDLE"] ?? "";
|
||||||
const catalogDir = process.env["MESH_LAB_CATALOG"] ?? "";
|
const catalogDir = process.env["MESH_LAB_CATALOG"] ?? "";
|
||||||
|
// What the installer is told to build. It carries a builder rather than a finished control plane
|
||||||
|
// (novox/hq ADR 0073), so genesis needs a repository and a commit — and a commit rather than a
|
||||||
|
// branch, because what is cloned is the trust anchor for everything this mesh will ever run.
|
||||||
|
const source = process.env["MESH_LAB_SOURCE"] ?? "";
|
||||||
|
const sourceRef = process.env["MESH_LAB_SOURCE_REF"] ?? "";
|
||||||
const KEEP = !!process.env["MESH_LAB_KEEP"];
|
const KEEP = !!process.env["MESH_LAB_KEEP"];
|
||||||
const FIXED_ID = process.env["MESH_LAB_INSTANCE_ID"] ?? (KEEP ? "genesis-single-live" : undefined);
|
const FIXED_ID = process.env["MESH_LAB_INSTANCE_ID"] ?? (KEEP ? "genesis-single-live" : undefined);
|
||||||
|
|
||||||
@@ -41,7 +46,9 @@ const skip =
|
|||||||
!capability.usable ? capability.why :
|
!capability.usable ? capability.why :
|
||||||
!binary ? "MESH_LAB_HOST_BINARY is not set to a built mesh-host" :
|
!binary ? "MESH_LAB_HOST_BINARY is not set to a built mesh-host" :
|
||||||
!installer ? "MESH_LAB_BOOTSTRAP_BINARY is not set to a built mesh-bootstrap (mesh-host `make " +
|
!installer ? "MESH_LAB_BOOTSTRAP_BINARY is not set to a built mesh-bootstrap (mesh-host `make " +
|
||||||
"bootstrap IMAGE=mesh-control:development`)" :
|
"bootstrap IMAGE=mesh-builder:development`)" :
|
||||||
|
!source ? "MESH_LAB_SOURCE is not set to the repository the control plane is built from" :
|
||||||
|
!sourceRef ? "MESH_LAB_SOURCE_REF is not set to the commit to build" :
|
||||||
!bundle || !existsSync(bundle) ? "MESH_LAB_BUNDLE is not set to a substrate template" :
|
!bundle || !existsSync(bundle) ? "MESH_LAB_BUNDLE is not set to a substrate template" :
|
||||||
!catalogDir || !existsSync(catalogDir) ? "MESH_LAB_CATALOG is not set to mesh-catalog/modules" :
|
!catalogDir || !existsSync(catalogDir) ? "MESH_LAB_CATALOG is not set to mesh-catalog/modules" :
|
||||||
false;
|
false;
|
||||||
@@ -72,6 +79,8 @@ before(async () => {
|
|||||||
// naming a registry that does not exist — the installer overwrites it, and leaving it proves
|
// naming a registry that does not exist — the installer overwrites it, and leaving it proves
|
||||||
// that it does.
|
// that it does.
|
||||||
bundleTemplate: substrateBundle(bundle, []),
|
bundleTemplate: substrateBundle(bundle, []),
|
||||||
|
source,
|
||||||
|
sourceRef,
|
||||||
log: (m) => console.log(m),
|
log: (m) => console.log(m),
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -44,6 +44,15 @@ export interface GenesisOptions {
|
|||||||
catalogueOnMachine?: string;
|
catalogueOnMachine?: string;
|
||||||
/** Where this mesh's own registry will answer. */
|
/** Where this mesh's own registry will answer. */
|
||||||
registry?: string;
|
registry?: string;
|
||||||
|
/**
|
||||||
|
* Where the control plane is built from, and the commit.
|
||||||
|
*
|
||||||
|
* The installer carries a builder rather than a finished control plane (novox/hq ADR 0073), so
|
||||||
|
* it has to be told what to make. A commit rather than a branch, because what genesis clones is
|
||||||
|
* the trust anchor for everything the mesh will ever run (ADR 0071).
|
||||||
|
*/
|
||||||
|
source: string;
|
||||||
|
sourceRef: string;
|
||||||
log?: (m: string) => void;
|
log?: (m: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +93,7 @@ export async function genesis(o: GenesisOptions): Promise<GenesisResult> {
|
|||||||
const name = await instanceNameOf(o.instanceId, node);
|
const name = await instanceNameOf(o.instanceId, node);
|
||||||
const version = await placeBootstrap(name, node, o.installer, (m) => log(`genesis:${m}`));
|
const version = await placeBootstrap(name, node, o.installer, (m) => log(`genesis:${m}`));
|
||||||
report.push(` installer ${version} at ${BOOTSTRAP_PATH}`);
|
report.push(` installer ${version} at ${BOOTSTRAP_PATH}`);
|
||||||
|
report.push(` builds from ${o.source} at ${o.sourceRef.slice(0, 8)}`);
|
||||||
|
|
||||||
// The catalogue. `mesh-bootstrap --catalog` reads manifests from a CHECKOUT on the machine,
|
// 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
|
// because at this moment the mesh has no forge, no build machine and — until the registry step
|
||||||
@@ -102,6 +112,8 @@ export async function genesis(o: GenesisOptions): Promise<GenesisResult> {
|
|||||||
|
|
||||||
const command = [
|
const command = [
|
||||||
BOOTSTRAP_PATH,
|
BOOTSTRAP_PATH,
|
||||||
|
`--source ${o.source}`,
|
||||||
|
`--source-ref ${o.sourceRef}`,
|
||||||
`--bundle /tmp/substrate-template.lock`,
|
`--bundle /tmp/substrate-template.lock`,
|
||||||
`--catalog ${catalogueOnMachine}`,
|
`--catalog ${catalogueOnMachine}`,
|
||||||
`--node ${node}`,
|
`--node ${node}`,
|
||||||
@@ -163,6 +175,25 @@ export async function genesis(o: GenesisOptions): Promise<GenesisResult> {
|
|||||||
`digest assigned by ${registry}.`);
|
`digest assigned by ${registry}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3a. THE CONTROL PLANE WAS BUILT, not carried.
|
||||||
|
//
|
||||||
|
// **The distinction the installer now exists to make** (novox/hq ADR 0073). A mesh running an
|
||||||
|
// image it was handed cannot rebuild the thing that runs it, and looks identical from the
|
||||||
|
// outside to one that can — same container, same digest, same registry. The difference is
|
||||||
|
// whether a build happened, and the only place that is visible is the installer saying so.
|
||||||
|
//
|
||||||
|
// Checked against the commit this bed asked for, not merely that some build occurred: an
|
||||||
|
// installer that quietly built something else would satisfy a weaker check and raise a mesh
|
||||||
|
// nobody asked for.
|
||||||
|
const wanted = o.sourceRef.slice(0, 8);
|
||||||
|
if (!new RegExp(`built mesh-control from ${wanted}`).test(said)) {
|
||||||
|
return stop("after the last step",
|
||||||
|
`the installer never said it built mesh-control from ${wanted}. What runs may have been ` +
|
||||||
|
`carried rather than made here, which is a mesh that cannot rebuild its own control plane. ` +
|
||||||
|
`The installer said:\n${said.split("\n").filter((l) => /built|build/.test(l)).join("\n") || "(nothing about building)"}`);
|
||||||
|
}
|
||||||
|
report.push(` built here mesh-control from ${wanted}, by the carried builder`);
|
||||||
|
|
||||||
// 3b. And the registry really serves it. A reference is a claim; a tag list is the registry agreeing.
|
// 3b. And the registry really serves it. A reference is a claim; a tag list is the registry agreeing.
|
||||||
const tags = await on(`curl -s --max-time 10 http://${registry}/v2/mesh-control/tags/list`);
|
const tags = await on(`curl -s --max-time 10 http://${registry}/v2/mesh-control/tags/list`);
|
||||||
report.push(` registry holds ${tags.out.trim() || "nothing"}`);
|
report.push(` registry holds ${tags.out.trim() || "nothing"}`);
|
||||||
|
|||||||
@@ -66,13 +66,18 @@ import {
|
|||||||
bootstrapBinaryPath, hostBinaryPath, placeBootstrap, BOOTSTRAP_PATH, HOST_PATH,
|
bootstrapBinaryPath, hostBinaryPath, placeBootstrap, BOOTSTRAP_PATH, HOST_PATH,
|
||||||
} from "../../src/lifecycle/place.ts";
|
} from "../../src/lifecycle/place.ts";
|
||||||
import { labIsUsable, destroyAll, substrateBundle, onTheMachine } from "./harness.ts";
|
import { labIsUsable, destroyAll, substrateBundle, onTheMachine } from "./harness.ts";
|
||||||
import type { HeldImage } from "../../src/pinning.ts";
|
import { referenceFor, type HeldImage } from "../../src/pinning.ts";
|
||||||
|
|
||||||
const capability = await labIsUsable();
|
const capability = await labIsUsable();
|
||||||
const binary = hostBinaryPath();
|
const binary = hostBinaryPath();
|
||||||
const installer = bootstrapBinaryPath();
|
const installer = bootstrapBinaryPath();
|
||||||
const bundle = process.env["MESH_LAB_BUNDLE"] ?? "";
|
const bundle = process.env["MESH_LAB_BUNDLE"] ?? "";
|
||||||
const modulesEnv = process.env["MESH_LAB_MODULES"] ?? "";
|
const modulesEnv = process.env["MESH_LAB_MODULES"] ?? "";
|
||||||
|
// What the installer is told to build. It carries a builder rather than a finished control plane
|
||||||
|
// (novox/hq ADR 0073), so genesis is given a repository and a commit — and a commit rather than a
|
||||||
|
// branch, because what is cloned is the trust anchor for everything this mesh will ever run.
|
||||||
|
const source = process.env["MESH_LAB_SOURCE"] ?? "";
|
||||||
|
const sourceRef = process.env["MESH_LAB_SOURCE_REF"] ?? "";
|
||||||
|
|
||||||
const skip = !capability.usable
|
const skip = !capability.usable
|
||||||
? `lab not usable: ${capability.why}`
|
? `lab not usable: ${capability.why}`
|
||||||
@@ -82,9 +87,13 @@ const skip = !capability.usable
|
|||||||
? "MESH_LAB_BUNDLE is not set to a substrate bundle (mesh-host examples/)"
|
? "MESH_LAB_BUNDLE is not set to a substrate bundle (mesh-host examples/)"
|
||||||
: !installer || !existsSync(installer)
|
: !installer || !existsSync(installer)
|
||||||
? "MESH_LAB_BOOTSTRAP_BINARY is not set to a built mesh-bootstrap (mesh-host `make " +
|
? "MESH_LAB_BOOTSTRAP_BINARY is not set to a built mesh-bootstrap (mesh-host `make " +
|
||||||
"bootstrap IMAGE=mesh-control:development`). The anchor is raised BY the installer now, " +
|
"bootstrap IMAGE=mesh-builder:development`). The anchor is raised BY the installer now, " +
|
||||||
"so a run without one would be testing the procedure this bed exists to stop testing"
|
"so a run without one would be testing the procedure this bed exists to stop testing"
|
||||||
: false;
|
: !source
|
||||||
|
? "MESH_LAB_SOURCE is not set to the repository the control plane is built from"
|
||||||
|
: !sourceRef
|
||||||
|
? "MESH_LAB_SOURCE_REF is not set to the commit to build"
|
||||||
|
: false;
|
||||||
|
|
||||||
const SCENARIO = "whole-mesh-full";
|
const SCENARIO = "whole-mesh-full";
|
||||||
/** novox hosts the substrate and the control plane; it is where `mesh` commands run. */
|
/** novox hosts the substrate and the control plane; it is where `mesh` commands run. */
|
||||||
@@ -350,11 +359,29 @@ function bundleFor(images: HeldImage[]): string {
|
|||||||
function loadManifest(name: string): { manifest: string; broker: boolean } {
|
function loadManifest(name: string): { manifest: string; broker: boolean } {
|
||||||
const path = resolve(catalogDir, name, "module.json");
|
const path = resolve(catalogDir, name, "module.json");
|
||||||
const m = JSON.parse(readFileSync(path, "utf8")) as {
|
const m = JSON.parse(readFileSync(path, "utf8")) as {
|
||||||
resources?: { type: string; image?: string; ports?: string[] }[];
|
resources?: { type: string; image?: string; artifact?: string; ports?: string[] }[];
|
||||||
};
|
};
|
||||||
const remap = REMAP[name] ?? {};
|
const remap = REMAP[name] ?? {};
|
||||||
for (const r of m.resources ?? []) {
|
for (const r of m.resources ?? []) {
|
||||||
if (r.type !== "container") continue;
|
if (r.type !== "container") continue;
|
||||||
|
// **A container naming an artifact is a module the mesh builds, and this bed does not build.**
|
||||||
|
// It pre-builds the same images on the workstation and stocks them, which is the lab standing
|
||||||
|
// in for the builder — so it does here what the builder does: replace the artifact with the
|
||||||
|
// reference the machine actually holds. Without this the unresolved field travels to the
|
||||||
|
// machine, whose declaration language has no such field, and the whole declaration is refused.
|
||||||
|
//
|
||||||
|
// The repository is `mesh-runtime-<module>`, which is not a guess: it is what this repository's
|
||||||
|
// own `scripts/build-module-runtime.sh <module>` produces and what the scenarios stock by name.
|
||||||
|
if (typeof r.artifact === "string" && typeof r.image !== "string") {
|
||||||
|
const reference = referenceFor(held, `mesh-runtime-${name}`);
|
||||||
|
assert.ok(reference,
|
||||||
|
`${name} declares the "${r.artifact}" artifact and this scenario stocked no ` +
|
||||||
|
`mesh-runtime-${name}. The mesh would have to build it, and this bed does not build — ` +
|
||||||
|
`add it to the machine's images: in the scenario, or build it with ` +
|
||||||
|
`scripts/build-module-runtime.sh ${name}`);
|
||||||
|
r.image = reference;
|
||||||
|
delete r.artifact;
|
||||||
|
}
|
||||||
if (typeof r.image === "string") r.image = pinned(r.image);
|
if (typeof r.image === "string") r.image = pinned(r.image);
|
||||||
if (Array.isArray(r.ports)) r.ports = r.ports.map((p) => remap[p] ?? p);
|
if (Array.isArray(r.ports)) r.ports = r.ports.map((p) => remap[p] ?? p);
|
||||||
}
|
}
|
||||||
@@ -526,6 +553,7 @@ async function genesis(images: HeldImage[]): Promise<GenesisResult> {
|
|||||||
const version = await placeBootstrap(name, CONTROL, installer as string,
|
const version = await placeBootstrap(name, CONTROL, installer as string,
|
||||||
(m) => console.log(`genesis:${m}`));
|
(m) => console.log(`genesis:${m}`));
|
||||||
report.push(` installer ${version} at ${BOOTSTRAP_PATH}`);
|
report.push(` installer ${version} at ${BOOTSTRAP_PATH}`);
|
||||||
|
report.push(` builds from ${source} at ${sourceRef.slice(0, 8)}`);
|
||||||
|
|
||||||
// The catalogue. `mesh-bootstrap --catalog` reads manifests from a CHECKOUT on the machine,
|
// 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 step 7 finishes —
|
// because at this moment the mesh has no forge, no build machine and — until step 7 finishes —
|
||||||
@@ -560,6 +588,8 @@ async function genesis(images: HeldImage[]): Promise<GenesisResult> {
|
|||||||
|
|
||||||
const command = [
|
const command = [
|
||||||
BOOTSTRAP_PATH,
|
BOOTSTRAP_PATH,
|
||||||
|
`--source ${source}`,
|
||||||
|
`--source-ref ${sourceRef}`,
|
||||||
`--bundle /tmp/substrate-template.lock`,
|
`--bundle /tmp/substrate-template.lock`,
|
||||||
`--catalog ${CATALOGUE_ON_MACHINE}`,
|
`--catalog ${CATALOGUE_ON_MACHINE}`,
|
||||||
`--node ${CONTROL}`,
|
`--node ${CONTROL}`,
|
||||||
@@ -632,6 +662,20 @@ async function genesis(images: HeldImage[]): Promise<GenesisResult> {
|
|||||||
`digest assigned by ${MESH_REGISTRY}.`);
|
`digest assigned by ${MESH_REGISTRY}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3a. THE CONTROL PLANE WAS BUILT, not carried.
|
||||||
|
//
|
||||||
|
// **The distinction the installer now exists to make** (novox/hq ADR 0073). A mesh running an
|
||||||
|
// image it was handed cannot rebuild the thing that runs it, and looks identical from the
|
||||||
|
// outside to one that can — same container, same digest, same registry. The difference is
|
||||||
|
// whether a build happened, and the only place that is visible is the installer saying so.
|
||||||
|
const wanted = sourceRef.slice(0, 8);
|
||||||
|
if (!new RegExp(`built mesh-control from ${wanted}`).test(said)) {
|
||||||
|
return stop("after the last step",
|
||||||
|
`the installer never said it built mesh-control from ${wanted}. What runs may have been ` +
|
||||||
|
`carried rather than made here, which is a mesh that cannot rebuild its own control plane.`);
|
||||||
|
}
|
||||||
|
report.push(` built here mesh-control from ${wanted}, by the carried builder`);
|
||||||
|
|
||||||
// 3b. And the registry really serves it, asked of the registry rather than of the container. A
|
// 3b. And the registry really serves it, asked of the registry rather than of the container. A
|
||||||
// reference is a claim; a tag list is the registry agreeing.
|
// reference is a claim; a tag list is the registry agreeing.
|
||||||
const tags = await on(CONTROL,
|
const tags = await on(CONTROL,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { test } from "node:test";
|
import { test } from "node:test";
|
||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
import { planned, controlPlaneImage } from "../src/rebuild.ts";
|
import { planned, carriedImage } from "../src/rebuild.ts";
|
||||||
import { repositories } from "../src/repos.ts";
|
import { repositories } from "../src/repos.ts";
|
||||||
import { loadScenario } from "../src/declaration/parse.ts";
|
import { loadScenario } from "../src/declaration/parse.ts";
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ test("the installer is built, carrying the image built in the same run", () => {
|
|||||||
|
|
||||||
const installer = builds.find((b) => b.what === "installer")!;
|
const installer = builds.find((b) => b.what === "installer")!;
|
||||||
assert.equal(installer.in, "/repo/host");
|
assert.equal(installer.in, "/repo/host");
|
||||||
assert.ok(installer.argv.includes(`IMAGE=${controlPlaneImage({})}`), installer.argv.join(" "));
|
assert.ok(installer.argv.includes(`IMAGE=${carriedImage({})}`), installer.argv.join(" "));
|
||||||
assert.ok(installer.argv.includes("BOOTSTRAP_OUT=/repo/host/mesh-bootstrap"), installer.argv.join(" "));
|
assert.ok(installer.argv.includes("BOOTSTRAP_OUT=/repo/host/mesh-bootstrap"), installer.argv.join(" "));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user