feat: add S3-backed documentation streaming service
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# Plan: tf_docs Node.js docs-display service + S3 upload redesign (redirect for big files)
|
||||
|
||||
TL;DR: docs (HTML/CSS/JS, обычно мелкие) стримятся через Node.js-сервис как раньше;
|
||||
любой файл, который либо не входит в whitelist расширений сайта, либо превышает
|
||||
порог размера (большие attachments/zip/pdf/видео), отдаётся через `302 Location`
|
||||
на прямой публичный S3 URL — байты через под в кластере не идут. Бакет `docs/*`
|
||||
уже задуман как public-read (mc policy public в DOCS_PIPELINE/publish-docs.sh),
|
||||
поэтому сервису не нужны S3-креды — только HTTP HEAD/GET к публичному bucket URL.
|
||||
|
||||
**Ответы пользователя (зафиксировано):**
|
||||
- Архитектура: redirect для больших файлов, HTML/CSS стримить через сервис (не полный redirect-only).
|
||||
- Бакет: публичный read, простой прямой URL (без presigned).
|
||||
- Публичный URL после перехода: "как лучше — так и делай" → решено: **site_url и текущая
|
||||
дружественная схема `https://tf-registry.containerk8s.services.ngcloud.ru/docs/<ns>/<name>/<version>/`
|
||||
НЕ меняются**, т.к. основная масса запросов (HTML/CSS/JS) всё равно идёт через сервис.
|
||||
- Объём работ по S3-заливке: восстановить `scripts/publish-docs.sh`, поправить `04_build_and_publish_docs.sh`
|
||||
при необходимости, гарантировать public policy — пользователь выбрал все три, но т.к. site_url не меняется,
|
||||
правка `04_build_and_publish_docs.sh`/mkdocs.yml не требуется (кроме проверки, что public policy сохраняется).
|
||||
|
||||
**Фаза 1 — tf_provider: восстановление заливки в S3**
|
||||
1. Восстановить `tf_provider/scripts/publish-docs.sh` на основе рабочей копии
|
||||
`tf_provider/DOCS_PIPELINE/publish-docs.sh` (тот же bucket `terraform-registry`,
|
||||
тот же префикс `docs/<namespace>/<name>/<version>/`, тот же `mc policy set public`).
|
||||
Это чинит разрыв, зафиксированный в `TMP/tf_provider_full_docs_pipeline_2026-09-02.md` (§7)
|
||||
и `tf_provider/HISTORY/2026-09-02_full_docs_pipeline_analysis.md`.
|
||||
2. Убедиться, что `.github/workflows/publish-docs.yml` и `TOOLS/scripts/04_build_and_publish_docs.sh`
|
||||
вызывают именно это имя файла (без изменений интерфейса).
|
||||
3. Конвенция для больших вложений (картинки/примеры/zip/pdf в `docs/curated/**`, `docs/30_registry/**`):
|
||||
класть их статическим файлом прямо в дерево `docs_dir` (mkdocs копирует не-markdown файлы
|
||||
в `site/` автоматически) — отдельного шага заливки не требуется, только структурная договорённость
|
||||
(например подпапка `attachments/` рядом со страницей).
|
||||
4. `mkdocs.yml` / `site_url` — БЕЗ ИЗМЕНЕНИЙ (см. решение выше).
|
||||
|
||||
**Фаза 2 — tf_docs: сам Node.js-сервис** (*зависит от подтверждения публичной policy бакета, иначе параллельно с Фазой 1*)
|
||||
5. Заменить заглушку в `tf_docs/server.js` (сейчас просто "hello" HTML) на роутер:
|
||||
- `GET /docs/:namespace/:name/:version/*rest` (+ вариант без rest → index).
|
||||
- `GET /healthz` → 200 для k8s-проб.
|
||||
6. Конфигурация через env (добавить в `tf_docs/package.json`/README):
|
||||
- `S3_PUBLIC_BASE_URL` (напр. `https://s3.msk-1.ngcloud.ru/terraform-registry`)
|
||||
- `PORT`, `CACHE_TTL_SECONDS` (по умолчанию 300)
|
||||
- `STREAM_MAX_BYTES` (по умолчанию 2_000_000)
|
||||
- `STREAM_EXTENSIONS` (по умолчанию: html,css,js,mjs,json,svg,png,jpg,jpeg,gif,ico,webp,woff,woff2,ttf,map,txt,xml)
|
||||
7. Маппинг пути → S3-ключ и fallback-цепочка (перенос правил из
|
||||
`tf_registry/HISTORY/docs-service-plan.md`): точный ключ → `<ключ>/index.html` → корневой `index.html`.
|
||||
Проверка существования — `HEAD` к `${S3_PUBLIC_BASE_URL}/<key>` (без SDK и кредов, т.к. бакет публичный).
|
||||
8. Ветвление по каждому разрешённому ключу:
|
||||
- расширение из `STREAM_EXTENSIONS` И размер (Content-Length из HEAD) ≤ `STREAM_MAX_BYTES`
|
||||
→ `GET`, стримить тело клиенту, `Content-Type` по расширению (fallback `text/html; charset=utf-8`
|
||||
для html/пусто, иначе `application/octet-stream`), `Cache-Control: public, max-age=<TTL>`,
|
||||
опциональный in-memory TTL-кэш по ключу+ETag.
|
||||
- иначе (большой файл или не-сайтовое расширение) → `302 Found`, `Location: ${S3_PUBLIC_BASE_URL}/<key>`,
|
||||
тело не читается вообще.
|
||||
- если ни один из fallback-ключей не резолвится (HEAD 404 везде) → 404.
|
||||
9. `tf_docs/Dockerfile` (node:18-alpine, `npm ci --omit=dev`, `CMD node server.js`) — свериться со стилем
|
||||
`tf_registry/Dockerfile` для консистентности образов.
|
||||
10. Ingress: путь `/docs/*` на хосте `tf-registry.containerk8s.services.ngcloud.ru` → сервис tf_docs;
|
||||
`/.well-known/*`, `/v1/providers/*`, `/v1/proxy` остаются на tf_registry (без изменений).
|
||||
|
||||
**Верификация**
|
||||
1. `node -c tf_docs/server.js` после каждой правки.
|
||||
2. Локально: поднять сервис с `S3_PUBLIC_BASE_URL` на реальный бакет, проверить curl:
|
||||
- маленькая html-страница → `200` с телом;
|
||||
- файл больше `STREAM_MAX_BYTES` или не из whitelist → `302` + корректный `Location`;
|
||||
- несуществующий путь → `404`.
|
||||
3. По аналогии с `tf_registry/tests/smoke.sh` — добавить smoke-скрипт для tf_docs.
|
||||
4. Перед релизом — проверить `mc policy get` (или эквивалент) на префиксе `docs/*`, что policy = public.
|
||||
|
||||
**Relevant files**
|
||||
- `tf_docs/server.js`, `tf_docs/package.json`, `tf_docs/README.md` — реализация сервиса.
|
||||
- `tf_docs/Dockerfile` — новый.
|
||||
- `tf_provider/scripts/publish-docs.sh` — восстановить (источник: `tf_provider/DOCS_PIPELINE/publish-docs.sh`).
|
||||
- `tf_provider/TOOLS/scripts/04_build_and_publish_docs.sh`, `.github/workflows/publish-docs.yml` — проверить вызов без изменений.
|
||||
- `tf_registry/HISTORY/docs-service-plan.md` — обновить (стриминг+кэш → гибрид stream/redirect по порогу).
|
||||
- `tf_registry/server/proxy.go` — референс уже применённого паттерна redirect-на-presigned-S3.
|
||||
|
||||
**Decisions**
|
||||
- Бакет `docs/*` публичный (mc policy public) → сервису не нужны S3 SDK/креды, только обычные HTTP HEAD/GET.
|
||||
- site_url и структура ссылок mkdocs не меняются — экономит объём правок, т.к. большинство запросов остаётся мелким HTML/CSS/JS.
|
||||
- Классификация "большой файл" — гибрид: whitelist расширений + порог размера (не только расширение), чтобы не полагаться на одно правило.
|
||||
- Конвенция вложений — положить статик-файлы прямо в `docs_dir` (без нового шага пайплайна).
|
||||
|
||||
**Further Considerations**
|
||||
1. Точное значение `STREAM_MAX_BYTES` и итоговый `S3_PUBLIC_BASE_URL` (path-style vs virtual-host style у Ceph RGW) — уточнить на этапе реализации/тестирования, не блокирует план.
|
||||
2. Нужен ли листинг версий/лендинг на tf_docs (как у registry `/v1/providers/*/versions`) — сейчас не включено в scope, можно добавить отдельным шагом при необходимости.
|
||||
Reference in New Issue
Block a user