# Roadmap **Код v1 (§1–6) готов** (включая opt-in LLM, local-watchdog, access-card). Дальше — твой облачный прогон. Пользовательский путь: [setup.md](setup.md) → `doctor` → `up`. Чеклист живого GPU: [spike-notes.md](spike-notes.md). ## 0.0 Квота GPU - [ ] Квота GPU в панели ≥ 1 (иначе тикет — текст в setup §2.3) - [ ] Тикет закрыт / не нужен - [ ] Сервисный пользователь `member` + `.env` заполнен - [ ] `gpu-rent doctor` exit 0 `flavors` / `dry-run` — по желанию перед первым `up`. ## 0. Ручной spike в панели Заполняй [spike-notes.md](spike-notes.md). В коде уже есть idle-killer, hold, snapshot, tunnel-watchdog — spike **проверяет** на живом GPU, не пишет заново. - [ ] RC-файл, `doctor` зелёный, квота > 0 - [ ] `flavors` / образ Driver **580** без Docker в пуле - [ ] `up --yes` → Idle backend + seed; время ACTIVE/SSH/Idle - [ ] `tunnel` → UI :17801 + API; `nvidia-smi` - [ ] idle-killer timer + `hold`; качалка UI → только hold - [ ] EXPIRED → tunnel unshelve или `up` - [ ] `stop` → диски живы → второй `up` - [ ] Boot snapshot `gpu-rent-boot-ok` → следующий boot из него - [ ] ₽/час и ₽/мес диска из панели (в API нет) Заметки — только в spike-notes.md, без секретов. ## 1. Каркас - [x] `pyproject.toml`, пакет `gpu_rent`, MIT - [x] config / state / Typer: doctor, dry-run, status, open, up, stop, destroy, ssh, logs, tunnel, hold, seed-*, push, pull-output, resize-data, flavors - [x] Windows: `gpu-rent.bat` / `gpu-rent.ps1`; Unix: `gpu-rent.sh`; также `python -m gpu_rent` - [x] [setup.md](setup.md) — квота, сервисный пользователь, RC, Civitai ## 2. OpenStack-клиент - [x] Token через openstacksdk (`authorize`), inventory flavors/квота/volume type - [x] Сеть find-or-create, SG, FIP, volumes, server, unshelve - [x] Preemptible tag 2.72, BDM boot+data, `delete_on_termination=false` - [x] Flavor fallback по `FLAVOR_PREFERENCE` (ранжирование + выбор на `up`) - [x] `doctor`: Keystone, квота, flavor, диск, Civitai `.red`, манифесты - [x] Тесты с моками / без облака ## 3. Сессия без туннеля - [x] `up` / `stop` / `status` / reconcile (compute+диски+SSH+bootstrap SwarmUI) - [x] `status`: диск used/free (SSH), TTL preempt 24 ч, killer/hold; ₽/час — «смотри панель» - [x] Второй `up` не создаёт второй GPU - [x] `resize-data` вверх - [x] Генерация `/.gpu-rent/id_ed25519` + keypair при первом `up` - [x] `seed-models` на живом диске (идемпотентно, SHA256) - [x] `push` / `push-models`: `Models/`, `Wildcards/`, `CustomWorkflows/` - [x] `pull-output` и `PULL_OUTPUT` на `stop` / повторный `up` - [x] `seed-extensions` + `systemctl restart swarmui` - [x] `destroy` только с флагом ## 4. Bootstrap SwarmUI + idle-killer - [x] Идемпотентный first-boot, маркер FS (`/mnt/swarm_data/.gpu-rent-ready`) - [x] Bind-mounts data volume → `/opt/swarmui`, systemd `swarmui` (auth SwarmUI ещё на spike) - [x] Clone `extensions.yaml` в Extensions / DLNodes до старта UI - [x] Autocomplete: danbooru.csv + Settings.fds; на каждом up — GitHub sha - [x] Civitai seed по манифесту; без токена — дефолт SwarmUI - [x] systemd idle-killer + application credential; льгота 45 мин; hold-файл; очередь/loading = busy; затем 30 мин пустой очереди; вооружение после seed/start (качалка UI = hold) - [x] Один snapshot `gpu-rent-boot-ok` после первого backend Idle; следующие create — из snapshot если есть - [x] `gpu-rent hold` / `hold --clear` по SSH - [x] `ready` по HTTP, затем backend Idle ## 5. Туннель - [x] `gpu-rent tunnel` → 17801, Ctrl+C не делает `stop` - [x] `gpu-rent open` / `tunnel --open` - [x] EXPIRED → unshelve + reconnect, пока туннель жив - [x] Сниппет MCP в stdout ## 6. UX - [x] Живой список flavors (`gpu-rent flavors` / dry-run / up), `--no-spot`, печать фоллбека - [x] Оценка ₽ честно («смотри панель»), предупреждение про диск 24/7 и idle-killer - [x] `NOTIFY_READY`: Windows toast + звук при backend Idle - [x] Пользовательский README поверх `docs/` - [x] Opt-in LLM + `setup`; нумерованные меню; interactive Selectel plan (flavor/disk/spot) - [x] Цветной CLI-лог; `capture` ссылок с VM - [x] Local-watchdog; access-card ## Вне скоупа v1 - `generate` в CLI, S3 как источник моделей - Автоправка Cursor `mcp.json` - Несколько GPU, публичный URL, Terraform как основной путь - Tailscale (туннеля достаточно; к сети с телефона не подключались)