proxy-monitor/app/docker_ops.py

125 lines
4.2 KiB
Python

import docker
_client = None
def _c():
global _client
if _client is None:
_client = docker.DockerClient(base_url="unix:///var/run/docker.sock", timeout=15)
return _client
def host_info():
try:
import shutil
client = _c()
info = client.info()
containers = client.containers.list(all=True, sparse=True)
running = sum(1 for c in containers if c.status == "running")
images = len(client.images.list())
mem_total = info.get("MemTotal", 0)
mem_used = 0
try:
with open("/proc/meminfo") as f:
mem = {}
for line in f.read().splitlines():
if ":" in line:
parts = line.split()
mem[parts[0].rstrip(":")] = int(parts[1]) * 1024
mem_total = mem.get("MemTotal", mem_total)
mem_used = mem_total - mem.get("MemAvailable", mem.get("MemFree", 0))
except Exception:
pass
disk_total = disk_used = 0
try:
d = shutil.disk_usage("/")
disk_total, disk_used = d.total, d.used
except Exception:
pass
return {
"name": info.get("Name", "?"),
"os": info.get("OperatingSystem", "?"),
"version": info.get("ServerVersion", "?"),
"kernel": info.get("KernelVersion", "?"),
"cpu": info.get("NCPU", 0),
"memory": mem_total,
"mem_used": mem_used,
"mem_total": mem_total,
"running": running,
"containers": len(containers),
"images": images,
"disk_total": disk_total,
"disk_used": disk_used,
"storage": info.get("DriverStatus", [["?", "?"]])[0][1] if info.get("DriverStatus") else "?",
"error": None,
}
except Exception as e:
return {"name": "?", "running": 0, "containers": 0, "images": 0, "error": str(e)}
def list_containers():
try:
client = _c()
return [
{
"id": c.short_id,
"name": c.name,
"image": c.image.tags[0] if c.image.tags else c.image.short_id[:19],
"status": c.status,
"ports": c.ports,
"created": c.attrs.get("Created", "")[:19],
}
for c in client.containers.list(all=True)
]
except Exception as e:
return {"error": str(e)}
def list_images():
try:
client = _c()
return [{"id": i.short_id, "tags": i.tags, "size": i.attrs.get("Size", 0)} for i in client.images.list()]
except Exception as e:
return {"error": str(e)}
def container_action(cid, action):
try:
client = _c()
c = client.containers.get(cid)
if action == "start":
c.start()
elif action == "stop":
c.stop(timeout=10)
elif action == "restart":
c.restart(timeout=10)
else:
return {"error": f"unknown action {action}"}
return {"status": f"{action}ed", "name": c.name}
except Exception as e:
return {"error": str(e)}
def container_stats(cid):
try:
client = _c()
c = client.containers.get(cid)
s = c.stats(stream=False)
mem_usage = s["memory_stats"].get("usage", 0)
mem_limit = s["memory_stats"].get("limit", 1)
cpu_delta = s["cpu_stats"]["cpu_usage"]["total_usage"] - s["precpu_stats"]["cpu_usage"]["total_usage"]
system_delta = s["cpu_stats"]["system_cpu_usage"] - s["precpu_stats"]["system_cpu_usage"]
cpu_percent = (cpu_delta / system_delta) * 100.0 * s["cpu_stats"].get("online_cpus", 1) if system_delta > 0 else 0
return {
"memory_usage": mem_usage,
"memory_limit": mem_limit,
"memory_pct": round(mem_usage / mem_limit * 100, 1) if mem_limit else 0,
"cpu_pct": round(cpu_percent, 1),
"pids": s["pids_stats"].get("current", 0),
"network_rx": s.get("networks", {}).get("eth0", {}).get("rx_bytes", 0),
"network_tx": s.get("networks", {}).get("eth0", {}).get("tx_bytes", 0),
}
except Exception as e:
return {"error": str(e)}