Reconcile: adopt initialization's consolidated HQ as canonical, re-home this session's new work #24
@@ -40,7 +40,7 @@ Two costs, both already accrued:
|
||||
| message bus | **LavinMQ** | In use, speaks AMQP, which is what [ADR 0001](0001-nodes-communicate-over-a-broker.md) assumes. Interchangeable with other AMQP brokers at the protocol level, which is what makes it a safe choice rather than a locked-in one. |
|
||||
| object store | **MinIO** | In use, speaks the S3 protocol, which is the closest thing to a portable object-store interface. |
|
||||
| image registry | **the OCI distribution registry** | In use, and the format is the standard rather than a vendor's. |
|
||||
| container runtime | **Docker** | In use. Podman is the plausible alternative and was not chosen for any deficiency — Docker is what the machines run today and what the current tooling assumes. |
|
||||
| container runtime | **Docker or Podman** — *detected, not chosen* | See below. The other four rows name one product; this one names two, and the difference is the point. |
|
||||
|
||||
### Outside the substrate
|
||||
|
||||
@@ -58,6 +58,15 @@ correction applies — a role is a legitimate abstraction, but the product belon
|
||||
a route is an ordinary grant. Recorded here because finding it was the point — naming the
|
||||
products is what made the unnamed role visible.
|
||||
|
||||
**The container runtime is the one row that is not a choice at all**, and it stopped being one
|
||||
after this record was written ([ADR 0060](0060-the-host-is-built-per-operating-system.md)). The
|
||||
host detects what the machine has and uses it, because adoption keeps a machine's existing
|
||||
configuration rather than replacing it — so naming a single runtime here contradicted a rule
|
||||
already decided. Both are supported, checked against a real podman: only the version probe
|
||||
differs, and one behavioural difference (podman has no daemon, so containers do not return after
|
||||
a reboot unless `podman-restart.service` is enabled) belongs in the declaration rather than the
|
||||
host.
|
||||
|
||||
**Identity is deliberately absent.** Whether an identity provider is substrate at all depends on
|
||||
whether the control plane delegates authentication, which is undecided
|
||||
([`07-the-substrate.md`](../03-DESIGN/01-to-be/07-the-substrate.md)). Naming a product before
|
||||
|
||||
@@ -63,18 +63,29 @@ That split is the tier boundary made concrete rather than an inconsistency.
|
||||
|
||||
### What it needs from an init, and why that is not a dependency
|
||||
|
||||
The host needs four things from whatever supervises it: start at boot, restart when it exits,
|
||||
give up after repeated failures, and run something else when it gives up.
|
||||
> **Overtaken by [ADR 0061](0061-the-host-asks-an-init-for-start-and-restart.md) and
|
||||
> [ADR 0060](0060-the-host-is-built-per-operating-system.md).** All three claims below were
|
||||
> true when written and are not now. Kept rather than rewritten, because what changed and why
|
||||
> is the useful part.
|
||||
|
||||
**Every machine the mesh targets already has systemd**, and the host already treats the service
|
||||
manager as a detected capability rather than an assumption. This is not a dependency in
|
||||
[ADR 0041](0041-the-host-depends-on-nothing.md)'s sense — 0041 is about what must be *installed
|
||||
before the host works*, and an init is not installed, it is what the machine already is.
|
||||
~~The host needs **four** things from whatever supervises it: start at boot, restart when it
|
||||
exits, give up after repeated failures, and run something else when it gives up.~~ **One**: run
|
||||
this at boot. The other three moved into a launcher the host ships, where they can be tested —
|
||||
a unit file's restart policy can only be read and hoped for
|
||||
([ADR 0061](0061-the-host-asks-an-init-for-start-and-restart.md)).
|
||||
|
||||
**Abstracting over init systems is not done**, because there is no second one to abstract over.
|
||||
The unit file is the only systemd-specific artefact, it belongs to the package rather than the
|
||||
binary, and a machine with a different supervisor would ship a different package — which is
|
||||
where that difference belongs.
|
||||
~~**Every machine the mesh targets already has systemd.**~~ **Alpine does not**, and it is the
|
||||
intended first node. It runs OpenRC.
|
||||
|
||||
~~**Abstracting over init systems is not done, because there is no second one to abstract
|
||||
over.**~~ There is now, and the answer is still not an abstraction: the host is built per
|
||||
operating system ([ADR 0060](0060-the-host-is-built-per-operating-system.md)), so each ships its
|
||||
own four-line init file. That the file is the *only* system-specific artefact is what survives,
|
||||
and it is what makes a second one transcription rather than a port.
|
||||
|
||||
The part that stands unchanged: **an init is not a dependency in
|
||||
[ADR 0041](0041-the-host-depends-on-nothing.md)'s sense.** 0041 is about what must be *installed
|
||||
before the host works*, and an init is not installed — it is what the machine already is.
|
||||
|
||||
### It never manages its own unit
|
||||
|
||||
|
||||
@@ -54,8 +54,15 @@ arrive together, as one decision somebody made when they installed the operating
|
||||
### Almost all of it is shared
|
||||
|
||||
Not a rewrite per operating system. The declaration vocabulary, the store, the apply loop, the
|
||||
read-back discipline, the refusal model, the bundle and the link are all portable. **What differs
|
||||
is two appliers**, and the rest is compiled around them.
|
||||
read-back discipline, the refusal model and the link are all portable. **What differs is two
|
||||
appliers**, and the rest is compiled around them.
|
||||
|
||||
**The bundle is the exception, and an earlier version of this record wrongly listed it as
|
||||
portable.** Its *mechanism* is — one embedded declaration, applied with no mesh present. Its
|
||||
*contents* are not: package names, unit names and service names all differ, so an Arch host
|
||||
embeds an Arch bundle and an Alpine host an Alpine one. That is the same thing this record says
|
||||
about package names one section down, and missing it here is what made the distinction hard to
|
||||
see.
|
||||
|
||||
### The control plane names the package, because the host does not decide
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ decisions:
|
||||
- 02-DECISIONS/0041-the-host-depends-on-nothing.md
|
||||
- 02-DECISIONS/0043-a-declaration-is-an-ordered-list-of-owned-resources.md
|
||||
- 02-DECISIONS/0057-the-host-is-a-root-service-installed-as-a-package.md
|
||||
- 02-DECISIONS/0060-the-host-is-built-per-operating-system.md
|
||||
- 02-DECISIONS/0061-the-host-asks-an-init-for-start-and-restart.md
|
||||
---
|
||||
|
||||
@@ -131,14 +132,18 @@ manages units and runs containers.
|
||||
Two steps, and there is nothing else:
|
||||
|
||||
```
|
||||
# 1 — put the host on the machine
|
||||
pacman -S nox-mesh-host
|
||||
systemctl enable --now nox-mesh-host
|
||||
# 1 — put the host on the machine, in that machine's own idiom
|
||||
apk add nox-mesh-host && rc-update add nox-mesh-host && rc-service nox-mesh-host start
|
||||
pacman -S nox-mesh-host && systemctl enable --now nox-mesh-host
|
||||
|
||||
# 2 — hand it the mesh
|
||||
# 2 — hand it the mesh. The same on every machine.
|
||||
nox-mesh-host enrol --token <one-time token>
|
||||
```
|
||||
|
||||
**Step 1 differs per system and step 2 never does**, which is the shape of
|
||||
[ADR 0060](../../02-DECISIONS/0060-the-host-is-built-per-operating-system.md): the package
|
||||
manager and the init file are the system's, and everything after them is the mesh's.
|
||||
|
||||
The token carries the broker's address, the fingerprint to expect, and the right to join
|
||||
([ADR 0051](../../02-DECISIONS/0051-the-enrolment-token-carries-the-mesh.md)). After that the
|
||||
node is in the mesh and takes declarations like every other one.
|
||||
|
||||
@@ -11,6 +11,7 @@ decisions:
|
||||
- 02-DECISIONS/0047-the-bundle-may-carry-actions-the-link-may-not.md
|
||||
- 02-DECISIONS/0048-the-substrate-is-named.md
|
||||
- 02-DECISIONS/0049-a-route-is-a-grant.md
|
||||
- 02-DECISIONS/0060-the-host-is-built-per-operating-system.md
|
||||
---
|
||||
|
||||
# The substrate
|
||||
@@ -118,7 +119,7 @@ is what keeps the bundle small enough for a person to read and check.
|
||||
The order, from [research 011](../../01-RESEARCH/011-the-module-graph/worked-provider.md):
|
||||
|
||||
```
|
||||
0 Docker exists detected, or installed as a package
|
||||
0 a container runtime exists detected — docker or podman — or installed
|
||||
1 PostgreSQL runs pulled by digest, from the bundle
|
||||
2 a database is created in it an action, run locally
|
||||
3 the control plane's schema applied an action, against that database
|
||||
@@ -131,8 +132,13 @@ Only PostgreSQL is raised from the bundle, for the reason in *The pinned bundle*
|
||||
rest of the substrate is wanted only once there is a control plane to provision it.
|
||||
|
||||
**Step 0 is easy to leave out and it is where several things meet.** A substrate service is a
|
||||
container, so Docker must be running before anything else happens — and Docker is a *package*,
|
||||
not a container. It is:
|
||||
container, so a container runtime must be working before anything else happens — and a runtime
|
||||
is a *package*, not a container.
|
||||
|
||||
**Which runtime is detected, not chosen**
|
||||
([ADR 0060](../../02-DECISIONS/0060-the-host-is-built-per-operating-system.md)): a machine that
|
||||
already has one keeps it. On a machine with none, the control plane names the package, because
|
||||
what it is called differs per system. It is:
|
||||
|
||||
- what the host's capability detection already reports, and the first use of that report by
|
||||
something other than a person;
|
||||
|
||||
@@ -12,6 +12,7 @@ decisions:
|
||||
- 02-DECISIONS/0051-the-enrolment-token-carries-the-mesh.md
|
||||
- 02-DECISIONS/0057-the-host-is-a-root-service-installed-as-a-package.md
|
||||
- 02-DECISIONS/0058-delivery-ends-in-a-declaration.md
|
||||
- 02-DECISIONS/0060-the-host-is-built-per-operating-system.md
|
||||
- 02-DECISIONS/0061-the-host-asks-an-init-for-start-and-restart.md
|
||||
---
|
||||
|
||||
@@ -51,17 +52,32 @@ same path, in an unusual order.
|
||||
|
||||
## unmanaged → hosted: installing
|
||||
|
||||
In the machine's own idiom, because the package manager and the init file are the system's
|
||||
([ADR 0060](../../02-DECISIONS/0060-the-host-is-built-per-operating-system.md)):
|
||||
|
||||
```
|
||||
# Alpine — the intended first node
|
||||
apk add nox-mesh-host
|
||||
rc-update add nox-mesh-host && rc-service nox-mesh-host start
|
||||
|
||||
# Arch
|
||||
pacman -S nox-mesh-host
|
||||
systemctl enable --now nox-mesh-host
|
||||
```
|
||||
|
||||
Two lines each, and the init file behind them is four
|
||||
([ADR 0061](../../02-DECISIONS/0061-the-host-asks-an-init-for-start-and-restart.md)) — it says
|
||||
*run the launcher at boot* and nothing else, so a third system is transcription rather than a
|
||||
port.
|
||||
|
||||
Or, where there is no repository to install from:
|
||||
|
||||
```
|
||||
curl -fsSL https://<release>/mesh-host-<version>-x86_64.tar.gz | tar -xz -C /usr/local/bin
|
||||
curl -fsSL https://<release>/mesh-host-<system>-<version>-x86_64.tar.gz | tar -xz -C /usr/local/bin
|
||||
```
|
||||
|
||||
**The binary is per system as well as per architecture**, because two of its appliers are.
|
||||
|
||||
**The tarball must never acquire a dependency**, because the mesh's own package repository is
|
||||
hosted on the mesh. Any route that needs the mesh in order to install the thing that joins the
|
||||
mesh is a circle — unusable on a first node, and unusable by whoever is repairing a mesh that is
|
||||
@@ -159,8 +175,8 @@ mesh-control token issue
|
||||
nox-mesh-host enrol --token <token>
|
||||
```
|
||||
|
||||
Step 1 is the bootstrap from [`07-the-substrate.md`](07-the-substrate.md): Docker, then
|
||||
PostgreSQL, then the database, then the schema, then the control plane. It needs no identity
|
||||
Step 1 is the bootstrap from [`07-the-substrate.md`](07-the-substrate.md): a container runtime,
|
||||
then PostgreSQL, then the database, then the schema, then the control plane. It needs no identity
|
||||
because nothing is being asked of anyone — the host is applying a declaration it already
|
||||
carries, to the machine it is already on.
|
||||
|
||||
@@ -377,7 +393,9 @@ the test of whether this is really uniform.
|
||||
2 the host verifies the new binary runs `nox-mesh-host version`, as a subprocess
|
||||
3 it finishes the apply and reports never mid-way
|
||||
4 it exits 0 having finished, not having been stopped
|
||||
5 systemd restarts it on the new binary
|
||||
5 the launcher starts it again on the new binary — it supervises the host
|
||||
rather than exec'ing it (ADR 0061), so this
|
||||
needs nothing from the init
|
||||
6 the new host reconciles on start trigger 1, confirming the machine still matches
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user