Undeclaring gives a unit back the state it was found in, and removes a process the mesh made (hq ADR 0118) #31

Merged
jschoubben merged 3 commits from feat/undeclaring-leaves-the-machines-units into main 2026-09-26 22:59:30 +00:00
Owner

Stacked on #30 (both touch remove()); retarget to main once #30 merges.

hq issue 130 / ADR 0118 (hq #142). Undeclaring used to stop every service: unassigning the private network stopped the container runtime (it declares docker.service only to reload it), unassigning sshd would stop ssh, and the uplink modules would have taken a machine offline.

  • The host records a unit's state the first time it applies it (store.Applied.Found: running/stopped, and boot where the declaration sets it) and carries it; later applies never overwrite it.
  • Undeclared: found running → left as is ("forgotten"); started/enabled by the mesh → stopped/disabled again ("restored") — the converge filter's rollback to adopted still works (that test is what rejected a first "never stop" draft). Nothing is started on the way out. A record predating Found → left alone.
  • Stateless services (ADR 0117) still forgotten.
  • The plan previews "restore" vs "forget" per undeclared service.
  • Found on the way: an undeclared process had no removal and failed every apply on its node. Now its timer (first), unit and bundle are removed; idempotent. user and archive have the same gap — left for their own decisions (noted in issue 130).

Tests: table over found states; record-once-and-carry; pre-existing record not backfilled; process removal (+ already-gone). make check green.

**Stacked on #30** (both touch `remove()`); retarget to main once #30 merges. hq issue 130 / ADR 0118 (hq #142). Undeclaring used to **stop every service**: unassigning the private network stopped the container runtime (it declares docker.service only to reload it), unassigning sshd would stop ssh, and the uplink modules would have taken a machine offline. - The host records a unit's state the **first** time it applies it (`store.Applied.Found`: running/stopped, and boot where the declaration sets it) and carries it; later applies never overwrite it. - Undeclared: found running → left as is ("forgotten"); started/enabled by the mesh → stopped/disabled again ("restored") — the converge filter's rollback to adopted still works (that test is what rejected a first "never stop" draft). Nothing is started on the way out. A record predating `Found` → left alone. - Stateless services (ADR 0117) still forgotten. - The plan previews "restore" vs "forget" per undeclared service. - **Found on the way:** an undeclared `process` had no removal and failed every apply on its node. Now its timer (first), unit and bundle are removed; idempotent. `user` and `archive` have the same gap — left for their own decisions (noted in issue 130). Tests: table over found states; record-once-and-carry; pre-existing record not backfilled; process removal (+ already-gone). `make check` green.
jschoubben changed target branch from feat/a-file-written-into-a-marked-block to main 2026-09-26 22:59:25 +00:00
jschoubben added 3 commits 2026-09-26 22:59:25 +00:00
A service undeclared used to be stopped: unassigning the private network stopped the container
runtime, unassigning sshd would stop ssh, an uplink module would take the machine offline. The
host now records the unit's state when it first applies it and restores that on undeclare —
found running stays running; started by the mesh (the converge filter) is stopped again; nothing
is started on the way out; a pre-existing record leaves the unit alone.

An undeclared process had no removal at all and failed every apply on its node; its unit, timer
and bundle are now removed.
removeProcess deletes filepath.Join(daemonRoot, name) whole; a process named ".." made that
/var/lib/mesh. The declaration and the removal now hold the name to one rule.
Records written before Found existed left the adoption guard and the converge filter loaded on
undeclare, then deleted their unit files from under them; a unit whose own file the mesh created
is now the mesh's, whatever its record says. Found is kept apart the moment it is read, so a
first apply that enabled and then failed is not read back as the machine's; boot is found the
first time the mesh sets it; a service once stateless, or moved to another unit, is found afresh
(the old unit given back). The unit is read after the reload that loads a file written in the
same apply, and removal reports what it actually did.
jschoubben merged commit 646be4fdf4 into main 2026-09-26 22:59:30 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-host#31