Веб-UI FastAPI, REST API v1, интерактивный setup без env.example
- Дашборд (Jinja2 + static), управление кластерами kind, задания и kubeconfig. - API: health, stats, clusters CRUD, versions, jobs; документация app/docs/api_routes.md. - Docker Compose: том app, uvicorn reload, KIND_K8S_PATCH_KUBECONFIG по умолчанию 1. - setup_env_interactive.py: список переменных в скрипте, удалён env.example. - Makefile: явный префикс docker/podman; прочие правки CLI и ядра кластеров.
This commit is contained in:
@@ -303,6 +303,37 @@ def read_meta_json(cluster_name: str) -> dict[str, object] | None:
|
||||
return None
|
||||
|
||||
|
||||
def _container_cli_bin() -> str:
|
||||
"""Имя CLI к сокету (docker / podman), как в kubeconfig_patch."""
|
||||
return (os.environ.get("CONTAINER_CLI") or "docker").strip() or "docker"
|
||||
|
||||
|
||||
def container_engine_ping(*, timeout_sec: float = 12.0) -> tuple[bool, str, str]:
|
||||
"""
|
||||
Проверить доступ к движку контейнеров (``docker info`` / ``podman info``).
|
||||
|
||||
Возвращает (успех, краткое сообщение или stderr, имя CLI).
|
||||
"""
|
||||
cli = _container_cli_bin()
|
||||
if not shutil.which(cli):
|
||||
return False, f"«{cli}» не найден в PATH", cli
|
||||
try:
|
||||
p = subprocess.run(
|
||||
[cli, "info"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=timeout_sec,
|
||||
)
|
||||
except subprocess.TimeoutExpired:
|
||||
logger.warning("%s info: таймаут %s с", cli, timeout_sec)
|
||||
return False, f"таймаут {timeout_sec} с", cli
|
||||
if p.returncode == 0:
|
||||
return True, "OK", cli
|
||||
err = (p.stderr or p.stdout or "").strip() or f"код {p.returncode}"
|
||||
logger.info("%s info неуспешно: %s", cli, err[:200])
|
||||
return False, err[:800], cli
|
||||
|
||||
|
||||
def kubectl_nodes_wide(*, kubeconfig: str | Path) -> tuple[int, str]:
|
||||
"""``kubectl get nodes -o wide``; возвращает (код, объединённый вывод)."""
|
||||
p = subprocess.run(
|
||||
@@ -325,6 +356,27 @@ def kubectl_nodes_wide(*, kubeconfig: str | Path) -> tuple[int, str]:
|
||||
return p.returncode, msg
|
||||
|
||||
|
||||
def kubectl_pods_all_namespaces(*, kubeconfig: str | Path) -> tuple[int, str]:
|
||||
"""``kubectl get pods -A``; сводка подов по кластеру."""
|
||||
p = subprocess.run(
|
||||
[
|
||||
"kubectl",
|
||||
"--kubeconfig",
|
||||
str(kubeconfig),
|
||||
"get",
|
||||
"pods",
|
||||
"-A",
|
||||
"--request-timeout=20s",
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
out = (p.stdout or "").strip()
|
||||
err = (p.stderr or "").strip()
|
||||
msg = out if out else err
|
||||
return p.returncode, msg
|
||||
|
||||
|
||||
def cluster_summary_for_api(name: str) -> dict[str, object]:
|
||||
"""Сводка по кластеру для JSON API (без блокирующих долгих вызовов)."""
|
||||
meta = read_meta_json(name) or {}
|
||||
|
||||
Reference in New Issue
Block a user