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/<name>` 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.
This commit is contained in:
+8
-15
@@ -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
|
||||
|
||||
|
||||
|
||||
+6
-9
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user