Rename mesh-control -> mesh-controller, substrate -> foundation
One name per thing, per the HQ glossary: the module/container/image/binary/repo becomes mesh-controller, the seat the-controller, and the store+broker pair the foundation (embedded base bundles, default template and example lock renamed with their go:embed directives). No behaviour change — a pure vocabulary rename. Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
@@ -6,10 +6,10 @@
|
||||
* project keeps saying cannot be checked any other way (novox/hq ADR 0001: every fault of
|
||||
* 2026-08-22 was found in production because nothing could be stood up locally).
|
||||
*
|
||||
* It needs a host binary and the substrate bundle:
|
||||
* It needs a host binary and the foundation bundle:
|
||||
*
|
||||
* MESH_LAB_HOST_BINARY=.../mesh-host
|
||||
* MESH_LAB_BUNDLE=.../examples/substrate-first-node.lock
|
||||
* MESH_LAB_BUNDLE=.../examples/foundation-first-node.lock
|
||||
*
|
||||
* The bundle's image references are rewritten to the ones this scenario's own registry serves.
|
||||
* A digest belongs to whatever registry serves it, so a committed bundle names a registry that is
|
||||
@@ -24,7 +24,7 @@ import { raise } from "../../src/lifecycle/raise.ts";
|
||||
import { pinnedInto, stillUnpinned, type HeldImage } from "../../src/pinning.ts";
|
||||
import { destroy, exec } from "../../src/lifecycle/operate.ts";
|
||||
import { hostBinaryPath, HOST_PATH } from "../../src/lifecycle/place.ts";
|
||||
import { labIsUsable, destroyAll, substrateBundle, onTheMachine } from "./harness.ts";
|
||||
import { labIsUsable, destroyAll, foundationBundle, onTheMachine } from "./harness.ts";
|
||||
import { incus } from "../../src/incus/client.ts";
|
||||
import { machineName } from "../../src/lifecycle/names.ts";
|
||||
import { ready, returnTo, keep, rememberStock, warmStock } from "../../src/warm.ts";
|
||||
@@ -36,7 +36,7 @@ const capability = await labIsUsable();
|
||||
const binary = hostBinaryPath();
|
||||
const bundle = process.env["MESH_LAB_BUNDLE"] ?? "";
|
||||
const builder = process.env["MESH_LAB_BUILDER"] ?? "";
|
||||
/** mesh-control's `examples/modules`, so the manifests proven here are the ones that ship. */
|
||||
/** mesh-controller's `examples/modules`, so the manifests proven here are the ones that ship. */
|
||||
const moduleExamples = process.env["MESH_LAB_MODULES"] ?? "";
|
||||
|
||||
const skip = !capability.usable
|
||||
@@ -44,7 +44,7 @@ const skip = !capability.usable
|
||||
: !binary || !existsSync(binary)
|
||||
? "MESH_LAB_HOST_BINARY is not set to a built mesh-host"
|
||||
: !bundle || !existsSync(bundle)
|
||||
? "MESH_LAB_BUNDLE is not set to a substrate bundle (mesh-host examples/)"
|
||||
? "MESH_LAB_BUNDLE is not set to a foundation bundle (mesh-host examples/)"
|
||||
: false;
|
||||
|
||||
const SCENARIO = "two-nodes";
|
||||
@@ -105,7 +105,7 @@ async function must(machine: string, command: string, timeoutMs?: number): Promi
|
||||
|
||||
/** The control plane, which runs in a container on the first node. */
|
||||
async function mesh(command: string, timeoutMs?: number): Promise<string> {
|
||||
return must("anchor", `docker exec mesh-control /mesh-control ${command}`, timeoutMs);
|
||||
return must("anchor", `docker exec mesh-controller /mesh-controller ${command}`, timeoutMs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,7 +144,7 @@ async function settled(node: string, withinMs = 480_000): Promise<void> {
|
||||
let said = "";
|
||||
try {
|
||||
const asked = await on("anchor",
|
||||
`docker exec mesh-control /mesh-control status --json`);
|
||||
`docker exec mesh-controller /mesh-controller status --json`);
|
||||
said = asked.out;
|
||||
// Parsed inside the try on purpose: a truncated answer from a struggling machine is the
|
||||
// same fact as no answer, and the likeliest moment for one is exactly the machine this
|
||||
@@ -186,11 +186,11 @@ async function settled(node: string, withinMs = 480_000): Promise<void> {
|
||||
* The bundle, as a machine should receive it.
|
||||
*
|
||||
* The committed example was written for a target that had a registry the lab raised. Its two
|
||||
* third-party images become upstream references the machine pulls itself; mesh-control, which
|
||||
* third-party images become upstream references the machine pulls itself; mesh-controller, which
|
||||
* exists in no registry, becomes the ID this machine was handed.
|
||||
*/
|
||||
function bundleFor(images: HeldImage[]): string {
|
||||
return substrateBundle(bundle, images);
|
||||
return foundationBundle(bundle, images);
|
||||
}
|
||||
|
||||
/** Take a token out of what `token issue` printed. It is the one base64url blob on its own line. */
|
||||
@@ -253,8 +253,8 @@ before(async () => {
|
||||
// because the control plane's image is named by the ID this machine holds it under, which is not
|
||||
// knowable until it has been handed over.
|
||||
held = raised.images;
|
||||
await must("anchor", `cat > /tmp/substrate.lock <<'MESHBUNDLE'\n${bundleFor(raised.images)}\nMESHBUNDLE`);
|
||||
await must("anchor", `${HOST_PATH} apply /tmp/substrate.lock`);
|
||||
await must("anchor", `cat > /tmp/foundation.lock <<'MESHBUNDLE'\n${bundleFor(raised.images)}\nMESHBUNDLE`);
|
||||
await must("anchor", `${HOST_PATH} apply /tmp/foundation.lock`);
|
||||
|
||||
// A build machine, so anything here can ask the mesh to build something. Placed rather than
|
||||
// assumed: nothing else in this scenario would start one.
|
||||
@@ -289,7 +289,7 @@ after(async () => {
|
||||
|
||||
test("a bare machine becomes a mesh", { skip, timeout: 600_000 }, async () => {
|
||||
const running = await must("anchor", `docker ps --format '{{.Names}}'`);
|
||||
for (const container of ["mesh-store", "mesh-broker", "mesh-control"]) {
|
||||
for (const container of ["mesh-store", "mesh-broker", "mesh-controller"]) {
|
||||
assert.match(running, new RegExp(container), `${container} is not running`);
|
||||
}
|
||||
// Answering, not merely up. A container that is running is not a control plane that replies —
|
||||
@@ -334,8 +334,8 @@ test("a credential reaches both ends and the mesh holds neither", { skip, timeou
|
||||
`"content":"PGHOST=$\{bound:postgres-database:at\}\\nPGPORT=$\{bound:postgres-database:port\}\\n` +
|
||||
`PGUSER=$\{bound:postgres-database:as\}\\nPGPASSWORD=$\{secret:postgres-database\}\\n"}]}' ` +
|
||||
`> /tmp/app.json`);
|
||||
await must("anchor", `docker cp /tmp/pg.json mesh-control:/pg.json`);
|
||||
await must("anchor", `docker cp /tmp/app.json mesh-control:/app.json`);
|
||||
await must("anchor", `docker cp /tmp/pg.json mesh-controller:/pg.json`);
|
||||
await must("anchor", `docker cp /tmp/app.json mesh-controller:/app.json`);
|
||||
await mesh("module add /pg.json");
|
||||
await mesh("module add /app.json");
|
||||
|
||||
@@ -423,7 +423,7 @@ test("when a machine cannot do what it was told, the mesh says which and why", {
|
||||
// is the situation `status` exists to distinguish from a machine that refused everything.
|
||||
await must("anchor", `printf %s '{"module":"impossible","version":"1","resources":[` +
|
||||
`{"id":"nothing","type":"package","package":"a-package-that-does-not-exist"}]}' > /tmp/imp.json`);
|
||||
await must("anchor", `docker cp /tmp/imp.json mesh-control:/imp.json`);
|
||||
await must("anchor", `docker cp /tmp/imp.json mesh-controller:/imp.json`);
|
||||
await mesh("module add /imp.json");
|
||||
await mesh("assign laptop impossible");
|
||||
await mesh("push laptop");
|
||||
@@ -471,7 +471,7 @@ test("a declaration waits for a machine that is switched off", { skip, timeout:
|
||||
|
||||
await must("anchor", `printf %s '{"module":"while-away","version":"1","resources":[` +
|
||||
`{"id":"note","type":"file","path":"/etc/mesh-while-away","content":"waited"}]}' > /tmp/away.json`);
|
||||
await must("anchor", `docker cp /tmp/away.json mesh-control:/away.json`);
|
||||
await must("anchor", `docker cp /tmp/away.json mesh-controller:/away.json`);
|
||||
await mesh("module add /away.json");
|
||||
await mesh("assign laptop while-away");
|
||||
await mesh("push laptop");
|
||||
@@ -512,13 +512,13 @@ test("a declaration waits for a machine that is switched off", { skip, timeout:
|
||||
test("unassigning takes away exactly what it should", { skip, timeout: 900_000 }, async () => {
|
||||
// Removal is the half nobody tests. The mesh takes away what IT declared and no longer declares,
|
||||
// and never what the machine raised for itself from its bundle — which is the fault that
|
||||
// destroyed a substrate once (novox/hq 04-ISSUES/010).
|
||||
// destroyed a foundation once (novox/hq 04-ISSUES/010).
|
||||
//
|
||||
// Two modules, so the test can tell "removed the right one" from "removed everything".
|
||||
for (const [name, path] of [["kept", "/etc/mesh-kept"], ["going", "/etc/mesh-going"]] as const) {
|
||||
await must("anchor", `printf %s '{"module":"${name}","version":"1","resources":[` +
|
||||
`{"id":"note","type":"file","path":"${path}","content":"${name}"}]}' > /tmp/${name}.json`);
|
||||
await must("anchor", `docker cp /tmp/${name}.json mesh-control:/${name}.json`);
|
||||
await must("anchor", `docker cp /tmp/${name}.json mesh-controller:/${name}.json`);
|
||||
await mesh(`module add /${name}.json`);
|
||||
await mesh(`assign anchor ${name}`);
|
||||
}
|
||||
@@ -536,11 +536,11 @@ test("unassigning takes away exactly what it should", { skip, timeout: 900_000 }
|
||||
assert.ok((await on("anchor", `test -f /etc/mesh-kept`)).ok,
|
||||
"unassigning one module took another one's file with it");
|
||||
|
||||
// And the substrate this machine raised from its own bundle is untouched. It was not declared by
|
||||
// And the foundation this machine raised from its own bundle is untouched. It was not declared by
|
||||
// the mesh, so the mesh must never remove it — the machine would take its own control plane
|
||||
// away, which is exactly what happened before origins existed.
|
||||
const running = await must("anchor", `docker ps --format '{{.Names}}'`);
|
||||
for (const container of ["mesh-store", "mesh-broker", "mesh-control"]) {
|
||||
for (const container of ["mesh-store", "mesh-broker", "mesh-controller"]) {
|
||||
assert.match(running, new RegExp(container),
|
||||
`${container} was removed by a declaration that never declared it`);
|
||||
}
|
||||
@@ -565,7 +565,7 @@ test("a machine that fell behind catches up without being named", { skip, timeou
|
||||
await must("anchor", `printf %s '{"module":"fixable","version":"1","resources":[` +
|
||||
`{"id":"pkg","type":"package","package":"a-package-that-does-not-exist-yet"},` +
|
||||
`{"id":"note","type":"file","path":"/etc/mesh-fixable","content":"here"}]}' > /tmp/fix.json`);
|
||||
await must("anchor", `docker cp /tmp/fix.json mesh-control:/fix.json`);
|
||||
await must("anchor", `docker cp /tmp/fix.json mesh-controller:/fix.json`);
|
||||
await mesh("module add /fix.json");
|
||||
await mesh("assign laptop fixable");
|
||||
await mesh("push laptop");
|
||||
@@ -585,7 +585,7 @@ test("a machine that fell behind catches up without being named", { skip, timeou
|
||||
// Fix the cause, the way somebody would: the module stops asking for the impossible thing.
|
||||
await must("anchor", `printf %s '{"module":"fixable","version":"1","resources":[` +
|
||||
`{"id":"note","type":"file","path":"/etc/mesh-fixable","content":"here"}]}' > /tmp/fix.json`);
|
||||
await must("anchor", `docker cp /tmp/fix.json mesh-control:/fix.json`);
|
||||
await must("anchor", `docker cp /tmp/fix.json mesh-controller:/fix.json`);
|
||||
await mesh("module add /fix.json");
|
||||
|
||||
// And nobody names the machine.
|
||||
@@ -626,7 +626,7 @@ test("the mesh runs its own artifact store", { skip, timeout: 900_000 }, async (
|
||||
// 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 must("anchor", `docker cp /root/registry/module.json mesh-controller:/registry.json`);
|
||||
await mesh("module add /registry.json");
|
||||
await mesh("assign anchor registry");
|
||||
await mesh("push anchor");
|
||||
@@ -658,7 +658,7 @@ test("a machine serves its internal name with a certificate the mesh issued", {
|
||||
`"certificate":{"into":"/etc/mesh/serving.crt","authority":"/etc/mesh/authority.crt"},` +
|
||||
`"resources":[{"id":"dir","type":"directory","path":"/etc/mesh","mode":"0755"}]}' ` +
|
||||
`> /tmp/served.json`);
|
||||
await must("anchor", `docker cp /tmp/served.json mesh-control:/served.json`);
|
||||
await must("anchor", `docker cp /tmp/served.json mesh-controller:/served.json`);
|
||||
await mesh("module add /served.json");
|
||||
await mesh("assign anchor served");
|
||||
await mesh("push anchor");
|
||||
@@ -768,7 +768,7 @@ test("a machine filters exactly what its modules declared, and nothing else", {
|
||||
`{"id":"filter","type":"service","unit":"mesh-filter.service","state":"running",` +
|
||||
`"boot":"enabled","restart-on":["filtering"]}]}' > /tmp/firewall.json`);
|
||||
for (const f of ["talker", "firewall"]) {
|
||||
await must("anchor", `docker cp /tmp/${f}.json mesh-control:/${f}.json`);
|
||||
await must("anchor", `docker cp /tmp/${f}.json mesh-controller:/${f}.json`);
|
||||
await mesh(`module add /${f}.json`);
|
||||
}
|
||||
await mesh("assign laptop talker");
|
||||
@@ -972,7 +972,7 @@ test("rotating a credential moves both ends, and the old one stops working", {
|
||||
`"resources":[{"id":"dir","type":"directory","path":"/etc/realapp","mode":"0755"}]}' ` +
|
||||
`> /tmp/realapp.json`);
|
||||
for (const f of ["realstore", "realapp"]) {
|
||||
await must("anchor", `docker cp /tmp/${f}.json mesh-control:/${f}.json`);
|
||||
await must("anchor", `docker cp /tmp/${f}.json mesh-controller:/${f}.json`);
|
||||
await mesh(`module add /${f}.json`);
|
||||
}
|
||||
await mesh("assign anchor realstore");
|
||||
@@ -1081,7 +1081,7 @@ test("a route is a grant: a workload is reached by the name it asked for", {
|
||||
`{"id":"app","type":"container","name":"storefront",` +
|
||||
`"image":"${ARTIFACT_STORE}","ports":["8088:5000"]}]}' > /tmp/storefront.json`);
|
||||
for (const f of ["frontdoor", "storefront"]) {
|
||||
await must("anchor", `docker cp /tmp/${f}.json mesh-control:/${f}.json`);
|
||||
await must("anchor", `docker cp /tmp/${f}.json mesh-controller:/${f}.json`);
|
||||
await mesh(`module add /${f}.json`);
|
||||
}
|
||||
await mesh("assign anchor frontdoor");
|
||||
@@ -1135,7 +1135,7 @@ test("a route is a grant: a workload is reached by the name it asked for", {
|
||||
assert.ok(withdrawn,
|
||||
`the route outlived the module that asked for it:\n${after}\n\n` +
|
||||
`the machine did apply — this is what the mesh would send now:\n` +
|
||||
`${(await on("anchor", `docker exec mesh-control /mesh-control plan anchor --files`)).out}`);
|
||||
`${(await on("anchor", `docker exec mesh-controller /mesh-controller plan anchor --files`)).out}`);
|
||||
|
||||
let gone = false;
|
||||
for (let i = 0; i < 15 && !gone; i++) {
|
||||
@@ -1159,7 +1159,7 @@ test("model access is answered by a record, and the key the mesh took is one it
|
||||
`"secrets":{"model-access":"/etc/assistant/key"},` +
|
||||
`"resources":[{"id":"dir","type":"directory","path":"/etc/assistant","mode":"0755"}]}' ` +
|
||||
`> /tmp/assistant.json`);
|
||||
await must("anchor", `docker cp /tmp/assistant.json mesh-control:/assistant.json`);
|
||||
await must("anchor", `docker cp /tmp/assistant.json mesh-controller:/assistant.json`);
|
||||
await mesh("module add /assistant.json");
|
||||
|
||||
// The licences first. With none recorded at all the honest answer is that nothing provides
|
||||
@@ -1171,7 +1171,7 @@ test("model access is answered by a record, and the key the mesh took is one it
|
||||
// then says the machine's set cannot be applied. The refusal names both candidates and the
|
||||
// command. ADR 0024 warns this will be felt — which is correct, and correct is not the same as
|
||||
// usable.
|
||||
const refused = await on("anchor", `docker exec mesh-control /mesh-control assign laptop assistant`);
|
||||
const refused = await on("anchor", `docker exec mesh-controller /mesh-controller assign laptop assistant`);
|
||||
assert.ok(!refused.ok,
|
||||
`a consumer was given model access without anybody saying which:\n${refused.out}`);
|
||||
for (const want of ["personal", "the-organisation", "licence use"]) {
|
||||
@@ -1182,7 +1182,7 @@ test("model access is answered by a record, and the key the mesh took is one it
|
||||
await mesh("licence use personal laptop assistant");
|
||||
|
||||
// Chosen, and still no key: the mesh has one thing to deliver and has not been given it.
|
||||
const noKey = await on("anchor", `docker exec mesh-control /mesh-control plan laptop`);
|
||||
const noKey = await on("anchor", `docker exec mesh-controller /mesh-controller plan laptop`);
|
||||
assert.ok(!noKey.ok, `a module was planned with a licence that has no key:\n${noKey.out}`);
|
||||
assert.match(noKey.out, /licence key personal/, noKey.out);
|
||||
|
||||
@@ -1190,7 +1190,7 @@ test("model access is answered by a record, and the key the mesh took is one it
|
||||
// command line is a key in shell history and in every process listing taken while it ran.
|
||||
const secret = "sk-test-" + "0123456789abcdef".repeat(2);
|
||||
const accepted = await must("anchor",
|
||||
`printf %s ${quote(secret)} | docker exec -i mesh-control /mesh-control licence key personal`);
|
||||
`printf %s ${quote(secret)} | docker exec -i mesh-controller /mesh-controller licence key personal`);
|
||||
assert.match(accepted, /sealed to 1 holder/, accepted);
|
||||
assert.doesNotMatch(accepted, new RegExp(secret),
|
||||
"the key was echoed back, so the one copy that matters is on a terminal");
|
||||
@@ -1298,11 +1298,11 @@ test("the board names the machine that is not doing what it was told", {
|
||||
await must("anchor", `printf %s '{"module":"board","version":"1",` +
|
||||
`"listens":[{"port":8090,"from":"mesh","why":"the board"}],` +
|
||||
`"resources":[]}' > /tmp/board.json`);
|
||||
await must("anchor", `docker cp /tmp/board.json mesh-control:/board.json`);
|
||||
await must("anchor", `docker cp /tmp/board.json mesh-controller:/board.json`);
|
||||
await mesh("module add /board.json");
|
||||
|
||||
// Served from the control plane's own container, reading the mesh on every request.
|
||||
await must("anchor", `docker exec -d mesh-control /mesh-control board --listen 0.0.0.0:8090`);
|
||||
await must("anchor", `docker exec -d mesh-controller /mesh-controller board --listen 0.0.0.0:8090`);
|
||||
await new Promise((r) => setTimeout(r, 3000));
|
||||
|
||||
const read = async (path: string) =>
|
||||
@@ -1325,7 +1325,7 @@ test("the board names the machine that is not doing what it was told", {
|
||||
await must("anchor", `printf %s '{"module":"impossible","version":"1",` +
|
||||
`"resources":[{"id":"nowhere","type":"service","unit":"nothing-like-this.service",` +
|
||||
`"state":"running"}]}' > /tmp/impossible.json`);
|
||||
await must("anchor", `docker cp /tmp/impossible.json mesh-control:/impossible.json`);
|
||||
await must("anchor", `docker cp /tmp/impossible.json mesh-controller:/impossible.json`);
|
||||
await mesh("module add /impossible.json");
|
||||
await mesh("assign laptop impossible");
|
||||
await mesh("push laptop");
|
||||
@@ -1389,7 +1389,7 @@ test("the hub can be filtered without severing the mesh", {
|
||||
`ExecStart=/usr/bin/nft -f ${rules}\\n[Install]\\nWantedBy=multi-user.target\\n"},` +
|
||||
`{"id":"filter","type":"service","unit":"hub-filter.service","state":"running",` +
|
||||
`"boot":"enabled","restart-on":["filtering"]}]}' > /tmp/hubfilter.json`);
|
||||
await must("anchor", `docker cp /tmp/hubfilter.json mesh-control:/hubfilter.json`);
|
||||
await must("anchor", `docker cp /tmp/hubfilter.json mesh-controller:/hubfilter.json`);
|
||||
await mesh("module add /hubfilter.json");
|
||||
await mesh("assign anchor hubfilter");
|
||||
await mesh("push anchor");
|
||||
@@ -1414,7 +1414,7 @@ test("the hub can be filtered without severing the mesh", {
|
||||
await must("anchor", `printf %s '{"module":"stillworks","version":"1",` +
|
||||
`"resources":[{"id":"marker","type":"file","path":"/etc/mesh-still-works",` +
|
||||
`"content":"yes","mode":"0644"}]}' > /tmp/stillworks.json`);
|
||||
await must("anchor", `docker cp /tmp/stillworks.json mesh-control:/stillworks.json`);
|
||||
await must("anchor", `docker cp /tmp/stillworks.json mesh-controller:/stillworks.json`);
|
||||
await mesh("module add /stillworks.json");
|
||||
await mesh("assign laptop stillworks");
|
||||
await mesh("push laptop");
|
||||
@@ -1450,7 +1450,7 @@ test("a container reaches another machine by the name the mesh gave it", {
|
||||
`"capabilities":["container-runtime"],` +
|
||||
`"resources":[{"id":"idle","type":"container","name":"resolves",` +
|
||||
`"image":"${ARTIFACT_STORE}"}]}' > /tmp/resolves.json`);
|
||||
await must("anchor", `docker cp /tmp/resolves.json mesh-control:/resolves.json`);
|
||||
await must("anchor", `docker cp /tmp/resolves.json mesh-controller:/resolves.json`);
|
||||
await mesh("module add /resolves.json");
|
||||
await mesh("assign laptop resolves");
|
||||
await mesh("push laptop");
|
||||
@@ -1539,7 +1539,7 @@ test("every name under a machine resolves to that machine", {
|
||||
});
|
||||
|
||||
test("a service is reached by a name under the machine it runs on", {
|
||||
skip: skip || (!moduleExamples ? "set MESH_LAB_MODULES to mesh-control's examples/modules" : false),
|
||||
skip: skip || (!moduleExamples ? "set MESH_LAB_MODULES to mesh-controller's examples/modules" : false),
|
||||
timeout: 900_000,
|
||||
}, async () => {
|
||||
// postgres.novox.internal, plex.ace.internal — the first label is the service and the rest is
|
||||
@@ -1555,7 +1555,7 @@ test("a service is reached by a name under the machine it runs on", {
|
||||
for (const name of ["dnsmasq", "resolved-split-dns"]) {
|
||||
const manifest = readFileSync(`${moduleExamples}/${name}.json`, "utf8");
|
||||
await must("anchor", `cat > /tmp/${name}.json <<'MANIFEST'\n${manifest}\nMANIFEST`);
|
||||
await must("anchor", `docker cp /tmp/${name}.json mesh-control:/${name}.json`);
|
||||
await must("anchor", `docker cp /tmp/${name}.json mesh-controller:/${name}.json`);
|
||||
await mesh(`module add /${name}.json`);
|
||||
}
|
||||
|
||||
@@ -1700,18 +1700,18 @@ test("a third-party workload is adopted, with the credential it already had", {
|
||||
},
|
||||
],
|
||||
}))} > /umami.json`);
|
||||
await must("anchor", `docker cp /umami.json mesh-control:/umami.json`);
|
||||
await must("anchor", `docker cp /umami.json mesh-controller:/umami.json`);
|
||||
await mesh("module add /umami.json");
|
||||
|
||||
// **Accepted, not generated.** The value is what the database already answers to; the mesh
|
||||
// seals it and cannot read it again. Given whole, as the environment lines the containers read.
|
||||
await must("anchor",
|
||||
`printf %s ${quote(`POSTGRES_PASSWORD=${password}`)} | ` +
|
||||
`docker exec -i mesh-control /mesh-control secret accept anchor umami database --from -`);
|
||||
`docker exec -i mesh-controller /mesh-controller secret accept anchor umami database --from -`);
|
||||
await must("anchor",
|
||||
`printf %s ${quote(
|
||||
`DATABASE_URL=postgresql://umami:${password}@umami-db:5432/umami`)} | ` +
|
||||
`docker exec -i mesh-control /mesh-control secret accept anchor umami app --from -`);
|
||||
`docker exec -i mesh-controller /mesh-controller secret accept anchor umami app --from -`);
|
||||
|
||||
await mesh("assign anchor umami");
|
||||
await mesh("push anchor", 300_000);
|
||||
@@ -1815,7 +1815,7 @@ test("the real modules resolve together, and compose a declaration a host accept
|
||||
}
|
||||
planned.push(name);
|
||||
await must("anchor", `printf %s ${quote(pinned)} > /${name}.json`);
|
||||
await must("anchor", `docker cp /${name}.json mesh-control:/${name}.json`);
|
||||
await must("anchor", `docker cp /${name}.json mesh-controller:/${name}.json`);
|
||||
await mesh(`module add /${name}.json`);
|
||||
}
|
||||
|
||||
@@ -1932,7 +1932,7 @@ test("the forge runs, on a database the mesh gave it", { skip, timeout: 900_000
|
||||
assert.deepEqual(stillUnpinned(pinned), [],
|
||||
`${name} still names an image nothing serves, so it could not start`);
|
||||
await must("anchor", `printf %s ${quote(pinned)} > /run-${name}.json`);
|
||||
await must("anchor", `docker cp /run-${name}.json mesh-control:/run-${name}.json`);
|
||||
await must("anchor", `docker cp /run-${name}.json mesh-controller:/run-${name}.json`);
|
||||
await mesh(`module add /run-${name}.json`);
|
||||
await mesh(`assign anchor ${name}`);
|
||||
}
|
||||
@@ -2018,7 +2018,7 @@ test("a consumer's cache grant means exactly its own keys", { skip, timeout: 600
|
||||
assert.deepEqual(stillUnpinned(pinned), [],
|
||||
"redis still names an image nothing serves, so it could not start");
|
||||
await must("anchor", `printf %s ${quote(pinned)} > /run-redis.json`);
|
||||
await must("anchor", `docker cp /run-redis.json mesh-control:/run-redis.json`);
|
||||
await must("anchor", `docker cp /run-redis.json mesh-controller:/run-redis.json`);
|
||||
await mesh("module add /run-redis.json");
|
||||
|
||||
// A consumer with no container: what is under test is the credential's reach, and files on the
|
||||
@@ -2030,7 +2030,7 @@ test("a consumer's cache grant means exactly its own keys", { skip, timeout: 600
|
||||
`"secrets":{"redis-cache":"/var/lib/cachetest/cache.secret"},` +
|
||||
`"resources":[{"id":"state","type":"directory","path":"/var/lib/cachetest","mode":"0700"}]}' ` +
|
||||
`> /cachetest.json`);
|
||||
await must("anchor", `docker cp /cachetest.json mesh-control:/cachetest.json`);
|
||||
await must("anchor", `docker cp /cachetest.json mesh-controller:/cachetest.json`);
|
||||
await mesh("module add /cachetest.json");
|
||||
|
||||
await mesh("assign anchor redis");
|
||||
|
||||
Reference in New Issue
Block a user