fix(release): require a reachable system message bus

This commit is contained in:
2026-10-13 20:12:07 +08:00
parent e95a25892f
commit a9b59e127f
2 changed files with 82 additions and 1 deletions
+39 -1
View File
@@ -120,6 +120,40 @@ def identity_conflicts() -> list[str]:
return errors
def system_bus() -> dict:
"""Transient bounded operator units need the actual system message bus."""
try:
endpoint = Path("/run/dbus/system_bus_socket")
protected(endpoint.parent, directory=True)
info = endpoint.lstat()
if not stat.S_ISSOCK(info.st_mode) or info.st_uid != 0:
raise DeliveryError("system message bus socket absent/unprotected")
protected(Path("/usr/bin/busctl"))
result = subprocess.run(
[
"/usr/bin/busctl",
"--system",
"--timeout=3",
"get-property",
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"Version",
],
capture_output=True,
text=True,
timeout=5,
env={"PATH": "/usr/bin", "LC_ALL": "C"},
)
if result.returncode or not re.fullmatch(
r's "262(?:[-+ .][A-Za-z0-9.+() -]{1,120})?"\n?', result.stdout
):
raise DeliveryError("system message bus manager unavailable/incompatible")
return {"manager_reachable": True, "version": result.stdout.strip()}
except (OSError, subprocess.SubprocessError) as error:
raise DeliveryError("system message bus unavailable") from error
def observe(payload: Path, *, bundle_data: dict, require_root: bool = True) -> dict:
errors = []
observations = {}
@@ -135,6 +169,10 @@ def observe(payload: Path, *, bundle_data: dict, require_root: bool = True) -> d
errors.append("unsupported distribution profile")
if Path("/proc/1/comm").read_text().strip() != "systemd":
errors.append("systemd PID1 required")
try:
observations["system_bus"] = system_bus()
except DeliveryError as error:
errors.append(str(error))
try:
observations["hardware"] = hardware()
flags = set(observations["hardware"]["processor"].get("flags", "").split())
@@ -258,7 +296,7 @@ def observe(payload: Path, *, bundle_data: dict, require_root: bool = True) -> d
protected(Path(directory), directory=True)
except (OSError, DeliveryError):
errors.append("installation ancestor unprotected")
# No socket is opened for a running service and no peer is contacted.
# Port occupation checks do not connect to application peers.
for port in (8000, 8100):
with socket.socket() as check:
try: