diff --git a/dashboard/plugin_api.py b/dashboard/plugin_api.py index ee932ec..9122795 100644 --- a/dashboard/plugin_api.py +++ b/dashboard/plugin_api.py @@ -5,7 +5,6 @@ import os import shutil import logging import time -import threading from typing import Optional from fastapi import APIRouter from fastapi.responses import JSONResponse @@ -16,6 +15,7 @@ router = APIRouter() _sshx_link = None _sshx_pid = None _sshx_log = "/tmp/sshx_link.log" +_sshx_pid_file = "/tmp/sshx_link.pid" LINK_RE = re.compile(r"https://sshx\.io/s/[A-Za-z0-9_-]+") @@ -39,12 +39,13 @@ def _kill_sshx(): if _sshx_pid: try: os.kill(_sshx_pid, 15) - except ProcessLookupError: + except (ProcessLookupError, PermissionError): pass - _sshx_pid = None + _sshx_pid = None _sshx_link = None - if os.path.exists(_sshx_log): - os.remove(_sshx_log) + for f in [_sshx_log, _sshx_pid_file]: + if os.path.exists(f): + os.remove(f) def _is_alive() -> bool: @@ -54,37 +55,49 @@ def _is_alive() -> bool: try: os.kill(_sshx_pid, 0) return True - except ProcessLookupError: + except (ProcessLookupError, PermissionError): return False +def _read_link_from_log() -> Optional[str]: + if not os.path.exists(_sshx_log): + return None + try: + with open(_sshx_log) as f: + content = f.read() + m = LINK_RE.search(content) + if m: + return m.group(0) + except Exception: + pass + return None + + def _start_sshx_background(): global _sshx_pid, _sshx_link _kill_sshx() _sshx_link = None - subprocess.Popen( - ["nohup", "sshx", "--quiet"], - stdout=open(_sshx_log, "w"), + log_fh = open(_sshx_log, "w") + proc = subprocess.Popen( + ["sshx", "--quiet"], + stdout=log_fh, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL, start_new_session=True, ) + _sshx_pid = proc.pid + with open(_sshx_pid_file, "w") as pf: + pf.write(str(proc.pid)) for _ in range(30): time.sleep(1) - if os.path.exists(_sshx_log) and os.path.getsize(_sshx_log) > 0: - with open(_sshx_log) as f: - content = f.read().strip() - m = LINK_RE.search(content) - if m: - _sshx_link = m.group(0) - try: - with open("/tmp/sshx_pid") as pf: - _sshx_pid = int(pf.read().strip()) - except Exception: - pass - return True + link = _read_link_from_log() + if link: + _sshx_link = link + return True + if proc.poll() is not None: + return False return False