ADR 0269 (proposed): what the mesh's own declaration stopped is started again when it goes
Unassigning the zfs module would leave the home server's pool with no scrub schedule: ADR 0118 never starts a unit on the way out, so the distribution's timer the module held stopped would stay stopped. The host now records what it declared beside what it found, and gives back only what the mesh's own declaration stopped.
This commit is contained in:
+90
@@ -0,0 +1,90 @@
|
||||
---
|
||||
topic: what runs on it
|
||||
status: proposed
|
||||
date: 2026-10-09
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
extends: 02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md
|
||||
---
|
||||
|
||||
# 269. What the mesh's own declaration stopped is started again when it goes
|
||||
|
||||
## Context
|
||||
|
||||
[ADR 0118](0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md) gives a unit back as the
|
||||
host found it, with one rule written against the direction of the rest: **never started on the way
|
||||
out.** A unit the mesh stopped is not started again when its declaration goes, because "starting
|
||||
something is a decision, and the operator makes it". When 0118 was written, the units the mesh stopped
|
||||
were its own: a packet filter it had started, a guard it had loaded. Stopping a unit the machine ran
|
||||
before the mesh came was not a case that existed.
|
||||
|
||||
It exists now. The `zfs` module owns the scrub schedule of the home server's pool. The machine already
|
||||
had one: the distribution's `zfs-scrub-weekly@<pool>.timer`, enabled by hand, found running and enabled.
|
||||
To leave exactly one schedule, the module declares that timer stopped and disabled, in the same
|
||||
declaration that starts its own. Unassigning the module removes the module's own timer, which the mesh
|
||||
made, and gives the distribution's back under 0118. That keeps it stopped and disabled. So the pool
|
||||
would be left with **no scrub schedule at all**, and nothing would say so. The second review of
|
||||
mesh-catalog #147 found this on 2026-10-09.
|
||||
|
||||
The host already knows half of what it needs. It records what it **found** (the unit's state and boot
|
||||
before the mesh touched it) and keeps that from the first apply on. It did not record what the mesh
|
||||
**declared**. So at removal it could not tell a unit that the mesh's own declaration stopped from one
|
||||
that somebody stopped since.
|
||||
|
||||
## Considered Options
|
||||
|
||||
1. **Keep 0118 as it is, and have the module say a required step before unassigning** (re-enable the
|
||||
distribution's timer by hand), with a health warning. Rejected: a step a person must remember is the
|
||||
failure mode of the record ("failure must be loud", ADR 0227). The warning would come from a module
|
||||
that is going away, so it would be said once and then never again.
|
||||
2. **Start again, on removal, every unit found running.** Rejected: a unit somebody else stopped after
|
||||
the mesh, an operator or another module, would be started behind their back. That is what 0118
|
||||
refused, for good reason.
|
||||
3. **Start again only what the mesh's own declaration stopped** — chosen. The host records what it
|
||||
declared beside what it found. At removal, a unit found running that the declaration held stopped is
|
||||
started again, and one found enabled that the declaration held disabled is enabled again.
|
||||
|
||||
## Decision
|
||||
|
||||
**The host records, for every service with a state, what the mesh declared: running or stopped, and
|
||||
enabled or disabled where the declaration says. When the service's declaration goes, a unit that was
|
||||
found running and declared stopped is started again, and one found enabled and declared disabled is
|
||||
enabled again. The report says so as `restored`, and the plan says it before the apply does.**
|
||||
|
||||
0118's other rules stand:
|
||||
|
||||
- a unit found running and never stopped by the mesh is left running;
|
||||
- a unit the mesh started is stopped again;
|
||||
- a unit whose file the mesh wrote is the mesh's own;
|
||||
- a unit with an unknown history is left alone. A record written before the host kept what it declared
|
||||
says nothing about who stopped the unit, so nothing is started.
|
||||
|
||||
"Never started on the way out" now reads **never started on the way out, but for what the mesh's own
|
||||
declaration stopped**. Starting something is still the operator's decision. Here the operator made it
|
||||
before the mesh came, and the mesh's stopping it was the mesh's doing, which goes with the mesh.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Unassigning the `zfs` module gives the home server back its distribution scrub timer, running and
|
||||
enabled. A module may take over a machine's unit by holding it stopped, and its removal undoes that.
|
||||
- A unit that is moved to another unit name (ADR 0118's "moved") is given back by the same rule.
|
||||
- **Harder:** a unit the mesh stopped and that should *stay* stopped after the module goes (one that
|
||||
was found running by accident) is now started again. Saying so needs a field on the resource, which
|
||||
no module needs yet. Until one does, the plan's `restore … started … again` step is where it is seen.
|
||||
|
||||
## How it is checked
|
||||
|
||||
| Rule | Checked by |
|
||||
|---|---|
|
||||
| A unit found running and enabled, declared stopped and disabled, is started and enabled again when undeclared, and the report says `restored` | mesh-host `internal/apply/giveback_test.go`, `TestAUnitTheMeshStoppedAndDisabledIsGivenBackRunningAndEnabled` |
|
||||
| A unit found stopped stays stopped; one never stopped by the mesh is left as it is | `TestOnlyWhatTheMeshsDeclarationStoppedIsStartedAgain` |
|
||||
| A record without what was declared starts nothing | `TestARecordWithoutWhatWasDeclaredStartsNothing` |
|
||||
| The plan says it before the apply does | `TestThePlanSaysAStoppedUnitIsStartedAgain` |
|
||||
| 0118's existing rules | mesh-host `internal/apply/found_test.go`, unchanged and passing |
|
||||
|
||||
## References
|
||||
|
||||
- [ADR 0118](0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md), which this widens.
|
||||
- mesh-host: the host's record (`store.Applied.Declared`), `startUnitBack` in `internal/apply/apply.go`,
|
||||
and the plan's step in `internal/apply/plan.go`.
|
||||
- mesh-catalog #147 (the `zfs` module's scrub schedule) and its second review, 2026-10-09.
|
||||
Reference in New Issue
Block a user