From f421ac1cb18ddd1683cf5b765618c1ef97aa9fbd Mon Sep 17 00:00:00 2001 From: MacRimi Date: Tue, 29 Sep 2026 20:56:02 +0200 Subject: [PATCH] fix(monitor): honour storage exclusions in the PVE storage capacity alert --- AppImage/scripts/health_monitor.py | 3 +++ AppImage/scripts/notification_manager.py | 3 ++- .../scripts/tests/test_benign_disk_notices.py | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/AppImage/scripts/health_monitor.py b/AppImage/scripts/health_monitor.py index 38bd237f..26d38470 100644 --- a/AppImage/scripts/health_monitor.py +++ b/AppImage/scripts/health_monitor.py @@ -6616,6 +6616,7 @@ class HealthMonitor: warn_pct, crit_pct = self._read_capacity_thresholds("pve_storage") available_storages = storage_status.get('available', []) or [] + excluded_names = health_persistence.get_excluded_storage_names('health') checks: Dict[str, Dict[str, Any]] = {} critical_labels: list[str] = [] warning_labels: list[str] = [] @@ -6631,6 +6632,8 @@ class HealthMonitor: continue pct = (used / total) * 100 name = st.get('name', 'unknown') + if name in excluded_names: + continue label = f'{name} ({stype})' entry = { 'detail': f'{pct:.1f}% used', diff --git a/AppImage/scripts/notification_manager.py b/AppImage/scripts/notification_manager.py index 8dcb4ca1..2b68d298 100644 --- a/AppImage/scripts/notification_manager.py +++ b/AppImage/scripts/notification_manager.py @@ -1277,7 +1277,8 @@ class NotificationManager: # Check storage exclusions for storage-related events. # If the storage is excluded from notifications, suppress the event entirely. - _STORAGE_EVENTS = {'storage_unavailable', 'storage_low_space', 'storage_warning', 'storage_error'} + _STORAGE_EVENTS = {'storage_unavailable', 'storage_low_space', 'storage_warning', 'storage_error', + 'pve_storage_full'} if event.event_type in _STORAGE_EVENTS: storage_name = event.data.get('storage_name') or event.data.get('name') if storage_name: diff --git a/AppImage/scripts/tests/test_benign_disk_notices.py b/AppImage/scripts/tests/test_benign_disk_notices.py index e04afabc..00c6944f 100644 --- a/AppImage/scripts/tests/test_benign_disk_notices.py +++ b/AppImage/scripts/tests/test_benign_disk_notices.py @@ -45,6 +45,7 @@ class StorageUsageDetail(unittest.TestCase): persistence = health_monitor.health_persistence with patch.dict(sys.modules, {'proxmox_storage_monitor': module}), \ patch.object(health_monitor, 'PROXMOX_STORAGE_AVAILABLE', True), \ + patch.object(persistence, 'get_excluded_storage_names', return_value=set()), \ patch.object(persistence, 'is_error_acknowledged', return_value=False), \ patch.object(persistence, 'record_error'), \ patch.object(persistence, 'get_active_errors', return_value=[]): @@ -52,6 +53,27 @@ class StorageUsageDetail(unittest.TestCase): entry = result['checks']['PBS-Cloud (pbs)'] self.assertEqual((entry['status'], entry['detail']), ('WARNING', '92.4% used')) + def test_a_storage_excluded_from_health_is_not_checked(self): + # Excluded in Health -> Exclusions, it raises nothing and its earlier + # error is cleared on the next cycle. + monitor = health_monitor.HealthMonitor.__new__(health_monitor.HealthMonitor) + monitor._read_capacity_thresholds = lambda section: (85, 95) + status = {'available': [{'name': 'Pluton', 'type': 'pbs', 'total': 1000, 'used': 860}]} + module = MagicMock() + module.proxmox_storage_monitor.get_storage_status.return_value = status + persistence = health_monitor.health_persistence + with patch.dict(sys.modules, {'proxmox_storage_monitor': module}), \ + patch.object(health_monitor, 'PROXMOX_STORAGE_AVAILABLE', True), \ + patch.object(persistence, 'get_excluded_storage_names', return_value={'Pluton'}), \ + patch.object(persistence, 'record_error') as record, \ + patch.object(persistence, 'clear_error') as clear, \ + patch.object(persistence, 'get_active_errors', + return_value=[{'error_key': 'pve_storage_full_Pluton'}]): + result = monitor._check_pve_storage_capacity() + self.assertIsNone(result) + record.assert_not_called() + clear.assert_called_once_with('pve_storage_full_Pluton') + class FstrimUnsupportedDevices(unittest.TestCase): def run_with(self, journal):