From a32b8cd4a357a4454ff6f83d90e246ea13ee38d4 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Sat, 12 Sep 2026 11:58:34 +0530 Subject: [PATCH] refactor(gateway): share the sudo-invoker home lookup, drop unreachable guards `_native_service_homes()` re-implemented the root+SUDO_USER -> `pw_dir/.hermes` resolution that `hermes_cli.main._resolve_sudo_user_profile_env` already did. Both now call `hermes_constants.sudo_invoker_default_home()`; main.py appends `profiles/` to it. Also removes the local `from pathlib import Path as _Path` (Path is a module import) and narrows the except to `KeyError`: `import pwd` cannot fail once `os.geteuid` exists, and `getpwnam(str)` raises nothing else. --- hermes_cli/gateway.py | 23 ++++++++--------------- hermes_cli/main.py | 15 ++++++--------- hermes_constants.py | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/hermes_cli/gateway.py b/hermes_cli/gateway.py index aab7419a72..1b3df77395 100644 --- a/hermes_cli/gateway.py +++ b/hermes_cli/gateway.py @@ -1955,23 +1955,16 @@ def _profile_name_from_home(home: Path, default: Path) -> str | None: def _native_service_homes() -> set[Path]: - """Homes that own the bare native gateway service name in this process.""" - from hermes_constants import _get_platform_default_hermes_home - from pathlib import Path as _Path + """Homes whose service name is the bare ``hermes-gateway``: this process's native default and, under + sudo, the invoking user's. Under sudo the process default is ``/root/.hermes`` but + ``_sync_hermes_home_from_systemd_unit()`` rewrites HERMES_HOME mid-command to the unit's home — the + invoking user's ``~/.hermes`` — which would otherwise hash and target a unit that does not exist.""" + from hermes_constants import _get_platform_default_hermes_home, sudo_invoker_default_home homes = {_get_platform_default_hermes_home().resolve()} - if getattr(os, "geteuid", lambda: -1)() != 0: - return homes - - sudo_user = os.environ.get("SUDO_USER", "").strip() - if not sudo_user or sudo_user == "root": - return homes - try: - import pwd - - homes.add((_Path(pwd.getpwnam(sudo_user).pw_dir) / ".hermes").resolve()) - except (ImportError, KeyError, AttributeError, TypeError): - pass + sudo_home = sudo_invoker_default_home() + if sudo_home is not None: + homes.add(sudo_home.resolve()) return homes diff --git a/hermes_cli/main.py b/hermes_cli/main.py index 167830d641..3f0a981fd0 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -453,18 +453,15 @@ def _resolve_sudo_user_profile_env(name: str) -> str | None: sudo invocations the best signal is SUDO_USER: root is only doing the privileged install/start action; the profile store belongs to the user. """ - if name == "default" or not hasattr(os, "geteuid") or os.geteuid() != 0: + if name == "default": return None - sudo_user = os.environ.get("SUDO_USER", "").strip() - if not sudo_user or sudo_user == "root": - return None - try: - import pwd + from hermes_constants import sudo_invoker_default_home - candidate = Path(pwd.getpwnam(sudo_user).pw_dir) / ".hermes" / "profiles" / name - return str(candidate) if candidate.is_dir() else None - except Exception: + sudo_home = sudo_invoker_default_home() + if sudo_home is None: return None + candidate = sudo_home / "profiles" / name + return str(candidate) if candidate.is_dir() else None def _under_gateway_supervisor(argv: list) -> bool: diff --git a/hermes_constants.py b/hermes_constants.py index 3589cf0435..8a191ece0e 100644 --- a/hermes_constants.py +++ b/hermes_constants.py @@ -51,6 +51,25 @@ def _get_platform_default_hermes_home() -> Path: return Path.home() / ".hermes" +def sudo_invoker_default_home() -> Path | None: + """The invoking user's native ``~/.hermes`` when this process is root under ``sudo``, else None. + + sudo strips HERMES_HOME and sets HOME=/root, so the process's own default is root's; the profile + store and the system service being operated on belong to SUDO_USER. + """ + if not hasattr(os, "geteuid") or os.geteuid() != 0: + return None + sudo_user = os.environ.get("SUDO_USER", "").strip() + if not sudo_user or sudo_user == "root": + return None + import pwd # windows-footgun: ok — unreachable without os.geteuid + + try: + return Path(pwd.getpwnam(sudo_user).pw_dir) / ".hermes" + except KeyError: # SUDO_USER not in passwd (chroot/container) + return None + + def _warn_profile_fallback_once() -> None: """Warn once when HERMES_HOME is unset but a non-default profile is sticky-active (wrong fallback).""" global _profile_fallback_warned