From 7d2c20593069361c02755c8ca4187b7de0c37275 Mon Sep 17 00:00:00 2001 From: kodi Date: Sun, 22 Mar 2026 11:24:25 +0100 Subject: [PATCH] feat: systemd unit acties via podman-helper Unix socket start/stop/restart van systemd units gaan nu via de host-helper (/run/podman-helper.sock) in plaats van directe systemctl subprocess vanuit de container. Hiermee wordt de user namespace isolatie omzeild die D-Bus calls vanuit de container onbetrouwbaar maakt. - common.py: _helper_call(action, unit) toegevoegd - app_system.py: /{action}/{unit} route gebruikt helper voor start/stop/restart - app_containers.py: container_action() gebruikt helper - daemon-reload en is-active blijven subprocess (read-only, werkt al) Co-Authored-By: Claude Sonnet 4.6 --- control/app_containers.py | 3 ++- control/app_system.py | 6 +++++- control/common.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/control/app_containers.py b/control/app_containers.py index 5eb8994..2092c9d 100644 --- a/control/app_containers.py +++ b/control/app_containers.py @@ -13,6 +13,7 @@ from fastapi import APIRouter, HTTPException from fastapi.responses import StreamingResponse from pydantic import BaseModel, Field from common import ( + _helper_call, _map_pod_to_unit, _podman_action_post, _podman_get_json, @@ -563,7 +564,7 @@ def init_containers_router( def _systemd_call(): if name in defined: - code, out = systemctl_func(["systemctl", "--user", action, name]) + code, out = _helper_call(action, f"{name}.service") _sys["code"] = code _sys["out"] = out if code == 0: diff --git a/control/app_system.py b/control/app_system.py index 6ffb126..ed34a55 100644 --- a/control/app_system.py +++ b/control/app_system.py @@ -3,6 +3,7 @@ import subprocess from fastapi import APIRouter, HTTPException from common import ( + _helper_call, _podman_get_json as _common_podman_get_json, _systemctl as _common_systemctl, run, @@ -93,7 +94,10 @@ def init_system_router(session, podman_api_base: str, workloads_dir: str) -> API if action not in ("status", "start", "stop", "restart"): raise HTTPException(status_code=400, detail="Invalid action") cmd = ["systemctl", "--user", action, unit] - code, out = _run_systemctl_action(action, unit) + if action in ("start", "stop", "restart"): + code, out = _helper_call(action, unit) + else: + code, out = _run_systemctl_action(action, unit) return {"cmd": " ".join(cmd), "exit": code, "output": out} return router diff --git a/control/common.py b/control/common.py index 871484b..ec3a6c6 100644 --- a/control/common.py +++ b/control/common.py @@ -1,7 +1,35 @@ +import json +import socket import subprocess from fastapi import HTTPException +HELPER_SOCKET = "/run/podman-helper.sock" + + +def _helper_call(action: str, unit: str) -> tuple[int, str]: + """Stuur start/stop/restart naar de host-helper via Unix socket. + Returntype identiek aan run(): (returncode, output).""" + payload = json.dumps({"action": action, "unit": unit}).encode() + try: + with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s: + s.settimeout(35) + s.connect(HELPER_SOCKET) + s.sendall(payload) + s.shutdown(socket.SHUT_WR) + data = b"" + while True: + chunk = s.recv(4096) + if not chunk: + break + data += chunk + resp = json.loads(data.decode()) + if resp.get("ok"): + return 0, resp.get("output", "") + return 1, resp.get("error", "mislukt") + except Exception as e: + return 1, f"helper niet bereikbaar: {e}" + def run(cmd): try: