docker services real
This commit is contained in:
@@ -7,7 +7,7 @@ same 2s push interval. Services remain mocked until systemd integration is added
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import random
|
import subprocess
|
||||||
import time
|
import time
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -61,16 +61,41 @@ def _get_net_throughput() -> tuple[float, float]:
|
|||||||
return rx_kbps, tx_kbps
|
return rx_kbps, tx_kbps
|
||||||
|
|
||||||
|
|
||||||
def _mock_services() -> list[dict]:
|
def _get_docker_services() -> list[dict]:
|
||||||
"""Mocked service status — same logic as mock_server.py."""
|
"""Query Docker for real container statuses with ternary status model."""
|
||||||
return [
|
try:
|
||||||
{"name": "docker", "status": random.choice(["running", "running", "running", "stopped"])},
|
result = subprocess.run(
|
||||||
{"name": "pihole", "status": random.choice(["running", "running", "running", "stopped"])},
|
["docker", "ps", "-a", "--format", "{{.Names}}\t{{.Status}}"],
|
||||||
{"name": "nginx", "status": random.choice(["running", "running", "stopped"])},
|
capture_output=True, text=True, timeout=5,
|
||||||
{"name": "sshd", "status": "running"},
|
)
|
||||||
{"name": "ph1", "status": "running"},
|
except (subprocess.TimeoutExpired, FileNotFoundError, OSError):
|
||||||
{"name": "ph2", "status": "stopped"},
|
return []
|
||||||
]
|
|
||||||
|
if result.returncode != 0:
|
||||||
|
return []
|
||||||
|
|
||||||
|
services = []
|
||||||
|
for line in result.stdout.strip().splitlines():
|
||||||
|
parts = line.split("\t", 1)
|
||||||
|
if len(parts) != 2:
|
||||||
|
continue
|
||||||
|
name, raw_status = parts
|
||||||
|
|
||||||
|
if raw_status.startswith("Up"):
|
||||||
|
if "unhealthy" in raw_status or "Restarting" in raw_status:
|
||||||
|
status = "warning"
|
||||||
|
else:
|
||||||
|
status = "running"
|
||||||
|
else:
|
||||||
|
status = "stopped"
|
||||||
|
|
||||||
|
services.append({"name": name, "status": status})
|
||||||
|
|
||||||
|
# Sort: warnings first, then stopped, then running (problems float to top)
|
||||||
|
order = {"warning": 0, "stopped": 1, "running": 2}
|
||||||
|
services.sort(key=lambda s: order.get(s["status"], 3))
|
||||||
|
|
||||||
|
return services
|
||||||
|
|
||||||
|
|
||||||
def _local_time_fields() -> dict:
|
def _local_time_fields() -> dict:
|
||||||
@@ -100,7 +125,7 @@ def generate_stats() -> dict:
|
|||||||
"uptime_hrs": round((time.time() - psutil.boot_time()) / 3600, 1),
|
"uptime_hrs": round((time.time() - psutil.boot_time()) / 3600, 1),
|
||||||
"net_rx_kbps": rx_kbps / 8,
|
"net_rx_kbps": rx_kbps / 8,
|
||||||
"net_tx_kbps": tx_kbps / 8, # kByte/s for humans
|
"net_tx_kbps": tx_kbps / 8, # kByte/s for humans
|
||||||
"services": _mock_services(),
|
"services": _get_docker_services(),
|
||||||
"timestamp": int(time.time()),
|
"timestamp": int(time.time()),
|
||||||
"local_time": _local_time_fields(),
|
"local_time": _local_time_fields(),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user