Files
KindClustersDashboard/app/core/readme_doc.py
Sergey Antropoff c1e867a01f Веб-UI: логи kind create, старт/стоп кластеров, документация README
- Потоковые логи в job_store и UI; kind create через Popen с построчным выводом
- POST /clusters/{name}/start|stop; create по сохранённому kind-config.yaml
- Страница /documentation: GET /api/v1/docs/readme, marked+DOMPurify из static/vendor
- Иконки действий, плавающие подсказки, модалка подтверждения вместо confirm
- Makefile: make docker|podman rebuild; compose: монтирование README.md
- Dockerfile: COPY README.md; readme_doc: несколько путей к README

Автор: Сергей Антропов — https://devops.org.ru
2026-04-04 06:21:00 +03:00

89 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Чтение README.md для API ``GET /api/v1/docs/readme`` и страницы «Документация».
Разметка Markdown преобразуется в браузере: ``/static/js/vendor/marked.min.js`` и
``purify.min.js`` (файлы входят в репозиторий, без CDN).
Путь к файлу: ``KIND_K8S_README_PATH`` или ``README.md`` в корне рядом с ``app/``;
в Docker-образе — ``/opt/kind-k8s/README.md``.
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
from __future__ import annotations
import logging
import os
from pathlib import Path
logger = logging.getLogger("kind_k8s.readme_doc")
# app/core/readme_doc.py: parents[2] = корень репозитория (рядом с app/) или /opt/kind-k8s в образе
_LIB_FILE = Path(__file__).resolve()
def _candidates_without_env() -> list[Path]:
"""
Возможные пути к README без KIND_K8S_README_PATH.
Порядок: родитель каталога app/ (типично репозиторий), затем фиксированный путь образа.
В compose рекомендуется монтировать ./README.md → /opt/kind-k8s/README.md (см. docker-compose.yml).
"""
out: list[Path] = []
seen: set[Path] = set()
try:
repo_readme = (_LIB_FILE.parents[2] / "README.md").resolve()
if repo_readme not in seen:
seen.add(repo_readme)
out.append(repo_readme)
except (IndexError, OSError):
pass
fixed = Path("/opt/kind-k8s/README.md")
try:
fixed_r = fixed.resolve()
if fixed_r not in seen:
seen.add(fixed_r)
out.append(fixed_r)
except OSError:
out.append(fixed)
return out
def get_readme_path() -> Path | None:
"""Первый существующий путь к README или ``None``."""
raw = (os.environ.get("KIND_K8S_README_PATH") or "").strip()
if raw:
p = Path(raw).expanduser().resolve()
return p if p.is_file() else None
for p in _candidates_without_env():
if p.is_file():
return p
return None
def read_readme_text() -> str:
"""Прочитать README как UTF-8; ``FileNotFoundError`` если файла нет."""
raw = (os.environ.get("KIND_K8S_README_PATH") or "").strip()
if raw:
p = Path(raw).expanduser().resolve()
if not p.is_file():
logger.warning("KIND_K8S_README_PATH: файл не найден: %s", p)
raise FileNotFoundError(str(p))
text = p.read_text(encoding="utf-8")
logger.debug("README из KIND_K8S_README_PATH, %s символов", len(text))
return text
for p in _candidates_without_env():
if p.is_file():
text = p.read_text(encoding="utf-8")
logger.info("README прочитан: %s (%s символов)", p, len(text))
return text
logger.warning(
"README.md не найден. Проверены пути: %s. "
"В Docker Compose добавьте монтирование ./README.md:/opt/kind-k8s/README.md "
"или пересоберите образ (COPY README.md в Dockerfile).",
[str(x) for x in _candidates_without_env()],
)
raise FileNotFoundError("README.md")