refactor(ui): reuse _launch_and_mark for Run tab
This commit is contained in:
@@ -1147,7 +1147,7 @@ RU: Применяет policy-rules и проверяет health. При оши
|
||||
if code == 0 and (out or "").strip().lower() == "active":
|
||||
cg = self._effective_cgroup_for_unit_retry(unit, timeout_sec=3.0)
|
||||
self._append_app_log(
|
||||
f"[profile] already running: app={key} target={tgt} unit={unit} (refreshing mark)"
|
||||
f"[app] already running: app={key} target={tgt} unit={unit} (refreshing mark)"
|
||||
)
|
||||
res = self.ctrl.traffic_appmarks_apply(
|
||||
op="add",
|
||||
@@ -1174,14 +1174,15 @@ RU: Применяет policy-rules и проверяет health. При оши
|
||||
self.refresh_appmarks_items(quiet=True)
|
||||
self.refresh_appmarks_counts()
|
||||
self.refresh_running_scopes(quiet=True)
|
||||
self.refresh_app_profiles(quiet=True)
|
||||
return
|
||||
|
||||
unit = f"svpn-{tgt}-{int(time.time())}.service"
|
||||
self._append_app_log(f"[profile] launching: app={key or '-'} target={tgt} ttl={ttl}s unit={unit}")
|
||||
self._append_app_log(f"[app] launching: app={key or '-'} target={tgt} ttl={ttl}s unit={unit}")
|
||||
cg, out = self._run_systemd_unit(cmdline, unit=unit)
|
||||
if out:
|
||||
self._append_app_log(f"[profile] systemd-run:\n{out}")
|
||||
self._append_app_log(f"[profile] ControlGroup: {cg}")
|
||||
self._append_app_log(f"[app] systemd-run:\n{out}")
|
||||
self._append_app_log(f"[app] ControlGroup: {cg}")
|
||||
self._set_last_scope(unit=unit, target=tgt, app_key=key, cmdline=cmdline, cgroup_id=0)
|
||||
|
||||
res = self.ctrl.traffic_appmarks_apply(
|
||||
@@ -1194,6 +1195,16 @@ RU: Применяет policy-rules и проверяет health. При оши
|
||||
timeout_sec=ttl,
|
||||
)
|
||||
if not res.ok:
|
||||
low = (res.message or "").lower()
|
||||
if "cgroupv2 path fails" in low or "no such file or directory" in low:
|
||||
raise RuntimeError(
|
||||
(res.message or "appmark apply failed")
|
||||
+ "\n\n"
|
||||
+ "EN: This usually means the app didn't stay inside the new systemd unit "
|
||||
+ "(often because it was already running). Close the app completely and run again.\n"
|
||||
+ "RU: Обычно это значит, что приложение не осталось в новом systemd unit "
|
||||
+ "(часто потому что оно уже было запущено). Полностью закрой приложение и запусти снова."
|
||||
)
|
||||
raise RuntimeError(res.message or "appmark apply failed")
|
||||
|
||||
self._append_app_log(f"[appmarks] OK: {res.message} cgroup_id={res.cgroup_id} timeout={res.timeout_sec}s")
|
||||
@@ -1208,6 +1219,7 @@ RU: Применяет policy-rules и проверяет health. При оши
|
||||
self.refresh_appmarks_items(quiet=True)
|
||||
self.refresh_appmarks_counts()
|
||||
self.refresh_running_scopes(quiet=True)
|
||||
self.refresh_app_profiles(quiet=True)
|
||||
|
||||
def _selected_app_profile(self):
|
||||
it = self.lst_app_profiles.currentItem()
|
||||
@@ -1972,132 +1984,10 @@ RU: Применяет policy-rules и проверяет health. При оши
|
||||
QMessageBox.warning(self, "Missing command", "Please enter a command to run.")
|
||||
return
|
||||
|
||||
app_key = ""
|
||||
try:
|
||||
args = shlex.split(cmdline or "")
|
||||
if args:
|
||||
app_key = str(args[0] or "").strip()
|
||||
except Exception:
|
||||
app_key = ""
|
||||
if not app_key:
|
||||
# Fallback: best-effort first token.
|
||||
app_key = (cmdline.split() or [""])[0].strip()
|
||||
|
||||
target = "vpn" if self.rad_app_vpn.isChecked() else "direct"
|
||||
ttl_sec = int(self.spn_app_ttl.value()) * 3600
|
||||
|
||||
# EN: If the app is already running inside the last svpn unit, don't spawn a new instance.
|
||||
# RU: Если приложение уже запущено в последнем svpn unit, не запускаем второй экземпляр.
|
||||
last_unit = (self._last_app_unit or "").strip()
|
||||
last_target = (self._last_app_target or "").strip().lower()
|
||||
last_key = (self._last_app_key or "").strip()
|
||||
if last_unit and last_target == target and last_key and last_key == app_key:
|
||||
code, out = self._systemctl_user(["is-active", last_unit])
|
||||
if code == 0 and (out or "").strip().lower() == "active":
|
||||
cg = self._effective_cgroup_for_unit_retry(last_unit, timeout_sec=3.0)
|
||||
self._append_app_log(
|
||||
f"[app] already running: app={app_key} target={target} unit={last_unit} (refreshing mark)"
|
||||
)
|
||||
res = self.ctrl.traffic_appmarks_apply(
|
||||
op="add",
|
||||
target=target,
|
||||
cgroup=cg,
|
||||
unit=last_unit,
|
||||
command=cmdline,
|
||||
app_key=app_key,
|
||||
timeout_sec=ttl_sec,
|
||||
)
|
||||
if res.ok:
|
||||
self._append_app_log(
|
||||
f"[appmarks] OK: {res.message} cgroup_id={res.cgroup_id} timeout={res.timeout_sec}s"
|
||||
)
|
||||
self._set_action_status(
|
||||
f"App mark refreshed: target={target} cgroup_id={res.cgroup_id}",
|
||||
ok=True,
|
||||
)
|
||||
self._set_last_scope(
|
||||
unit=last_unit,
|
||||
target=target,
|
||||
app_key=app_key,
|
||||
cmdline=cmdline,
|
||||
cgroup_id=int(res.cgroup_id or 0),
|
||||
)
|
||||
else:
|
||||
self._append_app_log(f"[appmarks] ERROR: {res.message}")
|
||||
self._set_action_status(
|
||||
f"App mark refresh failed: target={target} ({res.message})",
|
||||
ok=False,
|
||||
)
|
||||
QMessageBox.critical(self, "App mark error", res.message or "unknown error")
|
||||
self.refresh_appmarks_counts()
|
||||
self.refresh_running_scopes()
|
||||
self.refresh_app_profiles(quiet=True)
|
||||
return
|
||||
|
||||
unit = f"svpn-{target}-{int(time.time())}.service"
|
||||
|
||||
self._append_app_log(
|
||||
f"[app] launching: app={app_key or '-'} target={target} ttl={ttl_sec}s unit={unit}"
|
||||
)
|
||||
|
||||
cg, out = self._run_systemd_unit(cmdline, unit=unit)
|
||||
if out:
|
||||
self._append_app_log(f"[app] systemd-run:\n{out}")
|
||||
self._append_app_log(f"[app] ControlGroup: {cg}")
|
||||
self._set_last_scope(unit=unit, target=target, app_key=app_key, cmdline=cmdline, cgroup_id=0)
|
||||
|
||||
res = self.ctrl.traffic_appmarks_apply(
|
||||
op="add",
|
||||
target=target,
|
||||
cgroup=cg,
|
||||
unit=unit,
|
||||
command=cmdline,
|
||||
app_key=app_key,
|
||||
timeout_sec=ttl_sec,
|
||||
)
|
||||
if res.ok:
|
||||
self._append_app_log(
|
||||
f"[appmarks] OK: {res.message} cgroup_id={res.cgroup_id} timeout={res.timeout_sec}s"
|
||||
)
|
||||
self._set_action_status(
|
||||
f"App mark added: target={target} cgroup_id={res.cgroup_id}",
|
||||
ok=True,
|
||||
)
|
||||
self._set_last_scope(
|
||||
unit=unit,
|
||||
target=target,
|
||||
app_key=app_key,
|
||||
cmdline=cmdline,
|
||||
cgroup_id=int(res.cgroup_id or 0),
|
||||
)
|
||||
else:
|
||||
self._append_app_log(f"[appmarks] ERROR: {res.message}")
|
||||
self._set_action_status(
|
||||
f"App mark failed: target={target} ({res.message})",
|
||||
ok=False,
|
||||
)
|
||||
low = (res.message or "").lower()
|
||||
if "cgroupv2 path fails" in low or "no such file or directory" in low:
|
||||
QMessageBox.critical(
|
||||
self,
|
||||
"App mark error",
|
||||
(res.message or "unknown error")
|
||||
+ "\n\n"
|
||||
+ "EN: This usually means the app didn't stay inside the new systemd unit "
|
||||
+ "(often because it was already running). Close the app completely and run again from here.\n"
|
||||
+ "RU: Обычно это значит, что приложение не осталось в новом systemd unit "
|
||||
+ "(часто потому что оно уже было запущено). Полностью закрой приложение и запусти снова отсюда.",
|
||||
)
|
||||
else:
|
||||
QMessageBox.critical(
|
||||
self,
|
||||
"App mark error",
|
||||
res.message or "unknown error",
|
||||
)
|
||||
|
||||
self.refresh_appmarks_counts()
|
||||
self.refresh_running_scopes()
|
||||
self.refresh_app_profiles(quiet=True)
|
||||
app_key = self._infer_app_key_from_cmdline(cmdline)
|
||||
self._launch_and_mark(cmdline=cmdline, target=target, ttl_sec=ttl_sec, app_key=app_key)
|
||||
|
||||
self._safe(work, title="Run app error")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user