#!/usr/bin/env bash set -Eeuo pipefail usage() { cat <<'EOF' Usage: restore-from-s3.sh latest restore-from-s3.sh Examples: restore-from-s3.sh latest restore-from-s3.sh qlockify/qlockify-backup-YYYYMMDD-HHMMSS.tar.gz.enc Environment: DEPLOY_ROOT Deployment directory. Defaults to ~/qlockify-deployment. S3_BACKUP_BUCKET S3 bucket name. S3_BACKUP_PREFIX S3 object prefix. Defaults to qlockify. S3_BACKUP_ENDPOINT_URL S3-compatible endpoint URL. S3_BACKUP_ACCESS_KEY_ID S3 access key. S3_BACKUP_SECRET_ACCESS_KEY S3 secret key. BACKUP_ENCRYPTION_PASSPHRASE Passphrase used to decrypt backup archives. Existing RESTORE_SKIP_DB, RESTORE_SKIP_MEDIA, and RESTORE_SKIP_ENV flags are passed through to restore.sh. EOF } log() { printf '[restore-rclone] %s\n' "$*" } fail() { printf '[restore-rclone] %s\n' "$*" >&2 exit 1 } require_var() { local name="$1" [[ -n "${!name:-}" ]] || fail "$name is required" } load_env() { local env_path="$1" [[ -f "$env_path" ]] || fail "Deployment env file not found: $env_path" set -a # shellcheck disable=SC1090 . "$env_path" set +a } normalize_prefix() { local value="${1:-qlockify}" value="${value#/}" value="${value%/}" printf '%s' "$value" } rclone_remote_path() { printf 'parspack:%s/%s' "$S3_BACKUP_BUCKET" "$S3_BACKUP_PREFIX" } latest_object_name() { rclone lsf "$REMOTE_PATH" \ --config "$RCLONE_CONFIG" \ --s3-no-check-bucket \ --files-only \ | grep '\.tar\.gz\.enc$' \ | sort \ | tail -n 1 \ || true } if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then usage exit 0 fi REQUESTED_KEY="${1:-}" [[ -n "$REQUESTED_KEY" ]] || { usage exit 1 } command -v rclone >/dev/null 2>&1 || fail "rclone is required" command -v openssl >/dev/null 2>&1 || fail "openssl is required" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DEPLOY_ROOT="${DEPLOY_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}" DEPLOY_ENV="$DEPLOY_ROOT/.env" RESTORE_SCRIPT="$SCRIPT_DIR/restore.sh" [[ -x "$RESTORE_SCRIPT" ]] || fail "Restore script is not executable: $RESTORE_SCRIPT" load_env "$DEPLOY_ENV" S3_BACKUP_PREFIX="$(normalize_prefix "${S3_BACKUP_PREFIX:-qlockify}")" require_var S3_BACKUP_BUCKET require_var S3_BACKUP_ENDPOINT_URL require_var S3_BACKUP_ACCESS_KEY_ID require_var S3_BACKUP_SECRET_ACCESS_KEY require_var BACKUP_ENCRYPTION_PASSPHRASE WORK_DIR="$(mktemp -d)" trap 'rm -rf "$WORK_DIR"' EXIT RCLONE_CONFIG="$WORK_DIR/rclone.conf" cat > "$RCLONE_CONFIG" <