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