os-apply: tell an UPDATED conffile from a KEPT one (dpkg's two shapes, measured live on demo-hp)
gates / gates (push) Successful in 19s
gates / gates (push) Successful in 19s
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:
+13
-2
@@ -389,10 +389,21 @@ class Apply:
|
|||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
rc, out, err = self.g(APT_ENV + ["apt-get", "-y", "-q"] + DPKG_OPTS + args)
|
rc, out, err = self.g(APT_ENV + ["apt-get", "-y", "-q"] + DPKG_OPTS + args)
|
||||||
secs = time.time() - t0
|
secs = time.time() - t0
|
||||||
|
# dpkg says "Installing new version of config file X" when X was NOT changed locally (the package's new
|
||||||
|
# version is taken), and "Configuration file 'X'" + "Keeping old config file" when it was (--force-confold
|
||||||
|
# keeps the local one; the package's version lands as X.dpkg-dist). Measured live 2026-10-04 (debian_version).
|
||||||
|
conflict = None
|
||||||
for l in (out + err).splitlines():
|
for l in (out + err).splitlines():
|
||||||
m = re.search(r"Installing new version of config file (\S+)|Configuration file '([^']+)'", l)
|
m = re.search(r"Installing new version of config file (\S+?)\s*\.\.\.", l)
|
||||||
if m:
|
if m:
|
||||||
log(f"os-apply: CONFFILE kept {m.group(1) or m.group(2)}")
|
log(f"os-apply: CONFFILE updated {m.group(1)} (it was not changed locally)")
|
||||||
|
m = re.search(r"Configuration file '([^']+)'", l)
|
||||||
|
if m:
|
||||||
|
conflict = m.group(1)
|
||||||
|
if conflict and "Keeping old config file" in l:
|
||||||
|
log(f"os-apply: CONFFILE kept {conflict} (changed locally; the package's version is {conflict}.dpkg-dist)")
|
||||||
|
self.report.setdefault("conffiles_kept", []).append(conflict)
|
||||||
|
conflict = None
|
||||||
self.g(["apt-get", "clean"])
|
self.g(["apt-get", "clean"])
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
_, aud, _ = self.g(["dpkg", "--audit"])
|
_, aud, _ = self.g(["dpkg", "--audit"])
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ class Fake:
|
|||||||
if "=" in x and not x.startswith("-") and "::" not in x:
|
if "=" in x and not x.startswith("-") and "::" not in x:
|
||||||
n, v = x.split("=", 1)
|
n, v = x.split("=", 1)
|
||||||
self.installed[n] = v
|
self.installed[n] = v
|
||||||
return 0, "Setting up libc6 ...\n", ""
|
return 0, getattr(self, "install_out", "Setting up libc6 ...\n"), ""
|
||||||
if cmd == "df":
|
if cmd == "df":
|
||||||
return 0, f"Avail\n{self.free}\n", ""
|
return 0, f"Avail\n{self.free}\n", ""
|
||||||
if cmd == "docker":
|
if cmd == "docker":
|
||||||
@@ -438,6 +438,21 @@ class Refusals(unittest.TestCase):
|
|||||||
self.refused(f, "R13")
|
self.refused(f, "R13")
|
||||||
|
|
||||||
|
|
||||||
|
class Conffiles(unittest.TestCase):
|
||||||
|
# dpkg's two shapes, measured live 2026-10-04: an unchanged file is UPDATED; a locally changed one is KEPT.
|
||||||
|
def test_updated_vs_kept(self):
|
||||||
|
f = Fake()
|
||||||
|
f.install_out = ("Installing new version of config file /etc/debian_version ...\n"
|
||||||
|
"Configuration file '/etc/ssh/sshd_config'\n ==> Modified (by you or by a script) since installation.\n"
|
||||||
|
" ==> Keeping old config file as default.\n")
|
||||||
|
rc, rep = run(f)
|
||||||
|
self.assertEqual(rc, 0, rep)
|
||||||
|
self.assertIn("os-apply: CONFFILE updated /etc/debian_version (it was not changed locally)", f.logs)
|
||||||
|
self.assertTrue(any(l.startswith("os-apply: CONFFILE kept /etc/ssh/sshd_config") for l in f.logs), f.logs)
|
||||||
|
self.assertEqual(rep["conffiles_kept"], ["/etc/ssh/sshd_config"])
|
||||||
|
self.assertFalse(any("kept /etc/debian_version" in l for l in f.logs), "an updated file must not be reported as kept")
|
||||||
|
|
||||||
|
|
||||||
class Failure(unittest.TestCase):
|
class Failure(unittest.TestCase):
|
||||||
def test_install_failure_is_rc3_with_dpkg_state(self):
|
def test_install_failure_is_rc3_with_dpkg_state(self):
|
||||||
f = Fake()
|
f = Fake()
|
||||||
|
|||||||
Reference in New Issue
Block a user