diff --git a/Makefile b/Makefile index 1d8f6b2..d040546 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,8 @@ # make docker up | make docker down | make docker logs | … # make podman up | make podman down | … # make docker rebuild / make podman rebuild — образ без кэша и пересоздание контейнера -# Без префикса docker/podman цели up/down/logs/ps/build/rebuild/check-docker/kubectl завершатся с подсказкой. +# make docker restart / make podman restart — перезапуск сервиса kind-k8s-web +# Без префикса docker/podman цели up/down/restart/logs/ps/build/rebuild/check-docker/kubectl завершатся с подсказкой. # # Автор: Сергей Антропов — https://devops.org.ru @@ -15,7 +16,7 @@ else ifneq (,$(filter docker,$(MAKECMDGOALS))) COMPOSE := docker compose endif -.PHONY: help docker podman _require_runtime up down logs ps setup clusters-dir check-docker build rebuild kubectl +.PHONY: help docker podman _require_runtime up down restart logs ps setup clusters-dir check-docker build rebuild kubectl KIND_K8S_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) SETUP_ENV_SCRIPT := $(KIND_K8S_DIR)/scripts/setup_env_interactive.py @@ -30,6 +31,7 @@ help: ## Справка по целям @echo "Веб-UI kind — только с выбором Docker или Podman в одной команде с целью:" @echo " make docker up или make podman up → http://127.0.0.1:\$${KIND_K8S_WEB_PORT:-8080}" @echo " make docker down / make podman down" + @echo " make docker restart / make podman restart (перезапуск kind-k8s-web)" @echo " make docker logs / make podman logs (follow -f)" @echo " make docker ps / make podman ps (статус сервисов)" @echo " make docker build / make podman build" @@ -50,7 +52,7 @@ _require_runtime: @if [ -z "$(COMPOSE)" ]; then \ echo >&2 "Укажите среду в той же команде, что и цель:"; \ echo >&2 " make docker up | make podman up"; \ - echo >&2 " make docker down | make docker logs | make docker ps | make docker build | make docker rebuild | make docker check-docker | make docker kubectl CLUSTER=…"; \ + echo >&2 " make docker down | make docker restart | make docker logs | make docker ps | make docker build | make docker rebuild | make docker check-docker | make docker kubectl CLUSTER=…"; \ echo >&2 " (или то же с префиксом podman)"; \ exit 1; \ fi @@ -61,6 +63,9 @@ up: _require_runtime clusters-dir build ## (с docker/podman) Поднять в down: _require_runtime ## (с docker/podman) Остановить compose в этом каталоге cd "$(KIND_K8S_DIR)" && $(COMPOSE) down +restart: _require_runtime ## (с docker/podman) Перезапустить контейнер kind-k8s-web + cd "$(KIND_K8S_DIR)" && $(COMPOSE) restart kind-k8s-web + logs: _require_runtime ## (с docker/podman) Логи kind-k8s-web (follow -f) cd "$(KIND_K8S_DIR)" && $(COMPOSE) logs -f kind-k8s-web diff --git a/README.md b/README.md index 3bb1dda..0373e49 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,10 @@ - Верхняя **единая карточка**: заголовок, краткое описание и строка **состояния среды** (`kind` / `kubectl` / Docker или Podman API). - **Статистика**: число кластеров в kind, локальных каталогов, сумма workers из `meta.json`, счётчики фоновых заданий. - **Создание кластера**: форма с подсказкой тегов `kindest/node` (`GET /api/v1/versions`), фоновое задание и опрос статуса (JSON в сворачиваемом блоке). -- **Таблица кластеров**: признаки регистрации в kind и наличия kubeconfig, скачивание kubeconfig, просмотр узлов/подов в модальном окне, удаление. -- **Последние задания** создания (данные в памяти процесса; после перезапуска контейнера история сбрасывается). +- **Таблица кластеров**: признаки регистрации в kind и наличия kubeconfig, **старт** и **стоп** узлов (фоновые задания с тем же журналом, что и при создании), скачивание kubeconfig, просмотр узлов/подов в модальном окне, удаление. +- **Последние задания**: история в памяти процесса (до **200** записей; после перезапуска контейнера сбрасывается); кнопка **«Очистить завершённые»** вызывает **`DELETE /api/v1/jobs`** (из памяти удаляются только завершённые задания). - **Автообновление** таблиц и плашки среды каждые ~3,5 с (fetch к API без перезагрузки страницы). -- При создании кластера — **прогресс-бар** и текст текущего этапа; кнопка **«Отменить создание»** (между этапами; шаг `kind create` до конца не прерывается). +- При активном задании — **прогресс-бар**, **журнал** (в т.ч. скачивание образа и длительные команды; для `docker pull` по умолчанию используется **`--progress=plain`**, см. **`KIND_K8S_DOCKER_PULL_PLAIN`**), опрос статуса чаще, чем общие таблицы; кнопка **«Отменить»** — прерывание с завершением текущей дочерней команды. - Уведомления (toast) при успехе/ошибке; в подвале — копирайт и ссылка на **devops.org.ru**. **Шапка:** навигация в виде **пилюль** (стили `.nav-pill`); пункты **Swagger**, **ReDoc** и **Health** открывают страницу в **отдельном именованном окне** (~1240×840), чтобы не уходить с панели (см. скрипт в `base.html`). @@ -63,7 +63,7 @@ make docker up # или: make podman up Из родительского каталога: `make -C <каталог-корня-репозитория> docker up` (подставьте путь к каталогу с `Makefile`). -**Логи, статус и остановка:** `make docker logs` / `make podman logs` (follow), `make docker ps` / `make podman ps`, `make docker down` / `make podman down`. +**Логи, статус, перезапуск и остановка:** `make docker logs` / `make podman logs` (follow), `make docker ps` / `make podman ps`, **`make docker restart` / `make podman restart`** (перезапуск сервиса `kind-k8s-web`), `make docker down` / `make podman down`. ### Разработка UI и API без пересборки образа @@ -115,6 +115,7 @@ docker compose exec kind-k8s-web kubectl --kubeconfig=/work/clusters/<имя>/ku | `make help` | Краткая справка | | `make docker up` / `make podman up` | Поднять веб-UI (`kind-k8s-web`) | | `make docker down` / `make podman down` | Остановить compose в каталоге репозитория | +| `make docker restart` / `make podman restart` | Перезапустить контейнер сервиса `kind-k8s-web` (`compose restart`) | | `make docker logs` / `make podman logs` | Логи `kind-k8s-web` (stream, `-f`) | | `make docker ps` / `make podman ps` | Статус контейнеров текущего compose-проекта | | `make docker build` / `make podman build` | Собрать образ `kind-k8s-tools:local` | @@ -123,9 +124,9 @@ docker compose exec kind-k8s-web kubectl --kubeconfig=/work/clusters/<имя>/ku | `make docker kubectl CLUSTER=…` / `make podman kubectl CLUSTER=…` | **kubectl** в контейнере `kind-k8s-web` (опционально `KUBECTL_ARGS="…"`; по умолчанию `get nodes`). Сервис должен быть **up**. | | `make setup` | Интерактивно создать `.env` (список переменных в `scripts/setup_env_interactive.py`) | | `make clusters-dir` | Создать каталог `clusters/` | -| `make docker …` / `make podman …` | Префикс **обязателен** для целей `up`, `down`, `logs`, `ps`, `build`, `rebuild`, `check-docker`, `kubectl` | +| `make docker …` / `make podman …` | Префикс **обязателен** для целей `up`, `down`, `restart`, `logs`, `ps`, `build`, `rebuild`, `check-docker`, `kubectl` | -Цели `up`, `down`, `logs`, `ps`, `build`, `rebuild`, `check-docker` и `kubectl` **без** `docker`/`podman` в той же команде завершатся с подсказкой. +Цели `up`, `down`, `restart`, `logs`, `ps`, `build`, `rebuild`, `check-docker` и `kubectl` **без** `docker`/`podman` в той же команде завершатся с подсказкой. ## Переменные окружения @@ -169,7 +170,7 @@ make podman up | Путь | Назначение | |------|------------| -| `Makefile` | Запуск веб-UI; префикс `docker` или `podman` обязателен; цели `up`, `rebuild`, `build` и др. | +| `Makefile` | Запуск веб-UI; префикс `docker` или `podman` обязателен; цели `up`, `down`, `restart`, `logs`, `rebuild`, `build` и др. | | `scripts/setup_env_interactive.py` | Интерактивное создание `.env` (все ключи и дефолты внутри скрипта) | | `scripts/run_uvicorn.sh` | Точка входа контейнера: uvicorn с опциональным `--reload` | | `Dockerfile` | Образ: kind, kubectl, docker-cli, FastAPI | @@ -203,5 +204,5 @@ make podman up - Образ `kindest/node:v…` должен быть доступен для pull. - На **Windows** без WSL удобнее WSL2 + Docker Desktop. - **kubectl** на хосте **не обязателен**: используйте веб-UI или **`make docker kubectl`** / **`make podman kubectl`** (см. выше). -- История заданий создания в UI/API хранится в памяти (до **200** записей); после перезапуска контейнера очищается. +- История заданий в UI/API хранится в памяти (до **200** записей); после перезапуска контейнера очищается. Завершённые записи можно удалить из памяти кнопкой на панели или **`DELETE /api/v1/jobs`**. - При **`exec format error`** у kind пересоберите образ: `make docker rebuild COMPOSE_BUILD_FLAGS=--platform linux/arm64` (или `make podman …`, или **`make docker build`** без `--no-cache`, или `linux/amd64`). diff --git a/app/docs/api_routes.md b/app/docs/api_routes.md index 26e222a..6c9eb80 100644 --- a/app/docs/api_routes.md +++ b/app/docs/api_routes.md @@ -19,14 +19,14 @@ | Маршрут | Описание | |---------|----------| -| `GET /` | HTML-панель: единая карточка «панель + среда», статистика, создание кластера (прогресс, **журнал** операции в реальном времени, **отмена** с прерыванием текущей команды), таблица кластеров с **иконками** действий и **всплывающими подсказками**, модалка узлов/подов; шапка — пилюли, Swagger / ReDoc / Health в отдельных окнах. | +| `GET /` | HTML-панель: единая карточка «панель + среда», статистика, создание кластера (прогресс, **журнал** в реальном времени, **«Отменить»** прерывает текущую команду), **старт/стоп** кластера с тем же журналом (фоновые **POST …/start** и **…/stop**), таблица **последних заданий** с кнопкой **«Очистить завершённые»** (**DELETE /api/v1/jobs**), модалка узлов/подов; шапка — пилюли, Swagger / ReDoc / Health в отдельных окнах. | | `GET /documentation` | HTML-оболочка; **`documentation.js`**: без `path` — **`GET /api/v1/docs/readme`**, с `?path=app/docs/…` — **`GET /api/v1/docs/file`**; разбор Markdown из **`/static/js/vendor/`** (marked, DOMPurify). Каждая секция по **H2** — **одна карточка** (заголовок h2 и содержимое до следующего h2 вместе). Заголовок вкладки браузера: **«Документация — …»** + текст **первого H1** документа + имя приложения (`KIND_K8S_APP_TITLE` на `body`). В шапке на этой странице активна только **Документация**; **Панель** как обычная пилюля (на дашборде активна **Панель**). Путь к README: `KIND_K8S_README_PATH` или `README.md` рядом с `app/`; в образе — `/opt/kind-k8s/README.md`. | | `GET /ui` | Редирект **307** на `/` (удобный ярлык). | | `GET /static/…` | CSS (`style.css`), скрипты панели (`js/dashboard.js`) и документации (`js/documentation.js`); базовый URL API задаётся атрибутом `data-api-base` на `` (по умолчанию `/api/v1`). | Шаблоны: `app/templates/base.html` (шапка, навигация), `app/templates/dashboard.html` (контент панели), `app/templates/documentation.html` (README). -**kubectl на хосте не обязателен:** бинарник есть в образе; узлы и поды доступны через API (**`GET /api/v1/clusters/{name}/workloads`**) и веб-UI. Для интерактивной консоли из корня репозитория при запущенном compose: **`make docker kubectl CLUSTER=<имя>`** (или **`make podman kubectl …`**), внутри контейнера kubeconfig — **`/work/clusters/<имя>/kubeconfig`**. Подробности — **README.md** (раздел «kubectl без установки на хост»). +**kubectl на хосте не обязателен:** бинарник есть в образе; узлы и поды доступны через API (**`GET /api/v1/clusters/{name}/workloads`**) и веб-UI. Для интерактивной консоли из корня репозитория при запущенном compose: **`make docker kubectl CLUSTER=<имя>`** (или **`make podman kubectl …`**), внутри контейнера kubeconfig — **`/work/clusters/<имя>/kubeconfig`**. Перезапуск только веб-сервиса без `down`/`up`: **`make docker restart`** / **`make podman restart`**. Подробности — **README.md**. ---