From b0a2fcbc5bf8d40c472c7b4dc0200d3b73a53bd3 Mon Sep 17 00:00:00 2001 From: 6zev Date: Thu, 3 Sep 2026 05:57:43 +0000 Subject: [PATCH] fix: cron script path - copy to all HERMES_HOME candidates to fix /OPT/DATA/SCRIPTS/SCRIPTS doubling - _ensure_cron_script now copies to all candidates: HERMES_HOME, ~/.hermes, /opt/data, /opt/data/scripts handling - cron should use Script=sshx_link.sh (not scripts/sshx_link.sh) with Workdir empty or /opt/data (script must be inside HERMES_HOME/scripts, Workdir is cwd) - keep auto-start via nohup/systemd and dashboard visible (no cron needed) - bump v2.5.7 --- __init__.py | 57 ++++++++++++++++++++++++++--------------- dashboard/manifest.json | 2 +- plugin.yaml | 2 +- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/__init__.py b/__init__.py index ed4f0e8..92dbb10 100644 --- a/__init__.py +++ b/__init__.py @@ -548,34 +548,51 @@ def _stop_sshx(tool_ctx=None): def _ensure_cron_script(): """Copy scripts/sshx_link.sh to HERMES_HOME/scripts/sshx_link.sh so cron no_agent can find it. - Cron requires script inside HERMES_HOME/scripts, not inside plugin dir.""" + Cron requires script inside HERMES_HOME/scripts, not inside plugin dir. + Also copies to /opt/data/scripts for the research Workdir case.""" try: - # resolve HERMES_HOME + candidates = set() + # primary HERMES_HOME hermes_home = os.environ.get("HERMES_HOME", "").strip() - if not hermes_home: - # fallback to default: ~/.hermes or ~/.config/hermes etc. + if hermes_home: + candidates.add(hermes_home) + else: try: from hermes_constants import get_hermes_home - hermes_home = str(get_hermes_home()) + candidates.add(str(get_hermes_home())) except Exception: - hermes_home = os.path.expanduser("~/.hermes") + pass + candidates.add(os.path.expanduser("~/.hermes")) + # also handle /opt/data case seen on 13.140.132.105 + candidates.update(["/opt/data", "/opt/data/scripts/..", os.path.expanduser("~/.hermes")]) + # normalize + candidates = {os.path.abspath(os.path.expanduser(c)) for c in candidates if c} scripts_src = os.path.join(os.path.dirname(__file__), "scripts", "sshx_link.sh") if not os.path.exists(scripts_src): return - dest_dir = os.path.join(hermes_home, "scripts") - os.makedirs(dest_dir, exist_ok=True) - dest = os.path.join(dest_dir, "sshx_link.sh") - # copy if missing or different - import filecmp - try: - if not os.path.exists(dest) or not filecmp.cmp(scripts_src, dest, shallow=False): - shutil.copy2(scripts_src, dest) - os.chmod(dest, 0o755) - logger.info(f"cron script copied to {dest}") - except Exception as e: - # fallback without filecmp - shutil.copy2(scripts_src, dest) - os.chmod(dest, 0o755) + for home in candidates: + # if home ends with /scripts, use it directly + if home.endswith("/scripts"): + dest_dir = home + else: + dest_dir = os.path.join(home, "scripts") + # only if parent exists or is plausible + try: + os.makedirs(dest_dir, exist_ok=True) + dest = os.path.join(dest_dir, "sshx_link.sh") + import filecmp + need = True + try: + if os.path.exists(dest) and filecmp.cmp(scripts_src, dest, shallow=False): + need = False + except Exception: + pass + if need: + shutil.copy2(scripts_src, dest) + os.chmod(dest, 0o755) + logger.info(f"cron script copied to {dest}") + except Exception as e: + logger.debug(f"copy to {dest_dir} failed: {e}") except Exception as e: logger.debug(f"ensure cron script failed: {e}") diff --git a/dashboard/manifest.json b/dashboard/manifest.json index 991252b..b53671f 100644 --- a/dashboard/manifest.json +++ b/dashboard/manifest.json @@ -3,7 +3,7 @@ "label": "sshx.io Terminal", "description": "Auto-start sshx via nohup/systemd, copy cron script to HERMES_HOME/scripts, dashboard visible", "icon": "Terminal", - "version": "2.5.6", + "version": "2.5.7", "tab": { "path": "/sshx", "position": "end" diff --git a/plugin.yaml b/plugin.yaml index df56488..c884c9b 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,5 +1,5 @@ name: sshx-link -version: 2.5.6 +version: 2.5.7 description: Auto-start sshx via nohup/systemd, copy cron script to HERMES_HOME/scripts, dashboard visible author: sisyphus provides_tools: