mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 06:00:33 +02:00
Devices: fixes from review round 21
- Behind a jump host, a forward it couldn't open moves on to the next address; only a refused key stops (judged by ssh's words, not the step). - Add a headset suggests an alias no Host in ~/.ssh/config already uses. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
42b51afc5a
commit
8bd8d63546
2 files changed
+25
-3
No files matched your search
@@ -317,6 +317,15 @@ class Connecting(unittest.TestCase):
|
|||||||
self.assertFalse(fl.Link.is_target('Authenticated to bastion ([1.2.3.4]:22) using "publickey".', opts, "frame"))
|
self.assertFalse(fl.Link.is_target('Authenticated to bastion ([1.2.3.4]:22) using "publickey".', opts, "frame"))
|
||||||
self.assertTrue(fl.Link.is_target('Authenticated to 10.0.0.5 ([10.0.0.5]:22) using "publickey".', opts, "frame"))
|
self.assertTrue(fl.Link.is_target('Authenticated to 10.0.0.5 ([10.0.0.5]:22) using "publickey".', opts, "frame"))
|
||||||
|
|
||||||
|
def test_a_forward_the_jump_host_couldnt_open_tries_the_next_address(self):
|
||||||
|
said = ["Authenticated to bastion ([1.2.3.4]:22) using \"publickey\".",
|
||||||
|
"channel 0: open failed: connect failed: Connection refused", "stdio forwarding failed"]
|
||||||
|
self.link.state["stages"] = [{"id": i, "state": "pending", "started": None, "ended": None, "detail": ""}
|
||||||
|
for i, _ in fl.STAGES]
|
||||||
|
self.assertEqual(self.link.failed("login", said, False, "frame"), "next")
|
||||||
|
self.assertEqual(self.link.failed("login", ["steamos@frame: Permission denied (publickey)."], False, "frame"),
|
||||||
|
"stop")
|
||||||
|
|
||||||
def test_probes_from_an_earlier_attempt_leave_the_new_rows_alone(self):
|
def test_probes_from_an_earlier_attempt_leave_the_new_rows_alone(self):
|
||||||
self.link.state.update(attempt=2, probes=[{"host": "b", "state": "waiting"}])
|
self.link.state.update(attempt=2, probes=[{"host": "b", "state": "waiting"}])
|
||||||
self.link.probe_update(0, 1, state="answered", ip="10.0.0.2")
|
self.link.probe_update(0, 1, state="answered", ip="10.0.0.2")
|
||||||
@@ -528,6 +537,8 @@ class Connecting(unittest.TestCase):
|
|||||||
self.assertIn("frame-9", out["message"])
|
self.assertIn("frame-9", out["message"])
|
||||||
self.assertEqual(out["active"], d["id"])
|
self.assertEqual(out["active"], d["id"])
|
||||||
self.assertEqual(fl.next_alias(self.link), "frame")
|
self.assertEqual(fl.next_alias(self.link), "frame")
|
||||||
|
(self.dir / "ssh" / "config").write_text("Host frame lab-*\n HostName 10.0.0.7\n") # someone's own `frame`
|
||||||
|
self.assertEqual(fl.next_alias(self.link), "frame-2")
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(os.name == "nt", "the stand-in ssh is a POSIX script")
|
@unittest.skipIf(os.name == "nt", "the stand-in ssh is a POSIX script")
|
||||||
|
|||||||
+14
-3
@@ -914,7 +914,11 @@ class Link:
|
|||||||
self.fail("identity", "This address answered as a different headset (its SSH identity doesn't match). "
|
self.fail("identity", "This address answered as a different headset (its SSH identity doesn't match). "
|
||||||
"If SteamOS was reinstalled, use Forget Identity on the Devices tab.", text)
|
"If SteamOS was reinstalled, use Forget Identity on the Devices tab.", text)
|
||||||
return "next"
|
return "next"
|
||||||
if step == "login" or re.search(r"Permission denied", text):
|
# A refused key is the same at every address: stop. (Judged by ssh's own words, not
|
||||||
|
# the step: a jump host's progress lines look like the headset's.) A forward that
|
||||||
|
# a jump host couldn't open is about this address only: try the next.
|
||||||
|
forward = re.search(r"open failed|forwarding failed|Connection refused|Connection closed|timed out", text)
|
||||||
|
if re.search(r"Permission denied", text) and not forward:
|
||||||
self.fail("login", self.explain(text) or "The headset didn't accept this computer's key.", text)
|
self.fail("login", self.explain(text) or "The headset didn't accept this computer's key.", text)
|
||||||
return "stop"
|
return "stop"
|
||||||
if step == "connected":
|
if step == "connected":
|
||||||
@@ -1141,8 +1145,15 @@ def devices_action(link, body, open_setup, busy=lambda: 0):
|
|||||||
|
|
||||||
|
|
||||||
def next_alias(link):
|
def next_alias(link):
|
||||||
taken = {d["alias"] for d in link.reg.devices()} | {b["alias"] for b in frame_devices.parse_blocks(
|
"""A free alias for a new headset: not one Frame Control knows, nor any `Host` name
|
||||||
frame_devices.read_config())}
|
already in ~/.ssh/config (Set Up Connection's block would shadow it)."""
|
||||||
|
text = frame_devices.read_config()
|
||||||
|
taken = {d["alias"] for d in link.reg.devices()} | {b["alias"] for b in frame_devices.parse_blocks(text)}
|
||||||
|
taken |= {a for a in (link.session_alias, link.override, link.active_device().get("alias")) if a}
|
||||||
|
for line in text.splitlines():
|
||||||
|
f = line.split()
|
||||||
|
if f and f[0].lower() == "host":
|
||||||
|
taken |= {name for name in f[1:] if not any(c in name for c in "*?!")}
|
||||||
if "frame" not in taken:
|
if "frame" not in taken:
|
||||||
return "frame"
|
return "frame"
|
||||||
n = 2
|
n = 2
|
||||||
|
|||||||
Reference in new issue
Block a user