Sanitized mirror from private repository - 2026-04-05 11:58:57 UTC
This commit is contained in:
93
dashboard/api/routers/olares.py
Normal file
93
dashboard/api/routers/olares.py
Normal file
@@ -0,0 +1,93 @@
|
||||
"""Olares K3s pod listing and GPU status."""
|
||||
|
||||
import subprocess
|
||||
from fastapi import APIRouter, Query
|
||||
|
||||
router = APIRouter(tags=["olares"])
|
||||
|
||||
|
||||
def _ssh_olares(cmd: str, timeout: int = 10) -> str:
|
||||
"""Run a command on olares via SSH."""
|
||||
result = subprocess.run(
|
||||
["ssh", "-o", "ConnectTimeout=3", "olares", cmd],
|
||||
capture_output=True, text=True, timeout=timeout,
|
||||
)
|
||||
return result.stdout if result.returncode == 0 else ""
|
||||
|
||||
|
||||
@router.get("/olares/pods")
|
||||
def olares_pods(namespace: str | None = Query(None)):
|
||||
"""List K3s pods on olares."""
|
||||
if namespace:
|
||||
cmd = f"kubectl get pods -n {namespace} -o wide --no-headers"
|
||||
else:
|
||||
cmd = "kubectl get pods -A -o wide --no-headers"
|
||||
|
||||
output = _ssh_olares(cmd, timeout=15)
|
||||
if not output:
|
||||
return []
|
||||
|
||||
pods = []
|
||||
for line in output.strip().split("\n"):
|
||||
parts = line.split()
|
||||
if not parts:
|
||||
continue
|
||||
if namespace:
|
||||
# No namespace column when -n is used
|
||||
if len(parts) >= 7:
|
||||
pods.append({
|
||||
"namespace": namespace,
|
||||
"name": parts[0],
|
||||
"ready": parts[1],
|
||||
"status": parts[2],
|
||||
"restarts": parts[3],
|
||||
"age": parts[4],
|
||||
"ip": parts[5] if len(parts) > 5 else "",
|
||||
"node": parts[6] if len(parts) > 6 else "",
|
||||
})
|
||||
else:
|
||||
# Has namespace column
|
||||
if len(parts) >= 8:
|
||||
pods.append({
|
||||
"namespace": parts[0],
|
||||
"name": parts[1],
|
||||
"ready": parts[2],
|
||||
"status": parts[3],
|
||||
"restarts": parts[4],
|
||||
"age": parts[5],
|
||||
"ip": parts[6] if len(parts) > 6 else "",
|
||||
"node": parts[7] if len(parts) > 7 else "",
|
||||
})
|
||||
return pods
|
||||
|
||||
|
||||
@router.get("/olares/gpu")
|
||||
def olares_gpu():
|
||||
"""GPU status from olares."""
|
||||
output = _ssh_olares(
|
||||
"nvidia-smi --query-gpu=name,temperature.gpu,power.draw,power.limit,"
|
||||
"memory.used,memory.total,utilization.gpu --format=csv,noheader,nounits"
|
||||
)
|
||||
if not output:
|
||||
return {"available": False}
|
||||
|
||||
parts = [p.strip() for p in output.strip().split(",")]
|
||||
|
||||
def _float(val: str) -> float | None:
|
||||
try:
|
||||
return float(val)
|
||||
except (ValueError, TypeError):
|
||||
return None
|
||||
|
||||
if len(parts) >= 7:
|
||||
return {
|
||||
"available": True,
|
||||
"name": parts[0],
|
||||
"temp_c": _float(parts[1]),
|
||||
"power_draw_w": _float(parts[2]),
|
||||
"power_limit_w": _float(parts[3]),
|
||||
"memory_used_mb": _float(parts[4]),
|
||||
"memory_total_mb": _float(parts[5]),
|
||||
"utilization_pct": _float(parts[6]),
|
||||
}
|
||||
return {"available": False}
|
||||
Reference in New Issue
Block a user