doc: полный план из session-памяти + расхождения исходники-vs-деплой
This commit is contained in:
@@ -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 /` → `<h1>tf_registry v1.0.0</h1>`
|
||||
|
||||
### Ошибка: 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.
|
||||
@@ -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` |
|
||||
Reference in New Issue
Block a user