The lab names the modules as the catalogue does
Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
+17
-17
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"scenario": "one-node-mesh",
|
"scenario": "one-node-mesh",
|
||||||
"established": 19,
|
"established": 21,
|
||||||
"of": 22,
|
"of": 22,
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"code": "R1",
|
"code": "R1",
|
||||||
"title": "a bare machine becomes a mesh of one, raised by the installer",
|
"title": "a bare machine becomes a mesh of one, raised by the installer",
|
||||||
"status": "pass",
|
"status": "pass",
|
||||||
"seconds": 140,
|
"seconds": 141,
|
||||||
"why": ""
|
"why": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -56,21 +56,21 @@
|
|||||||
"code": "P1",
|
"code": "P1",
|
||||||
"title": "the mesh builds the shared base from source",
|
"title": "the mesh builds the shared base from source",
|
||||||
"status": "pass",
|
"status": "pass",
|
||||||
"seconds": 87,
|
"seconds": 77,
|
||||||
"why": ""
|
"why": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "P2",
|
"code": "P2",
|
||||||
"title": "the mesh builds and runs a store of its own",
|
"title": "the mesh builds and runs a store of its own",
|
||||||
"status": "pass",
|
"status": "pass",
|
||||||
"seconds": 39,
|
"seconds": 49,
|
||||||
"why": ""
|
"why": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "P3",
|
"code": "P3",
|
||||||
"title": "the mesh builds and runs its own catalogue",
|
"title": "the mesh builds and runs its own catalogue",
|
||||||
"status": "pass",
|
"status": "pass",
|
||||||
"seconds": 32,
|
"seconds": 26,
|
||||||
"why": ""
|
"why": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
"code": "N1",
|
"code": "N1",
|
||||||
"title": "the mesh puts itself on a private network, and its machine has a name",
|
"title": "the mesh puts itself on a private network, and its machine has a name",
|
||||||
"status": "pass",
|
"status": "pass",
|
||||||
"seconds": 7,
|
"seconds": 12,
|
||||||
"why": ""
|
"why": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -105,14 +105,14 @@
|
|||||||
"code": "U2",
|
"code": "U2",
|
||||||
"title": "the mesh runs a broker for that module to talk to",
|
"title": "the mesh runs a broker for that module to talk to",
|
||||||
"status": "pass",
|
"status": "pass",
|
||||||
"seconds": 31,
|
"seconds": 20,
|
||||||
"why": ""
|
"why": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "U3",
|
"code": "U3",
|
||||||
"title": "the anchor runs the module the mesh built",
|
"title": "the anchor runs the module the mesh built",
|
||||||
"status": "pass",
|
"status": "pass",
|
||||||
"seconds": 7,
|
"seconds": 6,
|
||||||
"why": ""
|
"why": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -139,23 +139,23 @@
|
|||||||
{
|
{
|
||||||
"code": "V4",
|
"code": "V4",
|
||||||
"title": "every resource the mesh declared is true on the machine",
|
"title": "every resource the mesh declared is true on the machine",
|
||||||
"status": "fail",
|
"status": "pass",
|
||||||
"seconds": 13,
|
"seconds": 12,
|
||||||
"why": "the machine is not what the mesh said it should be:\n container lavinmq.bootstrap: the container lavinmq-bootstrap was never created\n+ actual - expected\n\n+ [\n+ 'container lavinmq.bootstrap: the container lavinmq-bootstrap was never created'\n+ ]\n- []\n"
|
"why": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "E1",
|
"code": "E1",
|
||||||
"title": "a change to a module's source reaches the machine on its own",
|
"title": "a change to a module's source reaches the machine on its own",
|
||||||
"status": "skip",
|
"status": "pass",
|
||||||
"seconds": 0,
|
"seconds": 14,
|
||||||
"why": "not attempted — V4 (every resource the mesh declared is true on the machine) did not succeed"
|
"why": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "E2",
|
"code": "E2",
|
||||||
"title": "the mesh comes back after the machine reboots",
|
"title": "the mesh comes back after the machine reboots",
|
||||||
"status": "skip",
|
"status": "fail",
|
||||||
"seconds": 0,
|
"seconds": 30,
|
||||||
"why": "not attempted — E1 (a change to a module's source reaches the machine on its own) did not succeed"
|
"why": "every container came back and no host agent did, so the machine is running the right things and can no longer be told anything:\namqp-ping\tUp 3 seconds\nmesh-lavinmq\tUp 3 seconds\nlavinmq\tUp 3 seconds (health: starting)\nmesh-control\tUp 3 seconds\nmesh-catalog\tUp 3 seconds\nmesh-postgres\tUp 3 seconds\npostgres\tUp 3 seconds\nmesh-builder\tUp 3 seconds\nmesh-registry\tUp 3 seconds\nmesh-broker\tUp 4 seconds (health: starting)\nmesh-store\tUp 4 seconds\n"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ export function stepIn(said: string): string {
|
|||||||
export async function genesis(o: GenesisOptions): Promise<GenesisResult> {
|
export async function genesis(o: GenesisOptions): Promise<GenesisResult> {
|
||||||
const node = o.node;
|
const node = o.node;
|
||||||
const registry = o.registry ?? "127.0.0.1:5000";
|
const registry = o.registry ?? "127.0.0.1:5000";
|
||||||
const modules = o.catalogueModules ?? ["registry", "mesh-control", "builder"];
|
const modules = o.catalogueModules ?? ["distribution", "mesh-control", "builder"];
|
||||||
const catalogueOnMachine = o.catalogueOnMachine ?? "/opt/mesh-catalog";
|
const catalogueOnMachine = o.catalogueOnMachine ?? "/opt/mesh-catalog";
|
||||||
const log = o.log ?? (() => {});
|
const log = o.log ?? (() => {});
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ const NETWORK_MODULE = "networking";
|
|||||||
* claims a seat (`the-packet-filter`) because a machine has one of these and two things writing
|
* claims a seat (`the-packet-filter`) because a machine has one of these and two things writing
|
||||||
* rules is a coin toss about which survives.
|
* rules is a coin toss about which survives.
|
||||||
*/
|
*/
|
||||||
const FILTER_MODULE = "firewall";
|
const FILTER_MODULE = "nftables";
|
||||||
const STORE = { module: "postgres", repo: "mesh-catalog", path: "modules/postgres", container: "mesh-postgres" };
|
const STORE = { module: "postgres", repo: "mesh-catalog", path: "modules/postgres", container: "mesh-postgres" };
|
||||||
const CATALOGUE = { module: "mesh-catalog", repo: "mesh-catalog", path: "modules/mesh-catalog", container: "mesh-catalog" };
|
const CATALOGUE = { module: "mesh-catalog", repo: "mesh-catalog", path: "modules/mesh-catalog", container: "mesh-catalog" };
|
||||||
/** The control plane, rebuilt from its own repository — the step that ends the installer's tenure. */
|
/** The control plane, rebuilt from its own repository — the step that ends the installer's tenure. */
|
||||||
@@ -108,7 +108,7 @@ const CONTROL_PLANE = { module: "mesh-control", repo: "mesh-control", path: "",
|
|||||||
* the registry and the builder — are here too: they are carried in, and a mesh missing any of them
|
* the registry and the builder — are here too: they are carried in, and a mesh missing any of them
|
||||||
* is not one.
|
* is not one.
|
||||||
*/
|
*/
|
||||||
const MUST_HOLD = ["mesh-control", "registry", "builder", "mesh-tools", "postgres",
|
const MUST_HOLD = ["mesh-control", "distribution", "builder", "mesh-tools", "postgres",
|
||||||
"mesh-catalog", "lavinmq", "amqp-ping"];
|
"mesh-catalog", "lavinmq", "amqp-ping"];
|
||||||
const MUST_RUN = ["mesh-control", "mesh-registry", "mesh-broker", "mesh-store",
|
const MUST_RUN = ["mesh-control", "mesh-registry", "mesh-broker", "mesh-store",
|
||||||
"mesh-postgres", "mesh-catalog", "mesh-lavinmq", "amqp-ping"];
|
"mesh-postgres", "mesh-catalog", "mesh-lavinmq", "amqp-ping"];
|
||||||
@@ -779,7 +779,7 @@ before(async () => {
|
|||||||
// does. novox/hq issue 050 — on a fresh mesh the modules built before the catalogue existed
|
// does. novox/hq issue 050 — on a fresh mesh the modules built before the catalogue existed
|
||||||
// are exactly the ones it needed in order to exist, so the hole is always the foundation.
|
// are exactly the ones it needed in order to exist, so the hole is always the foundation.
|
||||||
const missing = MUST_HOLD.filter((m) =>
|
const missing = MUST_HOLD.filter((m) =>
|
||||||
!["registry", "builder"].includes(m) && !held.includes(m));
|
!["distribution", "builder"].includes(m) && !held.includes(m));
|
||||||
assert.deepEqual(missing, [],
|
assert.deepEqual(missing, [],
|
||||||
`the catalogue does not hold ${missing.join(", ")} — the mesh built them and its own ` +
|
`the catalogue does not hold ${missing.join(", ")} — the mesh built them and its own ` +
|
||||||
`record has no trace of it (novox/hq issue 050):\n${held}`);
|
`record has no trace of it (novox/hq issue 050):\n${held}`);
|
||||||
@@ -1004,9 +1004,14 @@ before(async () => {
|
|||||||
// **Containers coming back is not the mesh coming back.** The runtime restarts containers on
|
// **Containers coming back is not the mesh coming back.** The runtime restarts containers on
|
||||||
// its own; what makes a machine part of a mesh is an agent listening for what it should be. A
|
// its own; what makes a machine part of a mesh is an agent listening for what it should be. A
|
||||||
// machine whose containers returned and whose agent did not looks healthy and cannot be told
|
// machine whose containers returned and whose agent did not looks healthy and cannot be told
|
||||||
// anything — and the installer is explicit that a host started the way the lab starts it, with
|
// anything.
|
||||||
// --host-in-background, does not survive a reboot. So this asks, and a failure here is the
|
//
|
||||||
// packaging gap the design already records rather than a fault in the mesh.
|
// **A failure here is this lab's arrangement, not the mesh's capability.** mesh-host ships
|
||||||
|
// `nox-mesh-host.service` and two companions in packaging/; the installer declines to place
|
||||||
|
// them because a unit file is a packaging decision, and the lab starts the host with
|
||||||
|
// --host-in-background, which says in its own help that it does not survive a reboot. So this
|
||||||
|
// check is honest and the thing it catches is the step nobody runs — not a mesh that cannot
|
||||||
|
// come back.
|
||||||
const agent = (await on(CONTROL, `pgrep -af '[m]esh-host run' | head -3`)).out.trim();
|
const agent = (await on(CONTROL, `pgrep -af '[m]esh-host run' | head -3`)).out.trim();
|
||||||
assert.ok(agent,
|
assert.ok(agent,
|
||||||
`every container came back and no host agent did, so the machine is running the right ` +
|
`every container came back and no host agent did, so the machine is running the right ` +
|
||||||
|
|||||||
Reference in New Issue
Block a user