scripts/ci-qa-pipe-databases.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env bash
# Disposable PostgreSQL 17 + MySQL 8.4, TLS certificates and real API QA.
set -euo pipefail
repo=$(cd "$(dirname "$0")/.." && pwd)
api="$repo/target/debug/firecrab-api"
output="$repo/target/qa/pipe-databases.json"
browser=()
while [[ $# -gt 0 ]]; do
case "$1" in
--api) api=$2; shift 2 ;;
--output) output=$2; shift 2 ;;
--browser) browser=(--browser --frontend-dist "$repo/firecrab-frontend/dist"); shift ;;
*) printf 'Usage: %s [--api BINARY] [--output REPORT.json] [--browser]\n' "$0" >&2; exit 2 ;;
esac
done
[[ $(uname -s) == Linux && -x "$api" ]] || { echo 'Requires Linux and a built firecrab-api binary' >&2; exit 2; }
for command in docker openssl python3 psql mysql; do
command -v "$command" >/dev/null || { echo "Missing required command: $command" >&2; exit 2; }
done
docker info >/dev/null
temporary=$(mktemp -d)
suffix=$(python3 -c 'import uuid; print(uuid.uuid4().hex[:12])')
postgres="qa-pipe-postgres-$suffix"
mysql="qa-pipe-mysql-$suffix"
cleanup() {
local result=$?
trap - EXIT
docker rm -fv "$postgres" "$mysql" >/dev/null 2>&1 || true
if ! docker info >/dev/null 2>&1; then
echo 'WARNING cannot verify test container cleanup: Docker is unavailable' >&2
[[ $result -ne 0 ]] || result=1
else
for container in "$postgres" "$mysql"; do
if docker inspect "$container" >/dev/null 2>&1; then
echo "WARNING test container remains: $container" >&2
[[ $result -ne 0 ]] || result=1
fi
done
fi
rm -rf "$temporary"
exit "$result"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
openssl req -x509 -newkey rsa:2048 -nodes -days 1 -keyout "$temporary/ca.key" -out "$temporary/ca.pem" -subj '/CN=Firecrab disposable QA CA' -addext 'basicConstraints=critical,CA:TRUE' -addext 'keyUsage=critical,keyCertSign,cRLSign' >"$temporary/openssl.log" 2>&1
openssl req -newkey rsa:2048 -nodes -keyout "$temporary/server.key" -out "$temporary/server.csr" -subj '/CN=localhost' >>"$temporary/openssl.log" 2>&1
cat >"$temporary/extensions" <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:localhost,IP:127.0.0.1,IP:::1
EOF
openssl x509 -req -in "$temporary/server.csr" -CA "$temporary/ca.pem" -CAkey "$temporary/ca.key" -CAcreateserial -days 1 -extfile "$temporary/extensions" -out "$temporary/server.crt" >>"$temporary/openssl.log" 2>&1
# These credentials are valid only for this run's loopback test containers.
password=pipe-qa-only-password
docker run -d --name "$postgres" --tmpfs /var/lib/postgresql/data:rw,nosuid,size=256m -e POSTGRES_USER=firecrab_test -e POSTGRES_PASSWORD="$password" -e POSTGRES_DB=pipe_test -p 127.0.0.1::5432 postgres:17 >/dev/null
docker run -d --name "$mysql" --tmpfs /var/lib/mysql:rw,nosuid,size=1g -e MYSQL_ROOT_PASSWORD="$password" -e MYSQL_USER=firecrab_test -e MYSQL_PASSWORD="$password" -e MYSQL_DATABASE=pipe_test -p 127.0.0.1::3306 mysql:8.4 >/dev/null
wait_database() {
local container=$1
shift
for _ in $(seq 1 90); do
if docker exec "$container" "$@" >/dev/null 2>&1; then return; fi
[[ $(docker inspect -f '{{.State.Running}}' "$container") == true ]] || break
sleep 1
done
docker logs "$container" >&2
echo "Database did not become ready: $container" >&2
return 1
}
wait_database "$postgres" env PGPASSWORD="$password" psql -h127.0.0.1 -U firecrab_test -d pipe_test -c 'SELECT 1'
wait_database "$mysql" env MYSQL_PWD="$password" mysql --protocol=TCP -h127.0.0.1 -ufirecrab_test -Dpipe_test -e 'SELECT 1'
for container in "$postgres" "$mysql"; do
docker cp "$temporary/server.crt" "$container:/tmp/qa-server.crt"
docker cp "$temporary/server.key" "$container:/tmp/qa-server.key"
docker cp "$temporary/ca.pem" "$container:/tmp/qa-ca.pem"
done
docker exec -u 0 "$postgres" sh -c 'cp /tmp/qa-server.crt /var/lib/postgresql/data/server.crt; cp /tmp/qa-server.key /var/lib/postgresql/data/server.key; chown postgres:postgres /var/lib/postgresql/data/server.*; chmod 600 /var/lib/postgresql/data/server.key'
docker exec "$postgres" psql -U firecrab_test -d pipe_test -v ON_ERROR_STOP=1 -c "ALTER SYSTEM SET ssl = on"
docker exec "$postgres" psql -U firecrab_test -d pipe_test -v ON_ERROR_STOP=1 -c 'SELECT pg_reload_conf()'
docker exec -u 0 "$mysql" sh -c 'cp /tmp/qa-server.crt /var/lib/mysql/server-cert.pem; cp /tmp/qa-server.key /var/lib/mysql/server-key.pem; cp /tmp/qa-ca.pem /var/lib/mysql/ca.pem; chown mysql:mysql /var/lib/mysql/server-cert.pem /var/lib/mysql/server-key.pem /var/lib/mysql/ca.pem; chmod 600 /var/lib/mysql/server-key.pem'
docker exec -e MYSQL_PWD="$password" "$mysql" mysql -uroot -e 'ALTER INSTANCE RELOAD TLS'
postgres_port=$(docker inspect -f '{{(index (index .NetworkSettings.Ports "5432/tcp") 0).HostPort}}' "$postgres")
mysql_port=$(docker inspect -f '{{(index (index .NetworkSettings.Ports "3306/tcp") 0).HostPort}}' "$mysql")
export FIRECRAB_TEST_POSTGRES_URI="postgresql://firecrab_test:$password@127.0.0.1:$postgres_port/pipe_test"
export FIRECRAB_TEST_MYSQL_URI="mysql://firecrab_test:$password@127.0.0.1:$mysql_port/pipe_test"
export FIRECRAB_TEST_POSTGRES_CA="$temporary/ca.pem" FIRECRAB_TEST_MYSQL_CA="$temporary/ca.pem"
python3 "$repo/scripts/test-pipe-databases.py" --api "$api" --output "$output" --require-tls "${browser[@]}"