mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 06:00:33 +02:00
Devices: fixes from review round 19
- A switch the server refuses no longer drops answers the page is waiting for (an install's job id): only an actual change of headset does. - Test now goes through a jump host when the alias uses one. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
c3e3f2629c
commit
6597a90059
3 files changed
+20
-5
No files matched your search
+11
-1
@@ -382,7 +382,7 @@ class Connecting(unittest.TestCase):
|
|||||||
self.assertEqual(rows["::1"]["ssh"], "wrong")
|
self.assertEqual(rows["::1"]["ssh"], "wrong")
|
||||||
self.assertEqual(rows["nothing.invalid"]["state"], "unresolved")
|
self.assertEqual(rows["nothing.invalid"]["state"], "unresolved")
|
||||||
self.assertEqual(self.routes, [])
|
self.assertEqual(self.routes, [])
|
||||||
self.assertTrue(all("ControlPath=none" in c for c in self.calls()))
|
self.assertTrue(all("ControlPath=none" in c for c in self.calls() if "-G" not in c))
|
||||||
|
|
||||||
def test_switching_to_a_headset_that_never_answers_stops_using_the_last_one(self):
|
def test_switching_to_a_headset_that_never_answers_stops_using_the_last_one(self):
|
||||||
self.device("localhost")
|
self.device("localhost")
|
||||||
@@ -483,6 +483,16 @@ class Connecting(unittest.TestCase):
|
|||||||
self.assertIsNotNone(proc.poll())
|
self.assertIsNotNone(proc.poll())
|
||||||
self.assertIsNone(self.link.master)
|
self.assertIsNone(self.link.master)
|
||||||
|
|
||||||
|
def test_test_now_goes_through_a_jump_host(self):
|
||||||
|
d = self.device("10.99.99.99")
|
||||||
|
self.pin(d["id"])
|
||||||
|
self.hosts({"10.99.99.99": "ok"})
|
||||||
|
with mock.patch.object(fl, "ssh_g", return_value=("frame-t", 22, "steamos", True)):
|
||||||
|
self.link.test(d["id"])
|
||||||
|
row = self.link.snapshot()["tests"][d["id"]]["rows"][0]
|
||||||
|
self.assertEqual(row["ssh"], "ok", row)
|
||||||
|
self.assertIn("jump host", row["detail"])
|
||||||
|
|
||||||
def test_devices_api_checks_everything(self):
|
def test_devices_api_checks_everything(self):
|
||||||
d = self.device("localhost")
|
d = self.device("localhost")
|
||||||
bad = [{"action": "address-add", "id": d["id"], "host": "-oProxyCommand=touch /tmp/x"},
|
bad = [{"action": "address-add", "id": d["id"], "host": "-oProxyCommand=touch /tmp/x"},
|
||||||
|
|||||||
+9
-3
@@ -926,12 +926,18 @@ class Link:
|
|||||||
put()
|
put()
|
||||||
net = self.state["network"] or {}
|
net = self.state["network"] or {}
|
||||||
|
|
||||||
|
proxied = ssh_g(device["alias"])[3]
|
||||||
|
|
||||||
def one(i, a):
|
def one(i, a):
|
||||||
res = probe(a["host"], device["port"], update=lambda **f: (rows[i].update(f), put()))
|
if proxied: # through a jump host: a direct probe says nothing, ssh itself is the test
|
||||||
|
res = {"state": "answered", "detail": "Through a jump host", "ip": None, "rtt_ms": None}
|
||||||
|
else:
|
||||||
|
res = probe(a["host"], device["port"], update=lambda **f: (rows[i].update(f), put()))
|
||||||
rows[i].update({k: res.get(k) for k in ("state", "detail", "ip", "rtt_ms")})
|
rows[i].update({k: res.get(k) for k in ("state", "detail", "ip", "rtt_ms")})
|
||||||
put()
|
put()
|
||||||
if res["state"] != "answered":
|
if res["state"] != "answered":
|
||||||
return
|
return
|
||||||
|
lead = f"Answered in {res['rtt_ms']:g} ms" if res.get("rtt_ms") is not None else "Through the jump host"
|
||||||
rows[i]["ssh"] = "checking"
|
rows[i]["ssh"] = "checking"
|
||||||
put()
|
put()
|
||||||
argv = [*self.mux_base[:3], "-o", "ControlPath=none", "-o", "ConnectTimeout=8",
|
argv = [*self.mux_base[:3], "-o", "ControlPath=none", "-o", "ConnectTimeout=8",
|
||||||
@@ -942,10 +948,10 @@ class Link:
|
|||||||
errors="replace", timeout=20)
|
errors="replace", timeout=20)
|
||||||
err = r.stderr.strip()
|
err = r.stderr.strip()
|
||||||
if r.returncode == 0:
|
if r.returncode == 0:
|
||||||
rows[i].update(ssh="ok", detail=f"Answered in {res['rtt_ms']:g} ms · SSH works")
|
rows[i].update(ssh="ok", detail=f"{lead} · SSH works")
|
||||||
self.reg.record_success(device_id, a["host"], net.get("id"), res["rtt_ms"])
|
self.reg.record_success(device_id, a["host"], net.get("id"), res["rtt_ms"])
|
||||||
elif UNKNOWN.search(err):
|
elif UNKNOWN.search(err):
|
||||||
rows[i].update(ssh="unpinned", detail=f"Answered in {res['rtt_ms']:g} ms · identity not saved yet")
|
rows[i].update(ssh="unpinned", detail=f"{lead} · identity not saved yet")
|
||||||
elif CHANGED.search(err):
|
elif CHANGED.search(err):
|
||||||
rows[i].update(ssh="wrong", detail="Answered as a different headset")
|
rows[i].update(ssh="wrong", detail="Answered as a different headset")
|
||||||
elif DENIED.search(err):
|
elif DENIED.search(err):
|
||||||
|
|||||||
@@ -2676,7 +2676,6 @@ $("devSel").onchange = e => useDevice(e.target.value);
|
|||||||
async function useDevice(id) {
|
async function useDevice(id) {
|
||||||
const d = dv.list.find(x => x.id === id);
|
const d = dv.list.find(x => x.id === id);
|
||||||
if (!d || d.active) return;
|
if (!d || d.active) return;
|
||||||
devGen++; // from here on, answers about the last headset are dropped
|
|
||||||
const res = await act(`Switch to ${d.name}`, () => api("/api/devices", { action: "use", id }));
|
const res = await act(`Switch to ${d.name}`, () => api("/api/devices", { action: "use", id }));
|
||||||
if (!res) { // refused (an install is running): show the headset still in use
|
if (!res) { // refused (an install is running): show the headset still in use
|
||||||
const current = dv.list.find(x => x.active);
|
const current = dv.list.find(x => x.active);
|
||||||
|
|||||||
Reference in new issue
Block a user