Stage 1 — the host reports what a machine is and can do
Tier 0's first slice, per novox/hq 03-DESIGN/01-to-be/05-the-node-host.md. It applies nothing, connects to nothing, listens on nothing. 2.9 MB, static, no dynamic dependencies: copy it onto a machine and run it is the whole install, which is the property ADR 0041 rests on. A capability is detected, never assumed. Every detector runs something that only succeeds if the thing FUNCTIONS — the daemon is asked for its version, the package database is queried, the firewall is asked to list a ruleset, which needs the privilege as well as the tool. 04-ISSUES/007 is the fault this prevents: a client on disk with its daemon down looks exactly like a working runtime, and a node assigned work on that basis fails when the work arrives. Every verdict carries the reason and the method. A capability reported absent with no reason is the same fault in a new place: something nobody can act on. Two bugs found by running rather than reasoning, both silent: systemctl is-system-running exits non-zero for every state except `running` — including `degraded`, which means units failed and the init is emphatically there. Reading the exit code reported NO service manager on a machine whose init it was. That is 007 in the mirror, and both directions place work wrongly. A verdict now reads what a tool says about itself, not only how it exited. And `mesh-host inventory --json` printed text: the standard library stops parsing at the first non-flag argument, so the flag sat unread and the command exited 0 having ignored what was asked. The parser now takes the subcommand off the front, and a stray or mistyped argument is refused rather than dropped. Detection deliberately does NOT follow ADR 0008. That rule governs applying state, where a failed step means the machine is not what was asked for. A failed probe is a finding — "absent, because the probe failed" — and aborting would replace one legible absence with total ignorance of the rest. 25 tests: structure and logic with a fake runner, and the same detectors against this machine, because a test that fakes the system under detection asserts only that the fake behaves as expected.
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
# mesh-host
|
||||
|
||||
Tier 0 of the Novox Mesh. The one thing ever installed by hand, and the only thing that changes
|
||||
a machine.
|
||||
|
||||
```
|
||||
scp mesh-host root@machine:/usr/local/bin/
|
||||
mesh-host profile
|
||||
```
|
||||
|
||||
That is the whole installation. One statically linked binary, nothing else present, no runtime
|
||||
to install first ([`novox/hq` ADR 0041](https://git.novox.be/novox/hq)).
|
||||
|
||||
## What it is for
|
||||
|
||||
**Apply declared state on this machine.** Overlay membership, packet filtering, packages,
|
||||
services, containers and filesystems are not six concerns it carries; they are six instances of
|
||||
the one.
|
||||
|
||||
**It does not decide.** Anything needing knowledge of another node is the control plane's, and
|
||||
the host never queries the mesh database. It receives declarations and applies them.
|
||||
|
||||
## What exists today
|
||||
|
||||
**Stage 1 only: it reports.** It applies nothing, connects to nothing, and listens on nothing.
|
||||
|
||||
```
|
||||
mesh-host profile what this machine can be asked to do
|
||||
mesh-host inventory what this machine is, and what it holds
|
||||
--json machine-readable
|
||||
--timeout how long any single probe may take (default 10s)
|
||||
```
|
||||
|
||||
```
|
||||
$ mesh-host profile
|
||||
linux/amd64
|
||||
|
||||
yes container-runtime 29.7.2
|
||||
no firewall nft exited 1: Operation not permitted (you must be root)
|
||||
yes graphical-session x11: :1
|
||||
yes overlay wg0
|
||||
yes package-manager pacman 7.1.0
|
||||
no privileged effective uid 1000, not 0
|
||||
yes service-manager degraded
|
||||
|
||||
cannot be asked to: [firewall privileged]
|
||||
```
|
||||
|
||||
Stages 2 to 4 — applying from a pinned bundle, the link and the local store, and enrolment —
|
||||
are designed and not built.
|
||||
|
||||
## A capability is detected, never assumed
|
||||
|
||||
The reason this is the first thing built rather than a detail of it.
|
||||
|
||||
**An installed package is not a capability.** A container client on disk with its daemon down
|
||||
looks exactly like a working runtime, and a node assigned work on that basis fails at the
|
||||
moment the work arrives. So every detector runs something that only succeeds if the thing is
|
||||
**functioning** — the daemon is asked for its version, the package database is queried, the
|
||||
firewall is asked to list a ruleset, which needs the privilege as well as the tool.
|
||||
|
||||
**Every verdict says how it knows.** A capability reported absent with no reason is a fault
|
||||
nobody can act on. The reason is what a person reads when a node will not take work they
|
||||
expected it to take.
|
||||
|
||||
**Exit codes are not the whole answer.** Found by running against a real machine rather than by
|
||||
reasoning: `systemctl is-system-running` exits non-zero for every state except `running` —
|
||||
including `degraded`, which means some units failed and the init is emphatically there. Reading
|
||||
the exit code reported no service manager on a machine whose init it was. That is the same
|
||||
fault in the mirror — installed-but-broken reported present, working-but-imperfect reported
|
||||
absent — and both place work wrongly.
|
||||
|
||||
## Building
|
||||
|
||||
```
|
||||
go test ./... structure and logic, and the same checks against this machine
|
||||
CGO_ENABLED=0 go build -ldflags="-s -w" -o mesh-host ./cmd/mesh-host
|
||||
```
|
||||
|
||||
Roughly 3 MB, static, no dynamic dependencies. Cross-compiles with `GOOS`/`GOARCH`; a host is
|
||||
built once per architecture and copied, never built on the machine it runs on.
|
||||
|
||||
**Mocking the boundary is forbidden** ([`novox/hq` ADR 0034](https://git.novox.be/novox/hq)).
|
||||
Every detector is exercised against a fake runner for its logic *and* against this machine for
|
||||
its behaviour. The tests do not assert which capabilities a machine has — that varies, and is
|
||||
the point of detecting — they assert that detection tells the truth about whatever is there.
|
||||
|
||||
## Where the reasoning lives
|
||||
|
||||
Design and decisions are in [`novox/hq`](https://git.novox.be/novox/hq), not here. This
|
||||
repository carries implementation and does not carry decisions.
|
||||
|
||||
- `03-DESIGN/01-to-be/05-the-node-host.md` — what this is and the order it is built in
|
||||
- `02-DECISIONS/0037-the-host-applies-it-does-not-decide.md` — the one concern
|
||||
- `02-DECISIONS/0038-a-node-joins-by-linking-first.md` — one behaviour, two sources
|
||||
- `02-DECISIONS/0039-the-link-is-the-security-boundary.md` — a node owns no password
|
||||
- `02-DECISIONS/0041-the-host-depends-on-nothing.md` — why this is a static binary, and Go
|
||||
- `04-ISSUES/007-an-installed-package-is-not-a-capability` — why detection works this way
|
||||
Reference in New Issue
Block a user