diff --git a/HISTORY/2026-08-06-first-deploy.md b/HISTORY/2026-08-06-first-deploy.md new file mode 100644 index 0000000..5ec3360 --- /dev/null +++ b/HISTORY/2026-08-06-first-deploy.md @@ -0,0 +1,32 @@ +# 2026-08-06 — Первый деплой Flask (v1.0.0) + +## Хронология + +### 09:41 — Деплой v1.0.0 +- `gitPath`: `https://gitea.services.ngcloud.ru/Nail/tf_registry.git` +- `app.py`: минимальный Flask, `GET /` → `

tf_registry v1.0.0

` + +### Ошибка: Init:Error +``` +Cloning into '/tmp/app'... +fatal: could not read Username for 'https://gitea.services.ngcloud.ru' +``` +Причина: gitea — приватный репо, managed-сервис не имеет кредов для git clone. +Предыдущий деплой работал на `github.com/Foxyhhd/Baldurs-Gate-test.git` (публичный). + +### Решение +Репозиторий сделан публичным → передеплой → успешно. + +### Результат +`https://registry.pythonk8s.dev.nubes.ru/` → `tf_registry v1.0.0` ✅ + +## Далее + +По плану (`HISTORY/2026-08-06-plan-review.md`, `plan.md`): + +1. **Git-реорганизация** — `git checkout -b golang` (архив Go), удалить Go-код из master +2. **Полный `app.py`** — все 7 роутов (discovery, versions, download, proxy, docs, healthz, readyz) +3. **Проверка** — curl + terraform init + +## Урок +- gitea.services.ngcloud.ru — приватный. Либо сделать репо публичным, либо вшить `user:token@` в gitPath. diff --git a/HISTORY/plan-sonnet-full.md b/HISTORY/plan-sonnet-full.md new file mode 100644 index 0000000..a663ecb --- /dev/null +++ b/HISTORY/plan-sonnet-full.md @@ -0,0 +1,123 @@ +# Plan: Flask Registry — tf_registry (ПОЛНЫЙ ОРИГИНАЛ) + +> Создан на основе CHAT_SUMMARY_2026-08-06.md + анализа Go-кода. +> Сохранён из session-памяти в постоянный HISTORY. + +## TL;DR +Переписать Go-реестр (`server/main.go`) на Python/Flask для деплоя как managed-сервис в облаке. +Логика 1:1 — те же эндпоинты, та же S3-структура, тот же GPG-ключ. + +--- + +## Анализ Go-кода + +### ENV-переменные (те же в Flask): +| Переменная | По умолчанию | +|---|---| +| `REGISTRY_HOSTNAME` | `localhost:8080` | +| `S3_ENDPOINT` | — | +| `S3_ACCESS_KEY` | — | +| `S3_SECRET_KEY` | — | +| `S3_BUCKET` | `terraform-registry` | + +### S3-структура путей (ключи): +``` +Провайдер: {hostname}/{namespace}/{name}/{version}/terraform-provider-{name}_{version}_{os}_{arch}.zip +SHA256: {hostname}/{namespace}/{name}/{version}/terraform-provider-{name}_{version}_SHA256SUMS +Подпись: {hostname}/{namespace}/{name}/{version}/terraform-provider-{name}_{version}_SHA256SUMS.sig +Docs: docs/{namespace}/{name}/{version}/{path} +``` + +### Эндпоинты: +| Метод | URL | Что делает | +|---|---|---| +| GET | `/.well-known/terraform.json` | Discovery: `{"providers.v1": "/v1/providers/"}` | +| GET | `/v1/providers/{ns}/{name}/versions` | Список версий + платформ из S3 | +| GET | `/v1/providers/{ns}/{name}/{ver}/download/{os}/{arch}` | JSON с URL для скачивания | +| GET | `/v1/proxy?bucket=...&key=...` | Стриминг файла из S3 | +| GET | `/docs/{ns}/{name}/{ver}/...` | Статика документации из S3 | +| GET | `/healthz`, `/readyz` | Отвечают "ok" 200 | +| GET | `/` | HTML-страница "ONLINE" | + +### Платформы (listVersions): +Только два паттерна из имён файлов (в исходниках): +- `_linux_amd64.zip` → `{os: linux, arch: amd64}` +- `_windows_amd64.zip` → `{os: windows, arch: amd64}` + +> ⚠️ Живой Go-деплой также отдаёт `darwin_amd64` — operator собрал более новую версию. + +### GPG-ключ: +Жёстко зашит в `registrykeys/public_key.go`: +- `KeyID = "CB3A0DF161ECC416"` (legacy) +- `ASCIIArmor = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n..."` +Flask просто возвращает его как строку в JSON — **никакого python-gnupg не нужно**. + +> ⚠️ Живой Go-деплой отдаёт ДВА ключа: основной `3EC4673EB798238A` + legacy `CB3A0DF161ECC416`. + +### Прокси: +Параметры: `?bucket=...&key=...` (НЕ `?url=...` — в chat summary ошибка). +Стримит файл через `Response(stream_with_context(...))`. + +### Docs: +Кандидаты S3-ключей (в порядке попытки): +1. `docs/{ns}/{name}/{ver}/{rest}` (точный путь) +2. `docs/{ns}/{name}/{ver}/{rest}/index.html` (если нет расширения) +3. `docs/{ns}/{name}/{ver}/index.html` (fallback) +MIME по расширению файла. + +--- + +## Файлы для создания: + +``` +tf_registry/ +├── site/ +│ └── app.py # ~300 строк, весь Flask +└── requirements.txt # flask, boto3 +``` + +## Шаги: + +### Фаза 1 — Git-реорганизация (опционально) +1. `git checkout -b golang` — сохранить Go-код +2. `git checkout master` +3. Удалить: `server/`, `operator/`, `k8s/`, `charts/`, `scripts/`, `registrykeys/`, `REGISTRY_OVERVIEW.md` +4. Оставить: `site/app.py`, `requirements.txt`, `README.md` + +### Фаза 2 — Flask app.py + +**Структура app.py:** +1. Импорты: `flask`, `boto3`, `os`, `mimetypes`, `io` +2. Конфиг из ENV (5 переменных выше) +3. S3-клиент: `boto3.client('s3', endpoint_url=..., aws_access_key_id=..., aws_secret_access_key=...)` +4. GPG_KEY_ID и GPG_ASCII_ARMOR — константы +5. Роуты в точном соответствии с таблицей выше + +### Фаза 3 — Проверка +1. `python -m py_compile site/app.py` +2. Деплой в managed-сервис `registry` через UI +3. `curl /.well-known/terraform.json` +4. `curl /v1/providers/nubes-test/nubes/versions` +5. `terraform init` с новым `source` + +--- + +## Решения: +- GPG: только публичный ключ в JSON, никакой криптографии в Flask +- Прокси: `?bucket=&key=` (не `?url=`) +- Платформы: linux_amd64 + windows_amd64 (как в исходниках Go) → + darwin (как в живом деплое) +- Домен: `registry.pythonk8s.dev.nubes.ru` +- S3_PREFIX: `registry.kube5s.ru` (S3-ключи под старым хостнеймом) + +## Исключено из scope: +- Operator (остаётся в ветке golang) +- K8s-манифесты +- Docker-образы +- Docs-сервер как отдельный деплоймент + +## Расхождения исходники vs живой деплой (обнаружены при проверке): +| Что | Исходники | Живой Go | +|-----|-----------|----------| +| Платформы | linux, windows | linux, windows, **darwin** | +| GPG-ключи | 1 ключ (CB3A0D...) | **2 ключа** (3EC467... + CB3A0D...) | +| `id` в versions | `nubes-test/nubes` | `registry.kube5s.ru/nubes-test/nubes` |