Skip to content

fix(update): restart supervised and manually-started backends after update - #72192

Merged
teknium1 merged 4 commits into
mainfrom
fix/update-restart-backends
Jul 26, 2026
Merged

fix(update): restart supervised and manually-started backends after update#72192
teknium1 merged 4 commits into
mainfrom
fix/update-restart-backends

Conversation

@teknium1

@teknium1 teknium1 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Summary

After hermes update, killed dashboard/serve backends now come back automatically: systemd-supervised PIDs get their owning unit restarted, and manually-started processes are respawned with the argv they were launched with. Previously only the well-known hermes-dashboard.service unit was restarted — a remote backend under a custom unit name, or any manually-launched hermes serve, stayed dead until the operator SSHed in (#68934, Desktop loses connectivity after remote update).

Root cause: our SIGTERM reads as a clean stop to systemd, so Restart=on-failure never fires; and the manual-launch path never recorded launch args, so nothing could relaunch it.

Changes

  • hermes_cli/main.py:
    • _get_pid_cgroup_path / _get_systemd_service_for_pid / _extract_scope_from_cgroup / _try_restart_systemd_service — snapshot each killed PID's owning systemd unit from /proc/<pid>/cgroup before the kill, restart it after (user/system scope aware). Salvaged from fix(update): restart systemd-supervised remote backends after killing stale processes #69029 (@webtecnica, authorship preserved; unrelated profiles.py hunk dropped).
    • _dashboard_cmdline_for_pid / _respawn_dashboard_processes — capture manually-started processes' argv (/proc/<pid>/cmdline on Linux, ps -o command= on macOS) and respawn them detached post-update, --no-open forced, output to the active profile's logs/dashboard-restart.log. Salvaged from fix: auto-restart dashboard after update when argv is recoverable #41508 (@Variable85, authorship preserved) with the sweeper-review fixes: serve matching kept, profile-aware log path via get_hermes_home(), capture gated to the update path.
    • Restarts only run with restart_managed=True (the update path); hermes dashboard --stop remains a plain stop.
  • tests/hermes_cli/test_update_stale_dashboard.py: 11 new tests (unit restart + dedupe + failure hint, argv respawn + --no-open + failure fallback, /proc + ps capture, --stop never restarts). All 11 fail without the fix; the 26 pre-existing tests pass unchanged.

Validation

Before After
Custom systemd unit (e.g. hermes-serve.service) left dead (clean-stop) unit restarted via correct scope
Manually-started hermes serve / dashboard killed + manual hint respawned with original argv
hermes dashboard --stop stops stops (unchanged)
tests 26 pass 37 pass; new 11 fail on main

E2E on a live system (no mocks): real child process argv captured losslessly from /proc including embedded spaces; respawn ran detached with output landing in logs/dashboard-restart.log; full kill→respawn cycle through _kill_stale_dashboard_processes killed pid A and brought the same command back as pid B.

Closes #68934. Closes #40449.
Salvages #69029 and #41508 with contributor authorship preserved.

Infographic

update-backend-autorestart

webtecnica and others added 4 commits July 26, 2026 13:21
…update

Capture each manually-started dashboard/serve process's argv before the
stale-process kill (/proc/<pid>/cmdline on Linux, ps -o command= on macOS),
then respawn it detached after the update — headless (--no-open) with output
to logs/dashboard-restart.log under the active profile's HERMES_HOME.

Supervised PIDs keep their systemd-unit restart; --stop stays a plain stop.

Salvaged from PR #41508 with scope fixes: serve matching preserved, profile-
aware log path, restart only on the update path (restart_managed=True).
11 new tests: owning-unit restart + dedupe + failure hint (#68934),
argv capture/respawn + --no-open + failure fallback (#40449),
/proc and ps cmdline capture, --stop never restarts.
All fail without the fix; 26 pre-existing tests unchanged.
Windows-footguns lint: subprocess text=True without encoding= decodes
via locale.getpreferredencoding(). Match the file's house style.
@teknium1
teknium1 force-pushed the fix/update-restart-backends branch from 9518e8f to 7906dc4 Compare July 26, 2026 20:22
@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 7906dc4

ℹ️ Info

Desktop E2E visual evidence · View test artifacts · View job

1 visual diff.

inline evidence upload failed.

Failed to upload diff-665a0833239e-onboarding-overlay-diff.png with gh image (exit code 1): Error uploading /home/runner/work/_temp/e2e-evidence/diff-665a0833239e-onboarding-overlay-diff.png: step 0 (get upload token): uploadToken not found on repo page — do you have write access to NousResearch/hermes-agent? (or, if NousResearch enforces SAML SSO, authorize at https://github.com/orgs/NousResearch/sso)

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard area/install-update Installer, updater, packaging, wheels, doctor needs-decision Awaiting maintainer decision before any implementation sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Jul 26, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: #69029 and #69046 address the same update-triggered supervised-backend outage with different lifecycle mechanisms. This salvage uses post-kill cgroup/service restart and additionally covers manual process respawn; a maintainer should select the intended mechanism.

@teknium1
teknium1 merged commit 3dc2dec into main Jul 26, 2026
41 checks passed
@teknium1
teknium1 deleted the fix/update-restart-backends branch July 26, 2026 20:42
teknium1 pushed a commit that referenced this pull request Jul 26, 2026
… paths

- hermes dashboard --status now verifies each matched PID is alive AND
  bound to a listening socket before reporting it, so stale PIDs and the
  desktop app's IPC-only 'serve --port 0' backends no longer masquerade
  as running dashboards (#58578).
- The git and Windows ZIP update paths share one
  _finish_dashboard_update_cleanup(), so the ZIP fallback gets the same
  stop/restart reporting.
- _kill_stale_dashboard_processes returns a structured
  {matched, killed, failed, unrecovered} result; the explicit was-stopped
  notice fires only for processes that could NOT be auto-restarted,
  meshing with the auto-respawn from #72192.
@webtecnica

Copy link
Copy Markdown
Contributor

Closing — this fix was absorbed as part of the gateway reconnect-watchdog cluster (#70987) by @teknium1. The backend restart logic was cherry-picked and preserved with authorship credited. The reconnect watcher now handles post-update restart correctly on main.

randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
… paths

- hermes dashboard --status now verifies each matched PID is alive AND
  bound to a listening socket before reporting it, so stale PIDs and the
  desktop app's IPC-only 'serve --port 0' backends no longer masquerade
  as running dashboards (NousResearch#58578).
- The git and Windows ZIP update paths share one
  _finish_dashboard_update_cleanup(), so the ZIP fallback gets the same
  stop/restart reporting.
- _kill_stale_dashboard_processes returns a structured
  {matched, killed, failed, unrecovered} result; the explicit was-stopped
  notice fires only for processes that could NOT be auto-restarted,
  meshing with the auto-respawn from NousResearch#72192.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install-update Installer, updater, packaging, wheels, doctor comp/cli CLI entry point, hermes_cli/, setup wizard needs-decision Awaiting maintainer decision before any implementation P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remote backend update can stop hermes serve without restarting it hermes update does not detect or suggest restart for managed dashboard services

4 participants