arch-ops-server 3.0.1__py3-none-any.whl → 3.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,189 @@
1
+ # SPDX-License-Identifier: GPL-3.0-only OR MIT
2
+ """
3
+ System health check module.
4
+ Provides a comprehensive system health check by integrating multiple system diagnostics.
5
+ """
6
+
7
+ import logging
8
+ from typing import Dict, Any
9
+
10
+ from .utils import IS_ARCH
11
+ from . import (
12
+ get_system_info,
13
+ check_disk_space,
14
+ check_failed_services,
15
+ get_pacman_cache_stats,
16
+ check_updates_dry_run,
17
+ check_critical_news,
18
+ list_orphan_packages,
19
+ check_database_freshness,
20
+ check_mirrorlist_health
21
+ )
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+
26
+ async def run_system_health_check() -> Dict[str, Any]:
27
+ """
28
+ Run a comprehensive system health check.
29
+
30
+ This function integrates multiple system diagnostics to provide a complete
31
+ overview of the system's health status in a single call.
32
+
33
+ Returns:
34
+ Dict with comprehensive health check results
35
+ """
36
+ logger.info("Starting comprehensive system health check")
37
+
38
+ health_report = {
39
+ "status": "success",
40
+ "system_info": {},
41
+ "disk_space": {},
42
+ "services": {},
43
+ "pacman_cache": {},
44
+ "updates": {},
45
+ "news": {},
46
+ "orphans": {},
47
+ "database": {},
48
+ "mirrors": {},
49
+ "issues": [],
50
+ "suggestions": []
51
+ }
52
+
53
+ try:
54
+ # System information
55
+ logger.info("Checking system information")
56
+ system_info = await get_system_info()
57
+ health_report["system_info"] = system_info
58
+
59
+ # Disk space check
60
+ logger.info("Checking disk space")
61
+ disk_space = await check_disk_space()
62
+ health_report["disk_space"] = disk_space
63
+
64
+ # Check for low disk space
65
+ if disk_space.get("status") == "success":
66
+ for partition in disk_space.get("data", []):
67
+ if partition.get("used_percent", 0) > 90:
68
+ health_report["issues"].append({
69
+ "type": "critical",
70
+ "message": f"Low disk space on {partition['mount_point']}: {partition['used_percent']}% used",
71
+ "suggestion": "Clean up unnecessary files or resize the partition"
72
+ })
73
+ elif partition.get("used_percent", 0) > 80:
74
+ health_report["issues"].append({
75
+ "type": "warning",
76
+ "message": f"Disk space getting low on {partition['mount_point']}: {partition['used_percent']}% used",
77
+ "suggestion": "Consider cleaning up files to free up space"
78
+ })
79
+
80
+ # Failed services check
81
+ logger.info("Checking for failed services")
82
+ failed_services = await check_failed_services()
83
+ health_report["services"] = failed_services
84
+
85
+ if failed_services.get("status") == "success" and failed_services.get("data"):
86
+ health_report["issues"].append({
87
+ "type": "warning",
88
+ "message": f"{len(failed_services['data'])} failed systemd services detected",
89
+ "suggestion": "Check systemd journal logs for details about failed services"
90
+ })
91
+
92
+ # Pacman cache statistics
93
+ logger.info("Checking pacman cache")
94
+ cache_stats = await get_pacman_cache_stats()
95
+ health_report["pacman_cache"] = cache_stats
96
+
97
+ if cache_stats.get("status") == "success":
98
+ cache_size = cache_stats.get("data", {}).get("total_size_mb", 0)
99
+ if cache_size > 5000: # 5GB
100
+ health_report["suggestions"].append({
101
+ "message": f"Pacman cache is large ({cache_size:.1f}MB)",
102
+ "action": "Run 'paccache -r' to clean old packages"
103
+ })
104
+
105
+ # Updates check
106
+ logger.info("Checking for available updates")
107
+ updates = await check_updates_dry_run()
108
+ health_report["updates"] = updates
109
+
110
+ if updates.get("status") == "success":
111
+ if updates.get("updates_available"):
112
+ count = updates.get("count", 0)
113
+ health_report["suggestions"].append({
114
+ "message": f"{count} updates available",
115
+ "action": "Run 'sudo pacman -Syu' to update the system"
116
+ })
117
+
118
+ # Critical news check
119
+ logger.info("Checking for critical news")
120
+ critical_news = await check_critical_news()
121
+ health_report["news"] = critical_news
122
+
123
+ if critical_news.get("status") == "success" and critical_news.get("data"):
124
+ health_report["issues"].append({
125
+ "type": "critical",
126
+ "message": f"{len(critical_news['data'])} critical news items require attention",
127
+ "suggestion": "Review the news items before updating"
128
+ })
129
+
130
+ # Orphan packages check
131
+ logger.info("Checking for orphan packages")
132
+ orphans = await list_orphan_packages()
133
+ health_report["orphans"] = orphans
134
+
135
+ if orphans.get("status") == "success":
136
+ orphan_count = len(orphans.get("data", []))
137
+ if orphan_count > 0:
138
+ health_report["suggestions"].append({
139
+ "message": f"{orphan_count} orphan packages detected",
140
+ "action": "Run 'sudo pacman -Rns $(pacman -Qtdq)' to remove orphans"
141
+ })
142
+
143
+ # Database freshness
144
+ logger.info("Checking database freshness")
145
+ db_freshness = await check_database_freshness()
146
+ health_report["database"] = db_freshness
147
+
148
+ # Mirrorlist health
149
+ logger.info("Checking mirrorlist health")
150
+ mirror_health = await check_mirrorlist_health()
151
+ health_report["mirrors"] = mirror_health
152
+
153
+ if mirror_health.get("status") == "success":
154
+ if not mirror_health.get("data", {}).get("healthy", True):
155
+ health_report["issues"].append({
156
+ "type": "warning",
157
+ "message": "Mirrorlist configuration has issues",
158
+ "suggestion": "Run 'reflector' to update your mirrorlist"
159
+ })
160
+
161
+ # Overall health assessment
162
+ issue_count = len(health_report["issues"])
163
+ suggestion_count = len(health_report["suggestions"])
164
+
165
+ health_report["summary"] = {
166
+ "total_issues": issue_count,
167
+ "critical_issues": len([i for i in health_report["issues"] if i["type"] == "critical"]),
168
+ "warnings": len([i for i in health_report["issues"] if i["type"] == "warning"]),
169
+ "suggestions": suggestion_count
170
+ }
171
+
172
+ logger.info(f"Health check completed: {issue_count} issues, {suggestion_count} suggestions")
173
+
174
+ return health_report
175
+
176
+ except Exception as e:
177
+ logger.error(f"Health check failed: {e}")
178
+ return {
179
+ "status": "error",
180
+ "error": str(e),
181
+ "issues": [],
182
+ "suggestions": [],
183
+ "summary": {
184
+ "total_issues": 1,
185
+ "critical_issues": 1,
186
+ "warnings": 0,
187
+ "suggestions": 0
188
+ }
189
+ }