Beds read the catalogue: a shared loader, eight beds converted, the rest declared

catalogueModule() in the harness reads a module's manifest from the catalogue and
rewrites only what the lab must: the build section goes, each artifact becomes the
image the machine holds, images are pinned, and a bed may declare a host-port remap
or a lab-local address. confluence, gitlab, openai-consumer, audit-logger, ollama,
local-model-consumer, model-usage, mosquitto, anthropic-manager and
anthropic-consumer now install the catalogue's manifest. A unit test refuses any
inline copy naming a catalogue module unless the bed is declared with its reason;
the declared list is the debt (novox/hq 04-ISSUES/073).
This commit is contained in:
2026-09-21 14:27:49 +02:00
parent f2d29491b2
commit 2456b2f533
10 changed files with 259 additions and 361 deletions
+5 -31
View File
@@ -28,7 +28,7 @@ import { loadScenario } from "../../src/declaration/parse.ts";
import { raise } from "../../src/lifecycle/raise.ts";
import { destroy, exec } from "../../src/lifecycle/operate.ts";
import { hostBinaryPath, HOST_PATH } from "../../src/lifecycle/place.ts";
import { labIsUsable, destroyAll, foundationBundle, onTheMachine } from "./harness.ts";
import { labIsUsable, destroyAll, foundationBundle, onTheMachine, catalogueModule, catalogueIsPresent } from "./harness.ts";
import type { HeldImage } from "../../src/pinning.ts";
const capability = await labIsUsable();
@@ -41,7 +41,7 @@ const skip = !capability.usable
? "MESH_LAB_HOST_BINARY is not set to a built mesh-host"
: !bundle || !existsSync(bundle)
? "MESH_LAB_BUNDLE is not set to a foundation bundle (mesh-host examples/)"
: false;
: catalogueIsPresent();
const SCENARIO = "tools-gitlab";
const MACHINE = "anchor";
@@ -154,35 +154,9 @@ test("the mesh assigns gitlab: its tools-only runtime comes up and serves the fu
// gitlab is tools-only and outbound-only: no service, no listener, no provisioner — just a
// broker-bound runtime serving the module's tools. Its own token is a mesh-minted own-secret; the
// lab has no real GitLab, so the token points at nothing — and that is the case under test: the
// runtime must serve every tool regardless. The runtime container name and shape mirror the
// committed manifest, with the image pinned to what this scenario serves by digest.
const manifest = JSON.stringify({
module: "gitlab",
version: "1",
"own-secrets": {
token: "/var/lib/gitlab/token",
broker: "/var/lib/mesh/gitlab/broker",
},
resources: [
{ id: "mesh-state", type: "directory", path: "/var/lib/mesh/gitlab", mode: "0700" },
{ id: "state", type: "directory", path: "/var/lib/gitlab", mode: "0700" },
{ id: "config", type: "file", path: "/var/lib/gitlab/config.json", merge: "json", content: "{}", mode: "0600" },
{
id: "runtime", type: "container", name: "mesh-runtime-gitlab",
image: pinned("mesh-runtime-gitlab"), network: "host",
volumes: [
"/var/lib/gitlab/config.json:/run/config/config.json:ro",
"/var/lib/gitlab/token:/run/secrets/token:ro",
"/var/lib/mesh/gitlab/broker:/run/secrets/broker:ro",
],
env: {
MESH_GITLAB_TOKEN_FILE: "/run/secrets/token",
MESH_GITLAB_CONFIG_FILE: "/run/config/config.json",
MESH_BROKER_FILE: "/run/secrets/broker",
},
},
],
});
// runtime must serve every tool regardless. The manifest is the catalogue's own, its runtime
// artifact the image this scenario stocked (novox/hq 04-ISSUES/073).
const manifest = catalogueModule("gitlab", held);
await must(`printf %s ${quote(manifest)} > /tmp/gitlab.json && docker cp /tmp/gitlab.json mesh-controller:/gitlab.json`);
await mesh("module add /gitlab.json");