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
+14 -17
View File
@@ -73,12 +73,15 @@ class HealthCheckTest(unittest.TestCase):
self.assertIn(['ip', 'link', 'set', 'wlan0mon', 'up'], [r[0] for r in self.runs])
self.assertEqual(result['monitor_fixes'], 1)
def test_down_with_growing_sigsegv_disables_pool(self):
def test_down_restarts_pineapd_without_rewriting_uci(self):
self.ping_ok = False
self.sigsegs = 5
self.uci_state['pineapd.@ssidpool[0].ssid'] = 'QmVlcg=='
result = server.health_check()
self.assertIn('pool broadcast disabled', result['last_action'])
self.assertEqual(self.uci_state['pineapd.@ssidpool[0].disable'], '1')
self.assertEqual(result['last_action'], 'pineapd restart')
self.assertNotIn('pineapd.@ssidpool[0].disable', self.uci_state)
self.assertEqual(self.uci_state['pineapd.@ssidpool[0].ssid'], 'QmVlcg==')
self.assertFalse(any(r[0][:2] == ['uci', 'set'] for r in self.runs))
self.assertIn(['/etc/init.d/pineapd', 'restart'], [r[0] for r in self.runs])
self.assertEqual(result['fixes'], 1)
@@ -94,21 +97,15 @@ class HealthCheckTest(unittest.TestCase):
self.assertEqual(result['last_action'], 'pineapd restart')
self.assertIn(['/etc/init.d/pineapd', 'restart'], [r[0] for r in self.runs])
def test_down_stabilizes_known_crash_sources(self):
self.ping_ok = False
self.uci_state['pineapd.@ssidpool[0].disable'] = '1'
result = server.health_check()
self.assertEqual(self.uci_state['pineapd.wlan2mon.disable'], '1')
self.assertEqual(self.uci_state['pineapd.wlan1mon.bands'], '5')
self.assertIn('stabilized', result['last_action'])
def test_down_clears_refilled_pool_list(self):
def test_down_does_not_stabilize_or_clear_pool(self):
self.ping_ok = False
self.uci_state['pineapd.@ssidpool[0].disable'] = '1'
self.uci_state['pineapd.@ssidpool[0].ssid'] = 'QmVlcg=='
result = server.health_check()
self.assertNotIn('pineapd.@ssidpool[0].ssid', self.uci_state)
self.assertIn('pool-list cleared', result['last_action'])
self.assertEqual(result['last_action'], 'pineapd restart')
self.assertEqual(self.uci_state['pineapd.@ssidpool[0].ssid'], 'QmVlcg==')
self.assertNotIn('pineapd.wlan2mon.disable', self.uci_state)
self.assertNotIn('pineapd.wlan1mon.bands', self.uci_state)
def test_down_without_crash_brings_monitors_up(self):
self.ping_ok = False
@@ -118,12 +115,12 @@ class HealthCheckTest(unittest.TestCase):
self.assertEqual(result['last_action'], 'monitor interfaces brought up')
self.assertIn(['ip', 'link', 'set', 'wlan1mon', 'up'], [r[0] for r in self.runs])
def test_down_disables_pool_regardless_of_sigsegv_history(self):
def test_down_does_not_disable_pool_regardless_of_sigsegv_history(self):
self.ping_ok = False
server._health['sigsegv_last'] = 4
result = server.health_check()
self.assertIn('SSID pool broadcast disabled', result['last_action'])
self.assertEqual(self.uci_state['pineapd.@ssidpool[0].disable'], '1')
self.assertEqual(result['last_action'], 'pineapd restart')
self.assertNotIn('pineapd.@ssidpool[0].disable', self.uci_state)
def test_fix_cooldown_prevents_thrash(self):
self.ping_ok = False