feat(update): warn about legacy hermes.service units during hermes update (#11918)

Follow-up to #11909: surface the legacy-unit warning where users are most
likely to see it. After a 'hermes update', if a pre-rename hermes.service
is still installed alongside the current hermes-gateway.service, print
the list of legacy units + the 'hermes gateway migrate-legacy' command.

Profile-safe: reuses _find_legacy_hermes_units() which is an explicit
allowlist of hermes.service only — profile units never match.
Platform-gated: only prints on systemd hosts (the rename is Linux-only).
Non-blocking: just prints, never prompts, so gateway-spawned
hermes update --gateway runs aren't affected.
This commit is contained in:
Teknium 2026-04-17 19:35:12 -07:00 committed by GitHub
parent 07db20c72d
commit 53e4a2f2c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 209 additions and 0 deletions

View file

@ -5604,6 +5604,35 @@ def cmd_update(args):
except Exception as e:
logger.debug("Gateway restart during update failed: %s", e)
# Warn if legacy Hermes gateway unit files are still installed.
# When both hermes.service (from a pre-rename install) and the
# current hermes-gateway.service are enabled, they SIGTERM-fight
# for the same bot token (see PR #11909). Flagging here means
# every `hermes update` surfaces the issue until the user migrates.
try:
from hermes_cli.gateway import (
has_legacy_hermes_units,
_find_legacy_hermes_units,
supports_systemd_services,
)
if supports_systemd_services() and has_legacy_hermes_units():
print()
print("⚠ Legacy Hermes gateway unit(s) detected:")
for name, path, is_sys in _find_legacy_hermes_units():
scope = "system" if is_sys else "user"
print(f" {path} ({scope} scope)")
print()
print(" These pre-rename units (hermes.service) fight the current")
print(" hermes-gateway.service for the bot token and cause SIGTERM")
print(" flap loops. Remove them with:")
print()
print(" hermes gateway migrate-legacy")
print()
print(" (add `sudo` if any are in system scope)")
except Exception as e:
logger.debug("Legacy unit check during update failed: %s", e)
print()
print("Tip: You can now select a provider and model:")
print(" hermes model # Select provider and model")