#!/usr/bin/env bash # ============================================================================= # restore.sh — restore a backup to the live database. # WARNING: drops existing data. # ============================================================================= set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$ROOT_DIR" [ "${1:-}" ] || { echo "Usage: $0 backups/expenses-YYYYMMDD-HHMMSS.sql.gz"; exit 1; } FILE="$1" [ -f "$FILE" ] || { echo "ERROR: file not found: $FILE"; exit 1; } [ -f .env ] || { echo "ERROR: .env not found"; exit 1; } set -a; source .env; set +a : "${OCI_VM_NAME:=sk1-expense-tracker}" : "${POSTGRES_USER:?POSTGRES_USER must be set}" : "${POSTGRES_DB:?POSTGRES_DB must be set}" : "${OCI_SSH_PRIVATE_KEY_PATH:=$HOME/.ssh/id_ed25519}" OCI_SSH_PRIVATE_KEY_PATH="${OCI_SSH_PRIVATE_KEY_PATH/#\~/$HOME}" TENANCY_OCID="$(oci iam compartment list --query 'data[0]."compartment-id"' --raw-output)" COMPARTMENT_ID="${OCI_COMPARTMENT_ID:-$TENANCY_OCID}" INSTANCE_ID="$(oci compute instance list --compartment-id "$COMPARTMENT_ID" \ --display-name "$OCI_VM_NAME" --lifecycle-state RUNNING \ --query 'data[0].id' --raw-output)" VNIC_ID="$(oci compute instance list-vnics --instance-id "$INSTANCE_ID" --query 'data[0].id' --raw-output)" PUBLIC_IP="$(oci network vnic get --vnic-id "$VNIC_ID" --query 'data."public-ip"' --raw-output)" read -p "Restore $FILE → $POSTGRES_DB on $PUBLIC_IP? This WIPES existing data. [y/N] " ans [ "$ans" = "y" ] || [ "$ans" = "Y" ] || exit 1 echo "[restore] streaming dump..." gunzip -c "$FILE" | ssh -i "$OCI_SSH_PRIVATE_KEY_PATH" -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null ubuntu@"$PUBLIC_IP" \ "sg docker -c 'docker exec -i sk1-db pg_restore -U $POSTGRES_USER -d $POSTGRES_DB --clean --if-exists'" echo "[restore] done."