ui: avoid hangs (systemd-run no-block + timeouts for systemctl)

This commit is contained in:
beckline
2026-02-15 02:20:09 +03:00
parent 11a3eb1524
commit c287e98366

View File

@@ -917,13 +917,27 @@ RU: Применяет policy-rules и проверяет health. При оши
"systemd-run", "systemd-run",
"--user", "--user",
"--scope", "--scope",
"--no-block",
"--unit", "--unit",
unit, unit,
"--collect", "--collect",
"--same-dir", "--same-dir",
] + args ] + args
p = subprocess.run(run_cmd, capture_output=True, text=True, check=False) try:
p = subprocess.run(
run_cmd,
capture_output=True,
text=True,
check=False,
timeout=6,
)
except subprocess.TimeoutExpired as e:
raise RuntimeError(
"systemd-run timed out (UI would freeze without this guard). "
"Try again or verify that systemd --user is responsive.\n\n"
f"command: {' '.join(run_cmd)}"
) from e
out = ((p.stdout or "") + (p.stderr or "")).strip() out = ((p.stdout or "") + (p.stderr or "")).strip()
if p.returncode != 0: if p.returncode != 0:
raise RuntimeError(f"systemd-run failed: {p.returncode}\n{out}".strip()) raise RuntimeError(f"systemd-run failed: {p.returncode}\n{out}".strip())
@@ -1154,14 +1168,19 @@ RU: Применяет policy-rules и проверяет health. При оши
return "" return ""
def _systemctl_user(self, args: list[str]) -> tuple[int, str]: def _systemctl_user(self, args: list[str]) -> tuple[int, str]:
p = subprocess.run( cmd = ["systemctl", "--user"] + list(args or [])
["systemctl", "--user"] + list(args or []), try:
capture_output=True, p = subprocess.run(
text=True, cmd,
check=False, capture_output=True,
) text=True,
out = ((p.stdout or "") + (p.stderr or "")).strip() check=False,
return int(p.returncode or 0), out timeout=4,
)
out = ((p.stdout or "") + (p.stderr or "")).strip()
return int(p.returncode or 0), out
except subprocess.TimeoutExpired:
return 124, f"timeout running: {' '.join(cmd)}"
def _list_running_svpn_scopes(self) -> list[str]: def _list_running_svpn_scopes(self) -> list[str]:
code, out = self._systemctl_user( code, out = self._systemctl_user(