From 058e180058a8f7366198fba36bf44990936cc2be Mon Sep 17 00:00:00 2001 From: navigator Date: Wed, 7 Oct 2026 23:23:52 +0000 Subject: [PATCH 1/4] fix: keel-overlay-vip ships every unit off on the first installation keel-vip-check.timer was installed with plain dh_installsystemd, whose was-enabled defaults to true on a first installation and which does not read the preset, so a standalone machine ran keel vip check every minute. Every other overlay leaves its units off until keel spec apply enables the overlay (handbook decision 0041). The timer now has no [Install]; keel-vip.service wants it and the timer is PartOf the controller. keel enables the units the manifest names (keel-vip.service), so the check runs exactly while the VIP is enabled and stops with it; disabling the timer alone would have left it never running. Both units are installed with --no-enable --no-start and both are disabled in the preset. keel-overlay-vip 0.1.1. tests/overlay-install.bats installs the package on the booted trixie container of the install job with the other four overlays: keel-vip.service is disabled and inactive with the rest, the timer is static and inactive, PartOf the controller and wanted by it, and the preset names both. The job builds keel at befaaea (0.20.0, Keel-Linux/keel#81), which the package depends on. --- .github/workflows/packages.yml | 3 ++- packages/vip/debian/changelog | 15 ++++++++++++++ packages/vip/debian/rules | 3 +-- packages/vip/keel-overlay-vip.preset | 11 ++++++---- packages/vip/keel-vip-check.timer | 10 ++-------- packages/vip/keel-vip.service | 2 +- tests/overlay-install.bats | 30 +++++++++++++++++++++++----- 7 files changed, 53 insertions(+), 21 deletions(-) diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml index ced40b5b..b7022918 100644 --- a/.github/workflows/packages.yml +++ b/.github/workflows/packages.yml @@ -84,7 +84,7 @@ jobs: download: overlay-debs download-dir: dist run: | - KEEL_COMMIT=3c6e45636d9a3c9fb5e04fac3a0aecf7bfc8b58a + KEEL_COMMIT=befaaea21e9c983fbb8b2ad4e47f9625866ae857 INITHOOKS_COMMIT=2543d506590a17a762a4288e2ee99b0a3c160386 CONFCONSOLE_COMMIT=71828736ca7e99fff1d99ce5e9e9002c24dbd8b2 apt-get update -qq @@ -121,6 +121,7 @@ jobs: ./dist/keel-overlay-wireguard_*.deb \ ./dist/keel-overlay-etcd_*.deb \ ./dist/keel-overlay-crowdsec_*.deb \ + ./dist/keel-overlay-vip_*.deb \ ntpsec # unit states and manifests on the machine KEEL_OVERLAY_INSTALL_TEST=1 bats tests/overlay-install.bats diff --git a/packages/vip/debian/changelog b/packages/vip/debian/changelog index 1a7f6a3d..3a523029 100644 --- a/packages/vip/debian/changelog +++ b/packages/vip/debian/changelog @@ -1,3 +1,18 @@ +keel-overlay-vip (0.1.1) trixie; urgency=medium + + * Every unit is off on the first installation, like the other overlays + (handbook decision 0041). keel-vip-check.timer was enabled by + dh_installsystemd, whose was-enabled defaults to true and which does not + read the preset, so a standalone machine ran the check every minute. + The timer now has no [Install]: keel-vip.service wants it and it is + PartOf the controller, so the check runs exactly while keel spec apply + keeps the VIP enabled, and stops with it. Both units are installed with + --no-enable --no-start and both are disabled in the preset. + tests/overlay-install.bats installs the package on a booted trixie + machine and asserts both are disabled and inactive. + + -- Keel Linux maintainers Wed, 07 Oct 2026 23:22:41 +0000 + keel-overlay-vip (0.1.0) trixie; urgency=medium * First release: the units of keel's service VIP on the WireGuard mesh diff --git a/packages/vip/debian/rules b/packages/vip/debian/rules index bd90e57c..85f15446 100755 --- a/packages/vip/debian/rules +++ b/packages/vip/debian/rules @@ -25,5 +25,4 @@ execute_after_dh_auto_install: # installation: keel spec apply enables it with the overlay. The check's # timer runs in every mode. override_dh_installsystemd: - dh_installsystemd --no-enable --no-start keel-vip.service - dh_installsystemd keel-vip-check.timer + dh_installsystemd --no-enable --no-start keel-vip.service keel-vip-check.timer diff --git a/packages/vip/keel-overlay-vip.preset b/packages/vip/keel-overlay-vip.preset index d411fd9b..a66e7e76 100644 --- a/packages/vip/keel-overlay-vip.preset +++ b/packages/vip/keel-overlay-vip.preset @@ -1,5 +1,8 @@ -# keel-overlay-vip: the controller is off until keel spec apply enables -# the overlay (handbook decision 0041): Debian's presets enable every unit -# they do not name, on a first boot and on `systemctl preset-all`. The -# check's timer stays enabled; its service skips a node that knows no VIP. +# keel-overlay-vip: the controller and its check are off until keel spec +# apply enables the overlay (handbook decision 0041): Debian's presets enable +# every unit they do not name, on a first boot and on `systemctl +# preset-all`. The check's timer has no [Install] and runs only while +# keel-vip.service wants it; it is named here too, so no preset can turn it +# on by itself. disable keel-vip.service +disable keel-vip-check.timer diff --git a/packages/vip/keel-vip-check.timer b/packages/vip/keel-vip-check.timer index 6b351436..d4473ebc 100644 --- a/packages/vip/keel-vip-check.timer +++ b/packages/vip/keel-vip-check.timer @@ -3,11 +3,5 @@ # node that knows no VIP the service's condition skips it. [Unit] Description=keel vip: check the VIPs at boot and every minute - -[Timer] -OnBootSec=30s -OnUnitActiveSec=1min -AccuracySec=5s - -[Install] -WantedBy=timers.target +# The check belongs to the controller: keel-vip.service wants it, and it +# stops with it. It has no diff --git a/packages/vip/keel-vip.service b/packages/vip/keel-vip.service index 9caa1f60..65409ca7 100644 --- a/packages/vip/keel-vip.service +++ b/packages/vip/keel-vip.service @@ -19,7 +19,7 @@ Description=keel vip: the VIP's root helper with etcd Documentation=https://github.com/Keel-Linux/keel/blob/main/docs/vip.md After=network-online.target etcd.service wg-quick@wg0.service -Wants=network-online.target +Wants=network-online.target keel-vip-check.timer ConditionPathExists=/var/lib/keel/etcd/cluster.json StartLimitIntervalSec=0 diff --git a/tests/overlay-install.bats b/tests/overlay-install.bats index 7a66cb5c..c552c0ad 100644 --- a/tests/overlay-install.bats +++ b/tests/overlay-install.bats @@ -6,8 +6,8 @@ # This suite changes the machine it runs on: it removes, installs and # reinstalls packages and enables and disables units. It runs only where # KEEL_OVERLAY_INSTALL_TEST=1 says the machine is disposable, as root, after -# the four keel-overlay-* packages have been installed with their -# dependencies. OVERLAY_DEBS names the directory holding the four .deb files +# the five keel-overlay-* packages have been installed with their +# dependencies. OVERLAY_DEBS names the directory holding the five .deb files # (default dist/ of the repository). The CI job "install" runs it in a # booted trixie LXC container, where systemd is PID 1 and the is-active # assertions are made as well; in a machine where systemd does not run @@ -22,9 +22,9 @@ bats_require_minimum_version 1.5.0 -OVERLAYS=(installer wireguard etcd crowdsec) +OVERLAYS=(installer wireguard etcd crowdsec vip) # the units the simple installation of Keel Core keeps disabled and stopped -DISABLED_UNITS=(etcd.service crowdsec.service crowdsec-firewall-bouncer.service) +DISABLED_UNITS=(etcd.service crowdsec.service crowdsec-firewall-bouncer.service keel-vip.service) setup_file() { if [ "${KEEL_OVERLAY_INSTALL_TEST:-}" != 1 ]; then @@ -192,7 +192,7 @@ assert_simple_state() { # ------------------------------------------------------------ the packages -@test "the four overlay packages are installed" { +@test "the five overlay packages are installed" { local name for name in "${OVERLAYS[@]}"; do run dpkg-query -W -f='${db:Status-Status}' "keel-overlay-$name" @@ -252,6 +252,26 @@ assert_simple_state() { [ "$output" != active ] } +@test "the VIP check timer is not enabled and not running: it belongs to the controller" { + run systemctl is-enabled keel-vip-check.timer + echo "$output" + # no [Install]: systemd reports static, never enabled + [ "$output" = static ] + if systemd_running; then + run systemctl is-active keel-vip-check.timer + [ "$output" = inactive ] + fi + run systemctl show -p PartOf --value keel-vip-check.timer + [ "$output" = keel-vip.service ] + run systemctl show -p Wants --value keel-vip.service + [[ " $output " == *" keel-vip-check.timer "* ]] +} + +@test "the VIP preset disables the controller and its check" { + grep -qx 'disable keel-vip.service' /usr/lib/systemd/system-preset/20-keel-overlay-vip.preset + grep -qx 'disable keel-vip-check.timer' /usr/lib/systemd/system-preset/20-keel-overlay-vip.preset +} + @test "the preset systemd applies at first boot says disabled for each unit" { local unit for unit in "${DISABLED_UNITS[@]}"; do From a2d2eac0f4312beafe78912280a9c2d13e497dc6 Mon Sep 17 00:00:00 2001 From: navigator Date: Wed, 7 Oct 2026 23:32:43 +0000 Subject: [PATCH 2/4] debian: the changelog trailer names the package's Maintainer, so lintian does not read it as an NMU --- packages/vip/debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vip/debian/changelog b/packages/vip/debian/changelog index 3a523029..18184818 100644 --- a/packages/vip/debian/changelog +++ b/packages/vip/debian/changelog @@ -11,7 +11,7 @@ keel-overlay-vip (0.1.1) trixie; urgency=medium tests/overlay-install.bats installs the package on a booted trixie machine and asserts both are disabled and inactive. - -- Keel Linux maintainers Wed, 07 Oct 2026 23:22:41 +0000 + -- KeelLinux maintainers Wed, 07 Oct 2026 23:22:41 +0000 keel-overlay-vip (0.1.0) trixie; urgency=medium From 509b15bbf186c3436aeca28a8b71325665e82ce2 Mon Sep 17 00:00:00 2001 From: navigator Date: Wed, 7 Oct 2026 23:46:15 +0000 Subject: [PATCH 3/4] tests: the VIP units' relations as systemctl cat reads them --- tests/overlay-install.bats | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/overlay-install.bats b/tests/overlay-install.bats index c552c0ad..8e29cc38 100644 --- a/tests/overlay-install.bats +++ b/tests/overlay-install.bats @@ -261,10 +261,15 @@ assert_simple_state() { run systemctl is-active keel-vip-check.timer [ "$output" = inactive ] fi - run systemctl show -p PartOf --value keel-vip-check.timer - [ "$output" = keel-vip.service ] - run systemctl show -p Wants --value keel-vip.service - [[ " $output " == *" keel-vip-check.timer "* ]] + # the effective unit files as systemctl reads them: the timer is part of + # the controller, and the controller wants it + run systemctl cat keel-vip-check.timer + [ "$status" -eq 0 ] + grep -qx 'PartOf=keel-vip.service' <<<"$output" + run ! grep -q '^\[Install\]' <<<"$output" + run systemctl cat keel-vip.service + [ "$status" -eq 0 ] + grep -qE '^Wants=.*\bkeel-vip-check\.timer\b' <<<"$output" } @test "the VIP preset disables the controller and its check" { From 9e6e52f041a68222ba0b0d44d1843c0ec146f41d Mon Sep 17 00:00:00 2001 From: navigator Date: Wed, 7 Oct 2026 23:58:32 +0000 Subject: [PATCH 4/4] packages/vip: the check timer keeps its [Timer] section and its PartOf The previous commit cut the file at the first occurrence of the install section's name, which was in the new comment, so the timer shipped with no PartOf and no [Timer]; tests/overlay-install.bats caught it. --- packages/vip/keel-vip-check.timer | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/vip/keel-vip-check.timer b/packages/vip/keel-vip-check.timer index d4473ebc..1f1d3e74 100644 --- a/packages/vip/keel-vip-check.timer +++ b/packages/vip/keel-vip-check.timer @@ -1,7 +1,15 @@ # keel-overlay-vip: keel vip check at boot and every minute (handbook -# decision 0049: "at boot and on a timer"). It runs in every mode: on a -# node that knows no VIP the service's condition skips it. +# decision 0049: "at boot and on a timer"), while the VIP controller runs. +# The check belongs to the controller: keel-vip.service wants it and this +# timer is part of it, so it starts and stops with the controller. It has +# no install section of its own, so nothing enables it by itself, neither +# the package's installation nor a preset (handbook decision 0041: an +# overlay's units are off until keel spec apply enables the overlay). [Unit] Description=keel vip: check the VIPs at boot and every minute -# The check belongs to the controller: keel-vip.service wants it, and it -# stops with it. It has no +PartOf=keel-vip.service + +[Timer] +OnBootSec=30s +OnUnitActiveSec=1min +AccuracySec=5s