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. |
|
| 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. |
|
| 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. |
|
| 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
|
### 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
|
a route is an ordinary grant. Recorded here because finding it was the point — naming the
|
||||||
products is what made the unnamed role visible.
|
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
|
**Identity is deliberately absent.** Whether an identity provider is substrate at all depends on
|
||||||
whether the control plane delegates authentication, which is undecided
|
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
|
([`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
|
### 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,
|
> **Overtaken by [ADR 0061](0061-the-host-asks-an-init-for-start-and-restart.md) and
|
||||||
give up after repeated failures, and run something else when it gives up.
|
> [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
|
~~The host needs **four** things from whatever supervises it: start at boot, restart when it
|
||||||
manager as a detected capability rather than an assumption. This is not a dependency in
|
exits, give up after repeated failures, and run something else when it gives up.~~ **One**: run
|
||||||
[ADR 0041](0041-the-host-depends-on-nothing.md)'s sense — 0041 is about what must be *installed
|
this at boot. The other three moved into a launcher the host ships, where they can be tested —
|
||||||
before the host works*, and an init is not installed, it is what the machine already is.
|
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.
|
~~**Every machine the mesh targets already has systemd.**~~ **Alpine does not**, and it is the
|
||||||
The unit file is the only systemd-specific artefact, it belongs to the package rather than the
|
intended first node. It runs OpenRC.
|
||||||
binary, and a machine with a different supervisor would ship a different package — which is
|
|
||||||
where that difference belongs.
|
~~**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
|
### 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
|
### Almost all of it is shared
|
||||||
|
|
||||||
Not a rewrite per operating system. The declaration vocabulary, the store, the apply loop, the
|
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
|
read-back discipline, the refusal model and the link are all portable. **What differs is two
|
||||||
is two appliers**, and the rest is compiled around them.
|
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
|
### 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/0041-the-host-depends-on-nothing.md
|
||||||
- 02-DECISIONS/0043-a-declaration-is-an-ordered-list-of-owned-resources.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/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
|
- 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:
|
Two steps, and there is nothing else:
|
||||||
|
|
||||||
```
|
```
|
||||||
# 1 — put the host on the machine
|
# 1 — put the host on the machine, in that machine's own idiom
|
||||||
pacman -S nox-mesh-host
|
apk add nox-mesh-host && rc-update add nox-mesh-host && rc-service nox-mesh-host start
|
||||||
systemctl enable --now nox-mesh-host
|
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>
|
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
|
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
|
([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.
|
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/0047-the-bundle-may-carry-actions-the-link-may-not.md
|
||||||
- 02-DECISIONS/0048-the-substrate-is-named.md
|
- 02-DECISIONS/0048-the-substrate-is-named.md
|
||||||
- 02-DECISIONS/0049-a-route-is-a-grant.md
|
- 02-DECISIONS/0049-a-route-is-a-grant.md
|
||||||
|
- 02-DECISIONS/0060-the-host-is-built-per-operating-system.md
|
||||||
---
|
---
|
||||||
|
|
||||||
# The substrate
|
# 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):
|
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
|
1 PostgreSQL runs pulled by digest, from the bundle
|
||||||
2 a database is created in it an action, run locally
|
2 a database is created in it an action, run locally
|
||||||
3 the control plane's schema applied an action, against that database
|
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.
|
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
|
**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*,
|
container, so a container runtime must be working before anything else happens — and a runtime
|
||||||
not a container. It is:
|
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
|
- what the host's capability detection already reports, and the first use of that report by
|
||||||
something other than a person;
|
something other than a person;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ decisions:
|
|||||||
- 02-DECISIONS/0051-the-enrolment-token-carries-the-mesh.md
|
- 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/0057-the-host-is-a-root-service-installed-as-a-package.md
|
||||||
- 02-DECISIONS/0058-delivery-ends-in-a-declaration.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
|
- 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
|
## 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
|
pacman -S nox-mesh-host
|
||||||
systemctl enable --now 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:
|
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
|
**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
|
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
|
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>
|
nox-mesh-host enrol --token <token>
|
||||||
```
|
```
|
||||||
|
|
||||||
Step 1 is the bootstrap from [`07-the-substrate.md`](07-the-substrate.md): Docker, then
|
Step 1 is the bootstrap from [`07-the-substrate.md`](07-the-substrate.md): a container runtime,
|
||||||
PostgreSQL, then the database, then the schema, then the control plane. It needs no identity
|
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
|
because nothing is being asked of anyone — the host is applying a declaration it already
|
||||||
carries, to the machine it is already on.
|
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
|
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
|
3 it finishes the apply and reports never mid-way
|
||||||
4 it exits 0 having finished, not having been stopped
|
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
|
6 the new host reconciles on start trigger 1, confirming the machine still matches
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user