fix: ограничить PostgreSQL backup одним еженедельным dump #51

Merged
admin merged 3 commits from fix/backup-retention into main 2026-09-17 07:09:24 +00:00
Collaborator

Убран backup из каждого production deploy.

  • Добавлен еженедельный user cron через pg_dumpall для полного PostgreSQL-кластера.
  • Новый dump создаётся во временный файл и заменяет предыдущий только после успешного завершения.
  • После успешного backup удаляются старые dump-файлы miem_workers.
  • Cron устанавливается idempotently во время deploy.
  • Версия обновлена до 0.8.13.

Локально прошли sh -n и node --check; pytest не запущен, так как pytest отсутствует в окружении.

Убран backup из каждого production deploy. - Добавлен еженедельный user cron через `pg_dumpall` для полного PostgreSQL-кластера. - Новый dump создаётся во временный файл и заменяет предыдущий только после успешного завершения. - После успешного backup удаляются старые dump-файлы `miem_workers`. - Cron устанавливается idempotently во время deploy. - Версия обновлена до 0.8.13. Локально прошли `sh -n` и `node --check`; pytest не запущен, так как pytest отсутствует в окружении.
agent added 1 commit 2026-09-15 15:45:45 +00:00
fix: schedule weekly full postgres backup
Some checks failed
CI / test (pull_request) Failing after 4m45s
CI / deploy (pull_request) Has been skipped
384cd550d5
Author
Collaborator

Request changes.

  • P1 — CI гарантированно падает на версииapp/version.py:1-3 содержит 0.8.13, но tests/test_api.py:21, pyproject.toml:3 и README.md:138 всё ещё ожидают/указывают 0.8.12. test_health_returns_versions сравнивает API с 0.8.12, поэтому job pytest не может пройти. Синхронизировать все источники версии и expectation.
  • P1 — production replacement неатомарен и без rollback.gitea/workflows/ci.yml:83-91: release архив распаковывается tar’ом прямо поверх $PROD_PATH, затем выполняются docker compose up, runtime check и healthcheck. При ошибке во время распаковки/сборки/запуска каталог может остаться смешанным или частично обновлённым, а работающий сервис — на старой/неполной сборке. Нужна распаковка в отдельный release directory с атомарным switch либо явный rollback.
  • P2 — cron и backup жёстко привязаны к codex.gitea/workflows/ci.yml:87, infra/postgres-backup.sh:5-7,17: cron устанавливается для PROD_USER, но backup и cleanup используют /home/codex и /srv/miem_workers. При любом другом PROD_USER задача либо пишет не в его home, либо не имеет доступа. Передать пути из deploy-конфига или валидировать обязательное равенство пользователя.
  • P2 — нет CI-проверки новых shell-скриптов и backup-пути.gitea/workflows/ci.yml:11-25, infra/install-postgres-backup-cron.sh:1-9, infra/postgres-backup.sh:1-18: CI запускает pytest и JS syntax check, но не sh -n для скриптов; нет теста idempotent cron, atomic mv, empty/failed dump и cleanup failure cases. Добавить минимальную shell syntax/smoke проверку.

Проверен полный diff main...384cd550; новый dump действительно создаётся временно, проверяется через test -s, атомарно заменяется через mv, а старые miem_workers-*.sql удаляются только после успешного dump. Секреты в diff не добавляются.

Request changes. - **P1 — CI гарантированно падает на версии** — `app/version.py:1-3` содержит `0.8.13`, но `tests/test_api.py:21`, `pyproject.toml:3` и `README.md:138` всё ещё ожидают/указывают `0.8.12`. `test_health_returns_versions` сравнивает API с `0.8.12`, поэтому job `pytest` не может пройти. Синхронизировать все источники версии и expectation. - **P1 — production replacement неатомарен и без rollback** — `.gitea/workflows/ci.yml:83-91`: release архив распаковывается tar’ом прямо поверх `$PROD_PATH`, затем выполняются `docker compose up`, runtime check и healthcheck. При ошибке во время распаковки/сборки/запуска каталог может остаться смешанным или частично обновлённым, а работающий сервис — на старой/неполной сборке. Нужна распаковка в отдельный release directory с атомарным switch либо явный rollback. - **P2 — cron и backup жёстко привязаны к codex** — `.gitea/workflows/ci.yml:87`, `infra/postgres-backup.sh:5-7,17`: cron устанавливается для `PROD_USER`, но backup и cleanup используют `/home/codex` и `/srv/miem_workers`. При любом другом `PROD_USER` задача либо пишет не в его home, либо не имеет доступа. Передать пути из deploy-конфига или валидировать обязательное равенство пользователя. - **P2 — нет CI-проверки новых shell-скриптов и backup-пути** — `.gitea/workflows/ci.yml:11-25`, `infra/install-postgres-backup-cron.sh:1-9`, `infra/postgres-backup.sh:1-18`: CI запускает pytest и JS syntax check, но не `sh -n` для скриптов; нет теста idempotent cron, atomic `mv`, empty/failed dump и cleanup failure cases. Добавить минимальную shell syntax/smoke проверку. Проверен полный diff `main...384cd550`; новый dump действительно создаётся временно, проверяется через `test -s`, атомарно заменяется через `mv`, а старые `miem_workers-*.sql` удаляются только после успешного dump. Секреты в diff не добавляются.
agent added 1 commit 2026-09-15 15:50:34 +00:00
fix: finalize weekly postgres backup retention
All checks were successful
CI / test (pull_request) Successful in 9m11s
CI / deploy (pull_request) Has been skipped
b933f95302
Author
Collaborator

Request changes.

Исправлено:

  • version mismatch устранён: 0.8.13 согласована в app/version.py, pyproject.toml, README и tests/test_api.py;
  • hardcode /home/codex/фиксированного script path устранён: backup использует $HOME, а cron installer вычисляет app_dir.

Оставшиеся findings:

  • P1 — production replacement всё ещё неатомарен и без rollback.gitea/workflows/ci.yml:84-98: tar-архив распаковывается прямо поверх $PROD_PATH, после чего выполняются Compose/runtime/health checks. Сбой оставляет частично смешанный release без восстановления предыдущего состояния. Нужен отдельный release directory и атомарный switch либо rollback.
  • P2 — CI shell check проверяет только один из двух скриптов.gitea/workflows/ci.yml:26: sh -n infra/postgres-backup.sh infra/install-postgres-backup-cron.sh передаёт второй путь как positional argument первому shell, поэтому syntax error во втором файле не будет обнаружен. Запускать sh -n отдельно для каждого файла.
  • P2 — cron подавляет все ошибки без контроля результата backupinfra/install-postgres-backup-cron.sh:9: stdout/stderr перенаправлены в /dev/null, а flock -n молча пропускает запуск при занятом lock. При поломке cron/docker/pg_dumpall backup может неделями отсутствовать незамеченным. Нужен хотя бы persistent log/monitoring или проверяемый сигнал успешного backup.

Проверен полный diff main...b933f95 и backup flow: dump полный через pg_dumpall, временный файл проверяется test -s, замена через mv атомарна, старые deploy-backups удаляются только после успешной замены. Секреты в diff не добавляются.

Request changes. Исправлено: - version mismatch устранён: `0.8.13` согласована в `app/version.py`, `pyproject.toml`, README и `tests/test_api.py`; - hardcode `/home/codex`/фиксированного script path устранён: backup использует `$HOME`, а cron installer вычисляет `app_dir`. Оставшиеся findings: - **P1 — production replacement всё ещё неатомарен и без rollback** — `.gitea/workflows/ci.yml:84-98`: tar-архив распаковывается прямо поверх `$PROD_PATH`, после чего выполняются Compose/runtime/health checks. Сбой оставляет частично смешанный release без восстановления предыдущего состояния. Нужен отдельный release directory и атомарный switch либо rollback. - **P2 — CI shell check проверяет только один из двух скриптов** — `.gitea/workflows/ci.yml:26`: `sh -n infra/postgres-backup.sh infra/install-postgres-backup-cron.sh` передаёт второй путь как positional argument первому shell, поэтому syntax error во втором файле не будет обнаружен. Запускать `sh -n` отдельно для каждого файла. - **P2 — cron подавляет все ошибки без контроля результата backup** — `infra/install-postgres-backup-cron.sh:9`: stdout/stderr перенаправлены в `/dev/null`, а `flock -n` молча пропускает запуск при занятом lock. При поломке cron/docker/pg_dumpall backup может неделями отсутствовать незамеченным. Нужен хотя бы persistent log/monitoring или проверяемый сигнал успешного backup. Проверен полный diff `main...b933f95` и backup flow: dump полный через `pg_dumpall`, временный файл проверяется `test -s`, замена через `mv` атомарна, старые deploy-backups удаляются только после успешной замены. Секреты в diff не добавляются.
agent added 1 commit 2026-09-15 15:53:13 +00:00
fix: report scheduled backup failures
All checks were successful
CI / test (pull_request) Successful in 9m12s
CI / deploy (pull_request) Has been skipped
69c1dd52cf
Author
Collaborator

No blocking findings.

Повторно проверен полный diff main...69c1dd5 и backup workflow:

  • версии согласованы на 0.8.14 в runtime, pyproject.toml, README и API test;
  • weekly user cron устанавливается idempotently, использует вычисляемый app_dir, ожидает lock до 1 часа и логирует failure/skip через syslog;
  • pg_dumpall сохраняет полный cluster dump в temp-файл с umask 077, проверкой test -s и атомарным mv в тот же каталог;
  • старые deploy-backups удаляются только после успешной замены;
  • CI запускает отдельный sh -n для каждого нового скрипта;
  • секреты/пароли в diff не добавляются.

Статические проверки прошли: git diff --check и оба shell script через sh -n. Pre-existing deploy rollback намеренно не оценивается по scope ревью.

No blocking findings. Повторно проверен полный diff `main...69c1dd5` и backup workflow: - версии согласованы на `0.8.14` в runtime, `pyproject.toml`, README и API test; - weekly user cron устанавливается idempotently, использует вычисляемый `app_dir`, ожидает lock до 1 часа и логирует failure/skip через syslog; - `pg_dumpall` сохраняет полный cluster dump в temp-файл с `umask 077`, проверкой `test -s` и атомарным `mv` в тот же каталог; - старые deploy-backups удаляются только после успешной замены; - CI запускает отдельный `sh -n` для каждого нового скрипта; - секреты/пароли в diff не добавляются. Статические проверки прошли: `git diff --check` и оба shell script через `sh -n`. Pre-existing deploy rollback намеренно не оценивается по scope ревью.
admin merged commit 9fc7de113a into main 2026-09-17 07:09:24 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/miem_workers#51