#!/usr/bin/env bash # # Dezky restore helper. A backup you've never restored is a backup you don't # have — run a drill periodically. This wraps the common restic restore flows. # # sudo ./restore.sh snapshots # list snapshots (primary) # sudo ./restore.sh snapshots --dr # list from the DR box # sudo ./restore.sh restore [--dr] # sudo ./restore.sh restore latest /tmp/restore-test # safe drill target # # Restores go to an arbitrary target dir (NOT in place) so you can inspect first. # For Stalwart, stop the service, swap /opt/stalwart/data, then start it. set -euo pipefail RED='\033[0;31m'; GREEN='\033[0;32m'; BLUE='\033[0;34m'; NC='\033[0m' info() { echo -e "${BLUE}[INFO]${NC} $*"; } ok() { echo -e "${GREEN}[OK]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } BACKUP_HOME="/opt/dezky-backup" ENV_FILE="${ENV_FILE:-$BACKUP_HOME/restic.env}" [[ -f "$ENV_FILE" ]] || { error "Missing $ENV_FILE"; exit 1; } # shellcheck disable=SC1090 source "$ENV_FILE" export HOME="$BACKUP_HOME" export RESTIC_PASSWORD pick_repo() { if [[ "${*: -1}" == "--dr" ]]; then [[ -n "${BACKUP_DR_REPO:-}" ]] || { error "BACKUP_DR_REPO not set"; exit 1; } echo "$BACKUP_DR_REPO" else echo "$BACKUP_PRIMARY_REPO" fi } cmd="${1:-}"; shift || true case "$cmd" in snapshots) repo="$(pick_repo "$@")" info "Snapshots in $repo:" restic -r "$repo" snapshots --tag dezky ;; restore) snap="${1:?snapshot id (or 'latest')}"; target="${2:?target dir}" repo="$(pick_repo "$@")" mkdir -p "$target" info "Restoring $snap from $repo → $target" restic -r "$repo" restore "$snap" --target "$target" ok "Restored. Inspect $target before putting anything back in place." ;; *) error "Usage: $0 {snapshots|restore} ... (see header)" exit 1 ;; esac