issue 127: a declaration that shrinks to empty is skipped, so the node keeps what it should drop
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
---
|
||||
status: located
|
||||
opened: 2026-09-27
|
||||
located-in: [mesh-controller cmd/mesh-controller/push.go]
|
||||
---
|
||||
|
||||
# A declaration that shrinks to empty is skipped, so the node keeps what it should drop
|
||||
|
||||
## What was observed
|
||||
|
||||
Fixing the broker-opening leak (the foundation port scoped to the broker's host) made ace's
|
||||
declaration compose to **zero resources** — ace is adopted with nothing assigned, and the
|
||||
stray opening was its only resource. `push ace` then printed `ace is assigned nothing —
|
||||
skipped` and sent nothing. ace goes on holding `adoption.opening-tcp-5671-incoming` in its
|
||||
ufw, because it was never told the resource is gone.
|
||||
|
||||
`composeEach` (push.go) skips any node whose composed declaration has no resources. That is
|
||||
right for a node that never had anything. It is wrong for a node that **had** resources and
|
||||
now composes to none: the empty declaration is the correction, and skipping it leaves the last
|
||||
non-empty one in force forever.
|
||||
|
||||
## Why it matters
|
||||
|
||||
Any adopted node whose openings (or other baseline resources) are all removed keeps the stale
|
||||
ones until something else pushes a non-empty declaration to it. Converge is unaffected — it
|
||||
composes the full ruleset fresh — so this is an incremental-push gap, not a firewall-safety
|
||||
one. But "the mesh cannot tell a node to drop its last resource" is a real hole in reconcile.
|
||||
|
||||
## The fix, roughly
|
||||
|
||||
Send the empty declaration when the node's last-sent declaration was non-empty — i.e. skip
|
||||
only when empty-and-was-already-empty. Requires push to know (or the host to be told) that the
|
||||
node held something. Simplest: always send to a placed, enrolled node; let an empty declaration
|
||||
mean "own nothing", which the host already applies correctly when it receives one.
|
||||
|
||||
## Workaround used
|
||||
|
||||
On ace, one command drops it permanently (the corrected controller never re-composes it):
|
||||
`sudo ufw delete allow 5671`. At ace's converge it would clear on its own.
|
||||
Reference in New Issue
Block a user