fix(ops): проверка трейлера дампа падала на grep — ведущие -- принимались за опции (#2203) #3013
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
ИРД
вторичка
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#3013
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/backup-trailer-grep-dashdash"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что было
verify_dump_integrity()в обоих бэкап-скриптах делала:$trailer="-- PostgreSQL database dump complete"(и... cluster dump completeдля globals) — строка начинается с--. GNU grep трактует ведущие--в аргументе как конец списка опций/саму опцию, и без разделителя перед паттерном падает:Проверка из-за этого всегда возвращала «трейлера нет» — не потому что дамп оборван, а потому что сама grep-команда не могла выполниться. Вызывающий код удалял только что созданный валидный дамп и завершался с ошибкой; ретеншен не успевал отработать (ранний exit) — свежие бэкапы не создавались никогда, старые копии оставались молча (тихая заморозка бэкапов).
Воспроизведение (дословно, с прода)
удалил свежий дамп с сообщением «дамп оборван?» — на самом деле дамп был валиден, упал именно grep.
Почему не поймали раньше
Ни один тест не исполнял
verify_dump_integrity()на реальном gzip-потоке — код только читался/ревьюился глазами, аgrep -qF "текст, начинающийся с --"выглядит безобидно, пока не запущен.Фикс
В обоих файлах:
ops/backup.sh:74,tradein-mvp/deploy/backup-tradein-db.sh:59. Никакой другой логики не менял,bash -nна обоих зелен.Регрессионный тест
backend/tests/ops/test_2203_backup_trailer_grep_dashdash.py— извлекает телоverify_dump_integrity()из каждого скрипта и реально исполняет его (gunzip -c | tail -5 | grep -qF -- "$trailer") на настоящих gzip-потоках: валидный дамп с трейлером → rc=0, оборванный без трейлера → rc=1, плюс отдельная проверка что grep не падает сunrecognized option.Проверено локально:
--) тест падает 4/6 с тем жеgrep: unrecognized option, что и на проде;Гейт
bash -nв.forgejo/workflows/ci.yml(scripts/*.sh,ops/*.sh,ops/**/*.sh) покроетops/backup.sh, но неtradein-mvp/deploy/backup-tradein-db.sh— этот путь под маску не попадает. Регрессионный тест лежит вbackend/tests/ops/и гарантированно попадает вbackend-testsjob (paths-filterbackend/**), так что реальное исполнение обоих скриптов покрыто именно pytest-ом, а не синтаксическим гейтом. CI не трогал.