fix(infra): bootstrap_glitchtip — \gexec instead of DO block (psql var trap) #219

Merged
lekss361 merged 1 commit from fix/glitchtip-bootstrap-gexec into main 2026-05-16 15:54:30 +00:00

View file

@ -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 ─────────────────────────────────────────────