fix(packaging): add RPM ownership assertions, ghost group fix, and conffile check for #46
- Fix nfpm.yaml ghost directory to include `group: fenris` so RPM metadata matches the tmpfiles.d-created ownership (root:fenris 2750) - Add RPM-native ownership assertions: store dir reported as package-owned via `rpm -qf`, store contents verified as never owned by the package - Add RPM conffile assertion: `rpm -qc` verifies fenris.conf is listed - Unify store dir stat assertion across both formats (deb and rpm both assert mode 2750 root:fenris) - Remove unused `distro` parameter from `_find_package()` All 16 packaging tests pass across the full matrix (3 deb + 1 rpm × 4 scenarios). All 289 non-packaging tests pass. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
co-authored by
CommandCodeBot
parent
f1e1c0eebc
commit
b2243a85f7
@@ -39,6 +39,7 @@ contents:
|
|||||||
type: ghost
|
type: ghost
|
||||||
file_info:
|
file_info:
|
||||||
mode: 2750
|
mode: 2750
|
||||||
|
group: fenris
|
||||||
|
|
||||||
scripts:
|
scripts:
|
||||||
preinstall: packaging/preinst.sh
|
preinstall: packaging/preinst.sh
|
||||||
|
|||||||
+36
-12
@@ -55,7 +55,7 @@ def _container_exec(container: str, cmd: str) -> tuple[int, str]:
|
|||||||
return r.returncode, r.stdout + r.stderr
|
return r.returncode, r.stdout + r.stderr
|
||||||
|
|
||||||
|
|
||||||
def _find_package(fmt: str, distro: str | None = None) -> Path:
|
def _find_package(fmt: str) -> Path:
|
||||||
"""Locate the built package artifact."""
|
"""Locate the built package artifact."""
|
||||||
version = _get_version()
|
version = _get_version()
|
||||||
if fmt == "deb":
|
if fmt == "deb":
|
||||||
@@ -184,22 +184,46 @@ def _assert_dormant_layout(container: str, fmt: str, version: str) -> None:
|
|||||||
assert "device" in out.lower() or "devices" in out.lower() or "#" in out, \
|
assert "device" in out.lower() or "devices" in out.lower() or "#" in out, \
|
||||||
"Config does not appear to be placeholder-commented"
|
"Config does not appear to be placeholder-commented"
|
||||||
|
|
||||||
|
if fmt == "rpm":
|
||||||
|
# rpm-native: config marked noreplace (not replaced on upgrade)
|
||||||
|
rc, out = _container_exec(
|
||||||
|
container,
|
||||||
|
"rpm -qc fenris 2>/dev/null | grep fenris.conf || true",
|
||||||
|
)
|
||||||
|
assert "fenris.conf" in out, "fenris.conf not listed as conffile by RPM"
|
||||||
|
|
||||||
# fenris group exists
|
# fenris group exists
|
||||||
rc, out = _container_exec(container, "getent group fenris")
|
rc, out = _container_exec(container, "getent group fenris")
|
||||||
assert rc == 0, "fenris group not created"
|
assert rc == 0, "fenris group not created"
|
||||||
|
|
||||||
# Observation store directory
|
# Observation store directory
|
||||||
if fmt == "deb":
|
rc, out = _container_exec(container, "stat -c '%a %U %G' /var/lib/fenris")
|
||||||
rc, out = _container_exec(container, "stat -c '%a %U %G' /var/lib/fenris")
|
assert rc == 0, "Observation store directory not created"
|
||||||
assert rc == 0, "Observation store directory not created"
|
parts = out.strip().split()
|
||||||
parts = out.strip().split()
|
assert parts[0] == "2750", f"Store dir mode: expected 2750, got {parts[0]}"
|
||||||
assert parts[0] == "2750", f"Store dir mode: expected 2750, got {parts[0]}"
|
assert parts[1] == "root", f"Store dir owner: expected root, got {parts[1]}"
|
||||||
assert parts[1] == "root", f"Store dir owner: expected root, got {parts[1]}"
|
assert parts[2] == "fenris", f"Store dir group: expected fenris, got {parts[2]}"
|
||||||
assert parts[2] == "fenris", f"Store dir group: expected fenris, got {parts[2]}"
|
|
||||||
else:
|
if fmt == "rpm":
|
||||||
# rpm: directory owned by package (ghost)
|
# rpm-native: store dir reported as package-owned (ghost),
|
||||||
rc, _ = _container_exec(container, "test -d /var/lib/fenris")
|
# but no contents are owned by the package
|
||||||
assert rc == 0, "Observation store directory not found"
|
rc, out = _container_exec(container, "rpm -qf /var/lib/fenris 2>/dev/null")
|
||||||
|
assert rc == 0, "Store dir not reported as package-owned by RPM"
|
||||||
|
assert "fenris" in out.lower(), f"Store dir not owned by fenris package: {out}"
|
||||||
|
|
||||||
|
# No files inside the store should be package-owned
|
||||||
|
rc, out = _container_exec(
|
||||||
|
container,
|
||||||
|
"find /var/lib/fenris -mindepth 1 -type f -exec rpm -qf {} \\; 2>&1",
|
||||||
|
)
|
||||||
|
# rpm -qf exits 1 for unowned files; we expect all to be unowned
|
||||||
|
owned = [
|
||||||
|
line for line in out.strip().splitlines()
|
||||||
|
if not line.startswith("not owned by any package")
|
||||||
|
and "is not owned by any package" not in line
|
||||||
|
and rc == 0
|
||||||
|
]
|
||||||
|
assert not owned, f"Store contents owned by RPM (should not be): {owned}"
|
||||||
|
|
||||||
# Timer is disabled and inactive (dormant)
|
# Timer is disabled and inactive (dormant)
|
||||||
rc, out = _container_exec(
|
rc, out = _container_exec(
|
||||||
|
|||||||
Reference in New Issue
Block a user