From 6e0f64f08b1bd74040e30748c5f505b4a5f75b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Saparelli?= Date: Thu, 25 Jun 2026 03:56:30 +1200 Subject: [PATCH] feat(image): auto-restart services on package upgrade (needrestart) --- docs/spec/disk-images.md | 6 ++++++ image/configure.sh | 7 +++++++ image/files/needrestart/50-bes-autorestart.conf | 5 +++++ image/packages.sh | 7 +++++++ tests/test-image-structure.sh | 7 +++++++ 5 files changed, 32 insertions(+) create mode 100644 image/files/needrestart/50-bes-autorestart.conf diff --git a/docs/spec/disk-images.md b/docs/spec/disk-images.md index 989e7e9..2d90d22 100644 --- a/docs/spec/disk-images.md +++ b/docs/spec/disk-images.md @@ -146,6 +146,12 @@ Chrony must be installed and enabled as the system time synchronization daemon. No other time synchronization daemon (in particular, systemd-timesyncd) may be active on the running image. +r[image.packages.service-restart+2] +After an APT operation on the running system, any service whose executable or +a shared library it had mapped was replaced by that operation must be +restarted automatically so it runs the upgraded code. This must happen without +interactive prompting. + ## Bootloader r[image.boot.dracut] diff --git a/image/configure.sh b/image/configure.sh index b32f0de..65b4544 100755 --- a/image/configure.sh +++ b/image/configure.sh @@ -101,6 +101,13 @@ if [ -x /usr/lib/systemd/systemd-timesyncd ] || [ -f /usr/lib/systemd/system/sys systemctl mask systemd-timesyncd.service fi +# r[impl image.packages.service-restart+2] +# needrestart prompts by default; force non-interactive auto-restart so apt +# operations on the running image bounce affected services unattended. +mkdir -p /etc/needrestart/conf.d +install -m 644 /tmp/files/needrestart/50-bes-autorestart.conf \ + /etc/needrestart/conf.d/50-bes-autorestart.conf + # ============================================================ # Third-party APT repositories # ============================================================ diff --git a/image/files/needrestart/50-bes-autorestart.conf b/image/files/needrestart/50-bes-autorestart.conf new file mode 100644 index 0000000..f34d65c --- /dev/null +++ b/image/files/needrestart/50-bes-autorestart.conf @@ -0,0 +1,5 @@ +# r[impl image.packages.service-restart+2] +# Restart affected services automatically, without prompting. The upstream +# default is interactive ('i'), which on an unattended server image would +# leave outdated services running after every apt run. +$nrconf{restart} = 'a'; diff --git a/image/packages.sh b/image/packages.sh index 14a0f0c..9a142ee 100644 --- a/image/packages.sh +++ b/image/packages.sh @@ -36,6 +36,13 @@ PACKAGES=( cron sudo + # r[image.packages.service-restart+2] + # Restart services after upgrades. Pulled in by the server task on a stock + # install, but this is a --no-install-recommends minbase build, so it must + # be listed explicitly. Configured for non-interactive auto-restart in + # configure.sh. + needrestart + # APT key management gnupg diff --git a/tests/test-image-structure.sh b/tests/test-image-structure.sh index 6b4f425..e2cf3f1 100755 --- a/tests/test-image-structure.sh +++ b/tests/test-image-structure.sh @@ -725,6 +725,13 @@ else pass "systemd-timesyncd is not enabled" fi +# r[verify image.packages.service-restart+2] +check "needrestart binary exists" test -x "$MNT/usr/sbin/needrestart" +check "needrestart auto-restart drop-in installed" \ + test -f "$MNT/etc/needrestart/conf.d/50-bes-autorestart.conf" +check "needrestart set to auto-restart" \ + grep -q "restart} = 'a'" "$MNT/etc/needrestart/conf.d/50-bes-autorestart.conf" + case "$VARIANT" in metal|pi) # r[verify image.luks.keyfile]