|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# Provisions the one thing the e2e test suite needs but the base image can't |
| 4 | +# provide out of the box: |
| 5 | +# |
| 6 | +# * Postgres server – we run a native server (rather than the docker-compose |
| 7 | +# one) so it survives container restarts and is up before any test |
| 8 | +# runs, then apply the flyway migrations the harness expects to |
| 9 | +# already exist. |
| 10 | +# |
| 11 | +# anvil/forge come from the foundry devcontainer feature; their prebuilt binaries |
| 12 | +# run directly on the bookworm base image (glibc >= 2.32), so nothing to do here. |
| 13 | +# |
| 14 | +# Runs as `postCreateCommand` (once, when the container is created). |
| 15 | +set -euo pipefail |
| 16 | + |
| 17 | +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" |
| 18 | + |
| 19 | +# ----------------------------------------------------------------------------- |
| 20 | +echo "==> postgres" |
| 21 | +# Install a server only if no cluster exists yet (fresh container). Reuse whatever |
| 22 | +# version is already present otherwise, so this is safe to re-run. |
| 23 | +if ! ls -d /etc/postgresql/*/main >/dev/null 2>&1; then |
| 24 | + echo " installing postgresql-16..." |
| 25 | + sudo apt-get update -qq |
| 26 | + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq postgresql-16 |
| 27 | +fi |
| 28 | +PG_VERSION="$(ls /etc/postgresql | sort -n | tail -1)" |
| 29 | +echo " using cluster ${PG_VERSION}/main" |
| 30 | + |
| 31 | +# Start the cluster (shared with postStart so the two can't drift). |
| 32 | +bash "$REPO_ROOT/.devcontainer/start-postgres.sh" |
| 33 | + |
| 34 | +# Trust auth for local connections (development container only). |
| 35 | +HBA="/etc/postgresql/${PG_VERSION}/main/pg_hba.conf" |
| 36 | +sudo tee "$HBA" >/dev/null <<'EOF' |
| 37 | +local all all trust |
| 38 | +host all all 127.0.0.1/32 trust |
| 39 | +host all all ::1/128 trust |
| 40 | +EOF |
| 41 | +sudo pg_ctlcluster "$PG_VERSION" main reload |
| 42 | + |
| 43 | +# The e2e harness connects with the bare url `postgresql://`, which resolves to a |
| 44 | +# role and database named after $PGUSER/$PGDATABASE (see containerEnv in |
| 45 | +# devcontainer.json and DatabasePoolConfig::test_default). |
| 46 | +psql -h 127.0.0.1 -U postgres -d postgres -tAc \ |
| 47 | + "SELECT 1 FROM pg_roles WHERE rolname='${PGUSER}'" | grep -q 1 \ |
| 48 | + || psql -h 127.0.0.1 -U postgres -d postgres -c \ |
| 49 | + "CREATE ROLE \"${PGUSER}\" LOGIN SUPERUSER;" |
| 50 | +psql -h 127.0.0.1 -U postgres -d postgres -tAc \ |
| 51 | + "SELECT 1 FROM pg_database WHERE datname='${PGDATABASE}'" | grep -q 1 \ |
| 52 | + || psql -h 127.0.0.1 -U postgres -d postgres -c \ |
| 53 | + "CREATE DATABASE \"${PGDATABASE}\" OWNER \"${PGUSER}\";" |
| 54 | + |
| 55 | +# Apply the migrations with the same flyway image the rest of the repo uses |
| 56 | +# (see docker-compose.yaml). Flyway tracks what it has already applied, so this is |
| 57 | +# incremental and idempotent: re-running only applies new migrations and fails |
| 58 | +# loudly if one is incompatible with the current schema. The native server runs |
| 59 | +# on the host network namespace, so `--network=host` lets flyway reach it on |
| 60 | +# 127.0.0.1:${PGPORT}. |
| 61 | +echo " applying flyway migrations..." |
| 62 | +docker run --rm --network=host \ |
| 63 | + -v "$REPO_ROOT/database/sql:/flyway/sql:ro" \ |
| 64 | + -v "$REPO_ROOT/database/conf:/flyway/conf:ro" \ |
| 65 | + flyway/flyway:10.7.1 \ |
| 66 | + -url="jdbc:postgresql://127.0.0.1:${PGPORT}/${PGDATABASE}?user=${PGUSER}&password=" \ |
| 67 | + migrate |
| 68 | + |
| 69 | +echo "==> e2e environment ready (postgres)" |
0 commit comments