fix: the statement of an expired lease lives in the VIP's state directory (keel#178) #179

Merged
navigator merged 1 commit from fix/vip-gone-note-in-state-dir-178 into main 2026-10-15 17:01:38 -03:00
Owner

Fixes #178.

On real nodes (keel 0.23.27), the automatic failover with etcd left the VIP on no node. The root half of keel-vip.service wrote the statement of #165 to /var/lib/keel/database/old-primary-gone. The unit has ProtectSystem=strict and ReadWritePaths=/var/lib/keel/vip /etc/wireguard, so the write failed ([Errno 30] Read-only file system), and Ops.hold raised before it recorded the claim. The next turn took the claim from the counter with take(), which kept no lease for this node's own claim. The controller carries only a claim with its lease.

Change

  • The controller's statement is /var/lib/keel/vip/old-primary-gone. The operator's stays under /var/lib/keel/database. keel database follow reads and removes both.
  • A statement that cannot be written is said, and the claim is recorded with its lease all the same.
  • take() of this node's own claim keeps the lease that is signed into it.
  • The netns harness runs the VIP helper with the write paths of keel-vip.service, not the whole root of the node. That difference is why CI missed it.

Tests

RED first in tests/test_mesh_vipetcd.py: the note is in the state directory; a statement that cannot be written does not stop the claim (the VIP is carried, the lease recorded); a node's own claim taken from the counter keeps its lease and is carried.

Fixes #178. On real nodes (keel 0.23.27), the automatic failover with etcd left the VIP on no node. The root half of keel-vip.service wrote the statement of #165 to `/var/lib/keel/database/old-primary-gone`. The unit has `ProtectSystem=strict` and `ReadWritePaths=/var/lib/keel/vip /etc/wireguard`, so the write failed (`[Errno 30] Read-only file system`), and `Ops.hold` raised before it recorded the claim. The next turn took the claim from the counter with `take()`, which kept no lease for this node's own claim. The controller carries only a claim with its lease. ## Change - The controller's statement is `/var/lib/keel/vip/old-primary-gone`. The operator's stays under `/var/lib/keel/database`. `keel database follow` reads and removes both. - A statement that cannot be written is said, and the claim is recorded with its lease all the same. - `take()` of this node's own claim keeps the lease that is signed into it. - The netns harness runs the VIP helper with the write paths of keel-vip.service, not the whole root of the node. That difference is why CI missed it. ## Tests RED first in `tests/test_mesh_vipetcd.py`: the note is in the state directory; a statement that cannot be written does not stop the claim (the VIP is carried, the lease recorded); a node's own claim taken from the counter keeps its lease and is carried.
fix: the statement of an expired lease lives in the VIP's state directory (keel#178)
All checks were successful
security / security (pull_request) Successful in 1m27s
tests / vip (pull_request) Successful in 6m46s
tests / etcd (pull_request) Successful in 6m51s
tests / mesh (pull_request) Successful in 10m56s
tests / etcd-auth (pull_request) Successful in 5m15s
tests / package (pull_request) Successful in 7s
tests / mariadb (pull_request) Successful in 5m37s
tests / vip-upgrade (pull_request) Successful in 7m35s
tests / mariadb-simple (pull_request) Successful in 4m49s
tests / postgres (pull_request) Successful in 10m51s
tests / tests (pull_request) Successful in 27m55s
dd1cdccbb0
On real nodes, the automatic failover of the PostgreSQL pair with etcd
left the VIP on no node. The root half of keel-vip.service wrote the
statement of keel#165 to /var/lib/keel/database/old-primary-gone. The
unit has ProtectSystem=strict and ReadWritePaths=/var/lib/keel/vip
/etc/wireguard, so the write failed with a read-only file system, and
Ops.hold raised before it recorded the claim. The next turn took the
claim from the counter with take(), which kept no lease for this node's
own claim, and the controller carries only a claim with its lease.

- The controller's statement is /var/lib/keel/vip/old-primary-gone. The
  operator's stays /var/lib/keel/database/old-primary-gone. keel
  database follow reads and removes both.
- A statement that cannot be written is said, and the claim is recorded
  with its lease all the same.
- take() of this node's own claim keeps the lease that is signed into
  it, so a claim that etcd holds is renewed and carried.
- The netns harness runs the VIP helper with the write paths of
  keel-vip.service, not the whole root of the node. CI missed the
  failure because of that.
navigator force-pushed fix/vip-gone-note-in-state-dir-178 from dd1cdccbb0
All checks were successful
security / security (pull_request) Successful in 1m27s
tests / vip (pull_request) Successful in 6m46s
tests / etcd (pull_request) Successful in 6m51s
tests / mesh (pull_request) Successful in 10m56s
tests / etcd-auth (pull_request) Successful in 5m15s
tests / package (pull_request) Successful in 7s
tests / mariadb (pull_request) Successful in 5m37s
tests / vip-upgrade (pull_request) Successful in 7m35s
tests / mariadb-simple (pull_request) Successful in 4m49s
tests / postgres (pull_request) Successful in 10m51s
tests / tests (pull_request) Successful in 27m55s
to ce7073eee2
Some checks failed
security / security (pull_request) Successful in 1m39s
tests / etcd (pull_request) Successful in 7m17s
tests / vip (pull_request) Successful in 7m10s
tests / mesh (pull_request) Successful in 11m19s
tests / etcd-auth (pull_request) Successful in 5m14s
tests / package (pull_request) Successful in 7s
tests / vip-upgrade (pull_request) Successful in 7m17s
tests / mariadb-simple (pull_request) Successful in 4m26s
tests / mariadb (pull_request) Successful in 5m50s
tests / postgres (pull_request) Successful in 10m56s
tests / tests (pull_request) Failing after 30m1s
2026-10-15 16:05:35 -03:00
Compare
navigator force-pushed fix/vip-gone-note-in-state-dir-178 from ce7073eee2
Some checks failed
security / security (pull_request) Successful in 1m39s
tests / etcd (pull_request) Successful in 7m17s
tests / vip (pull_request) Successful in 7m10s
tests / mesh (pull_request) Successful in 11m19s
tests / etcd-auth (pull_request) Successful in 5m14s
tests / package (pull_request) Successful in 7s
tests / vip-upgrade (pull_request) Successful in 7m17s
tests / mariadb-simple (pull_request) Successful in 4m26s
tests / mariadb (pull_request) Successful in 5m50s
tests / postgres (pull_request) Successful in 10m56s
tests / tests (pull_request) Failing after 30m1s
to e7205daf77
All checks were successful
security / security (pull_request) Successful in 1m18s
tests / etcd-auth (pull_request) Successful in 4m49s
tests / vip (pull_request) Successful in 7m5s
tests / etcd (pull_request) Successful in 7m15s
tests / vip-upgrade (pull_request) Successful in 7m40s
tests / package (pull_request) Successful in 5s
tests / mesh (pull_request) Successful in 11m9s
tests / mariadb-simple (pull_request) Successful in 4m32s
tests / mariadb (pull_request) Successful in 5m53s
tests / postgres (pull_request) Successful in 9m55s
tests / tests (pull_request) Successful in 24m23s
2026-10-15 16:37:01 -03:00
Compare
Sign in to join this conversation.
No description provided.