Skip to content

fix(gateway): harden Docker/container gateway pathway - #8614

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-84d7b091
Apr 12, 2026
Merged

fix(gateway): harden Docker/container gateway pathway#8614
teknium1 merged 1 commit into
mainfrom
hermes/hermes-84d7b091

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Salvage of #8573 by @alt-glitch — cherry-picked onto current main with unrelated files removed.

Fixes the FileNotFoundError: systemctl crash when running gateway commands inside Docker containers.

What changed

Core: centralized container detection

  • Added is_container() to hermes_constants.py with process-lifetime caching (matches is_wsl()/is_termux() pattern)
  • Deduped _is_inside_container() in config.py to delegate to the new function
  • Replaced inline /.dockerenv check in voice_mode.py

Gateway: defense-in-depth

  • Added _run_systemctl() wrapper — catches FileNotFoundError and raises RuntimeError with clear messaging. All 10 bare subprocess.run(_systemctl_cmd(...)) call sites now route through it
  • supports_systemd_services() now returns False in containers AND when systemctl binary is absent (shutil.which check)
  • Docker-specific guidance in gateway_command() for install/uninstall/start — exit 0 instead of crashing

CLI: accurate Docker status

  • hermes status shows "Manager: docker (foreground)" in containers
  • hermes dump shows "running (docker, pid N)" or "stopped (docker)"
  • setup_gateway() shows Docker restart policy instructions in containers

Changes from original PR

Removed from #8573:

  • spec.md (unrelated contributor notes)
  • Dockerfile.test (contributor's local testing artifact)
  • uv.lock changes (unrelated Matrix dependency additions)

All substantive code and tests preserved as-is.

Test results

113 targeted tests pass. One pre-existing failure in test_auth_commands.py unrelated to these changes.

Fixes #7420
Closes #8573

Centralize container detection in hermes_constants.is_container() with
process-lifetime caching, matching existing is_wsl()/is_termux() patterns.
Dedup _is_inside_container() in config.py to delegate to the new function.

Add _run_systemctl() wrapper that converts FileNotFoundError to RuntimeError
for defense-in-depth — all 10 bare subprocess.run(_systemctl_cmd(...)) call
sites now route through it.

Make supports_systemd_services() return False in containers and when
systemctl binary is absent (shutil.which check).

Add Docker-specific guidance in gateway_command() for install/uninstall/start
subcommands — exit 0 with helpful instructions instead of crashing.

Make 'hermes status' show 'Manager: docker (foreground)' and 'hermes dump'
show 'running (docker, pid N)' inside containers.

Fix setup_gateway() to use supports_systemd instead of _is_linux for all
systemd-related branches, and show Docker restart policy instructions in
containers.

Replace inline /.dockerenv check in voice_mode.py with is_container().

Fixes #7420

Co-authored-by: teknium1 <teknium1@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: Install hook files modified

These files can execute code during package installation or interpreter startup.

Files:

hermes_cli/setup.py
tests/hermes_cli/test_setup.py

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: No such file or directory: 'systemctl'

2 participants