fix: harden UI actions and daemon calls for reliable control (v1.3.2)

Retry and serialize pineapd/hak5 calls, queue virtual-pager keys, and grey out buttons until the pager finishes. Deploy now installs python3-light after factory firmware. Bump version to 1.3.2.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-20 15:49:10 -05:00
co-authored by Cursor
parent cd26553d21
commit 7d48b7ad06
25 changed files with 3625 additions and 782 deletions
+19 -13
View File
@@ -106,15 +106,19 @@ class EnvCheckTest(unittest.TestCase):
self.assertEqual(server.ENV_CHECK_STATE['pool_runtime'], 'disabled')
self.assertNotIn(['_pineap', 'SSIDPOOL', 'DISABLE'], self.runs)
def test_applies_sane_defaults_when_missing(self):
def test_warns_sane_defaults_when_missing_without_mutating(self):
self.uci_state['pineapd.@ssidpool[0].ssid'] = 'QmVlcg=='
report = server.env_check()
self.assertEqual(self.steps(report, 'sane-off UCI defaults applied')[0]['ok'], 'fixed')
self.assertEqual(
self.steps(report, 'runtime safety settings changed')[0]['ok'],
'fixed')
self.assertIn(['/etc/init.d/pineapd', 'restart'], self.runs)
for key, value in server.PINEAPD_SAFE_UCI.items():
self.assertEqual(self.uci_state[key], value)
self.steps(report, 'live PineAP UCI left unchanged')[0]['ok'], 'warn')
self.assertNotIn(['/etc/init.d/pineapd', 'restart'], self.runs)
self.assertNotIn(['/etc/init.d/pineapd', 'stop'], self.runs)
self.assertFalse(any(a[:2] == ['uci', 'set'] for a in self.runs))
self.assertFalse(any(a[:2] == ['uci', 'commit'] for a in self.runs))
self.assertFalse(any(a[:2] == ['uci', 'delete'] for a in self.runs))
self.assertEqual(self.uci_state['pineapd.@ssidpool[0].ssid'], 'QmVlcg==')
for key in server.PINEAPD_SAFE_UCI:
self.assertNotIn(key, self.uci_state)
def test_uci_pass_when_already_set(self):
self.safe_set()
@@ -213,17 +217,19 @@ class EnvCheckTest(unittest.TestCase):
report = server.env_check()
self.assertEqual(self.steps(report, 'no radio0 AP pins wlan0mon')[0]['ok'], 'pass')
def test_sta_uplink_disabled_when_enabled(self):
def test_sta_uplink_warns_when_enabled_without_mutating(self):
self.safe_set()
self.uci_state['wireless.dummy_radio0.mode'] = 'sta'
self.uci_state['wireless.dummy_radio0.ifname'] = 'wlan0'
self.uci_state['wireless.dummy_radio0.disabled'] = '0'
report = server.env_check()
self.assertEqual(self.steps(report, 'dummy_radio0 STA uplink disabled')[0]['ok'], 'fixed')
self.assertEqual(self.uci_state['wireless.dummy_radio0.disabled'], '1')
self.assertIn(['ip', 'link', 'set', 'wlan0', 'down'], self.runs)
self.assertNotIn(['wifi', 'reload'], self.runs,
'STA fix must not bounce the radios')
self.assertEqual(self.steps(report, 'dummy_radio0 STA uplink is enabled')[0]['ok'], 'warn')
self.assertEqual(self.uci_state['wireless.dummy_radio0.disabled'], '0')
self.assertNotIn(['ip', 'link', 'set', 'wlan0', 'down'], self.runs)
self.assertNotIn(['wifi', 'reload'], self.runs)
self.assertFalse(any(
a[:2] == ['uci', 'set'] and 'dummy_radio0' in a[2]
for a in self.runs if len(a) > 2))
def test_sta_uplink_pass_when_absent(self):
self.safe_set()