Merge pull request 'The host self-updates, and an archive cannot be undeclared' (#212) from issue/161-resolved-and-162-an-archive-cannot-be-removed into main
This commit was merged in pull request #212.
This commit is contained in:
@@ -118,3 +118,23 @@ is back on its hand-placed binary until it is answered.
|
|||||||
**The fallback is what made that safe**, and it was not luck: the launcher runs the pinned version, or
|
**The fallback is what made that safe**, and it was not luck: the launcher runs the pinned version, or
|
||||||
the newest delivered one, or the one placed by hand — so moving the delivered versions aside restored
|
the newest delivered one, or the one placed by hand — so moving the delivered versions aside restored
|
||||||
the machine in one step.
|
the machine in one step.
|
||||||
|
|
||||||
|
## Self-update works (2026-09-30, end of the day)
|
||||||
|
|
||||||
|
```
|
||||||
|
running: /usr/lib/nox-mesh-host/versions/093231796eb0/nox-mesh-host
|
||||||
|
mesh-controller node show shanks
|
||||||
|
host 093231796eb0
|
||||||
|
```
|
||||||
|
|
||||||
|
One machine runs a host the mesh compiled, published, delivered and started, applying declarations and
|
||||||
|
reporting the version it was delivered as. The two facts a delivered binary was missing are
|
||||||
|
[issue 161](../161-a-delivered-host-carries-none-of-its-link-time-facts/01-resolution.md) and resolved:
|
||||||
|
the system comes from the artifact, the version from where the binary sits.
|
||||||
|
|
||||||
|
**Three machines still run a hand-placed host**, and rolling each forward is one assignment and one
|
||||||
|
push. The control node is worth last.
|
||||||
|
|
||||||
|
One thing this found on the way out: an archive cannot be undeclared, and the attempt stops the machine
|
||||||
|
applying anything at all — [issue 162](../162-an-archive-cannot-be-undeclared/00-report.md). It is how
|
||||||
|
undoing the first delivery froze the workstation, and it is not specific to the host.
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
status: located
|
status: resolved
|
||||||
opened: 2026-09-30
|
opened: 2026-09-30
|
||||||
located-in:
|
located-in:
|
||||||
- mesh-host cmd/mesh-host/main.go (version and builtFor, both set at link time)
|
- mesh-host cmd/mesh-host/main.go (version and builtFor, both set at link time)
|
||||||
- mesh-controller internal/builder (the toolchain, which deliberately takes nothing from the module)
|
- mesh-controller internal/builder (the toolchain, which deliberately takes nothing from the module)
|
||||||
fixed-by:
|
fixed-by: mesh-controller (the system stamp, and one linker flag rather than two), mesh-host (the version read from the path) — verified on a machine 2026-09-30, 01-resolution.md
|
||||||
amended-design:
|
amended-design:
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# 161 — resolved: a host the mesh built runs a machine
|
||||||
|
|
||||||
|
*2026-09-30. Measured on the workstation.*
|
||||||
|
|
||||||
|
```
|
||||||
|
running: /usr/lib/nox-mesh-host/versions/093231796eb0/nox-mesh-host
|
||||||
|
agent: active
|
||||||
|
reconciles in the last six minutes: 1
|
||||||
|
|
||||||
|
mesh-controller node show shanks
|
||||||
|
host 093231796eb0
|
||||||
|
```
|
||||||
|
|
||||||
|
A binary the mesh compiled, published to its own registry, delivered over the bus, started by the
|
||||||
|
launcher, applying declarations, and reporting a version that names the build it came from.
|
||||||
|
|
||||||
|
## The two facts, and where each now comes from
|
||||||
|
|
||||||
|
**The system it was built for comes from the artifact.** ADR 0142 already made the target a property
|
||||||
|
of the artifact rather than of the recipe, so the toolchain names the variable it fills and the
|
||||||
|
artifact supplies the value. It is the one thing a toolchain takes from a module, and it is stated
|
||||||
|
rather than inferred.
|
||||||
|
|
||||||
|
**The version comes from where the binary sits**, which is what
|
||||||
|
[ADR 0142](../../02-DECISIONS/0142-the-mesh-delivers-its-own-components-as-binaries.md) decided and
|
||||||
|
nothing had implemented: a delivered host reads the directory it was unpacked into. A host placed by
|
||||||
|
hand keeps its link-time stamp, which is the honest answer for one the mesh did not deliver — and is
|
||||||
|
every other machine today.
|
||||||
|
|
||||||
|
## Two mistakes on the way, both found by reading the output
|
||||||
|
|
||||||
|
**A repeated flag is not a merged one.** The stamp was appended as a second `-ldflags`, and the Go
|
||||||
|
command takes the last and drops the first. The binary gained its system and lost `-s -w`: 12.2MB
|
||||||
|
against 8.5MB, with its debug info. The comment I had written said the linker "accepts and merges"
|
||||||
|
them. It does not. Linker flags are the toolchain's own list now, composed into one flag, and a test
|
||||||
|
refuses a compile line that carries `-ldflags` itself.
|
||||||
|
|
||||||
|
**The delivered binary was named after its package.** `cmd/mesh-host` builds `mesh-host`; every
|
||||||
|
machine runs `nox-mesh-host`, which is what the launcher looks for inside a version. The first
|
||||||
|
delivery landed, reported `created … 1 file(s)`, and was invisible. An artifact says what its
|
||||||
|
executable is called now.
|
||||||
|
|
||||||
|
Both were caught by listing the directory and reading the binary rather than believing the line that
|
||||||
|
said it worked.
|
||||||
|
|
||||||
|
## What this cost while it was wrong, and what saved it
|
||||||
|
|
||||||
|
A delivered host that cannot apply is a machine the mesh cannot repair, because the declaration that
|
||||||
|
would fix it is the declaration it cannot apply. The workstation was restored by moving the delivered
|
||||||
|
versions aside so the launcher fell back to the hand-placed binary — **the fallback in the launcher,
|
||||||
|
working exactly as designed**, and the reason this was an inconvenience rather than an expedition.
|
||||||
|
|
||||||
|
It also loops if you are not careful: the working binary applies, delivers a version, stands aside,
|
||||||
|
and the broken one starts. Stopping the unit while the fix was built was the way through.
|
||||||
|
|
||||||
|
## What is left
|
||||||
|
|
||||||
|
**Three machines still run a hand-placed host.** Rolling them forward is one assignment and one push
|
||||||
|
each, and the control node is worth doing last and watching.
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
status: located
|
||||||
|
opened: 2026-09-30
|
||||||
|
located-in: [mesh-host internal/apply (no removal for an archive)]
|
||||||
|
fixed-by:
|
||||||
|
amended-design:
|
||||||
|
---
|
||||||
|
|
||||||
|
# 162 — An archive cannot be undeclared, and trying stops the machine applying anything
|
||||||
|
|
||||||
|
## What was observed
|
||||||
|
|
||||||
|
*2026-09-30, unassigning the host module from the workstation to undo a delivery.*
|
||||||
|
|
||||||
|
```
|
||||||
|
holding this machine: 0 applied, and map[apply:applying "mesh-host.next": no way to remove a "archive"
|
||||||
|
0 resource(s) were applied and remain; everything was attempted, so what is not listed as failed was done.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nothing was applied at all** — not the archive, not the other forty resources that had nothing to do
|
||||||
|
with it. The machine stopped reconciling and stayed that way until the module was assigned again.
|
||||||
|
|
||||||
|
## Why it matters
|
||||||
|
|
||||||
|
Every other resource kind can be taken away. A file is removed and what was found under it is put
|
||||||
|
back; a container is stopped and removed; a unit is given back the state it was found in
|
||||||
|
([ADR 0118](../../02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md)). An
|
||||||
|
archive has no removal at all, so:
|
||||||
|
|
||||||
|
- **a module with an archive can never be unassigned** — the attempt fails for ever;
|
||||||
|
- **the failure takes the whole apply with it**, so the machine applies nothing else either, and one
|
||||||
|
unassignable resource is a machine frozen against every other change;
|
||||||
|
- it is silent in the mesh's terms: the push reported sent, and only the machine's own journal says
|
||||||
|
what happened.
|
||||||
|
|
||||||
|
The host module is the obvious case and not the only one. An archive is for what inlining cannot
|
||||||
|
serve — a theme, an icon set, a tree of configuration — and any module using one is in the same
|
||||||
|
position.
|
||||||
|
|
||||||
|
## What the right answer probably is, and the question in it
|
||||||
|
|
||||||
|
The other kinds answer this by remembering what they found. An archive unpacks many files into a
|
||||||
|
directory the mesh did not necessarily create, so removal has a real question in it: **remove what the
|
||||||
|
archive put there, or remove the directory?** The first needs the applier to have recorded the file
|
||||||
|
list; the second would delete whatever else lives there — and for the host's own versions directory,
|
||||||
|
that is every other delivered version.
|
||||||
|
|
||||||
|
Recording what was unpacked is the answer that matches how the rest of the host behaves, and it is
|
||||||
|
what [issue 126](../126-a-volume-path-is-not-in-the-spec-comparison/00-report.md) and ADR 0118 already
|
||||||
|
argue for elsewhere: the mesh gives back what it found.
|
||||||
|
|
||||||
|
## How a fix is checked
|
||||||
|
|
||||||
|
A module with an archive is assigned, pushed, unassigned and pushed again; what the archive put on the
|
||||||
|
machine is gone, anything that was in the directory beforehand is still there, and the apply that
|
||||||
|
removed it applied everything else in the same declaration.
|
||||||
Reference in New Issue
Block a user