fix: show LXC storage in --dry-run summary #25
@@ -1038,6 +1038,10 @@ class SystemHealthMonitor:
|
||||
if health_report['system_health']['issues']:
|
||||
logger.info(f"\nSystem Issues: {len(health_report['system_health']['issues'])} found")
|
||||
|
||||
# LXC container storage (previously omitted from the dry-run summary; issue #23)
|
||||
for line in self._format_lxc_dry_run(health_report.get('lxc_health', {})):
|
||||
logger.info(line)
|
||||
|
||||
# PBS status
|
||||
pbs = health_report.get('pbs_health', {})
|
||||
if pbs.get('is_pbs_node'):
|
||||
@@ -3998,6 +4002,31 @@ class SystemHealthMonitor:
|
||||
logger.error(f"Failed to write Prometheus metrics: {e}")
|
||||
return False
|
||||
|
||||
def _format_lxc_dry_run(self, lxc_health: Dict[str, Any]) -> List[str]:
|
||||
"""Build the LXC-storage lines for the --dry-run summary.
|
||||
|
||||
The LXC storage check runs in every mode, but its results were previously
|
||||
absent from the dry-run summary output, making it look like LXC storage was
|
||||
not checked (issue #23). Returns a list of log lines (possibly empty).
|
||||
"""
|
||||
lines: List[str] = []
|
||||
containers = lxc_health.get('containers', [])
|
||||
if containers:
|
||||
lines.append("\nLXC Storage:")
|
||||
warn = self.CONFIG['THRESHOLDS']['LXC_WARNING']
|
||||
for c in containers:
|
||||
for fs in c.get('filesystems', []):
|
||||
flag = "⚠️ " if fs.get('usage_percent', 0) >= warn else ""
|
||||
lines.append(
|
||||
f" {flag}CT{c['vmid']} {fs['mountpoint']}: "
|
||||
f"{fs['usage_percent']:.1f}% used"
|
||||
)
|
||||
if lxc_health.get('issues'):
|
||||
lines.append(f" Issues: {len(lxc_health['issues'])} found")
|
||||
elif lxc_health.get('status') == 'ERROR':
|
||||
lines.append(f"\nLXC Storage: check error ({len(lxc_health.get('issues', []))} issue(s))")
|
||||
return lines
|
||||
|
||||
def _check_lxc_storage(self) -> Dict[str, Any]:
|
||||
"""
|
||||
Check storage utilization for all running LXC containers
|
||||
|
||||
@@ -503,3 +503,36 @@ class TestAttributeThresholds:
|
||||
"""Age is still *tracked* (just not ticketed) — new-drive detection must work."""
|
||||
assert monitor._is_new_drive(100) is True # ~4 days
|
||||
assert monitor._is_new_drive(64860) is False # ~7.4 years
|
||||
|
||||
|
||||
# ── _format_lxc_dry_run (LXC storage shown in --dry-run summary; issue #23) ────
|
||||
|
||||
class TestLxcDryRunSummary:
|
||||
def test_includes_container_usage_and_flags_over_threshold(self, monitor):
|
||||
"""Regression for issue #23: dry-run summary must surface LXC storage."""
|
||||
lxc = {
|
||||
'status': 'WARNING',
|
||||
'issues': ['LXC 105 high storage usage: 84.0% on /'],
|
||||
'containers': [
|
||||
{'vmid': '105', 'filesystems': [{'mountpoint': '/', 'usage_percent': 84.0}]},
|
||||
],
|
||||
}
|
||||
text = '\n'.join(monitor._format_lxc_dry_run(lxc))
|
||||
assert 'LXC Storage:' in text
|
||||
assert 'CT105 /' in text and '84.0% used' in text
|
||||
assert '⚠️' in text # flagged: over the 80% warning threshold
|
||||
assert 'Issues: 1 found' in text
|
||||
|
||||
def test_healthy_container_not_flagged(self, monitor):
|
||||
lxc = {'status': 'OK', 'issues': [],
|
||||
'containers': [{'vmid': '119', 'filesystems': [{'mountpoint': '/', 'usage_percent': 26.0}]}]}
|
||||
text = '\n'.join(monitor._format_lxc_dry_run(lxc))
|
||||
assert 'CT119 /' in text and '26.0% used' in text
|
||||
assert '⚠️' not in text
|
||||
|
||||
def test_empty_when_no_containers(self, monitor):
|
||||
assert monitor._format_lxc_dry_run({'status': 'OK', 'containers': [], 'issues': []}) == []
|
||||
|
||||
def test_error_status_is_reported(self, monitor):
|
||||
lines = monitor._format_lxc_dry_run({'status': 'ERROR', 'containers': [], 'issues': ['boom']})
|
||||
assert any('check error' in ln for ln in lines)
|
||||
|
||||
Reference in New Issue
Block a user