Raise genesis on the bus the mesh runs on, from one bundle (hq issue 146, ADR 0331)
mesh/merge-gate head 37947ca4eed1 merged into trunk d8e785bb4b4b — pass: the change touches no module of the mesh's graph
mesh/repo-check head 37947ca4eed1 merged into trunk d8e785bb4b4b — pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate head 37947ca4eed1 merged into trunk d8e785bb4b4b — pass: the change touches no module of the mesh's graph
mesh/repo-check head 37947ca4eed1 merged into trunk d8e785bb4b4b — pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request
The installer could not raise a first node: the old bundle's control plane had no MESH_BUS_NATS and crash-looped, and the NATS bundle was refused because rootsecrets only knew the previous broker's guest:guest@ template. One bundle now, the NATS one. rootsecrets makes the controller's bus account and puts it in both placeholders (the address and the bcrypt hash in the carried user list), kept with its hash so a re-run writes the same bundle. Preflight refuses a template naming no bus connection it knows, naming the placeholder, instead of waiting out the verify step. The broker step adopts the bus as the nats module and refuses, by name, a catalogue without it or a server that is not the foundation's container.
This commit is contained in:
+19
-33
@@ -2,51 +2,37 @@
|
||||
|
||||
## `foundation-first-node.lock`
|
||||
|
||||
What a machine must be before a mesh exists — the bootstrap in
|
||||
[novox/hq `07-the-foundation.md`](https://git.novox.be/novox/hq), whole:
|
||||
The one genesis bundle (novox/hq ADR 0331): what a machine must be before a mesh exists — the
|
||||
bootstrap in [novox/hq `07-the-foundation.md`](https://git.novox.be/novox/hq), whole, on the bus the
|
||||
mesh runs on:
|
||||
|
||||
```
|
||||
0 a container runtime
|
||||
0 a container runtime, and a filter before anything listens
|
||||
1 the store runs
|
||||
2 a database per context `inventory` and `identity`
|
||||
2 a database per context `inventory`, `identity` and `licences`
|
||||
3 those contexts' schemas mesh-controller migrate
|
||||
4 the broker runs with a certificate it generated itself
|
||||
5 the control plane runs mesh-controller serve
|
||||
4 the bus's certificate mesh-controller broker certificate
|
||||
5 the bus runs NATS, with the controller's account as its first user
|
||||
6 the control plane runs mesh-controller serve, given the bus (MESH_BUS_NATS)
|
||||
```
|
||||
|
||||
**A machine that applies this is a mesh** — one node, with nothing joined to it yet, which is
|
||||
exactly what the first node is (novox/hq ADR 0004). From here it hands out tokens and everything
|
||||
else joins the ordinary way.
|
||||
|
||||
This file said it stopped at step 4 for longer than that was true, which is its own small lesson:
|
||||
a comment about what something does not do is a comment nobody updates.
|
||||
It is a **template**: `mesh-bootstrap` reads it, makes the store's superuser and the controller's
|
||||
account on the bus, and writes them where the template says `bootstrap` (internal/bootstrap,
|
||||
rootsecrets.go). A template whose bus connection it does not recognise is refused at preflight,
|
||||
naming the placeholder it looked for. The bundle that raised the previous broker was deleted with
|
||||
ADR 0331; there is one bundle, and every lab bed names it.
|
||||
|
||||
Build a host carrying it:
|
||||
Build an installer carrying a builder, and point it at this:
|
||||
|
||||
```
|
||||
make host SYSTEM=arch BUNDLE=examples/foundation-first-node.lock
|
||||
make bootstrap IMAGE=<builder image>
|
||||
mesh-bootstrap --bundle examples/foundation-first-node.lock …
|
||||
```
|
||||
|
||||
**The registry address and digests have to be replaced before this is useful.** They are written
|
||||
as `192.0.2.250:5000/…@sha256:…` because a digest belongs to whatever registry serves it — here,
|
||||
one a lab scenario raises, which reports its digests when it comes up. That is not a placeholder
|
||||
to be tidied away: a bundle is built *for a target*, and which registry that target pulls from is
|
||||
part of the target.
|
||||
|
||||
### What was verified, and how
|
||||
|
||||
On a lab machine confirmed sealed — `curl https://example.com` times out, the lab registry answers
|
||||
200 — the whole bundle applied from bare: eight resources, `inventory` created and `mesh` nowhere,
|
||||
the `node` table present with its indexes, the migration recorded, and LavinMQ answering
|
||||
`lavinmqctl status` with AMQP listening on 5672.
|
||||
|
||||
Three consecutive reconciles after that: **already matches — 8 resource(s) checked**, each time.
|
||||
|
||||
Then the machine was **rebooted**, and everything came back: docker from `boot: enabled`, both
|
||||
containers because the host creates every container `--restart unless-stopped`
|
||||
(`internal/apply/apply.go`), the schema intact in its named volume, and reconcile still finding
|
||||
nothing to do.
|
||||
|
||||
The reboot is worth doing rather than assuming. Nothing in the declaration asks for a container to
|
||||
return, so that it does is a property of the host, and the only way to know it holds is to take
|
||||
the machine away and give it back.
|
||||
**The registry address is the lab's.** The images are written as `192.0.2.250:5000/…@sha256:…`; the
|
||||
lab rewrites the third-party ones to upstream references by the same digest, and the installer
|
||||
replaces the control plane's with the image it built.
|
||||
|
||||
Reference in New Issue
Block a user