Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/panopticon/terminal/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from __future__ import annotations

import socket as socket_module
import subprocess
import sys
import tempfile
Expand Down Expand Up @@ -69,14 +70,21 @@ def switch_to(
host: str | None = None,
switch_file: Path,
detach: Callable[[], None] = _tmux_detach,
local_host: Callable[[], str] = socket_module.gethostname,
) -> None:
"""The dashboard's `t` hook, run inside its tmux session: record the picked ``session`` for
the supervisor, then detach this client so the supervisor attaches the task. The dashboard
process keeps running (detached), so returning to it shows the same live view.

When ``host`` is set the switch-file carries ``<host>\\t<session>`` so the
supervisor can ssh-wrap the attach; a plain ``<session>`` (no tab) means local.
``host`` is the claiming runner's registered hostname (ADR 0013 §6) — populated even for the
ordinary local runner. It only means "remote" when it differs from this machine's own
hostname (``local_host``, injectable for tests); otherwise it's treated as local so `t` never
ssh-wraps a same-machine attach. When genuinely remote, the switch-file carries
``<host>\\t<session>`` so the supervisor can ssh-wrap the attach; a plain ``<session>`` (no
tab) means local.
"""
if host == local_host():
host = None
switch_file.write_text(f"{host}\t{session}" if host else session)
detach()

Expand Down
19 changes: 18 additions & 1 deletion tests/test_console.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,28 @@ def test_switch_to_with_remote_host_encodes_host_and_session(tmp_path: Path) ->
# parse it and pass host= to attach_command for the ssh-wrapped attach.
switch = tmp_path / "switch"

switch_to("panopticon-t1", host="box.example.com", switch_file=switch, detach=lambda: None)
switch_to(
"panopticon-t1", host="box.example.com", switch_file=switch, detach=lambda: None,
local_host=lambda: "this-machine",
)

assert switch.read_text() == "box.example.com\tpanopticon-t1"


def test_switch_to_with_own_hostname_is_treated_as_local(tmp_path: Path) -> None:
# The ordinary local runner registers its own hostname too (ADR 0013 §6), but that must not
# ssh-wrap a same-machine attach: when host == local_host() it's dropped, so the switch-file
# carries a plain session (no tab) just like the no-host case.
switch = tmp_path / "switch"

switch_to(
"panopticon-t1", host="this-machine", switch_file=switch, detach=lambda: None,
local_host=lambda: "this-machine",
)

assert switch.read_text() == "panopticon-t1"


def test_supervisor_parses_remote_host_from_switch_file(tmp_path: Path) -> None:
# run_console_local's attach() closure parses "<host>\t<session>" from the switch-file and
# passes host= to attach_command; a plain session (no tab) means local (host=None).
Expand Down
Loading