fix(update): kill gateway via PID file before restart
cmd_update only ran 'systemctl --user restart hermes-gateway', which left manually-started gateway processes alive, causing duplicates. Now uses get_running_pid() from gateway/status.py (scoped to HERMES_HOME) to find and SIGTERM this installation's gateway before restarting. Safe with multiple Hermes installations since each HERMES_HOME has its own PID file. If no systemd service exists, informs the user to restart manually. Based on PR #1131 by teknium1. Dropped the cli.py Rich from_ansi changes (already on main).
This commit is contained in:
parent
f7c5d8a749
commit
e7d3f1f3ba
1 changed files with 50 additions and 18 deletions
|
|
@ -2301,26 +2301,58 @@ def cmd_update(args):
|
||||||
print()
|
print()
|
||||||
print("✓ Update complete!")
|
print("✓ Update complete!")
|
||||||
|
|
||||||
# Auto-restart gateway if it's running as a systemd service
|
# Auto-restart gateway if it's running.
|
||||||
|
# Uses the PID file (scoped to HERMES_HOME) to find this
|
||||||
|
# installation's gateway — safe with multiple installations.
|
||||||
try:
|
try:
|
||||||
check = subprocess.run(
|
from gateway.status import get_running_pid, remove_pid_file
|
||||||
["systemctl", "--user", "is-active", "hermes-gateway"],
|
import signal as _signal
|
||||||
capture_output=True, text=True, timeout=5,
|
|
||||||
)
|
existing_pid = get_running_pid()
|
||||||
if check.stdout.strip() == "active":
|
has_systemd_service = False
|
||||||
print()
|
|
||||||
print("→ Gateway service is running — restarting to pick up changes...")
|
try:
|
||||||
restart = subprocess.run(
|
check = subprocess.run(
|
||||||
["systemctl", "--user", "restart", "hermes-gateway"],
|
["systemctl", "--user", "is-active", "hermes-gateway"],
|
||||||
capture_output=True, text=True, timeout=15,
|
capture_output=True, text=True, timeout=5,
|
||||||
)
|
)
|
||||||
if restart.returncode == 0:
|
has_systemd_service = check.stdout.strip() == "active"
|
||||||
print("✓ Gateway restarted.")
|
except (FileNotFoundError, subprocess.TimeoutExpired):
|
||||||
else:
|
pass
|
||||||
print(f"⚠ Gateway restart failed: {restart.stderr.strip()}")
|
|
||||||
print(" Try manually: hermes gateway restart")
|
if existing_pid or has_systemd_service:
|
||||||
except (FileNotFoundError, subprocess.TimeoutExpired):
|
print()
|
||||||
pass # No systemd (macOS, WSL1, etc.) — skip silently
|
|
||||||
|
# Kill the PID-file-tracked process (may be manual or systemd)
|
||||||
|
if existing_pid:
|
||||||
|
try:
|
||||||
|
os.kill(existing_pid, _signal.SIGTERM)
|
||||||
|
print(f"→ Stopped gateway process (PID {existing_pid})")
|
||||||
|
except ProcessLookupError:
|
||||||
|
pass # Already gone
|
||||||
|
except PermissionError:
|
||||||
|
print(f"⚠ Permission denied killing gateway PID {existing_pid}")
|
||||||
|
remove_pid_file()
|
||||||
|
|
||||||
|
# Restart the systemd service (starts a fresh process)
|
||||||
|
if has_systemd_service:
|
||||||
|
import time as _time
|
||||||
|
_time.sleep(1) # Brief pause for port/socket release
|
||||||
|
print("→ Restarting gateway service...")
|
||||||
|
restart = subprocess.run(
|
||||||
|
["systemctl", "--user", "restart", "hermes-gateway"],
|
||||||
|
capture_output=True, text=True, timeout=15,
|
||||||
|
)
|
||||||
|
if restart.returncode == 0:
|
||||||
|
print("✓ Gateway restarted.")
|
||||||
|
else:
|
||||||
|
print(f"⚠ Gateway restart failed: {restart.stderr.strip()}")
|
||||||
|
print(" Try manually: hermes gateway restart")
|
||||||
|
elif existing_pid:
|
||||||
|
print(" ℹ️ Gateway was running manually (not as a service).")
|
||||||
|
print(" Restart it with: hermes gateway run")
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug("Gateway restart during update failed: %s", e)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
print("Tip: You can now select a provider and model:")
|
print("Tip: You can now select a provider and model:")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue