fix(desktop): keep named-profile desktop backends per-profile (#44510)
Desktop spawns its dashboard backend with `--profile <name>` and `HERMES_DESKTOP=1`. cmd_dashboard's unified-launch routing treats any named profile as a request for the shared machine dashboard: it re-execs as the default profile (dropping HERMES_HOME) or, when one is already listening, prints "Machine dashboard already running ... Managing profile '<name>'" and exits 0. Either way the desktop-spawned child exits before the app sees a ready backend, so Desktop retries forever — the Windows named-profile boot loop in the post-mortem. Skip the machine-dashboard reroute when HERMES_DESKTOP=1 so desktop pool backends stay per-profile (which is what the pool expects). Carved out of #44478. Co-authored-by: AJ <yspdev@gmail.com>
This commit is contained in:
@@ -10332,6 +10332,8 @@ def cmd_dashboard(args):
|
|||||||
_launch_profile not in ("default", "custom")
|
_launch_profile not in ("default", "custom")
|
||||||
and not getattr(args, "isolated", False)
|
and not getattr(args, "isolated", False)
|
||||||
and not getattr(args, "open_profile", "")
|
and not getattr(args, "open_profile", "")
|
||||||
|
# Desktop pool backends are intentionally per-profile.
|
||||||
|
and os.environ.get("HERMES_DESKTOP") != "1"
|
||||||
):
|
):
|
||||||
url = f"http://{args.host or '127.0.0.1'}:{args.port}/?profile={_launch_profile}"
|
url = f"http://{args.host or '127.0.0.1'}:{args.port}/?profile={_launch_profile}"
|
||||||
if _dashboard_listening(args.host, args.port):
|
if _dashboard_listening(args.host, args.port):
|
||||||
|
|||||||
@@ -82,6 +82,29 @@ class TestUnifiedDashboardRouting:
|
|||||||
# Profile HERMES_HOME dropped so the child binds the machine root.
|
# Profile HERMES_HOME dropped so the child binds the machine root.
|
||||||
assert "HERMES_HOME" not in env
|
assert "HERMES_HOME" not in env
|
||||||
|
|
||||||
|
def test_desktop_profile_backend_skips_machine_dashboard_reroute(self, main_mod, monkeypatch):
|
||||||
|
"""A desktop-spawned named-profile backend (HERMES_DESKTOP=1) must NOT
|
||||||
|
reroute into the machine dashboard. The reroute re-execs as the default
|
||||||
|
profile and exits, so the desktop never sees a ready backend → boot
|
||||||
|
loop. The guard keeps desktop pool backends per-profile."""
|
||||||
|
monkeypatch.setenv("HERMES_DESKTOP", "1")
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"hermes_cli.profiles.get_active_profile_name", lambda: "worker_x"
|
||||||
|
)
|
||||||
|
listening_calls = []
|
||||||
|
monkeypatch.setattr(
|
||||||
|
main_mod, "_dashboard_listening",
|
||||||
|
lambda host, port: listening_calls.append(1) or False,
|
||||||
|
)
|
||||||
|
execs = []
|
||||||
|
monkeypatch.setattr(main_mod.os, "execvpe", lambda *a, **k: execs.append(a))
|
||||||
|
monkeypatch.setitem(sys.modules, "fastapi", None)
|
||||||
|
|
||||||
|
with pytest.raises((SystemExit, AttributeError, ImportError, TypeError)):
|
||||||
|
main_mod.cmd_dashboard(_args())
|
||||||
|
assert listening_calls == []
|
||||||
|
assert execs == []
|
||||||
|
|
||||||
def test_isolated_flag_skips_routing(self, main_mod, monkeypatch):
|
def test_isolated_flag_skips_routing(self, main_mod, monkeypatch):
|
||||||
monkeypatch.setattr(
|
monkeypatch.setattr(
|
||||||
"hermes_cli.profiles.get_active_profile_name", lambda: "worker_x"
|
"hermes_cli.profiles.get_active_profile_name", lambda: "worker_x"
|
||||||
|
|||||||
Reference in New Issue
Block a user