Say which machine is unreachable instead of FIX FAILED

The Bible TV PC's Wi-Fi dropped for ~30 s at 06:17 on 2026-10-11; the
hold could not reach it and showed FIX FAILED, though nothing on the PC
was broken. An ssh fix that cannot reach its machine now shows e.g.
"BIBLE APP NOT REACHABLE".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-11 06:20:02 -04:00
co-authored by Claude Opus 5.5
parent ae28bb3c6d
commit 3417f00f1b
2 changed files with 16 additions and 1 deletions
+5
View File
@@ -1553,6 +1553,11 @@ def execute_fix(cfg, fix_id, chk):
wake_on_lan(host["mac"], host.get("wake_broadcast")) wake_on_lan(host["mac"], host.get("wake_broadcast"))
log.info("FIX %s -> %s does not answer: Wake-on-LAN sent to %s", label, fix["host"], host["mac"]) log.info("FIX %s -> %s does not answer: Wake-on-LAN sent to %s", label, fix["host"], host["mac"])
return WAKING return WAKING
if r.returncode == 255 and kind == "ssh":
# The machine itself is off the network (e.g. the Bible TV PC's Wi-Fi dropped,
# 2026-10-11): say so instead of a bare FIX FAILED.
log.info("FIX %s -> %s not reachable: %s", label, fix["host"], detail)
return "%s NOT\nREACHABLE" % fix.get("short", fix["host"].upper())
log.info("FIX %s -> %s%s", label, "ok" if r.returncode == 0 else "exit %d" % r.returncode, log.info("FIX %s -> %s%s", label, "ok" if r.returncode == 0 else "exit %d" % r.returncode,
(": " + detail) if detail else "") (": " + detail) if detail else "")
conn = chk.get("conn") or fix.get("conn") conn = chk.get("conn") or fix.get("conn")
+11 -1
View File
@@ -838,7 +838,8 @@ class TestFixes(unittest.TestCase):
mock.patch.object(sp, "wake_on_lan", side_effect=lambda mac, bc=None: woke.append((mac, bc))): mock.patch.object(sp, "wake_on_lan", side_effect=lambda mac, bc=None: woke.append((mac, bc))):
self.assertEqual(sp.execute_fix(CONFIG, "obs", {"conn": "OBS-Youtube"}), sp.WAKING) self.assertEqual(sp.execute_fix(CONFIG, "obs", {"conn": "OBS-Youtube"}), sp.WAKING)
self.assertEqual(woke, [("6c:24:08:d7:fb:57", "10.1.255.255")]) self.assertEqual(woke, [("6c:24:08:d7:fb:57", "10.1.255.255")])
self.assertFalse(sp.execute_fix(CONFIG, "arena", {"conn": "arena"})) # no MAC: just fails self.assertEqual(sp.execute_fix(CONFIG, "arena", {"conn": "arena"}), # no MAC: says so
"ARENA NOT\nREACHABLE")
self.assertEqual(len(woke), 1) self.assertEqual(len(woke), 1)
# the button says so # the button says so
self.snap.conns["OBS-Youtube"]["category"] = "error" self.snap.conns["OBS-Youtube"]["category"] = "error"
@@ -848,6 +849,15 @@ class TestFixes(unittest.TestCase):
time.sleep(0.2) time.sleep(0.2)
self.assertEqual(self.engine.step(self.snap, time.time())["obs"]["x"], "OBS\nWAKING PC\nOBS") self.assertEqual(self.engine.step(self.snap, time.time())["obs"]["x"], "OBS\nWAKING PC\nOBS")
def test_an_unreachable_pc_is_named_not_failed(self):
from unittest import mock
gone = mock.Mock(returncode=255, stdout="", stderr="ssh: connect to host 10.6.7.13 port 22: Operation timed out")
with mock.patch.object(sp.subprocess, "run", return_value=gone):
self.assertEqual(sp.execute_fix(CONFIG, "bibleapp", {}), "BIBLE APP NOT\nREACHABLE")
refused = mock.Mock(returncode=1, stdout="", stderr="") # reached it, the command failed
with mock.patch.object(sp.subprocess, "run", return_value=refused):
self.assertFalse(sp.execute_fix(CONFIG, "bibleapp", {}))
def test_magic_packet(self): def test_magic_packet(self):
from unittest import mock from unittest import mock
with mock.patch.object(sp.socket, "socket") as sock: with mock.patch.object(sp.socket, "socket") as sock: