#!/bin/bash # Ensures a local PostgreSQL server is available for the live integration # tests. Idempotent and safe to re-run. # # Layout (matches the goal plan): # data dir: /tmp/pgdata # socket dir: /tmp/pgrun # port: 5433 # test role: postgres (the initdb superuser) # test db: sqltest (created if missing) # # Must run as root (uses `su postgres`); if not root we try without su # so the script still works in environments where we already are the # postgres user or own the server. set -u PGBIN="${PGBIN:-/usr/bin}" PGDATA="${PGDATA:-/tmp/pgdata}" PGSOCK="${PGSOCK:-/tmp/pgrun}" PGPORT="${PGPORT:-5433}" PGUSER_NAME="${PGUSER_NAME:-postgres}" PGDATABASE="${PGDATABASE:-sqltest}" PSQL="$PGBIN/psql" INITDB="$PGBIN/initdb" PG_CTL="$PGBIN/pg_ctl" PG_ISREADY="$PGBIN/pg_isready" run_as_pg() { # Run a command as the postgres user when we are root; otherwise # run it directly. if [ "$(id -u)" = "0" ]; then su "$PGUSER_NAME" -s /bin/bash -c "$*" else bash -c "$*" fi } # --- 1. Server binaries present? ----------------------------------------- for bin in psql initdb pg_ctl; do if [ ! -x "$PGBIN/$bin" ]; then echo "ensure-postgres: $PGBIN/$bin not found — PostgreSQL server not installed" >&2 exit 2 fi done # --- 2. Data directory ---------------------------------------------------- if [ ! -f "$PGDATA/PG_VERSION" ]; then echo "ensure-postgres: initialising data directory at $PGDATA" mkdir -p "$(dirname "$PGDATA")" mkdir -p "$PGDATA" chown "$PGUSER_NAME":"$PGUSER_NAME" "$PGDATA" 2>/dev/null || true chmod 700 "$PGDATA" if ! run_as_pg "$INITDB -D $PGDATA --auth=trust -E SQL_ASCII --locale=C" \ > /tmp/ensure-postgres-initdb.log 2>&1; then echo "ensure-postgres: initdb failed:" >&2 tail -20 /tmp/ensure-postgres-initdb.log >&2 exit 3 fi # trust auth for local + loopback so the test binary can connect as # the postgres role without a password from any local user. cat > "$PGDATA/pg_hba.conf" << 'HBA' local all all trust host all all 127.0.0.1/32 trust host all all ::1/128 trust local replication all trust host replication all 127.0.0.1/32 trust host replication all ::1/128 trust HBA chown "$PGUSER_NAME":"$PGUSER_NAME" "$PGDATA/pg_hba.conf" 2>/dev/null || true fi # --- 3. Server running? ---------------------------------------------------- mkdir -p "$PGSOCK" chown "$PGUSER_NAME":"$PGUSER_NAME" "$PGSOCK" 2>/dev/null || true chmod 775 "$PGSOCK" if ! run_as_pg "$PG_ISREADY -h $PGSOCK -p $PGPORT -q"; then echo "ensure-postgres: starting server on socket $PGSOCK port $PGPORT" if ! run_as_pg "$PG_CTL -D $PGDATA -l /tmp/ensure-postgres.log -w -t 30 start -o '-k $PGSOCK -p $PGPORT'" \ >> /tmp/ensure-postgres.log 2>&1; then echo "ensure-postgres: server failed to start:" >&2 tail -20 /tmp/ensure-postgres.log >&2 exit 4 fi fi # --- 4. Test database ------------------------------------------------------ # SQL is piped over stdin so no nested shell quoting (and no shared # temp files with permission races) are needed. CHECK_SQL="SELECT 1 FROM pg_database WHERE datname = '$PGDATABASE'" CREATE_SQL="CREATE DATABASE \"$PGDATABASE\"" if ! printf '%s\n' "$CHECK_SQL" | run_as_pg "$PSQL -h $PGSOCK -p $PGPORT -U $PGUSER_NAME -d postgres -tA" | grep -q 1; then echo "ensure-postgres: creating database $PGDATABASE" printf '%s\n' "$CREATE_SQL" | run_as_pg "$PSQL -h $PGSOCK -p $PGPORT -U $PGUSER_NAME -d postgres" >/dev/null fi echo "ensure-postgres: server ready (socket $PGSOCK, port $PGPORT, db $PGDATABASE)" exit 0