39 lines
1.6 KiB
Python
39 lines
1.6 KiB
Python
import httpx
|
|
from fastapi import APIRouter
|
|
from config import DOCKER_PROXY_URL
|
|
|
|
router = APIRouter()
|
|
|
|
@router.get("/containers")
|
|
async def list_containers():
|
|
async with httpx.AsyncClient() as c:
|
|
r = await c.get(f"{DOCKER_PROXY_URL}/containers/json", params={"all": "true"})
|
|
return [{"id": x["Id"][:12], "name": x["Names"][0].lstrip("/"), "state": x["State"],
|
|
"status": x["Status"], "image": x["Image"]} for x in r.json()]
|
|
|
|
@router.post("/containers/{container_id}/{action}")
|
|
async def container_action(container_id: str, action: str):
|
|
if action not in ("start", "stop", "restart"):
|
|
return {"error": "invalid action"}
|
|
async with httpx.AsyncClient() as c:
|
|
r = await c.post(f"{DOCKER_PROXY_URL}/containers/{container_id}/{action}")
|
|
return {"ok": r.status_code < 400}
|
|
|
|
@router.get("/containers/{container_id}/logs")
|
|
async def container_logs(container_id: str, tail: int = 200):
|
|
async with httpx.AsyncClient() as c:
|
|
r = await c.get(f"{DOCKER_PROXY_URL}/containers/{container_id}/logs",
|
|
params={"stdout": "true", "stderr": "true", "tail": str(tail), "timestamps": "true"})
|
|
# Strip docker stream header bytes (8 bytes per line)
|
|
lines = []
|
|
raw = r.content
|
|
i = 0
|
|
while i < len(raw):
|
|
if i + 8 <= len(raw):
|
|
size = int.from_bytes(raw[i+4:i+8], "big")
|
|
lines.append(raw[i+8:i+8+size].decode("utf-8", errors="replace"))
|
|
i += 8 + size
|
|
else:
|
|
break
|
|
return {"logs": "".join(lines)}
|