#!/usr/bin/env bash # restore.sh — PostgreSQL restore for Trainingssoftware # # CAUTION: This drops and recreates the target database. Never run against # production without explicit human confirmation and a pre-restore # backup of the target. # # Usage: # TARGET_DATABASE_URL=postgres://user:pass@host:5432/dbname_restore \ # ops/scripts/restore.sh s3://my-bucket/backups/trainingssoftware-20260101T120000Z.dump # # — or with a local file — # # TARGET_DATABASE_URL=postgres://... \ # ops/scripts/restore.sh /tmp/trainingssoftware-20260101T120000Z.dump set -euo pipefail SOURCE="${1:-}" if [[ -z "${SOURCE}" ]]; then echo "Usage: $0 " >&2 exit 1 fi if [[ -z "${TARGET_DATABASE_URL:-}" ]]; then echo "ERROR: TARGET_DATABASE_URL is not set." >&2 exit 1 fi DUMP_FILE="${SOURCE}" # Download from S3 if needed if [[ "${SOURCE}" == s3://* ]]; then DUMP_FILE="/tmp/restore-$(date -u +%Y%m%dT%H%M%SZ).dump" echo "[restore] Downloading ${SOURCE} → ${DUMP_FILE}" aws s3 cp "${SOURCE}" "${DUMP_FILE}" fi echo "[restore] Source dump: ${DUMP_FILE}" echo "[restore] Target: ${TARGET_DATABASE_URL}" echo "" echo "WARNING: This will DROP all objects in the target database and restore" echo " from the dump. Data in the target will be permanently lost." echo "" read -r -p "Type 'yes' to continue: " CONFIRM if [[ "${CONFIRM}" != "yes" ]]; then echo "[restore] Aborted." exit 1 fi echo "[restore] Restoring…" pg_restore \ --format=custom \ --clean \ --if-exists \ --no-acl \ --no-owner \ --dbname="${TARGET_DATABASE_URL}" \ "${DUMP_FILE}" echo "[restore] Restore complete." # Cleanup temp download if [[ "${SOURCE}" == s3://* ]]; then rm -f "${DUMP_FILE}" fi echo "[restore] Done."