Защита бэкапов от пустой БД пропускает БД без таблиц (счётчики «?») (#74) #100

Merged
NotBigGhost merged 1 commits from issue-74-backup-guard into dev 2026-09-30 13:04:37 +03:00
Collaborator

Что сделано

  1. guard_empty. Неизвестные счётчики ? (в БД нет таблиц users/matches) теперь дают отказ, как пустая БД: mark run-* err, понятный лог, подсказка про --allow-empty. Раньше такой снимок уходил в оба репозитория, становился latest, и restore latest --repo vps в сценарии «Pi умер» падал на verify_staging.
  2. entrypoint.sh. Перед самым первым бэкапом (локальных снимков ещё нет) контейнер ждёт /api/health приложения — не дольше BACKUP_APP_WAIT_SECONDS, по умолчанию 600 с. Health отвечает только после миграций и bootstrap. Не дождался — пробует всё равно, п. 1 не пропустит БД без таблиц. Зависимость в compose не добавлял: при восстановлении app остановлен, и depends_on: service_healthy не дал бы стартовать backup.
  3. README, раздел 9. Обновлены ожидаемые строки журнала при первом запуске на новом Pi. Совет смотреть list vps и выбирать снимок с числами остался: снимки с ? больше не создаются, но могли остаться от старой версии. Семантика restore latest не менялась.

Коммиты

  • f5f8dc0 Бэкапы: БД без таблиц не становится снимком, первый бэкап ждёт приложение

Проверки

Образ backup собран локально:

  • БД только с alembic_version (без users/matches) → fs-backup run → «в БД нет таблиц users/matches … ОШИБКА: fs-backup run --allow-empty», код 1, репозиторий даже не создан;
  • та же БД → run --allow-empty → снимок создан (обход работает);
  • копия dev-БД → run → снимок игроков 11, партий 24;
  • штатный entrypoint с BACKUP_APP_HOST=nonexistent-app, BACKUP_APP_WAIT_SECONDS=20 и пустым томом → «жду приложение (до 20 с)» → «не ответило за 20 с — пробую бэкап без него» → «Бэкап завершён» → расписание.

Отклонения от плана

Нет.

Closes #74

🤖 Generated with Claude Code

https://claude.ai/code/session_01LqSoRj99iwVEH5U5fnZgsd

## Что сделано 1. **`guard_empty`.** Неизвестные счётчики `?` (в БД нет таблиц `users`/`matches`) теперь дают отказ, как пустая БД: `mark run-* err`, понятный лог, подсказка про `--allow-empty`. Раньше такой снимок уходил в оба репозитория, становился `latest`, и `restore latest --repo vps` в сценарии «Pi умер» падал на `verify_staging`. 2. **`entrypoint.sh`.** Перед **самым первым** бэкапом (локальных снимков ещё нет) контейнер ждёт `/api/health` приложения — не дольше `BACKUP_APP_WAIT_SECONDS`, по умолчанию 600 с. Health отвечает только после миграций и bootstrap. Не дождался — пробует всё равно, п. 1 не пропустит БД без таблиц. Зависимость в compose не добавлял: при восстановлении `app` остановлен, и `depends_on: service_healthy` не дал бы стартовать `backup`. 3. **README, раздел 9.** Обновлены ожидаемые строки журнала при первом запуске на новом Pi. Совет смотреть `list vps` и выбирать снимок с числами остался: снимки с `?` больше не создаются, но могли остаться от старой версии. Семантика `restore latest` не менялась. ## Коммиты - `f5f8dc0` Бэкапы: БД без таблиц не становится снимком, первый бэкап ждёт приложение ## Проверки Образ `backup` собран локально: - БД только с `alembic_version` (без `users`/`matches`) → `fs-backup run` → «в БД нет таблиц users/matches … ОШИБКА: fs-backup run --allow-empty», код 1, репозиторий даже не создан; - та же БД → `run --allow-empty` → снимок создан (обход работает); - копия dev-БД → `run` → снимок `игроков 11, партий 24`; - штатный `entrypoint` с `BACKUP_APP_HOST=nonexistent-app`, `BACKUP_APP_WAIT_SECONDS=20` и пустым томом → «жду приложение (до 20 с)» → «не ответило за 20 с — пробую бэкап без него» → «Бэкап завершён» → расписание. ## Отклонения от плана Нет. Closes #74 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LqSoRj99iwVEH5U5fnZgsd
Agent added 1 commit 2026-09-19 03:16:03 +03:00
guard_empty считал неизвестные счётчики («?» — нет таблиц users/matches)
непустыми, и снимок без данных уходил в оба репозитория и становился latest —
restore latest в сценарии «Pi умер» падал на verify_staging. Теперь это отказ,
как для пустой БД (обход — --allow-empty).

entrypoint перед самым первым бэкапом ждёт /api/health приложения (до
BACKUP_APP_WAIT_SECONDS, 600 с): оно отвечает только после миграций. Не дождались —
пробуем всё равно, guard не пропустит БД без таблиц. README, раздел 9: новые
строки журнала, снимки с «?» больше не создаются. #74

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqSoRj99iwVEH5U5fnZgsd
NotBigGhost merged commit d12afe62d0 into dev 2026-09-30 13:04:37 +03:00
NotBigGhost deleted branch issue-74-backup-guard 2026-09-30 13:04:37 +03:00
Sign in to join this conversation.