fix status 5
All checks were successful
Build and Deploy MITM Webserver / build (push) Successful in 8s

This commit is contained in:
2026-01-28 19:57:17 +01:00
parent 815c666d32
commit cc3d91a91b

View File

@@ -121,80 +121,96 @@ def get_unit_fragment_path(service_name: str) -> Optional[str]:
logger.exception("systemctl show FragmentPath failed for %s", service_name) logger.exception("systemctl show FragmentPath failed for %s", service_name)
return None return None
def parse_unit_execstart(service_name: str) -> Optional[Dict]: def parse_unit_execstart(service_name: str) -> Dict:
""" """
Query systemd for ExecStart and parse the script name and qnum. Parse ExecStart using systemctl --no-pager show (canonical).
Handles: Handles structured ExecStart blobs with argv[] entries.
- plain ExecStart strings
- systemd structured blobs like:
{ path=... ; argv[]=/usr/bin/python /srv/fw-scripts/foo.py 5 ; ... }
- argv[] values containing spaces/newlines and quoted entries
Returns dict with keys: service, exec_start, name, script_path, qnum, extra
""" """
unit = _systemctl_unit_name(service_name) unit = service_name if service_name.endswith(".service") else service_name + ".service"
try: try:
p = subprocess.run( p = subprocess.run(
["systemctl", "--no-pager","show", "-p", "ExecStart", "--value", unit], ["systemctl", "--no-pager", "show", "-p", "ExecStart", "--value", unit],
capture_output=True, text=True, check=False, timeout=2 capture_output=True,
text=True,
check=False,
timeout=3,
) )
exec_start_raw = (p.stdout or "").strip() raw = (p.stdout or "").strip()
except Exception: except Exception:
logger.exception("systemctl show ExecStart failed for %s", service_name) logger.exception("systemctl show ExecStart failed for %s", service_name)
return {"service": service_name, "exec_start": None, "name": None, "script_path": None, "qnum": None, "extra": None} return {
"service": service_name,
"exec_start": None,
"name": None,
"script_path": None,
"qnum": None,
"extra": None,
}
if not exec_start_raw: if not raw:
return {"service": service_name, "exec_start": None, "name": None, "script_path": None, "qnum": None, "extra": None} return {
"service": service_name,
"exec_start": None,
"name": None,
"script_path": None,
"qnum": None,
"extra": None,
}
exec_start = exec_start_raw exec_start = raw
# If structured form with argv[] entries, extract and reconstruct the argv commandline. # Handle structured ExecStart: { path=... ; argv[]=... ; ... }
if "argv[]=" in exec_start_raw: if "argv[]=" in raw:
# Capture argv[]=... entries up to the next semicolon (allow newlines). # extract argv[] entries safely, across spaces/newlines
# Accept quoted arguments too: "..." or '...' argv_entries = re.findall(r'argv\[\]=([^;]+)', raw, flags=re.DOTALL)
argv_matches = re.findall(r'argv\[\]=(("(?:\\.|[^"])*"|\'(?:\\.|[^\'])*\'|[^;]*?))(?:\s*;|\s*$)', exec_start_raw, flags=re.DOTALL) argv_parts = [a.strip() for a in argv_entries if a.strip()]
argv_parts = []
for m in argv_matches:
val = m[0]
if not val:
continue
v = val.strip()
# strip surrounding quotes if present
if (v.startswith('"') and v.endswith('"')) or (v.startswith("'") and v.endswith("'")):
v = v[1:-1]
argv_parts.append(v)
if argv_parts: if argv_parts:
# join argv entries with space to form a single commandline
exec_start = " ".join(argv_parts) exec_start = " ".join(argv_parts)
else:
# fallback: remove braces and keep raw
exec_start = exec_start_raw
# Now try to find the script path under /srv/fw-scripts # Extract script path
m = re.search(r'(/[^ \t\n\r"]*/srv/fw-scripts/(?P<name>[A-Za-z0-9_.-]+)\.py)\b', exec_start) m = re.search(
r'(/[^ \t\n\r"]*/srv/fw-scripts/(?P<name>[A-Za-z0-9_.-]+)\.py)\b',
exec_start,
)
if not m: if not m:
# return raw exec_start but no parsed metadata return {
return {"service": service_name, "exec_start": exec_start, "name": None, "script_path": None, "qnum": None, "extra": None} "service": service_name,
"exec_start": exec_start,
"name": None,
"script_path": None,
"qnum": None,
"extra": None,
}
script_path = m.group(1) script_path = m.group(1)
name = m.group("name") name = m.group("name")
# Find integer qnum after the script path (first integer token) # Extract queue number (first integer after script path)
after = exec_start[m.end():].strip() after = exec_start[m.end():].strip()
qnum = None qnum = None
extra = None extra = None
if after: if after:
toks = after.split() tokens = after.split()
for i, t in enumerate(toks): for i, t in enumerate(tokens):
try: try:
val = int(t) val = int(t)
if 0 <= val <= 65535: if 0 <= val <= 65535:
qnum = val qnum = val
extra = " ".join(toks[i+1:]) if len(toks) > i+1 else "" extra = " ".join(tokens[i + 1 :]) if i + 1 < len(tokens) else ""
break break
except Exception: except ValueError:
continue continue
return {"service": service_name, "exec_start": exec_start, "name": name, "script_path": script_path, "qnum": qnum, "extra": extra} return {
"service": service_name,
"exec_start": exec_start,
"name": name,
"script_path": script_path,
"qnum": qnum,
"extra": extra,
}
def is_unit_active(service_name: str) -> bool: def is_unit_active(service_name: str) -> bool: