Merge pull request 'ADR 0207: a module depends on the node seats that apply its resources' (#354) from decision/0207-a-module-depends-on-the-seats-that-apply-its-resources into main
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
This commit is contained in:
@@ -78,6 +78,12 @@ another — and a mesh you cannot name precisely is a mesh two people describe d
|
|||||||
mesh-scoped exclusive claim is how the mesh says "there is one of me". A foundation seat is
|
mesh-scoped exclusive claim is how the mesh says "there is one of me". A foundation seat is
|
||||||
named after the server it guards: the `mesh-controller`, `postgres` and `lavinmq` modules claim
|
named after the server it guards: the `mesh-controller`, `postgres` and `lavinmq` modules claim
|
||||||
the `mesh-controller`, `mesh-store` and `mesh-broker` seats ([ADR 0079](../02-DECISIONS/0079-the-foundation-seats-are-named-after-their-servers.md)).
|
the `mesh-controller`, `mesh-store` and `mesh-broker` seats ([ADR 0079](../02-DECISIONS/0079-the-foundation-seats-are-named-after-their-servers.md)).
|
||||||
|
- **depends on a seat** — a module needing a seat held on its node by some module, without holding
|
||||||
|
it. Derived from the resources it declares, never stated: a `service` depends on
|
||||||
|
`node-service-manager`, a `package` on `node-package-manager`, a `container` on
|
||||||
|
`node-container-runtime` ([ADR 0207](../02-DECISIONS/0207-a-module-depends-on-the-node-seats-that-apply-its-resources.md)).
|
||||||
|
Not a claim: a module **claims** a seat it holds and **declares** resources. Nothing claims a
|
||||||
|
package.
|
||||||
- **provision** — a service one module `provides` and others `require`; the mesh resolves a provider
|
- **provision** — a service one module `provides` and others `require`; the mesh resolves a provider
|
||||||
and wires the two with an endpoint and a credential. A provision is a service you offer, a seat
|
and wires the two with an endpoint and a credential. A provision is a service you offer, a seat
|
||||||
is a role you occupy, and the two meet where a seat delivers a provision: occupying the seat is
|
is a role you occupy, and the two meet where a seat delivers a provision: occupying the seat is
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
---
|
||||||
|
topic: the mesh
|
||||||
|
status: accepted
|
||||||
|
date: 2026-10-04
|
||||||
|
deciders: jochen
|
||||||
|
reconstructed: false
|
||||||
|
extends: 02-DECISIONS/0177-a-unit-may-be-user-scoped-and-the-service-manager-is-a-node-seat.md
|
||||||
|
---
|
||||||
|
|
||||||
|
# 207. A module depends on the node seats that apply its resources
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
A module declares resources: packages, services, containers, files. Some of those are applied
|
||||||
|
through software on the machine that is itself a module:
|
||||||
|
|
||||||
|
- a service through the service manager;
|
||||||
|
- a package through the package manager;
|
||||||
|
- a container through the container runtime.
|
||||||
|
|
||||||
|
Until now nothing said so. A module carried a *capability* such as `service-manager` or
|
||||||
|
`package-manager`, which the host detects on the machine. A capability says the software is
|
||||||
|
installed. It does not say that a module of the mesh holds the role and answers for it.
|
||||||
|
|
||||||
|
The cost showed on 2026-10-04:
|
||||||
|
|
||||||
|
- **A networking module declared the service manager's own package.** The controller allows one
|
||||||
|
declaration of a resource per node, so the module that *is* the service manager could not declare
|
||||||
|
its package and had been written without it. The networking module's real relation to the service
|
||||||
|
manager, that it needs one held on its node, was nowhere.
|
||||||
|
- **The container runtime** has had this decided for its own case since ADR 0165 and ADR 0166
|
||||||
|
(proposed): a module that delivers a container needs the runtime seat held on its machine, derived
|
||||||
|
from the container resource, with no manifest field.
|
||||||
|
- **The operator's order for building the machines' modules** (to-be 42) is *the most core first*.
|
||||||
|
That is an order the mesh should enforce, not one a person should remember.
|
||||||
|
|
||||||
|
## Considered Options
|
||||||
|
|
||||||
|
1. **Keep capabilities as the only gate.** Rejected: a capability is a fact about the machine, not
|
||||||
|
about the mesh. Software installed by hand satisfies it, and nothing then answers for it.
|
||||||
|
2. **A manifest field per module naming the seats it needs.** Rejected: a module would restate what
|
||||||
|
its resources already say, and a module that adds a service but forgets the field passes.
|
||||||
|
3. **Derive the dependency from the resources,** as ADR 0165 already does for containers, and refuse
|
||||||
|
an assignment whose seats are not held on the node. Chosen.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
**1. Three node seats apply resources,** each in the mesh's own set:
|
||||||
|
|
||||||
|
| resource | applied through | seat | first holder |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `service` | the service manager | `node-service-manager` (ADR 0177) | `systemd` |
|
||||||
|
| `package` | the package manager | `node-package-manager` (new) | `pacman` |
|
||||||
|
| `container` | the container runtime | `node-container-runtime` (ADR 0166) | `docker` |
|
||||||
|
|
||||||
|
`node-package-manager` is new and has no verbs yet. `node-container-runtime` is seeded now as ADR 0166
|
||||||
|
names it. Its verbs, and the host creating containers through its holder, stay with that record's
|
||||||
|
acceptance.
|
||||||
|
|
||||||
|
**2. A module depends on each seat its resources need.** The controller derives this from the
|
||||||
|
resource types the module declares. A module never states it.
|
||||||
|
|
||||||
|
**3. A dependency is met when any module assigned to the same node holds the seat,** the module
|
||||||
|
itself included. The holders of these seats declare resources of each other's kinds: the service
|
||||||
|
manager's package needs the package manager, and the package manager's timer needs the service
|
||||||
|
manager. They are therefore judged as the node's whole set of assignments, never one at a time.
|
||||||
|
|
||||||
|
**4. Where it is checked:**
|
||||||
|
|
||||||
|
- **At `assign`,** an assignment whose dependencies are unmet by the node's assignments, including the
|
||||||
|
new one, is refused. The refusal names each seat and the modules in the catalogue that can hold it.
|
||||||
|
- **At composition,** an unmet dependency on a node is **reported** in `status` until the three holders
|
||||||
|
are assigned to every node. Then it is **refused** like any unresolved requirement. The switch is one
|
||||||
|
line in the controller, made when `status` reports none.
|
||||||
|
|
||||||
|
**5. The mesh's own foundation is exempt.** These are the pieces genesis lays before any module exists:
|
||||||
|
the host, the private network and the bootstrap runtime. Their declarations are the installation's,
|
||||||
|
not a module's.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- The order of to-be 42 becomes the mesh's: `systemd`, `pacman` and `docker` on a node before
|
||||||
|
anything that installs, runs or contains.
|
||||||
|
- **Two modules no longer declare one shared package to say they need it.** A component's module
|
||||||
|
(networkd's) declares what it configures and depends on the seat. The component's own package
|
||||||
|
belongs to the module that holds the seat.
|
||||||
|
- Capabilities stay what they are, facts about the machine, used where a module needs the machine to
|
||||||
|
be able to do something.
|
||||||
|
- **What got harder:** a module can no longer be tried on a node that lacks the core three. That is
|
||||||
|
the point.
|
||||||
|
|
||||||
|
## How it is checked
|
||||||
|
|
||||||
|
| Rule | Checked by |
|
||||||
|
|---|---|
|
||||||
|
| The dependency is derived from resources: a service, a package and a container each need their seat | the controller's resolve tests |
|
||||||
|
| A node whose assignments hold the seats passes; one missing a holder is refused at `assign`, naming the seat and its possible holders | the same tests, and `assign` live |
|
||||||
|
| Mutual dependencies among the holders resolve when they are assigned together | the same tests |
|
||||||
|
| Until the switch, an unmet dependency is reported in `status` and does not refuse a push | the controller's status test |
|
||||||
|
| Foundation declarations are exempt | the composition test with genesis's declarations |
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [ADR 0165](0165-container-runtime-is-what-a-machine-can-run-and-a-running-runtime-is-its-holders-health.md),
|
||||||
|
[ADR 0166](0166-the-container-runtime-is-a-node-seat-and-the-host-creates-containers-through-its-holder.md),
|
||||||
|
[ADR 0177](0177-a-unit-may-be-user-scoped-and-the-service-manager-is-a-node-seat.md)
|
||||||
|
- [To-be 42](../03-DESIGN/01-to-be/42-the-machines-modules-in-order.md)
|
||||||
@@ -191,6 +191,7 @@ python3 00-META/checks/index.py fail if stale
|
|||||||
- **0189** — [The store keeps what the records name, and a maintenance step holds its writers still](0189-the-store-keeps-what-the-records-name.md)
|
- **0189** — [The store keeps what the records name, and a maintenance step holds its writers still](0189-the-store-keeps-what-the-records-name.md)
|
||||||
- **0190** — [A seat's work is shared by its holders, and building is the first such role](0190-a-seats-work-is-shared-by-its-holders-and-building-is-the-first-such-role.md)
|
- **0190** — [A seat's work is shared by its holders, and building is the first such role](0190-a-seats-work-is-shared-by-its-holders-and-building-is-the-first-such-role.md)
|
||||||
- **0202** — [A provider declares what it derives for each consumer, and the mesh tells both ends](0202-a-provider-declares-what-it-derives-for-each-consumer.md)
|
- **0202** — [A provider declares what it derives for each consumer, and the mesh tells both ends](0202-a-provider-declares-what-it-derives-for-each-consumer.md)
|
||||||
|
- **0207** — [A module depends on the node seats that apply its resources](0207-a-module-depends-on-the-node-seats-that-apply-its-resources.md)
|
||||||
|
|
||||||
### Its tiers, from the bottom up
|
### Its tiers, from the bottom up
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ decisions:
|
|||||||
- 02-DECISIONS/0203-the-accounts-environment-is-one-modules-and-every-module-contributes-to-it.md
|
- 02-DECISIONS/0203-the-accounts-environment-is-one-modules-and-every-module-contributes-to-it.md
|
||||||
- 02-DECISIONS/0204-a-module-contributes-shell-code-to-the-login-shell-in-named-slots.md
|
- 02-DECISIONS/0204-a-module-contributes-shell-code-to-the-login-shell-in-named-slots.md
|
||||||
- 02-DECISIONS/0205-software-the-distribution-does-not-package-ships-as-a-pinned-archive-of-the-module.md
|
- 02-DECISIONS/0205-software-the-distribution-does-not-package-ships-as-a-pinned-archive-of-the-module.md
|
||||||
|
- 02-DECISIONS/0207-a-module-depends-on-the-node-seats-that-apply-its-resources.md
|
||||||
---
|
---
|
||||||
|
|
||||||
# 42. The machines' modules, in order
|
# 42. The machines' modules, in order
|
||||||
@@ -65,6 +66,12 @@ In order:
|
|||||||
| 10 | scripts | the operator's own scripts, shared and per role (research 027/03) | under no version control, copied by hand |
|
| 10 | scripts | the operator's own scripts, shared and per role (research 027/03) | under no version control, copied by hand |
|
||||||
| 11 | `kernel` | kernel, microcode, boot entries | two machines without microcode |
|
| 11 | `kernel` | kernel, microcode, boot entries | two machines without microcode |
|
||||||
|
|
||||||
|
`systemd`, `pacman` and `docker` hold the three seats that apply resources
|
||||||
|
([ADR 0207](../../02-DECISIONS/0207-a-module-depends-on-the-node-seats-that-apply-its-resources.md)):
|
||||||
|
every module that declares a service, a package or a container depends on them being held on its node.
|
||||||
|
They go on every machine before the rest, and once they have, an unmet dependency is refused rather
|
||||||
|
than reported.
|
||||||
|
|
||||||
`kernel` is last because a mistake in it costs a boot. `docker` stays a module without the runtime seat
|
`kernel` is last because a mistake in it costs a boot. `docker` stays a module without the runtime seat
|
||||||
until ADRs 0165 and 0166 are accepted.
|
until ADRs 0165 and 0166 are accepted.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user