| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- #!/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
|