From ed94ee31f465c27a774f7fd99f077bc81986cb29 Mon Sep 17 00:00:00 2001 From: kodi Date: Mon, 23 Mar 2026 11:39:10 +0100 Subject: [PATCH] feat (helper): daemon-reload via helper; verwijder D-Bus afhankelijkheid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - podman-helper: voeg daemon-reload toe aan ALLOWED_ACTIONS; actions in NO_UNIT_ACTIONS slaan unit-validatie over en bouwen cmd zonder unit argument - app_system: /daemon-reload endpoint gebruikt nu _helper_call in plaats van directe subprocess; verwijder subprocess import - app_system: health check legt systemd_reachable af van helper_ok in plaats van systemctl --user list-units — de helper draait als host-user en impliceert systemd bereikbaarheid - CLAUDE.md: verwijder DBUS_SESSION_BUS_ADDRESS env var; D-Bus mount is niet meer nodig Deploy: kopieer podman-helper.py naar host, daemon-reload, restart helper, rebuild backend image, herstart container zonder bus mount. Co-Authored-By: Claude Sonnet 4.6 --- CLAUDE.md | 1 - control/app_system.py | 22 ++++++---------------- podman-helper/podman-helper.py | 21 +++++++++++++-------- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index a4cb6d5..c50397e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -42,7 +42,6 @@ podman pod create --name mvp-pod -p 8080:8000 -p 8081:8081 --userns=keep-id podman run -d --pod mvp-pod --name mvp-backend \ --ipc=host --pid=host \ -e XDG_RUNTIME_DIR=/run/user/1000 \ - -e DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \ -v /run/user/1000/podman/podman.sock:/run/user/1000/podman/podman.sock:rw \ -v /run/user/1000/podman-mvp:/run/podman-mvp \ -v /home/kodi/.config/containers:/app/workloads:rw \ diff --git a/control/app_system.py b/control/app_system.py index ba22691..64cc78f 100644 --- a/control/app_system.py +++ b/control/app_system.py @@ -1,6 +1,5 @@ import os import socket -import subprocess from fastapi import APIRouter, HTTPException from common import ( @@ -29,19 +28,6 @@ def init_system_router(session, podman_api_base: str, workloads_dir: str) -> API except Exception: podman_ok = False - systemd_reachable = False - try: - res = subprocess.run( - ["systemctl", "--user", "list-units", "--no-pager", "--no-legend"], - capture_output=True, - text=True, - check=False, - timeout=2, - ) - systemd_reachable = (res.returncode == 0) - except Exception: - systemd_reachable = False - helper_ok = False try: with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s: @@ -51,7 +37,11 @@ def init_system_router(session, podman_api_base: str, workloads_dir: str) -> API except Exception: helper_ok = False - ok = podman_ok and systemd_reachable + # Helper draait op de host als de kodi-user en voert systemctl --user uit. + # Als de helper bereikbaar is, is systemd ook bereikbaar. + systemd_reachable = helper_ok + + ok = podman_ok and helper_ok return { "ok": ok, "podman": {"ok": podman_ok}, @@ -92,7 +82,7 @@ def init_system_router(session, podman_api_base: str, workloads_dir: str) -> API @router.post("/daemon-reload") def api_daemon_reload(): try: - code, out = _systemctl(["systemctl", "--user", "daemon-reload"]) + code, out = _helper_call("daemon-reload", "") return { "cmd": "systemctl --user daemon-reload", "exit": code, diff --git a/podman-helper/podman-helper.py b/podman-helper/podman-helper.py index f0f91b9..733b41b 100644 --- a/podman-helper/podman-helper.py +++ b/podman-helper/podman-helper.py @@ -6,13 +6,14 @@ Unix socket helper die op de HOST draait als de gewone gebruiker. Ontvangt JSON verzoeken van de API container en voert systemctl --user uit. Beveiligingsmodel: -- Alleen start / stop / restart toegestaan -- Alleen .service units -- Unit naam mag alleen letters, cijfers, punt, koppelteken en underscore bevatten +- Alleen start / stop / restart / daemon-reload toegestaan +- start/stop/restart: alleen .service units met veilige tekens +- daemon-reload: geen unit naam, wordt genegeerd - Meerdere gelijktijdige verbindingen worden afgehandeld via asyncio Protocol: Inkomend: {"action": "start"|"stop"|"restart", "unit": "naam.service"} + {"action": "daemon-reload", "unit": ""} Uitkomend: {"ok": true, "output": "..."} of {"ok": false, "error": "..."} """ @@ -42,22 +43,26 @@ logging.basicConfig( log = logging.getLogger("podman-helper") # ── Whitelist ───────────────────────────────────────────────────────────────── -ALLOWED_ACTIONS = {"start", "stop", "restart"} -UNIT_PATTERN = re.compile(r'^[a-zA-Z0-9._\-]+\.service$') +ALLOWED_ACTIONS = {"start", "stop", "restart", "daemon-reload"} +UNIT_PATTERN = re.compile(r'^[a-zA-Z0-9._\-]+\.service$') +NO_UNIT_ACTIONS = {"daemon-reload"} def validate(action: str, unit: str) -> str | None: """Geeft een foutmelding terug als het verzoek niet toegestaan is, anders None.""" if action not in ALLOWED_ACTIONS: return f"Actie '{action}' niet toegestaan. Gebruik: {', '.join(sorted(ALLOWED_ACTIONS))}" - if not UNIT_PATTERN.match(unit): + if action not in NO_UNIT_ACTIONS and not UNIT_PATTERN.match(unit): return f"Ongeldige unit naam '{unit}'. Alleen .service units met veilige tekens." return None async def run_systemctl(action: str, unit: str) -> dict: - """Voert systemctl --user uit en geeft het resultaat terug.""" - cmd = ["systemctl", "--user", action, unit] + """Voert systemctl --user [unit] uit en geeft het resultaat terug.""" + if action in NO_UNIT_ACTIONS: + cmd = ["systemctl", "--user", action] + else: + cmd = ["systemctl", "--user", action, unit] log.info("Uitvoeren: %s", " ".join(cmd)) try: