#!/usr/bin/env bash set -euo pipefail ENV_FILE="${ENV_FILE:-./.env}" if [[ -f "$ENV_FILE" ]]; then set -a # shellcheck source=/dev/null . "$ENV_FILE" set +a fi if [[ -z "${DATABASE_URL:-}" && -z "${BACKUP_DATABASE_URL:-}" ]]; then echo "DATABASE_URL or BACKUP_DATABASE_URL is required." exit 1 fi BACKUP_URL="${BACKUP_DATABASE_URL:-$DATABASE_URL}" extract_host() { local url="$1" sed -E 's#^[a-zA-Z][a-zA-Z0-9+.-]*://[^@/]+@([^/:?]+).*$#\1#' <<< "$url" } extract_db() { local url="$1" sed -E 's#^[a-zA-Z][a-zA-Z0-9+.-]*://[^/]+/([^?]+).*$#\1#' <<< "$url" } if [[ "${BACKUP_ENFORCE_TARGET_CHECK:-0}" == "1" ]]; then BACKUP_EXPECTED_HOST="${EXPECTED_BACKUP_DB_HOST:-${EXPECTED_PROD_DB_HOST:-}}" BACKUP_EXPECTED_NAME="${EXPECTED_BACKUP_DB_NAME:-${EXPECTED_PROD_DB_NAME:-}}" if [[ -z "$BACKUP_EXPECTED_HOST" || -z "$BACKUP_EXPECTED_NAME" ]]; then echo "BACKUP_ENFORCE_TARGET_CHECK=1 requires EXPECTED_BACKUP_DB_HOST/NAME (or EXPECTED_PROD_DB_HOST/NAME)." exit 1 fi ACTUAL_HOST="$(extract_host "$BACKUP_URL")" ACTUAL_DB="$(extract_db "$BACKUP_URL")" if [[ "$ACTUAL_HOST" == "$BACKUP_URL" || "$ACTUAL_DB" == "$BACKUP_URL" ]]; then echo "Unable to parse backup database URL." exit 1 fi if [[ "$ACTUAL_HOST" != "$BACKUP_EXPECTED_HOST" ]]; then echo "Backup target host mismatch. expected=$BACKUP_EXPECTED_HOST actual=$ACTUAL_HOST" exit 1 fi if [[ "$ACTUAL_DB" != "$BACKUP_EXPECTED_NAME" ]]; then echo "Backup target db mismatch. expected=$BACKUP_EXPECTED_NAME actual=$ACTUAL_DB" exit 1 fi fi OUT_DIR="${BACKUP_DIR:-./backups}" mkdir -p "$OUT_DIR" STAMP="$(date +%F_%H%M%S)" OUT_FILE="${OUT_DIR}/skymoney_${STAMP}.dump" OUT_BASENAME="$(basename "$OUT_FILE")" OUT_DIR_ABS="$(cd "$OUT_DIR" && pwd)" START_TS="$(date +%s)" pg_dump "$BACKUP_URL" -Fc -f "$OUT_FILE" (cd "$OUT_DIR_ABS" && sha256sum "$OUT_BASENAME" > "${OUT_BASENAME}.sha256") END_TS="$(date +%s)" RUNTIME_SEC="$((END_TS - START_TS))" echo "Backup written to: $OUT_FILE" echo "Checksum written to: ${OUT_FILE}.sha256" echo "Backup runtime seconds: $RUNTIME_SEC"