feat: report a FreeBSD host as needing a reboot when its installed kernel is not the running one
CI / test (3.10) (push) Successful in 25s
CI / test (3.11) (push) Successful in 22s
CI / test (3.12) (push) Successful in 23s
CI / test (3.10) (pull_request) Successful in 24s
CI / test (3.11) (pull_request) Successful in 22s
CI / test (3.12) (pull_request) Successful in 24s

HOST_STATUS_COMMAND also prints freebsd-version -k and -r where
freebsd-version exists. When the two differ, a kernel update was installed
and is not running yet, so the host needs a reboot. When they match, it does
not.
This commit is contained in:
2026-10-08 12:08:21 +02:00
parent 7ba84acad3
commit e1ce72cc5c
3 changed files with 65 additions and 1 deletions
+19
View File
@@ -16,6 +16,8 @@ carries the command across.
- A kernel newer than the running one is installed, of the same flavour. A
Raspberry Pi carries ``rpi-v8`` and ``rpi-2712`` builds side by side, and only
the running one's counts.
- On FreeBSD, ``freebsd-version -k`` (the installed kernel) differs from
``freebsd-version -r`` (the running one): a patch replaced the kernel.
It is ``None`` when none of these could be read, for example in a container
without a ``/lib/modules`` of its own.
@@ -50,6 +52,9 @@ HOST_STATUS_COMMAND = (
"if command -v needs-restarting >/dev/null 2>&1; then echo '[needs-restarting]'; "
"needs-restarting -r >/dev/null 2>&1; echo $?; fi; "
"echo '[kernel]'; uname -r; echo '[modules]'; ls -1 /lib/modules 2>/dev/null; "
"if command -v freebsd-version >/dev/null 2>&1; then "
"echo '[freebsd-kernel]'; freebsd-version -k; "
"echo '[freebsd-running]'; freebsd-version -r; fi; "
"if command -v apt-config >/dev/null 2>&1; then echo '[apt-config]'; "
"apt-config dump 2>/dev/null | grep '^APT::Periodic::Unattended-Upgrade '; fi; "
f"echo '[timers]'; for u in {_APT_TIMER} {' '.join(_DNF_TIMERS)}; do "
@@ -100,12 +105,26 @@ def kernel_reboot_pending(running: str, installed: List[str]) -> Optional[str]:
return None
def _freebsd_reboot(sections: Dict[str, List[str]]) -> Optional[Tuple[bool, Optional[str]]]:
"""FreeBSD's answer from freebsd-version, or None on any other system."""
installed = (sections.get("freebsd-kernel") or [""])[0]
running = (sections.get("freebsd-running") or [""])[0]
if not (installed and running):
return None
if installed != running:
return True, f"kernel {installed} installed, {running} running"
return False, None
def _reboot(sections: Dict[str, List[str]]) -> Tuple[Optional[bool], Optional[str]]:
if "reboot-required" in sections:
return True, f"{_REBOOT_FILE} is present"
needs = sections.get("needs-restarting")
if needs and needs[0] == "1":
return True, "needs-restarting -r reports a reboot"
freebsd = _freebsd_reboot(sections)
if freebsd is not None:
return freebsd
running = (sections.get("kernel") or [""])[0]
modules = sections.get("modules") or []
newer = kernel_reboot_pending(running, modules) if running and modules else None