0118: give a unit back the state it was found in — never-stop broke the converge rollback; process removal found and fixed
This commit is contained in:
+35
-16
@@ -7,7 +7,7 @@ reconstructed: false
|
|||||||
extends: 0102-the-mesh-writes-into-a-shared-file-never-over-it.md
|
extends: 0102-the-mesh-writes-into-a-shared-file-never-over-it.md
|
||||||
---
|
---
|
||||||
|
|
||||||
# 118. Undeclaring removes what the mesh made, gives back what it changed, and leaves the machine's units as they are
|
# 118. Undeclaring removes what the mesh made, and gives a unit back the state it was found in
|
||||||
|
|
||||||
## Context
|
## Context
|
||||||
|
|
||||||
@@ -57,34 +57,53 @@ keeps the dangerous behaviour as the default for exactly the units that matter m
|
|||||||
runtime, the ssh daemon, the network — and each new module is one forgotten field away from a
|
runtime, the ssh daemon, the network — and each new module is one forgotten field away from a
|
||||||
machine that goes dark when it is unassigned.
|
machine that goes dark when it is unassigned.
|
||||||
|
|
||||||
**3. The line is ownership.** Chosen.
|
**3. Never stop a unit the mesh did not create.** Rejected, found while implementing it. The
|
||||||
|
mesh's packet filter is a unit the distribution installed and the mesh started at converge;
|
||||||
|
returning a node to adopted ([ADR 0100](0100-a-node-in-use-is-adopted-before-it-is-converged.md))
|
||||||
|
unloads it by undeclaring it. Never stopping it would leave the mesh's filter loaded beside the
|
||||||
|
predecessor's firewall re-enabled — the one rollback a converge promises, broken. Who wrote the
|
||||||
|
unit file is not the line; what the mesh *did* to the unit is.
|
||||||
|
|
||||||
|
**4. Give the unit back the state it was found in.** Chosen.
|
||||||
|
|
||||||
## Decision
|
## Decision
|
||||||
|
|
||||||
**Undeclaring removes what the mesh made, gives back what it changed, and leaves what was the
|
**Undeclaring removes what the mesh made and gives back what it changed.** For a unit the mesh
|
||||||
machine's as it is.** For a unit, that means: **the host never stops, starts, disables or
|
did not create, what it changed is the unit's state, so that is what is given back: **the host
|
||||||
enables a unit it did not create when that unit stops being declared.** An undeclared `service`
|
records the state it first found the unit in, and undeclaring returns the unit to it.**
|
||||||
is forgotten — reported as such — and the unit keeps whatever state it is in.
|
|
||||||
|
|
||||||
- A unit the mesh *did* create — a `process` resource's unit, which the host writes — is still
|
- **Recorded once**, the first time the host applies the service — whether it was running, and,
|
||||||
stopped and removed with it. That is the mesh's own code.
|
where the declaration sets it, whether it was enabled at boot — and carried in the host's
|
||||||
|
record from then on. Later applies never overwrite it: by then the unit's state is the mesh's
|
||||||
|
doing.
|
||||||
|
- **A unit found running is left running.** The container runtime, the ssh daemon, a network
|
||||||
|
manager: running before the mesh arrived, running after it leaves.
|
||||||
|
- **A unit the mesh started is stopped again**, and one it enabled is disabled again — the packet
|
||||||
|
filter a converge loaded, which returning to adopted unloads.
|
||||||
|
- **Never started on the way out.** A unit the mesh stopped is not started again when its
|
||||||
|
declaration goes; starting something is a decision, and the operator makes it.
|
||||||
|
- **Unknown is left alone.** A record written before the host kept what it found says nothing
|
||||||
|
about the unit before the mesh; the unit is left exactly as it is. A unit left running can be
|
||||||
|
stopped by the operator; one stopped by mistake may be the link the operator needed to do it.
|
||||||
|
- A unit the mesh *did* create — a `process` resource's unit and bundle — is stopped and removed
|
||||||
|
with its declaration. That is the mesh's own code. (Before this record there was no way to
|
||||||
|
remove one at all: an undeclared process failed every apply on its node.)
|
||||||
- The service's settings the mesh wrote are given back by their own resources (a kept original
|
- The service's settings the mesh wrote are given back by their own resources (a kept original
|
||||||
restored, a region or keys removed). A running service keeps running on what it read until it
|
restored, a region or keys removed). A running service keeps running on what it read until it
|
||||||
next reads its configuration; the mesh does not restart it to make it notice.
|
next reads its configuration; the mesh does not restart it to make it notice.
|
||||||
- A service declared with no `state` (ADR 0117) remains the way to say the mesh must not
|
- A service declared with no `state` (ADR 0117) remains the way to say the mesh must not
|
||||||
**start** a unit either; this record is about what happens when a declaration goes away, and
|
**start** a unit either; undeclared, it is forgotten.
|
||||||
covers every service.
|
|
||||||
- An operator who wants a unit stopped when its module goes says so first: declare it
|
|
||||||
`stopped`, push, then unassign. Stopping a machine's unit is a decision, made visibly — never
|
|
||||||
a side effect of removing a module.
|
|
||||||
|
|
||||||
## Consequences
|
## Consequences
|
||||||
|
|
||||||
- Unassigning the private network no longer stops the container runtime; unassigning sshd no
|
- Unassigning the private network no longer stops the container runtime; unassigning sshd no
|
||||||
longer stops ssh; no uplink module can take a machine's network down on its way out.
|
longer stops ssh; no uplink module can take a machine's network down on its way out.
|
||||||
- The host's removal report says "forgotten; the unit is the machine's" where it used to say
|
- The host's removal report says what it gave back — "restored: stopped again, as the host
|
||||||
"stopped". A module that relied on its daemon stopping when unassigned — none in the catalogue
|
found it" — or "forgotten: it was running before the mesh; left as it is" where it used to say
|
||||||
today does on purpose — needs the explicit step above.
|
"stopped". Its plan names each unit an undeclare will stop, before it does.
|
||||||
|
- On a fresh machine where the mesh installed and started a service, unassigning its module
|
||||||
|
stops it again — the mesh gave, the mesh takes back. An operator who wants it kept declares it
|
||||||
|
in a module of their own, or starts it themselves after.
|
||||||
- A daemon can keep running after its module is gone, on configuration that was taken back from
|
- A daemon can keep running after its module is gone, on configuration that was taken back from
|
||||||
under it. That is a visible, running process the operator can see and stop; the alternative
|
under it. That is a visible, running process the operator can see and stop; the alternative
|
||||||
was an invisible outage.
|
was an invisible outage.
|
||||||
@@ -200,7 +200,7 @@ python3 00-META/checks/index.py fail if stale
|
|||||||
- **0114** — [A credential two parties hold rotates over two credentials; one a single party holds rotates in place, staged; and retiring a credential never removes what it reached](0114-a-shared-credential-rotates-over-two-credentials.md) *(proposed)*
|
- **0114** — [A credential two parties hold rotates over two credentials; one a single party holds rotates in place, staged; and retiring a credential never removes what it reached](0114-a-shared-credential-rotates-over-two-credentials.md) *(proposed)*
|
||||||
- **0115** — [One assignment of a module per node: the module's name is the assignment's identity](0115-one-assignment-of-a-module-per-node.md) *(proposed)*
|
- **0115** — [One assignment of a module per node: the module's name is the assignment's identity](0115-one-assignment-of-a-module-per-node.md) *(proposed)*
|
||||||
- **0117** — [A machine's uplink is a seat: the mesh configures the manager, never the link](0117-a-machines-uplink-is-a-seat.md)
|
- **0117** — [A machine's uplink is a seat: the mesh configures the manager, never the link](0117-a-machines-uplink-is-a-seat.md)
|
||||||
- **0118** — [Undeclaring removes what the mesh made, gives back what it changed, and leaves the machine's units as they are](0118-undeclaring-leaves-the-machines-units-running.md)
|
- **0118** — [Undeclaring removes what the mesh made, and gives a unit back the state it was found in](0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md)
|
||||||
|
|
||||||
### How it is built
|
### How it is built
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
status: located
|
status: located
|
||||||
opened: 2026-09-27
|
opened: 2026-09-27
|
||||||
located-in: [mesh-host internal/apply/apply.go (remove)]
|
located-in: [mesh-host internal/apply/apply.go (remove)]
|
||||||
amended-design: 02-DECISIONS/0118-undeclaring-leaves-the-machines-units-running.md
|
amended-design: 02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md
|
||||||
---
|
---
|
||||||
|
|
||||||
# 130 — undeclaring a service stops it, even one the mesh only reloads or only keeps running
|
# 130 — undeclaring a service stops it, even one the mesh only reloads or only keeps running
|
||||||
@@ -45,10 +45,22 @@ reaches it by.
|
|||||||
|
|
||||||
## Resolution
|
## Resolution
|
||||||
|
|
||||||
[ADR 0118](../../02-DECISIONS/0118-undeclaring-leaves-the-machines-units-running.md): undeclaring
|
[ADR 0118](../../02-DECISIONS/0118-undeclaring-gives-a-unit-back-the-state-it-was-found-in.md):
|
||||||
removes what the mesh made, gives back what it changed, and leaves the machine's units as they
|
undeclaring removes what the mesh made and gives back what it changed. The host records the state
|
||||||
are. An undeclared `service` is forgotten, never stopped — the host did not create the unit.
|
it first found a unit in, and undeclaring returns the unit to it — a unit found running (the
|
||||||
That covers the runtime, sshd and the uplink modules at once, without each module opting out;
|
container runtime, sshd, a network manager) is left running; one the mesh started (the packet
|
||||||
the private network and the sshd module need no change. A `process`'s unit, which the host does
|
filter a converge loaded) is stopped again; nothing is started on the way out; a record from
|
||||||
write, is still stopped and removed. The unassign preview asked for above is left open for the
|
before the host kept what it found leaves the unit alone. That covers the runtime, sshd and the
|
||||||
controller.
|
uplink modules at once, without each module opting out; the private network and the sshd module
|
||||||
|
need no change.
|
||||||
|
|
||||||
|
A first draft — never stop a unit the mesh did not create — was rejected while implementing it:
|
||||||
|
returning a converged node to adopted unloads the mesh's filter by exactly this path.
|
||||||
|
|
||||||
|
Found on the way: an undeclared `process` failed every apply on its node (`remove` had no case
|
||||||
|
for it). Now removed with its unit, timer and bundle — the mesh's own code. `user` and `archive`
|
||||||
|
have the same gap and are left for their own decisions: removing a login or unpacked files is not
|
||||||
|
something to settle in passing.
|
||||||
|
|
||||||
|
The unassign preview is partly answered — the host's plan names each unit it will stop — and the
|
||||||
|
controller's side is left open.
|
||||||
|
|||||||
Reference in New Issue
Block a user