150 lines
6.3 KiB
Bash
Executable File
150 lines
6.3 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
PACKAGE=${1:?usage: smoke-postgresql-fnos-package.sh postgresql-service.fpk [temporary-directory]}
|
|
SMOKE_TMP_ROOT="${2:-${POSTGRES_SERVICE_SMOKE_TMPDIR:-${TMPDIR:-/tmp}}}"
|
|
mkdir -p "$SMOKE_TMP_ROOT"
|
|
SMOKE_TMP_ROOT=$(CDPATH= cd -- "$SMOKE_TMP_ROOT" && pwd)
|
|
WORK_DIR=$(mktemp -d "${SMOKE_TMP_ROOT%/}/postgres-service-fnos-smoke.XXXXXX")
|
|
PACKAGE_ROOT="$WORK_DIR/package"
|
|
APP_ROOT="$WORK_DIR/app"
|
|
DATA_ROOT="$WORK_DIR/var"
|
|
VOLUME_ROOT="$WORK_DIR/volume"
|
|
API_PORT=${POSTGRES_SERVICE_SMOKE_API_PORT:-19433}
|
|
PG_PORT=${POSTGRES_SERVICE_SMOKE_PG_PORT:-19432}
|
|
ADMIN_PASSWORD='Postgres-Admin-Smoke-2026!'
|
|
ENROLLMENT_TOKEN='Postgres-Enrollment-Smoke-2026!'
|
|
CONTROL="$PACKAGE_ROOT/cmd/main"
|
|
|
|
cleanup() {
|
|
status=$?
|
|
if [ -x "$CONTROL" ]; then
|
|
TRIM_APPDEST="$APP_ROOT" TRIM_PKGVAR="$DATA_ROOT" TRIM_APPDEST_VOL="$VOLUME_ROOT" \
|
|
TRIM_SERVICE_PORT="$API_PORT" POSTGRES_SERVICE_PORT="$PG_PORT" \
|
|
"$CONTROL" stop >/dev/null 2>&1 || true
|
|
fi
|
|
if [ "$status" -ne 0 ]; then
|
|
printf '%s\n' 'PostgreSQL fnOS smoke test failed; service logs follow:' >&2
|
|
for log_file in "$DATA_ROOT/log/postgresql.log" "$DATA_ROOT/log/postgres-service.log"; do
|
|
if [ -f "$log_file" ]; then
|
|
printf '%s\n' "--- $log_file ---" >&2
|
|
tail -n 160 "$log_file" >&2 || true
|
|
fi
|
|
done
|
|
fi
|
|
rm -rf -- "$WORK_DIR"
|
|
return "$status"
|
|
}
|
|
trap cleanup EXIT HUP INT TERM
|
|
|
|
mkdir -p "$PACKAGE_ROOT" "$APP_ROOT" "$VOLUME_ROOT"
|
|
tar -xzf "$PACKAGE" -C "$PACKAGE_ROOT"
|
|
tar -xzf "$PACKAGE_ROOT/app.tgz" -C "$APP_ROOT"
|
|
if [ -n "${POSTGRES_SERVICE_SMOKE_SERVER_OVERLAY:-}" ]; then
|
|
test -x "$POSTGRES_SERVICE_SMOKE_SERVER_OVERLAY/PostgresService.WebApi" || {
|
|
printf 'invalid API overlay: %s\n' "$POSTGRES_SERVICE_SMOKE_SERVER_OVERLAY" >&2
|
|
exit 1
|
|
}
|
|
cp -a "$POSTGRES_SERVICE_SMOKE_SERVER_OVERLAY/." "$APP_ROOT/server/"
|
|
fi
|
|
|
|
export TRIM_APPDEST="$APP_ROOT"
|
|
export TRIM_PKGVAR="$DATA_ROOT"
|
|
export TRIM_APPDEST_VOL="$VOLUME_ROOT"
|
|
export TRIM_SERVICE_PORT="$API_PORT"
|
|
export POSTGRES_SERVICE_PORT="$PG_PORT"
|
|
|
|
wizard_postgres_admin_password="$ADMIN_PASSWORD" \
|
|
wizard_postgres_admin_password_confirm="$ADMIN_PASSWORD" \
|
|
wizard_postgres_enrollment_token="$ENROLLMENT_TOKEN" \
|
|
wizard_postgres_enrollment_token_confirm="$ENROLLMENT_TOKEN" \
|
|
"$PACKAGE_ROOT/cmd/install_callback"
|
|
"$CONTROL" start
|
|
"$CONTROL" status
|
|
|
|
BASE_URL="http://127.0.0.1:$API_PORT"
|
|
curl -fsS "$BASE_URL/health/ready" | grep -q '"status":"ready"'
|
|
curl -fsS "$BASE_URL/" | grep -q '<div id="app"></div>'
|
|
|
|
COOKIE_JAR="$WORK_DIR/cookies.txt"
|
|
curl -fsS -c "$COOKIE_JAR" -H 'Content-Type: application/json' \
|
|
--data "{\"username\":\"admin\",\"password\":\"$ADMIN_PASSWORD\"}" \
|
|
"$BASE_URL/api/v1/auth/login" >/dev/null
|
|
curl -fsS -b "$COOKIE_JAR" "$BASE_URL/api/v1/overview" | grep -q '"version"'
|
|
curl -fsS -b "$COOKIE_JAR" "$BASE_URL/api/v1/sessions" | grep -q '^\['
|
|
|
|
enroll() {
|
|
app_id=$1
|
|
display_name=$2
|
|
extensions=$3
|
|
destination=$4
|
|
curl -fsS \
|
|
-H "Authorization: Bearer $ENROLLMENT_TOKEN" \
|
|
-H 'Content-Type: application/json' \
|
|
--data "{\"appId\":\"$app_id\",\"displayName\":\"$display_name\",\"requestedExtensions\":$extensions}" \
|
|
"$BASE_URL/internal/v1/enroll" >"$destination"
|
|
}
|
|
|
|
enroll liverecorder 'Live Recorder' '[]' "$WORK_DIR/live.json"
|
|
enroll imagefind-test 'ImageFind Test Client' '["vector"]' "$WORK_DIR/image.json"
|
|
|
|
json_field() {
|
|
field=$1
|
|
file=$2
|
|
sed -n "s/.*\"$field\":\"\([^\"]*\)\".*/\1/p" "$file"
|
|
}
|
|
|
|
LIVE_DB=$(json_field database "$WORK_DIR/live.json")
|
|
LIVE_USER=$(json_field username "$WORK_DIR/live.json")
|
|
LIVE_PASSWORD=$(json_field password "$WORK_DIR/live.json")
|
|
IMAGE_DB=$(json_field database "$WORK_DIR/image.json")
|
|
IMAGE_USER=$(json_field username "$WORK_DIR/image.json")
|
|
IMAGE_PASSWORD=$(json_field password "$WORK_DIR/image.json")
|
|
test -n "$LIVE_DB" && test -n "$LIVE_USER" && test -n "$LIVE_PASSWORD"
|
|
test -n "$IMAGE_DB" && test -n "$IMAGE_USER" && test -n "$IMAGE_PASSWORD"
|
|
test "$LIVE_DB" != "$IMAGE_DB"
|
|
test "$LIVE_USER" != "$IMAGE_USER"
|
|
|
|
PG_BIN="$APP_ROOT/runtime/usr/lib/postgresql/15/bin"
|
|
PG_LIB="$APP_ROOT/runtime/usr/lib/postgresql/15/lib"
|
|
RUNTIME_LIBS="$APP_ROOT/runtime/usr/lib/x86_64-linux-gnu:$APP_ROOT/runtime/lib/x86_64-linux-gnu:$PG_LIB"
|
|
run_client_psql() {
|
|
password=$1
|
|
shift
|
|
env LD_LIBRARY_PATH="$RUNTIME_LIBS" PGPASSWORD="$password" "$PG_BIN/psql" "$@"
|
|
}
|
|
|
|
run_client_psql "$LIVE_PASSWORD" -h 127.0.0.1 -p "$PG_PORT" -U "$LIVE_USER" -d "$LIVE_DB" \
|
|
-v ON_ERROR_STOP=1 -c 'CREATE TABLE smoke_live(id integer PRIMARY KEY, value text); INSERT INTO smoke_live VALUES (1, '\''live'\'');' >/dev/null
|
|
run_client_psql "$IMAGE_PASSWORD" -h 127.0.0.1 -p "$PG_PORT" -U "$IMAGE_USER" -d "$IMAGE_DB" \
|
|
-v ON_ERROR_STOP=1 -c 'CREATE TABLE smoke_vectors(id integer PRIMARY KEY, embedding vector(3)); INSERT INTO smoke_vectors VALUES (1, '\''[1,2,3]'\''); SELECT embedding <-> '\''[1,2,4]'\'' FROM smoke_vectors;' >/dev/null
|
|
|
|
if run_client_psql "$LIVE_PASSWORD" -h 127.0.0.1 -p "$PG_PORT" -U "$LIVE_USER" -d "$IMAGE_DB" -Atqc 'SELECT 1' >/dev/null 2>&1; then
|
|
printf '%s\n' 'role isolation failed: Live Recorder connected to ImageFind database' >&2
|
|
exit 1
|
|
fi
|
|
|
|
curl -fsS -b "$COOKIE_JAR" -H 'Content-Type: application/json' \
|
|
--data "{\"database\":\"$IMAGE_DB\",\"sql\":\"SELECT count(*) FROM smoke_vectors\"}" \
|
|
"$BASE_URL/api/v1/query" | grep -q '"rowCount":1'
|
|
if curl -fsS -b "$COOKIE_JAR" -H 'Content-Type: application/json' \
|
|
--data "{\"database\":\"$IMAGE_DB\",\"sql\":\"DELETE FROM smoke_vectors\"}" \
|
|
"$BASE_URL/api/v1/query" >/dev/null 2>&1; then
|
|
printf '%s\n' 'read-only SQL console accepted a write statement' >&2
|
|
exit 1
|
|
fi
|
|
|
|
curl -fsS -b "$COOKIE_JAR" -H 'Content-Type: application/json' \
|
|
--data "{\"database\":\"$LIVE_DB\"}" "$BASE_URL/api/v1/backups" | grep -q '"sha256"'
|
|
|
|
POSTMASTER_PID=$(sed -n '1p' "$DATA_ROOT/postgres/postmaster.pid")
|
|
test -n "$POSTMASTER_PID"
|
|
kill -0 "$POSTMASTER_PID"
|
|
|
|
"$CONTROL" restart
|
|
"$CONTROL" status
|
|
curl -fsS "$BASE_URL/health/ready" | grep -q '"status":"ready"'
|
|
run_client_psql "$LIVE_PASSWORD" -h 127.0.0.1 -p "$PG_PORT" -U "$LIVE_USER" -d "$LIVE_DB" -Atqc 'SELECT value FROM smoke_live WHERE id = 1' | grep -q '^live$'
|
|
|
|
printf '%s\n' 'PostgreSQL fnOS smoke test passed: shared process, SCRAM isolation, pgvector, read-only SQL, backup and restart are ready'
|