import time import docker import httpx from fastapi import APIRouter from config import CC_CONNECT_URL, DOCKER_HOST router = APIRouter() client = docker.DockerClient(base_url=DOCKER_HOST, timeout=5) def _get_cc_connect_container(): matches = client.containers.list(all=True, filters={"name": "cc-connect"}) return matches[0] if matches else None @router.post("/start") def start_cc_connect(): try: container = _get_cc_connect_container() except Exception as exc: return { "ok": False, "status": "down", "container_status": None, "error": f"docker check failed: {exc}", } if not container: return { "ok": False, "status": "down", "container_status": "not_found", "error": "cc-connect container not found", } try: container.start() container.reload() container_status = container.status return { "ok": container_status == "running", "status": "up" if container_status == "running" else "down", "container_status": container_status, "error": None if container_status == "running" else "cc-connect failed to start", } except Exception as exc: return { "ok": False, "status": "down", "container_status": container.status, "error": f"docker start failed: {exc}", } @router.post("/stop") def stop_cc_connect(): try: container = _get_cc_connect_container() except Exception as exc: return { "ok": False, "status": "down", "container_status": None, "error": f"docker check failed: {exc}", } if not container: return { "ok": False, "status": "down", "container_status": "not_found", "error": "cc-connect container not found", } try: container.stop() container.reload() container_status = container.status return { "ok": container_status != "running", "status": "down", "container_status": container_status, "error": None if container_status != "running" else "cc-connect failed to stop", } except Exception as exc: return { "ok": False, "status": "down", "container_status": container.status, "error": f"docker stop failed: {exc}", } @router.get("/health") async def cc_connect_health(): url = (CC_CONNECT_URL or "").strip() container = None try: container = _get_cc_connect_container() except Exception as exc: return { "ok": False, "status": "down", "source": "docker", "container_name": None, "container_status": None, "endpoint": None, "http_status": None, "latency_ms": None, "error": f"docker check failed: {exc}", } container_name = container.name if container else None container_status = container.status if container else "not_found" container_up = container_status == "running" if not url: return { "ok": container_up, "status": "up" if container_up else "down", "source": "docker", "container_name": container_name, "container_status": container_status, "endpoint": None, "http_status": None, "latency_ms": None, "error": None if container_up else "cc-connect container is not running", } timeout = httpx.Timeout(2.0) started = time.perf_counter() try: async with httpx.AsyncClient(timeout=timeout) as http_client: response = await http_client.get(url) latency_ms = round((time.perf_counter() - started) * 1000, 1) if response.is_success and container_up: return { "ok": True, "status": "up", "source": "docker+http", "container_name": container_name, "container_status": container_status, "endpoint": url, "http_status": response.status_code, "latency_ms": latency_ms, "error": None, } if response.is_success and not container_up: return { "ok": False, "status": "down", "source": "docker+http", "container_name": container_name, "container_status": container_status, "endpoint": url, "http_status": response.status_code, "latency_ms": latency_ms, "error": "HTTP probe succeeded but cc-connect container is not running", } return { "ok": False, "status": "down", "source": "docker+http", "container_name": container_name, "container_status": container_status, "endpoint": url, "http_status": response.status_code, "latency_ms": latency_ms, "error": f"HTTP probe returned {response.status_code}", } except Exception as exc: return { "ok": False, "status": "down", "source": "docker+http", "container_name": container_name, "container_status": container_status, "endpoint": url, "http_status": None, "latency_ms": None, "error": str(exc), }