os-apply: the host restart scan no longer hides lxc-start (skip ':/lxc/' not 'lxc'), and the host scans on every pass so a reboot clears 'reboot needed' (reboot_scanned reaches the hub) — both found live on demo-felhom
gates / gates (push) Successful in 18s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-04 13:39:14 +02:00
parent 3bf77c3423
commit a6bc3f1197
4 changed files with 67 additions and 1 deletions
+38
View File
@@ -551,6 +551,27 @@ class HostLayer(unittest.TestCase):
rc, rep = run(f)
self.assertTrue(rep["reboot_needed"], rep)
def test_host_scans_every_pass_guest_only_after_install(self):
# A host pass that installs nothing still scans, so a reboot clears the flag (the hub alarm reads it).
f = Fake()
f.plan["layer"] = "host"
f.plan["mode"] = "inventory"
f.restart_out = "2101 lxc-start\n"
rc, rep = run(f)
self.assertEqual(rc, 0, rep)
self.assertTrue(rep["reboot_scanned"], rep)
self.assertTrue(rep["reboot_needed"], rep)
f = Fake()
f.plan["layer"] = "host"
f.plan["mode"] = "inventory"
f.restart_out = "" # after the reboot: nothing maps a deleted file
rc, rep = run(f)
self.assertTrue(rep["reboot_scanned"] and rep["reboot_needed"] is False, rep)
f = Fake()
f.plan["mode"] = "inventory"
rc, rep = run(f)
self.assertFalse(rep["reboot_scanned"], "the guest scans only after an install (R-845)")
def test_no_reboot_for_ordinary_daemons(self):
f = Fake()
f.plan["layer"] = "host"
@@ -586,5 +607,22 @@ class Failure(unittest.TestCase):
self.assertTrue(any(l.startswith("os-apply: FAILED rc=100 step=install") for l in f.logs))
class RestartSkipPattern(unittest.TestCase):
"""The cgroup filter runs as `grep -q PATTERN /proc/<pid>/cgroup`; check it with grep itself against the cgroup
lines measured on demo-felhom 2026-10-04."""
def grep(self, pattern, line):
return subprocess.run(["grep", "-q", pattern], input=line + "\n", text=True).returncode == 0
def test_restart_skip_patterns_against_real_cgroups(self):
host = osapply.RESTART_SKIP_CGROUP["host"]
self.assertTrue(self.grep(host, "0::/lxc/9201/ns/system.slice/docker.service"), "a guest process must be skipped")
self.assertFalse(self.grep(host, "0::/lxc.monitor/9201"), "lxc-start must NOT be skipped (it runs the guest)")
self.assertFalse(self.grep(host, "0::/system.slice/pve-cluster.service"), "a host daemon must NOT be skipped")
guest = osapply.RESTART_SKIP_CGROUP["guest"]
self.assertTrue(self.grep(guest, "0::/system.slice/docker-0123abcd.scope"))
self.assertFalse(self.grep(guest, "0::/system.slice/cron.service"))
if __name__ == "__main__":
unittest.main()