Skip to content

Commit 45cd648

Browse files
kirson-gitclaudeosu
authored
fix(rest-postgres): idempotent DB init so a partial init can't silently drop databases (#2623)
## Problem `rest-api/deploy/kustomize/base/postgres/init-configmap.yaml` runs once via `docker-entrypoint-initdb.d` under `psql -v ON_ERROR_STOP=1`. If any statement errors, psql aborts and the remaining `CREATE DATABASE`/`CREATE USER` statements are skipped, leaving a **partial** state — e.g. `nico`+`keycloak` created but `temporal`/`temporal_visibility` missing. Because PostgreSQL only runs init scripts on an **empty** data dir, the script **never re-runs**, so the missing databases are silent and permanent. The Temporal install then fails its pre-install hook: ``` Error: failed pre-install: timed out waiting for the condition FATAL: password authentication failed for user "temporal" DETAIL: Role "temporal" does not exist. ``` Reproduced during a clean v0.10.3 bring-up. ## Fix Make every database/role creation **idempotent**: - `SELECT … WHERE NOT EXISTS (…)\gexec` guard for `CREATE DATABASE` - `DO $$ … IF NOT EXISTS … $$` for roles The script is now safe to re-run, and a single benign "already exists" error no longer aborts it and skips later databases. ## Test Re-applied against a partially-initialized postgres (had only nico+keycloak): all four DBs (`nico`, `keycloak`, `temporal`, `temporal_visibility`) present; Temporal install proceeds. Signed-off-by: ekirson <ekirson@nvidia.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Hasan Khan <hasank@nvidia.com>
1 parent d406520 commit 45cd648

1 file changed

Lines changed: 17 additions & 18 deletions

File tree

rest-api/deploy/kustomize/base/postgres/init-configmap.yaml

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,40 @@ data:
1313
-- Enable pg_trgm extension (required for text search)
1414
CREATE EXTENSION IF NOT EXISTS pg_trgm;
1515
16-
-- Create nico database and user (used by API, Workflow)
17-
CREATE DATABASE nico WITH ENCODING 'UTF8';
18-
CREATE USER nico WITH PASSWORD 'nico';
16+
-- nico database + user (idempotent: safe on re-run / partial init)
17+
SELECT 'CREATE DATABASE nico WITH ENCODING ''UTF8'''
18+
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'nico')\gexec
19+
DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname='nico') THEN CREATE ROLE nico LOGIN PASSWORD 'nico'; END IF; END $$;
1920
GRANT ALL PRIVILEGES ON DATABASE nico TO nico;
20-
21-
-- Connect to nico database to set up permissions
2221
\c nico
2322
GRANT ALL ON SCHEMA public TO nico;
2423
CREATE EXTENSION IF NOT EXISTS pg_trgm;
25-
26-
-- Create keycloak database
2724
\c postgres
28-
CREATE DATABASE keycloak WITH ENCODING 'UTF8';
29-
CREATE USER keycloak WITH PASSWORD 'keycloak';
30-
GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;
3125
26+
-- keycloak database + user
27+
SELECT 'CREATE DATABASE keycloak WITH ENCODING ''UTF8'''
28+
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'keycloak')\gexec
29+
DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname='keycloak') THEN CREATE ROLE keycloak LOGIN PASSWORD 'keycloak'; END IF; END $$;
30+
GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;
3231
\c keycloak
3332
GRANT ALL ON SCHEMA public TO keycloak;
34-
35-
-- Create temporal databases (for Temporal workflow engine)
3633
\c postgres
37-
CREATE DATABASE temporal WITH ENCODING 'UTF8';
38-
CREATE USER temporal WITH PASSWORD 'temporal' CREATEDB;
34+
35+
-- temporal databases (for Temporal workflow engine)
36+
SELECT 'CREATE DATABASE temporal WITH ENCODING ''UTF8'''
37+
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'temporal')\gexec
38+
DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname='temporal') THEN CREATE ROLE temporal LOGIN PASSWORD 'temporal' CREATEDB; END IF; END $$;
3939
GRANT ALL PRIVILEGES ON DATABASE temporal TO temporal;
4040
ALTER DATABASE temporal OWNER TO temporal;
41-
4241
\c temporal
4342
GRANT ALL ON SCHEMA public TO temporal;
4443
ALTER SCHEMA public OWNER TO temporal;
45-
4644
\c postgres
47-
CREATE DATABASE temporal_visibility WITH ENCODING 'UTF8';
45+
46+
SELECT 'CREATE DATABASE temporal_visibility WITH ENCODING ''UTF8'''
47+
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'temporal_visibility')\gexec
4848
GRANT ALL PRIVILEGES ON DATABASE temporal_visibility TO temporal;
4949
ALTER DATABASE temporal_visibility OWNER TO temporal;
50-
5150
\c temporal_visibility
5251
GRANT ALL ON SCHEMA public TO temporal;
5352
ALTER SCHEMA public OWNER TO temporal;

0 commit comments

Comments
 (0)