fix(infra): bootstrap_glitchtip — \gexec instead of DO block (psql var trap)
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.
This commit is contained in:
parent
277499684b
commit
a1091cdd5a
1 changed files with 16 additions and 17 deletions
|
|
@ -48,28 +48,27 @@ for i in $(seq 1 30); do
|
||||||
done
|
done
|
||||||
|
|
||||||
# ── Create glitchtip DB + user (idempotent) ────────────────────────────────
|
# ── Create glitchtip DB + user (idempotent) ────────────────────────────────
|
||||||
# Password is passed via psql variable -v to avoid SQL injection from special
|
# psql var :'gt_pass' НЕ подставляется внутри DO $$..$$ — тело dollar-quote
|
||||||
# chars (quotes, backslashes) in $GLITCHTIP_DB_PASS. format('%L', :'gt_pass')
|
# уходит на сервер as-is. Используем \gexec в psql-стриме client-side.
|
||||||
# properly quotes the value server-side, so the shell never interpolates it
|
#
|
||||||
# into the SQL string.
|
# \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)..."
|
echo "==> Creating glitchtip database and user (idempotent)..."
|
||||||
$COMPOSE exec -T postgres \
|
$COMPOSE exec -T postgres \
|
||||||
psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" \
|
psql -U "$POSTGRES_USER" -d postgres \
|
||||||
-v "gt_pass=$GLITCHTIP_DB_PASS" \
|
-v ON_ERROR_STOP=1 \
|
||||||
-v ON_ERROR_STOP=on <<'SQL'
|
-v "gt_pass=$GLITCHTIP_DB_PASS" <<'SQL'
|
||||||
DO $$
|
SELECT 'CREATE ROLE glitchtip LOGIN PASSWORD ' || quote_literal(:'gt_pass') || ';'
|
||||||
BEGIN
|
WHERE NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'glitchtip')
|
||||||
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'glitchtip') THEN
|
\gexec
|
||||||
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$$;
|
|
||||||
|
|
||||||
SELECT 'CREATE DATABASE glitchtip OWNER glitchtip'
|
SELECT 'CREATE DATABASE glitchtip OWNER glitchtip;'
|
||||||
WHERE NOT EXISTS (SELECT 1 FROM pg_database WHERE datname = 'glitchtip')
|
WHERE NOT EXISTS (SELECT 1 FROM pg_database WHERE datname = 'glitchtip')
|
||||||
\gexec
|
\gexec
|
||||||
|
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE glitchtip TO glitchtip;
|
||||||
SQL
|
SQL
|
||||||
|
|
||||||
# ── Start GlitchTip containers ─────────────────────────────────────────────
|
# ── Start GlitchTip containers ─────────────────────────────────────────────
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue