From 31edb76e155adaed21c61c2ebb6f91171e96b0e0 Mon Sep 17 00:00:00 2001 From: malmert Date: Wed, 28 Jan 2026 19:30:59 +0100 Subject: [PATCH] fix status 2 --- backend/src/api/packet_scripting_api.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/backend/src/api/packet_scripting_api.py b/backend/src/api/packet_scripting_api.py index 6301e51..578a589 100644 --- a/backend/src/api/packet_scripting_api.py +++ b/backend/src/api/packet_scripting_api.py @@ -36,7 +36,7 @@ os.makedirs(VENV_BASE, exist_ok=True) # ---------- Logging ---------- logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s [%(name)s] %(message)s") -logger = logging.getLogger("script-router-systemd") +logger = logging.getLogger("script-router") # ---------- Router ---------- router = APIRouter(prefix="/scripts", tags=["scripts"]) @@ -124,8 +124,8 @@ def get_unit_fragment_path(service_name: str) -> Optional[str]: def parse_unit_execstart(service_name: str) -> Optional[Dict]: """ Query systemd for ExecStart (most reliable) and parse the script name and qnum. + Handles both plain ExecStart values and systemd's structured values that include argv[] entries. Returns dict with keys: service, exec_start, name, script_path, qnum, extra - or None on irrecoverable error. """ unit = _systemctl_unit_name(service_name) try: @@ -137,12 +137,27 @@ def parse_unit_execstart(service_name: str) -> Optional[Dict]: return {"service": service_name, "exec_start": None, "name": None, "script_path": None, "qnum": None, "extra": None} if not exec_start_raw: - # no ExecStart known return {"service": service_name, "exec_start": None, "name": None, "script_path": None, "qnum": None, "extra": None} - exec_start = exec_start_raw.strip() + # systemd may return a structured blob like: + # { path=/usr/bin/python3 ; argv[]=/usr/bin/python3 /srv/fw-scripts/icmp_drop.py 5 ; ... } + # or a plain commandline. We try to extract argv[] entries if present. + exec_start = exec_start_raw + # detect structured form starting with '{' and containing 'argv[]=' + if exec_start_raw.lstrip().startswith("{") and "argv[]=" in exec_start_raw: + # extract all argv[] values (non-greedy until ';' or end) + argv_matches = re.findall(r'argv\[\]=(.*?)(?:\s*;|\s*$)', exec_start_raw) + # strip and join; entries may already contain spaces (they are quoted or raw), keep as-is + argv_parts = [m.strip() for m in argv_matches if m and m.strip()] + if argv_parts: + # join with space to reconstruct commandline + exec_start = " ".join(argv_parts) + else: + # fallback to raw + exec_start = exec_start_raw - # Find script path under /srv/fw-scripts + # Now exec_start is either a reconstructed argv[]-based commandline or the raw value. + # Find the script path under /srv/fw-scripts m = re.search(r'(/[^ \t\n\r"]*/srv/fw-scripts/(?P[A-Za-z0-9_.-]+)\.py)\b', exec_start) if not m: # Return raw ExecStart but no parsed metadata