From a1091cdd5a7e4e794cde217f1469c4a1ddec4788 Mon Sep 17 00:00:00 2001 From: lekss361 Date: Sat, 16 May 2026 18:28:42 +0300 Subject: [PATCH] =?UTF-8?q?fix(infra):=20bootstrap=5Fglitchtip=20=E2=80=94?= =?UTF-8?q?=20\gexec=20instead=20of=20DO=20block=20(psql=20var=20trap)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit psql variables (:'gt_pass') are substituted client-side in the psql stream but NOT inside dollar-quoted DO $$..$$ bodies — those are sent to the server as literal text, causing syntax error. Replace DO block with \gexec pattern: quote_literal(:'gt_pass') builds the CREATE ROLE statement client-side, then \gexec executes it. WHERE NOT EXISTS makes both role and DB steps idempotent. Also connect to 'postgres' db (not app db) for CREATE DATABASE to work. --- scripts/bootstrap_glitchtip.sh | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/scripts/bootstrap_glitchtip.sh b/scripts/bootstrap_glitchtip.sh index 007bb5df..36db58c8 100644 --- a/scripts/bootstrap_glitchtip.sh +++ b/scripts/bootstrap_glitchtip.sh @@ -48,28 +48,27 @@ for i in $(seq 1 30); do done # ── Create glitchtip DB + user (idempotent) ──────────────────────────────── -# Password is passed via psql variable -v to avoid SQL injection from special -# chars (quotes, backslashes) in $GLITCHTIP_DB_PASS. format('%L', :'gt_pass') -# properly quotes the value server-side, so the shell never interpolates it -# into the SQL string. +# psql var :'gt_pass' НЕ подставляется внутри DO $$..$$ — тело dollar-quote +# уходит на сервер as-is. Используем \gexec в psql-стриме client-side. +# +# \gexec builds SQL client-side via quote_literal(:'gt_pass'), then executes it. +# quote_literal escapes apostrophes and backslashes — no SQL injection possible. +# If WHERE NOT EXISTS filters the row, \gexec receives no input → no-op, no error. +# ON_ERROR_STOP=1 ensures \gexec-executed statements also cause psql to exit non-zero. echo "==> Creating glitchtip database and user (idempotent)..." $COMPOSE exec -T postgres \ - psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" \ - -v "gt_pass=$GLITCHTIP_DB_PASS" \ - -v ON_ERROR_STOP=on <<'SQL' -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'glitchtip') THEN - EXECUTE format('CREATE ROLE glitchtip LOGIN PASSWORD %L', :'gt_pass'); - RAISE NOTICE 'Created role glitchtip'; - ELSE - RAISE NOTICE 'Role glitchtip already exists'; - END IF; -END$$; + psql -U "$POSTGRES_USER" -d postgres \ + -v ON_ERROR_STOP=1 \ + -v "gt_pass=$GLITCHTIP_DB_PASS" <<'SQL' +SELECT 'CREATE ROLE glitchtip LOGIN PASSWORD ' || quote_literal(:'gt_pass') || ';' +WHERE NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'glitchtip') +\gexec -SELECT 'CREATE DATABASE glitchtip OWNER glitchtip' +SELECT 'CREATE DATABASE glitchtip OWNER glitchtip;' WHERE NOT EXISTS (SELECT 1 FROM pg_database WHERE datname = 'glitchtip') \gexec + +GRANT ALL PRIVILEGES ON DATABASE glitchtip TO glitchtip; SQL # ── Start GlitchTip containers ─────────────────────────────────────────────