#!/bin/sh set -eu if [ "$#" -ne 1 ]; then echo "usage: $0 " >&2 exit 2 fi backup_dir="$1" image="${ASSISTANT_RESTORE_IMAGE:-postgres:18.6-alpine}" container="assistant-postgres-restore-check-$(date -u +%Y%m%dT%H%M%SZ)-$$" password="$(od -An -N24 -tx1 /dev/urandom | tr -d ' \n')" created=false cleanup() { if [ "$created" = true ]; then docker rm -f "$container" >/dev/null 2>&1 || true fi } trap cleanup EXIT HUP INT TERM for file in assistant.dump globals.sql database.name owner.name SHA256SUMS; do if [ ! -f "$backup_dir/$file" ]; then echo "Backup file is missing: $file" >&2 exit 1 fi done ( cd "$backup_dir" sha256sum -c SHA256SUMS ) database="$(sed -n '1p' "$backup_dir/database.name")" owner="$(sed -n '1p' "$backup_dir/owner.name")" [ -n "$database" ] && [ -n "$owner" ] || { echo "Database metadata is empty" >&2 exit 1 } case "$database:$owner" in *[!A-Za-z0-9_:.-]*) echo "Unsafe database metadata" >&2; exit 1 ;; esac docker run -d --name "$container" \ --tmpfs /var/lib/postgresql:rw,noexec,nosuid,size=1g \ -e POSTGRES_PASSWORD="$password" \ "$image" >/dev/null created=true attempt=0 until docker exec "$container" pg_isready -U postgres -d postgres >/dev/null 2>&1; do attempt=$((attempt + 1)) if [ "$attempt" -ge 60 ]; then docker logs "$container" >&2 echo "Restore-check PostgreSQL did not become ready" >&2 exit 1 fi sleep 1 done docker exec -i "$container" psql -v ON_ERROR_STOP=1 -U postgres -d postgres <"$backup_dir/globals.sql" >/dev/null docker exec "$container" psql -v ON_ERROR_STOP=1 -U postgres -d postgres \ -c "CREATE DATABASE \"$database\" OWNER \"$owner\"" >/dev/null docker exec -i "$container" pg_restore --exit-on-error --no-password -U postgres -d "$database" <"$backup_dir/assistant.dump" >/dev/null schema_count="$(docker exec "$container" psql -U postgres -d "$database" -Atqc "select count(*) from information_schema.schemata where schema_name not in ('pg_catalog','information_schema') and schema_name not like 'pg_toast%'")" table_count="$(docker exec "$container" psql -U postgres -d "$database" -Atqc "select count(*) from information_schema.tables where table_schema not in ('pg_catalog','information_schema')")" if [ "$schema_count" -lt 1 ] || [ "$table_count" -lt 1 ]; then echo "Restored database lacks expected user objects" >&2 exit 1 fi printf 'restore verified: database=%s schemas=%s tables=%s\n' "$database" "$schema_count" "$table_count"