doc: HISTORY/README-NEW-CHAT.md — полная история для нового чата

This commit is contained in:
“Naeel”
2026-08-06 12:27:22 +04:00
parent 5ed2948abb
commit 857a632f55
+205
View File
@@ -0,0 +1,205 @@
# tf_registry — Полная история (для нового чата)
> **Дата**: 2026-08-06
> **Проект**: Переписываем Go-реестр Terraform-провайдеров на Python/Flask (managed-сервис Nubes)
> **Репозиторий**: `https://gitea.services.ngcloud.ru/Nail/tf_registry.git` (master)
> **Управляемый сервис**: `registry` (instanceUid: `309fdf08-8544-407f-96bd-91c8ae70baf8`)
> **URL**: `https://registry.pythonk8s.dev.nubes.ru`
---
## 1. Контекст
### Что такое реестр
Свой реестр Terraform-провайдеров для `nubes` (кастомный провайдер NGCloud). Работает по HashiCorp Provider Registry Protocol.
### Как было (Go)
- Go-сервер в K8s (личный кластер `iot-naeel`, ВМ `5.172.178.213`)
- Домен: `registry.kube5s.ru`
- S3: `s3.msk-1.ngcloud.ru`, бакет `terraform-registry`
- Креды S3: Secret `s3-credentials` в namespace `terra`
### Как стало/становится (Flask)
- Managed-сервис Nubes `pythonk8s`
- Домен: `registry.pythonk8s.dev.nubes.ru`
- Тот же S3
---
## 2. Структура проекта (как сейчас в master)
```
tf_registry/
├── site/
│ └── app.py # Flask-приложение (7 роутов)
├── requirements.txt # flask, boto3
├── secrets/
│ └── env.txt # S3-креды + jsonEnv (в .gitignore)
├── HISTORY/ # Документация
│ ├── plan-sonnet-full.md
│ ├── 2026-08-06-plan-review.md
│ └── 2026-08-06-first-deploy.md
├── .gitignore # secrets/, __pycache__/
├── server/ # [LEGACY] Go-код (оставлен для справки)
├── operator/ # [LEGACY]
├── k8s/ # [LEGACY]
├── charts/ # [LEGACY]
├── registrykeys/ # [LEGACY] GPG-ключ (устарел!)
└── scripts/ # [LEGACY]
```
### Ключевое правило Nubes для Flask
```
repo/
├── requirements.txt
└── site/
└── app.py ← точка входа, `app.run(host="0.0.0.0", port=5000)`
```
- **НЕЛЬЗЯ** `site/__init__.py` — конфликтует со stdlib
- **НЕЛЬЗЯ** factory pattern — платформа ждёт `app` на уровне модуля
- **НЕЛЬЗЯ** `from site.xxx import` — импорт без префикса
---
## 3. Эндпоинты (все реализованы)
| # | Маршрут | Что делает |
|---|---|---|
| 1 | `GET /.well-known/terraform.json` | `{"providers.v1": "/v1/providers/"}` |
| 2 | `GET /v1/providers/{ns}/{name}/versions` | Список версий + платформы из S3 |
| 3 | `GET /v1/providers/{ns}/{name}/{ver}/download/{os}/{arch}` | JSON: download_url, shasums, сигнатуры, GPG |
| 4 | `GET /v1/proxy?bucket=...&key=...` | Стриминг файла из S3 |
| 5 | `GET /docs/{ns}/{name}/{ver}/...` | Статика из S3 (кандидаты ключей) |
| 6 | `GET /healthz`, `GET /readyz` | `"ok"` 200 |
| 7 | `GET /` | HTML с версией |
---
## 4. Конфигурация (jsonEnv в UI)
```json
{
"REGISTRY_HOSTNAME": "registry.pythonk8s.dev.nubes.ru",
"S3_ENDPOINT": "s3.msk-1.ngcloud.ru",
"S3_ACCESS_KEY": "0GLQRD38H4I6RBDB0EWJ",
"S3_SECRET_KEY": "eTFibiHmBd96IApj9PYsboTR6OBoD7osxoarHykw",
"S3_BUCKET": "terraform-registry"
}
```
### Параметры managed-сервиса (appConfiguration)
```json
{
"gitPath": "https://gitea.services.ngcloud.ru/Nail/tf_registry.git",
"version": "3.12",
"healthPath": ""
}
```
---
## 5. Ключевые детали реализации
### S3_PREFIX vs HOSTNAME
```python
HOSTNAME = os.getenv("REGISTRY_HOSTNAME", "localhost:8080") # для URL
S3_PREFIX = "registry.kube5s.ru" # для S3-ключей (старый Go-хостнейм!)
```
S3-ключи лежат под `registry.kube5s.ru/...`, а managed-домен — `registry.pythonk8s.dev.nubes.ru`. Поэтому S3-префикс жёстко `registry.kube5s.ru`.
### S3-клиент (boto3 + MinIO)
```python
s3 = boto3.client(
"s3",
endpoint_url=f"https://{S3_ENDPOINT}",
config=Config(signature_version="s3v4"), # важно для MinIO
use_ssl=True,
)
```
### Пагинация S3
Используется `get_paginator("list_objects_v2")` — не `list_objects_v2` напрямую (макс 1000).
### Платформы
Обнаруживаются по имени файла: `_darwin_amd64.zip`, `_linux_amd64.zip`, `_windows_amd64.zip`.
### GPG-ключи (ДВА — из живого Go-деплоя!)
```python
GPG_PRIMARY_KEY_ID = "3EC4673EB798238A" # основной (живой деплой)
GPG_LEGACY_KEY_ID = "CB3A0DF161ECC416" # старый (из исходников)
```
Оба возвращаются в `signing_keys.gpg_public_keys`.
### Docs-кандидаты (1:1 с Go)
```
/docs/{ns}/{name}/{ver}/style.css
1) docs/{ns}/{name}/{ver}/style.css (exact)
2) НЕ пробует style.css/index.html (есть расширение .css)
3) docs/{ns}/{name}/{ver}/index.html (fallback)
/docs/{ns}/{name}/{ver}/folder/
1) docs/{ns}/{name}/{ver}/folder/ (exact)
2) docs/{ns}/{name}/{ver}/folder/index.html (заканчивается на /)
3) docs/{ns}/{name}/{ver}/index.html (fallback)
```
### Content-Length при стриминге
`head_object``ContentLength` → выставляется в заголовках.
### Порядок роутов
`/` — ПОСЛЕДНИЙ, иначе перехватит `/docs/`.
---
## 6. История деплоев
| # | Коммит | Что | Результат |
|---|---|---|---|
| 1 | `7c2b030` | Минимальный Flask (только `/`) | ❌ Init:Error — gitea приватный |
| 2 | — | Репо сделан публичным, редеплой | ✅ `tf_registry v1.0.0` |
| 3 | `3fa15cd` | Полный Flask (7 роутов) | ✅ Страница ONLINE, API — пустые versions |
| 4 | `a89b1f1` | Fix: S3_PREFIX, GPG, darwin | ⏳ Ожидает редеплоя |
| 5 | `f8f6343` | Версия на главной | ⏳ |
| 6 | `5ed2948` | HISTORY-документация | ✅ |
---
## 7. Текущий статус (последний пуш: `5ed2948`)
- app.py: написан, проверен `py_compile`, все 7 роутов ✅
- S3_PREFIX: `registry.kube5s.ru`
- GPG: 2 ключа из живого Go ✅
- Платформы: darwin + linux + windows ✅
- Версия на главной: `v1.0.0`
- **НУЖЕН РЕДЕПЛОЙ** через UI → проверить `versions` и `download`
---
## 8. Что дальше
1. Редеплой через UI
2. Проверить `curl /.well-known/terraform.json`
3. Проверить `curl /v1/providers/nubes-test/nubes/versions` — должны быть версии
4. Проверить `curl /v1/providers/nubes-test/nubes/5.1.16/download/linux/amd64` — shasum не пустой
5. `terraform init` с `source = "registry.pythonk8s.dev.nubes.ru/nubes-test/nubes"`
---
## 9. Как продолжить в новом чате
1. Открыть workspace `~/tf_registry`
2. Прочитать этот файл
3. `git pull` (на всякий случай)
4. Сказать: «Продолжаем tf_registry Flask-реестр. Контекст в HISTORY/README-NEW-CHAT.md»
---
## 10. Правила проекта
- После каждого коммита → сразу push
- Перед каждым коммитом → `python3 -m py_compile site/app.py`
- `gitPath` в UI: `https://gitea.services.ngcloud.ru/Nail/tf_registry.git`
- Репо должен быть публичным (или вшить токен в gitPath)
- Кубер — только через ВМ: `ssh naeel@5.172.178.213`
- Не удалять Go-файлы — оставлены для справки
- S3_PREFIX = `registry.kube5s.ru` (НЕ managed-домен!)