From 492edc2ec027dac6157dd235a3e26097ce79618c Mon Sep 17 00:00:00 2001 From: kodi Date: Sat, 28 Feb 2026 10:02:42 +0100 Subject: [PATCH] refactor(api): remove DI callables, routers import common directly --- control/app.py | 61 +-------------------------------------- control/app_containers.py | 31 ++++++++++---------- control/app_pods.py | 46 +++++++++++++++-------------- 3 files changed, 40 insertions(+), 98 deletions(-) diff --git a/control/app.py b/control/app.py index 3bb097a..16c5471 100644 --- a/control/app.py +++ b/control/app.py @@ -8,16 +8,8 @@ from app_networks import init_networks_router from fastapi import FastAPI, HTTPException import requests_unixsocket from common import ( - _build_pod_to_containers_map as _common_build_pod_to_containers_map, - _map_pod_to_unit as _common_map_pod_to_unit, - _podman_action_post as _common_podman_action_post, - _podman_delete as _common_podman_delete, _podman_get_json as _common_podman_get_json, - _podman_get_json_checked as _common_podman_get_json_checked, - _podman_get_text as _common_podman_get_text, - _podman_post as _common_podman_post, _systemctl as _common_systemctl, - _systemd_then_podman as _common_systemd_then_podman, ) import uvicorn @@ -30,28 +22,6 @@ WORKLOADS_DIR = "/app/workloads" async def _startup_stats_poller(): await start_stats_poller() -# --- ADAPTERS (contract-neutral helpers) --- -# Centralize Podman socket and systemctl invocation. -# MUST NOT change endpoint outputs, status codes, or side-effects. - -def _podman_get_json_checked(url: str): - return _common_podman_get_json_checked(SESSION, url) - -def _podman_get_json(url: str): - return _common_podman_get_json(SESSION, url) - -def _podman_get_text(url: str) -> str: - return _common_podman_get_text(SESSION, url) - -def _podman_post(url: str, **kwargs): - return _common_podman_post(SESSION, url, **kwargs) - -def _podman_action_post(kind: str, name: str, action: str): - return _common_podman_action_post(SESSION, PODMAN_API_BASE, kind, name, action) - -def _podman_delete(url: str): - return _common_podman_delete(SESSION, url) - def _systemctl(cmd): return _common_systemctl(cmd, run) @@ -90,20 +60,6 @@ def health(): return {"ok": ok, "podman": {"ok": podman_ok}, "systemd_user": {"reachable": systemd_reachable}} -# --- DASHBOARD HELPERS (contract-neutral, no ordering/sorting changes) --- - -def _build_pod_to_containers_map(containers: list): - return _common_build_pod_to_containers_map(containers) - - -def _map_pod_to_unit(podname: str) -> str | None: - return _common_map_pod_to_unit(podname) - - -def _systemd_then_podman(systemd_callable, podman_callable): - return _common_systemd_then_podman(systemd_callable, podman_callable) - - # --- ROUTERS --- # Images API lives in dedicated modules to keep this file from growing further. app.include_router(init_images_router(SESSION, PODMAN_API_BASE)) @@ -113,28 +69,13 @@ app.include_router(init_containers_router( SESSION, PODMAN_API_BASE, WORKLOADS_DIR, - _podman_get_json, - _podman_get_text, - _podman_post, - _podman_action_post, - _podman_delete, _systemctl, - _systemd_then_podman, - _map_pod_to_unit, - _build_pod_to_containers_map, )) app.include_router(init_pods_router( SESSION, PODMAN_API_BASE, WORKLOADS_DIR, - _podman_get_json, - _podman_post, - _podman_delete, _systemctl, - _podman_action_post, - _map_pod_to_unit, - _systemd_then_podman, - _build_pod_to_containers_map, )) @@ -151,7 +92,7 @@ def test_hybrid(): # 2. Check Podman API try: - api_containers = _podman_get_json(f"{PODMAN_API_BASE}/libpod/containers/json?all=true") + api_containers = _common_podman_get_json(SESSION, f"{PODMAN_API_BASE}/libpod/containers/json?all=true") except Exception as e: api_containers = f"API Fout: {str(e)}" diff --git a/control/app_containers.py b/control/app_containers.py index 467a79d..2224ab6 100644 --- a/control/app_containers.py +++ b/control/app_containers.py @@ -4,6 +4,13 @@ import json from fastapi import APIRouter from fastapi.responses import StreamingResponse +from common import ( + _map_pod_to_unit, + _podman_action_post, + _podman_get_json, + _podman_get_text, + _systemd_then_podman, +) _SESSION = None @@ -97,15 +104,7 @@ def init_containers_router( session, podman_api_base: str, workloads_dir: str, - podman_get_json, - podman_get_text, - podman_post, - podman_action_post, - podman_delete, systemctl_func, - systemd_then_podman, - map_pod_to_unit, - build_pod_to_containers_map, ) -> APIRouter: router = APIRouter(tags=["containers"]) @@ -203,7 +202,7 @@ def init_containers_router( return ok # A) echte containers (runtime) - real = podman_get_json(f"{podman_api_base}/libpod/containers/json?all=true") + real = _podman_get_json(session, f"{podman_api_base}/libpod/containers/json?all=true") for c in real: _ensure_container_status_field(c) @@ -231,7 +230,7 @@ def init_containers_router( else: # 2) Extra: zit container in een pod die via systemd (kube/quadlet) draait? podname = (c.get("PodName") or "").strip() - pod_unit = map_pod_to_unit(podname) if podname else None + pod_unit = _map_pod_to_unit(podname) if podname else None if pod_unit and _unit_is_active(pod_unit): c["_dashboard_source"] = "systemd" @@ -260,16 +259,16 @@ def init_containers_router( def list_containers(): # Ook hier ?all=true voor gestopte containers url = f"{podman_api_base}/libpod/containers/json?all=true" - return podman_get_json(url) + return _podman_get_json(session, url) @router.get("/containers/inspect/{name}") def inspect_container(name: str): - return podman_get_json(f"{podman_api_base}/libpod/containers/{name}/json") + return _podman_get_json(session, f"{podman_api_base}/libpod/containers/{name}/json") @router.get("/containers/logs/{name}") def get_container_logs(name: str): # We vragen de laatste 100 regels op (tail=100) - txt = podman_get_text(f"{podman_api_base}/libpod/containers/{name}/logs?stdout=true&stderr=true&tail=100") + txt = _podman_get_text(session, f"{podman_api_base}/libpod/containers/{name}/logs?stdout=true&stderr=true&tail=100") # Podman logs komen vaak met wat binaire metadata, we decoden dit als tekst return {"logs": txt} @@ -322,7 +321,7 @@ def init_containers_router( def get_dashboard(): # Legacy dashboard view (keep shape) try: - api_containers = podman_get_json(f"{podman_api_base}/libpod/containers/json?all=true") + api_containers = _podman_get_json(session, f"{podman_api_base}/libpod/containers/json?all=true") except: api_containers = [] items = [] @@ -357,7 +356,7 @@ def init_containers_router( return None def _podman_call(systemd_res): - res = podman_action_post("containers", name, action) + res = _podman_action_post(session, podman_api_base, "containers", name, action) if res.status_code in (200, 204): return {"method": "podman", "name": name, "cmd": f"podman {action} {name}", "status_code": res.status_code} @@ -383,6 +382,6 @@ def init_containers_router( return {"method": "podman", "name": name, "cmd": f"podman {action} {name}", "status_code": res.status_code} - return systemd_then_podman(_systemd_call, _podman_call) + return _systemd_then_podman(_systemd_call, _podman_call) return router diff --git a/control/app_pods.py b/control/app_pods.py index eb70e3c..da4cb18 100644 --- a/control/app_pods.py +++ b/control/app_pods.py @@ -1,20 +1,22 @@ import os from fastapi import APIRouter +from common import ( + _build_pod_to_containers_map, + _map_pod_to_unit, + _podman_action_post, + _podman_delete, + _podman_get_json, + _podman_post, + _systemd_then_podman, +) def init_pods_router( session, podman_api_base: str, workloads_dir: str, - podman_get_json, - podman_post, - podman_delete, systemctl_func, - podman_action_post, - map_pod_to_unit, - systemd_then_podman, - build_pod_to_containers_map, ) -> APIRouter: router = APIRouter(tags=["pods"]) @@ -23,7 +25,7 @@ def init_pods_router( for p in api_pods: name = p.get("Name") status = p.get("Status", "unknown") - unit = map_pod_to_unit(name) if name else "" + unit = _map_pod_to_unit(name) if name else "" dashboard.append({ "Name": name, "Status": status, @@ -39,7 +41,7 @@ def init_pods_router( if f.endswith((".yaml", ".yml")): base = os.path.splitext(os.path.basename(f))[0] pod_name = f"pod{base}" - unit_name = map_pod_to_unit(pod_name) + unit_name = _map_pod_to_unit(pod_name) if pod_name not in by_name: code, out = systemctl_func(["systemctl", "--user", "is-active", unit_name]) @@ -54,7 +56,7 @@ def init_pods_router( def try_systemd_pod_action(action: str, podname: str): # If systemd unit exists/allowed, prefer it. - unit = map_pod_to_unit(podname) + unit = _map_pod_to_unit(podname) if not unit: return None code, out = systemctl_func(["systemctl", "--user", action, unit]) @@ -71,7 +73,7 @@ def init_pods_router( def list_pods(): # Cruciaal: ?all=true zorgt dat EXIT_STATE pods ook getoond worden url = f"{podman_api_base}/libpod/pods/json?all=true" - return podman_get_json(url) + return _podman_get_json(session, url) @router.post("/actions/{action}/{name}") def take_action(action: str, name: str): @@ -81,7 +83,7 @@ def init_pods_router( if action == "start": # STAP 1: Probeer direct de pod te starten (de 'Cockpit' methode) for target in possible_names: - res = podman_post(f"{podman_api_base}/libpod/pods/{target}/start") + res = _podman_post(session, f"{podman_api_base}/libpod/pods/{target}/start") if res.status_code in (200, 204): return {"status": "started", "target": target, "method": "direct"} @@ -96,15 +98,15 @@ def init_pods_router( if target_path: with open(target_path, 'r') as file: yaml_content = file.read() - res = podman_post(f"{podman_api_base}/libpod/kube/play", data=yaml_content) + res = _podman_post(session, f"{podman_api_base}/libpod/kube/play", data=yaml_content) # SPECIALE CASE: Pod bestaat al, forceer dan restart if res.status_code == 500 and "already exists" in res.text: print(f"DEBUG: Forceer herstart voor {name} wegens conflict") for target in possible_names: - podman_delete(f"{podman_api_base}/libpod/pods/{target}?force=true") + _podman_delete(session, f"{podman_api_base}/libpod/pods/{target}?force=true") # Probeer het nu opnieuw - retry_res = podman_post(f"{podman_api_base}/libpod/kube/play", data=yaml_content) + retry_res = _podman_post(session, f"{podman_api_base}/libpod/kube/play", data=yaml_content) return retry_res.json() return res.json() @@ -113,7 +115,7 @@ def init_pods_router( if action == "stop": for target in possible_names: - res = podman_post(f"{podman_api_base}/libpod/pods/{target}/stop") + res = _podman_post(session, f"{podman_api_base}/libpod/pods/{target}/stop") if res.status_code in (200, 204): return {"status": "stopped", "target": target} return {"status": "not found"} @@ -125,11 +127,11 @@ def init_pods_router( dashboard = [] # 0) Bouw mapping: pod_name -> [container_names...] - containers = podman_get_json(f"{podman_api_base}/libpod/containers/json?all=true") - pod_to_containers = build_pod_to_containers_map(containers) + containers = _podman_get_json(session, f"{podman_api_base}/libpod/containers/json?all=true") + pod_to_containers = _build_pod_to_containers_map(containers) # 1) A) echte pods - api_pods = podman_get_json(f"{podman_api_base}/libpod/pods/json?all=true") + api_pods = _podman_get_json(session, f"{podman_api_base}/libpod/pods/json?all=true") by_name = {p.get("Name"): p for p in api_pods} _append_podman_pods_dashboard_rows(dashboard, api_pods, pod_to_containers) @@ -151,10 +153,10 @@ def init_pods_router( def _podman_call(systemd_res): if systemd_res: note = "systemd failed; falling back to podman" - podman = podman_action_post("pods", podname, action).json() + podman = _podman_action_post(session, podman_api_base, "pods", podname, action).json() return {"method": "systemd_then_podman", "note": note, "systemd": systemd_res, "podman": podman} - return {"method": "podman", "result": podman_action_post("pods", podname, action).json()} + return {"method": "podman", "result": _podman_action_post(session, podman_api_base, "pods", podname, action).json()} - return systemd_then_podman(_systemd_call, _podman_call) + return _systemd_then_podman(_systemd_call, _podman_call) return router