fix: auto-start link visible even when dashboard backend 404 (hermes kill)
- both gateway (__init__.py) and dashboard (plugin_api.py) now write link to dashboard/dist/link.json in addition to /tmp/sshx_link.txt - frontend now fallbacks to fetch /dashboard-plugins/sshx-link/dist/link.json when /api/plugins/sshx-link/status returns 404, so link shows immediately even before dashboard restart - keeps nohup with fallback (setsid/Python Popen) for systems without nohup - bump v2.3.4
This commit is contained in:
parent
d956b94826
commit
2fbb915c38
24
__init__.py
24
__init__.py
|
|
@ -28,6 +28,22 @@ SSHX_BIN_ALT = os.path.expanduser("~/.local/bin/sshx")
|
||||||
SSHX_TAR = "/tmp/sshx.tar.gz"
|
SSHX_TAR = "/tmp/sshx.tar.gz"
|
||||||
SSHX_LINK_FILE = "/tmp/sshx_link.txt"
|
SSHX_LINK_FILE = "/tmp/sshx_link.txt"
|
||||||
SSHX_PID_FILE = "/tmp/sshx.pid"
|
SSHX_PID_FILE = "/tmp/sshx.pid"
|
||||||
|
# also write to dashboard static dist so frontend can fetch without backend mount
|
||||||
|
def _dist_link_file():
|
||||||
|
try:
|
||||||
|
return os.path.join(os.path.dirname(__file__), "dashboard", "dist", "link.json")
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _write_dist_link(link: str):
|
||||||
|
try:
|
||||||
|
p = _dist_link_file()
|
||||||
|
if p:
|
||||||
|
os.makedirs(os.path.dirname(p), exist_ok=True)
|
||||||
|
with open(p, "w") as f:
|
||||||
|
f.write(link)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"write dist link failed: {e}")
|
||||||
|
|
||||||
LINK_RE = re.compile(r"https://sshx\.io/s/[A-Za-z0-9\-_]+(?:#[^\s\"']*)?")
|
LINK_RE = re.compile(r"https://sshx\.io/s/[A-Za-z0-9\-_]+(?:#[^\s\"']*)?")
|
||||||
|
|
||||||
|
|
@ -213,10 +229,14 @@ def _run_sshx_nohup() -> str | None:
|
||||||
link = _read_link_file()
|
link = _read_link_file()
|
||||||
if link:
|
if link:
|
||||||
_sshx_link = link
|
_sshx_link = link
|
||||||
|
_write_dist_link(link)
|
||||||
logger.info(f"sshx fallback ready: {link}")
|
logger.info(f"sshx fallback ready: {link}")
|
||||||
return link
|
return link
|
||||||
logger.warning(f"sshx fallback timeout, file: {open(SSHX_LINK_FILE).read()[-400:] if os.path.exists(SSHX_LINK_FILE) else 'no file'}")
|
logger.warning(f"sshx fallback timeout, file: {open(SSHX_LINK_FILE).read()[-400:] if os.path.exists(SSHX_LINK_FILE) else 'no file'}")
|
||||||
return _read_link_file()
|
link = _read_link_file()
|
||||||
|
if link:
|
||||||
|
_write_dist_link(link)
|
||||||
|
return link
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_sshx_last_error = f"fallback Popen failed: {e}"
|
_sshx_last_error = f"fallback Popen failed: {e}"
|
||||||
logger.error(_sshx_last_error, exc_info=True)
|
logger.error(_sshx_last_error, exc_info=True)
|
||||||
|
|
@ -240,6 +260,7 @@ def _run_sshx_nohup() -> str | None:
|
||||||
link = _read_link_file()
|
link = _read_link_file()
|
||||||
if link:
|
if link:
|
||||||
_sshx_link = link
|
_sshx_link = link
|
||||||
|
_write_dist_link(link)
|
||||||
logger.info(f"sshx nohup ready: {link}")
|
logger.info(f"sshx nohup ready: {link}")
|
||||||
return link
|
return link
|
||||||
# if process died early, check
|
# if process died early, check
|
||||||
|
|
@ -257,6 +278,7 @@ def _run_sshx_nohup() -> str | None:
|
||||||
link = _read_link_file()
|
link = _read_link_file()
|
||||||
if link:
|
if link:
|
||||||
_sshx_link = link
|
_sshx_link = link
|
||||||
|
_write_dist_link(link)
|
||||||
return link
|
return link
|
||||||
logger.warning(f"sshx nohup timeout, file content: {open(SSHX_LINK_FILE).read()[-400:] if os.path.exists(SSHX_LINK_FILE) else 'no file'}")
|
logger.warning(f"sshx nohup timeout, file content: {open(SSHX_LINK_FILE).read()[-400:] if os.path.exists(SSHX_LINK_FILE) else 'no file'}")
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,32 @@
|
||||||
try {
|
try {
|
||||||
const r = await fetchJSONAllowError("/api/plugins/sshx-link/status");
|
const r = await fetchJSONAllowError("/api/plugins/sshx-link/status");
|
||||||
if (r.detail && r.detail.includes("No such API endpoint")) {
|
if (r.detail && r.detail.includes("No such API endpoint")) {
|
||||||
|
// backend not mounted (needs restart) -> fallback to static file written by gateway nohup
|
||||||
|
try {
|
||||||
|
const staticRes = await fetch("/dashboard-plugins/sshx-link/dist/link.json", { cache: "no-store" });
|
||||||
|
if (staticRes.ok) {
|
||||||
|
const txt = (await staticRes.text()).trim();
|
||||||
|
const m = txt.match(/https:\/\/sshx\.io\/s\/[A-Za-z0-9\-_]+(?:#[^\s"']*)?/);
|
||||||
|
if (m) { setLink(m[0]); setStatus("running"); setMsg("Link từ static file (gateway nohup) — backend chưa mount nhưng vẫn hiển thị được"); return; }
|
||||||
|
}
|
||||||
|
} catch(_){}
|
||||||
setStatus("needs_restart");
|
setStatus("needs_restart");
|
||||||
setMsg("Backend chưa mount (404) — Dashboard chưa restart sau update. Cần restart.");
|
setMsg("Backend chưa mount (404) — Dashboard chưa restart sau update. Đang thử đọc /dashboard-plugins/sshx-link/dist/link.json (gateway đã tạo). Nếu vẫn không có, sẽ tự restart sau 1.5s.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (r.link) { setLink(r.link); setStatus("running"); setMsg(null); }
|
if (r.link) { setLink(r.link); setStatus("running"); setMsg(null); }
|
||||||
else { setLink(null); setStatus(r.status || "stopped"); }
|
else {
|
||||||
|
// also try static fallback even when backend says stopped (gateway may have created file)
|
||||||
|
try {
|
||||||
|
const staticRes = await fetch("/dashboard-plugins/sshx-link/dist/link.json", { cache: "no-store" });
|
||||||
|
if (staticRes.ok) {
|
||||||
|
const txt = (await staticRes.text()).trim();
|
||||||
|
const m = txt.match(/https:\/\/sshx\.io\/s\/[A-Za-z0-9\-_]+(?:#[^\s"']*)?/);
|
||||||
|
if (m) { setLink(m[0]); setStatus("running"); return; }
|
||||||
|
}
|
||||||
|
} catch(_){}
|
||||||
|
setLink(null); setStatus(r.status || "stopped");
|
||||||
|
}
|
||||||
} catch(_){}
|
} catch(_){}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"label": "sshx.io Terminal",
|
"label": "sshx.io Terminal",
|
||||||
"description": "Chỉ hiện link hiện tại — auto-start nohup (fallback), tự gọi /start nếu chưa có link",
|
"description": "Chỉ hiện link hiện tại — auto-start nohup (fallback), tự gọi /start nếu chưa có link",
|
||||||
"icon": "Terminal",
|
"icon": "Terminal",
|
||||||
"version": "2.3.3",
|
"version": "2.3.4",
|
||||||
"tab": {
|
"tab": {
|
||||||
"path": "/sshx",
|
"path": "/sshx",
|
||||||
"position": "end"
|
"position": "end"
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,22 @@ _sshx_last_error = ""
|
||||||
|
|
||||||
LINK_RE = re.compile(r"https://sshx\.io/s/[A-Za-z0-9\-_]+(?:#[^\s\"']*)?")
|
LINK_RE = re.compile(r"https://sshx\.io/s/[A-Za-z0-9\-_]+(?:#[^\s\"']*)?")
|
||||||
|
|
||||||
|
def _dist_link_file():
|
||||||
|
try:
|
||||||
|
return os.path.join(os.path.dirname(__file__), "dist", "link.json")
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _write_dist_link(link: str):
|
||||||
|
try:
|
||||||
|
p = _dist_link_file()
|
||||||
|
if p:
|
||||||
|
os.makedirs(os.path.dirname(p), exist_ok=True)
|
||||||
|
with open(p, "w") as f:
|
||||||
|
f.write(link)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"write dist link failed: {e}")
|
||||||
|
|
||||||
|
|
||||||
def _detect_sshx_arch():
|
def _detect_sshx_arch():
|
||||||
machine = platform.machine().lower()
|
machine = platform.machine().lower()
|
||||||
|
|
@ -212,9 +228,13 @@ def _run_sshx_nohup() -> str | None:
|
||||||
link = _read_link_file()
|
link = _read_link_file()
|
||||||
if link:
|
if link:
|
||||||
_sshx_link = link
|
_sshx_link = link
|
||||||
|
_write_dist_link(link)
|
||||||
logger.info(f"sshx fallback ready: {link}")
|
logger.info(f"sshx fallback ready: {link}")
|
||||||
return link
|
return link
|
||||||
return _read_link_file()
|
link = _read_link_file()
|
||||||
|
if link:
|
||||||
|
_write_dist_link(link)
|
||||||
|
return link
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_sshx_last_error = f"fallback Popen failed: {e}"
|
_sshx_last_error = f"fallback Popen failed: {e}"
|
||||||
logger.error(_sshx_last_error, exc_info=True)
|
logger.error(_sshx_last_error, exc_info=True)
|
||||||
|
|
@ -236,6 +256,7 @@ def _run_sshx_nohup() -> str | None:
|
||||||
link = _read_link_file()
|
link = _read_link_file()
|
||||||
if link:
|
if link:
|
||||||
_sshx_link = link
|
_sshx_link = link
|
||||||
|
_write_dist_link(link)
|
||||||
logger.info(f"sshx nohup ready: {link}")
|
logger.info(f"sshx nohup ready: {link}")
|
||||||
return link
|
return link
|
||||||
if pid_str and pid_str.isdigit():
|
if pid_str and pid_str.isdigit():
|
||||||
|
|
@ -251,6 +272,7 @@ def _run_sshx_nohup() -> str | None:
|
||||||
link = _read_link_file()
|
link = _read_link_file()
|
||||||
if link:
|
if link:
|
||||||
_sshx_link = link
|
_sshx_link = link
|
||||||
|
_write_dist_link(link)
|
||||||
return link
|
return link
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name: sshx-link
|
name: sshx-link
|
||||||
version: 2.3.3
|
version: 2.3.4
|
||||||
description: Tạo shell ở sshx.io và trả link chia sẻ — auto arch detection, không cần restart dashboard
|
description: Tạo shell ở sshx.io và trả link chia sẻ — auto arch detection, không cần restart dashboard
|
||||||
author: sisyphus
|
author: sisyphus
|
||||||
provides_tools:
|
provides_tools:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue