fix(infra): bootstrap_glitchtip — \gexec instead of DO block (psql var trap) #219
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
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#219
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/glitchtip-bootstrap-gexec"
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?
Контекст
scripts/bootstrap_glitchtip.shупал в проде (см. #204) с ошибкой:Корень проблемы
В исходной версии скрипта пароль для CREATE ROLE передавался внутрь
DO $$ ... $$блока через psql-переменную:'gt_pass'.Это не работает: psql client-side переменные подставляются только в SQL-стриме psql, не внутри dollar-quoted body. Содержимое
DO $$ ... $$уходит на сервер как литеральный текст, и Postgres не знает что такое:'gt_pass'→ syntax error.Фикс
Заменил
DO $$ ... $$на\gexec-паттерн — он строит SQL-команду client-side черезquote_literal(:'gt_pass'), потом\gexecотправляет результат на сервер.Свойства:
WHERE NOT EXISTSфильтрует,\gexecполучает 0 строк → no-op без ошибки.quote_literalserver-side эскейпит апострофы и бэкслеши.ON_ERROR_STOP=1гарантирует что ошибка в самом\gexec-команде уронит psql и скрипт.Дополнительные фиксы
-d postgresвместо-d "$POSTGRES_DB"—CREATE DATABASEтребует подключения к другой БД (нельзя создавать БД, будучи к ней подключенным). Раньше скрипт пытался создатьglitchtipсидя в gendesign — могло работать случайно если приложение\c-ало, но это хрупко.GRANT ALL PRIVILEGES ON DATABASE glitchtip TO glitchtip— отсутствовало в оригинале. Без этого пользовательglitchtipне имел прав на свою же БД (owner-права отдельны от GRANT).Test plan
bash -n scripts/bootstrap_glitchtip.sh— syntax OKRelated
Verdict: ✅ APPROVE
Root cause — корректно диагностирован
psql client-side вары
:'name'НЕ раскрываются внутри dollar-quoted body ($$ ... $$) — Postgres получает текст as-is и не знает что такое:'gt_pass'→ syntax error. Документация psql прямо это оговаривает.Фикс — правильный
:'gt_pass'подставляется psql client-side до отправки на сервер — это валидная позиция (SQL-стрим psql, не dollar-quote).quote_literalвыполняется server-side в первом SELECT, эскейпит апострофы/бэкслеши — SQL-injection невозможна.WHERE NOT EXISTS→ 0 rows →\gexecno-op → идемпотентно без exception.ON_ERROR_STOP=1распространяется на команды, отправленные\gexec(psql exits non-zero).Дополнительные фиксы — обоснованы
-d postgresвместо-d "$POSTGRES_DB"— best practice дляCREATE DATABASE(избегаем edge-case с активными соединениями к создаваемой БД).GRANT ALL PRIVILEGES ON DATABASE glitchtip TO glitchtip— формально redundant если роль = OWNER (owner имеет implicit privileges), но defensive и harmless + идемпотентно при повторном запуске.Security
$GLITCHTIP_DB_PASS→quote_literal→ нет injection-вектора.psqlinvoke без--echo-queries/--echo-all→ password не уходит в stderr/logs.<<'SQL'(single-quoted) — нет shell interpolation внутри SQL.Nits (non-blocking)
GRANTран unconditionally — нормально (GRANT идемпотентен), но можно было обернуть в тот же\gexec-pattern для consistency.Test plan — отмечен в PR body
bash -nsyntax checkAuto-merge: scripts/ scope (не в blocked-list) → squash merge.