mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-06 12:52:11 +00:00
fix(gateway): honor --start-now/--start-on-login flags and support non-TTY headless installs
When running `hermes gateway install` on Linux/systemd, the command unconditionally prompts with two `prompt_yes_no` questions, breaking headless installs (SSH, CI, provisioning scripts) and ignoring the existing --start-now / --start-on-login CLI flags that the Windows branch already respects. The fix mirrors the Windows path: read CLI flags first, prompt only when flags are not provided AND stdin is a TTY, and fall back to True defaults for non-TTY contexts. The argparse help strings are promoted from SUPPRESS to visible so users can discover the flags. Fixes #42065
This commit is contained in:
parent
5e7bca95d9
commit
831d443b03
3 changed files with 105 additions and 6 deletions
|
|
@ -6268,8 +6268,24 @@ def _gateway_command_inner(args):
|
|||
" Or use tmux/screen for persistence: tmux new -s hermes 'hermes gateway run'"
|
||||
)
|
||||
print()
|
||||
start_now = prompt_yes_no("Start the gateway now after installing the service?", True)
|
||||
start_on_login = prompt_yes_no("Start the gateway automatically on login/boot with systemd?", True)
|
||||
# Honor CLI flags (--start-now / --no-start-now, --start-on-login /
|
||||
# --no-start-on-login). When not provided, prompt interactively or
|
||||
# fall back to True for non-TTY / headless contexts (SSH, CI, pipes).
|
||||
_sn = getattr(args, "start_now", None)
|
||||
if _sn is not None:
|
||||
start_now = _sn
|
||||
elif sys.stdin.isatty():
|
||||
start_now = prompt_yes_no("Start the gateway now after installing the service?", True)
|
||||
else:
|
||||
start_now = True
|
||||
|
||||
_sol = getattr(args, "start_on_login", None)
|
||||
if _sol is not None:
|
||||
start_on_login = _sol
|
||||
elif sys.stdin.isatty():
|
||||
start_on_login = prompt_yes_no("Start the gateway automatically on login/boot with systemd?", True)
|
||||
else:
|
||||
start_on_login = True
|
||||
systemd_install(
|
||||
force=force,
|
||||
system=system,
|
||||
|
|
|
|||
|
|
@ -169,26 +169,26 @@ def build_gateway_parser(
|
|||
dest="start_now",
|
||||
action="store_true",
|
||||
default=None,
|
||||
help=argparse.SUPPRESS,
|
||||
help="Start the gateway service immediately after installing",
|
||||
)
|
||||
gateway_install.add_argument(
|
||||
"--no-start-now",
|
||||
dest="start_now",
|
||||
action="store_false",
|
||||
help=argparse.SUPPRESS,
|
||||
help="Do not start the gateway service after installing",
|
||||
)
|
||||
gateway_install.add_argument(
|
||||
"--start-on-login",
|
||||
dest="start_on_login",
|
||||
action="store_true",
|
||||
default=None,
|
||||
help=argparse.SUPPRESS,
|
||||
help="Enable the service to start automatically on login/boot",
|
||||
)
|
||||
gateway_install.add_argument(
|
||||
"--no-start-on-login",
|
||||
dest="start_on_login",
|
||||
action="store_false",
|
||||
help=argparse.SUPPRESS,
|
||||
help="Do not enable the service to start on login/boot",
|
||||
)
|
||||
gateway_install.add_argument(
|
||||
"--elevated-handoff",
|
||||
|
|
|
|||
|
|
@ -444,6 +444,7 @@ def test_gateway_install_in_container_with_operational_systemd_uses_systemd(monk
|
|||
monkeypatch.setattr(gateway, "is_wsl", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_macos", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_managed", lambda: False)
|
||||
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
|
||||
|
||||
calls = []
|
||||
monkeypatch.setattr(gateway, "prompt_yes_no", lambda question, default=True: calls.append(("prompt", question, default)) or True)
|
||||
|
|
@ -796,6 +797,7 @@ def test_gateway_install_can_decline_start_now_and_startup(monkeypatch):
|
|||
monkeypatch.setattr(gateway, "is_wsl", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_macos", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_managed", lambda: False)
|
||||
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
|
||||
|
||||
answers = iter([False, False])
|
||||
calls = []
|
||||
|
|
@ -817,6 +819,87 @@ def test_gateway_install_can_decline_start_now_and_startup(monkeypatch):
|
|||
]
|
||||
|
||||
|
||||
def test_gateway_install_systemd_honors_start_now_flag(monkeypatch):
|
||||
"""--start-now / --no-start-now should bypass the interactive prompt."""
|
||||
monkeypatch.setattr(gateway, "supports_systemd_services", lambda: True)
|
||||
monkeypatch.setattr(gateway, "is_wsl", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_macos", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_managed", lambda: False)
|
||||
|
||||
calls = []
|
||||
monkeypatch.setattr(gateway, "prompt_yes_no", lambda question, default=True: calls.append(("prompt", question)))
|
||||
monkeypatch.setattr(
|
||||
gateway,
|
||||
"systemd_install",
|
||||
lambda force=False, system=False, run_as_user=None, enable_on_startup=True: calls.append(("install", enable_on_startup)),
|
||||
)
|
||||
monkeypatch.setattr(gateway, "systemd_start", lambda system=False: calls.append(("start",)))
|
||||
|
||||
args = SimpleNamespace(
|
||||
gateway_command="install", force=False, system=False,
|
||||
run_as_user=None, start_now=True, start_on_login=False,
|
||||
)
|
||||
gateway.gateway_command(args)
|
||||
|
||||
assert ("prompt", "Start the gateway now after installing the service?") not in calls
|
||||
assert ("start",) in calls
|
||||
assert ("install", False) in calls
|
||||
|
||||
|
||||
def test_gateway_install_systemd_non_tty_uses_defaults(monkeypatch):
|
||||
"""Non-TTY stdin (headless/CI) should use True defaults without prompting."""
|
||||
monkeypatch.setattr(gateway, "supports_systemd_services", lambda: True)
|
||||
monkeypatch.setattr(gateway, "is_wsl", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_macos", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_managed", lambda: False)
|
||||
monkeypatch.setattr("sys.stdin.isatty", lambda: False)
|
||||
|
||||
calls = []
|
||||
monkeypatch.setattr(gateway, "prompt_yes_no", lambda question, default=True: calls.append(("prompt", question)))
|
||||
monkeypatch.setattr(
|
||||
gateway,
|
||||
"systemd_install",
|
||||
lambda force=False, system=False, run_as_user=None, enable_on_startup=True: calls.append(("install", enable_on_startup)),
|
||||
)
|
||||
monkeypatch.setattr(gateway, "systemd_start", lambda system=False: calls.append(("start",)))
|
||||
|
||||
args = SimpleNamespace(gateway_command="install", force=False, system=False, run_as_user=None)
|
||||
gateway.gateway_command(args)
|
||||
|
||||
# No prompts — defaults used (start_now=True, start_on_login=True)
|
||||
assert all(c[0] != "prompt" for c in calls)
|
||||
assert ("install", True) in calls
|
||||
assert ("start",) in calls
|
||||
|
||||
|
||||
def test_gateway_install_systemd_no_start_now_flag_non_tty(monkeypatch):
|
||||
"""--no-start-now in non-TTY should skip starting the service."""
|
||||
monkeypatch.setattr(gateway, "supports_systemd_services", lambda: True)
|
||||
monkeypatch.setattr(gateway, "is_wsl", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_macos", lambda: False)
|
||||
monkeypatch.setattr(gateway, "is_managed", lambda: False)
|
||||
monkeypatch.setattr("sys.stdin.isatty", lambda: False)
|
||||
|
||||
calls = []
|
||||
monkeypatch.setattr(gateway, "prompt_yes_no", lambda question, default=True: calls.append(("prompt", question)))
|
||||
monkeypatch.setattr(
|
||||
gateway,
|
||||
"systemd_install",
|
||||
lambda force=False, system=False, run_as_user=None, enable_on_startup=True: calls.append(("install", enable_on_startup)),
|
||||
)
|
||||
monkeypatch.setattr(gateway, "systemd_start", lambda system=False: calls.append(("start",)))
|
||||
|
||||
args = SimpleNamespace(
|
||||
gateway_command="install", force=False, system=False,
|
||||
run_as_user=None, start_now=False, start_on_login=True,
|
||||
)
|
||||
gateway.gateway_command(args)
|
||||
|
||||
assert all(c[0] != "prompt" for c in calls)
|
||||
assert ("install", True) in calls
|
||||
assert ("start",) not in calls
|
||||
|
||||
|
||||
def test_find_gateway_pids_falls_back_to_pid_file_when_process_scan_fails(monkeypatch):
|
||||
monkeypatch.setattr(gateway, "_get_service_pids", lambda: set())
|
||||
monkeypatch.setattr(gateway, "is_windows", lambda: False)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue