#!/usr/bin/env bash set -euo pipefail BACKUP_DIR="${BACKUP_DIR:-/mnt2/homey-backup}" RESTORE_BASE="${RESTORE_BASE:-/mnt/replicas}" usage() { echo "Usage: $0 [--dry-run]" echo "" echo "Restores a Longhorn volume backup to the replicas directory." echo "" echo "Arguments:" echo " pvc-name-or-friendly-name The PVC ID or friendly name" echo " --dry-run Show what would be done without copying" echo "" echo "Examples:" echo " $0 nextcloud-data-pvc" echo " $0 nextcloud-data-pvc --dry-run" echo "" echo "WARNING: This will overwrite existing data in $RESTORE_BASE" exit 1 } if [[ $# -lt 1 ]]; then usage fi SEARCH_NAME="$1" DRY_RUN=false if [[ "${2:-}" == "--dry-run" ]]; then DRY_RUN=true fi MANIFEST="$BACKUP_DIR/manifest.json" if [[ ! -f "$MANIFEST" ]]; then echo "Error: Manifest not found at $MANIFEST_DIR" exit 1 fi find_volume() { local search="$1" while IFS= read -r line; do pvc_id=$(echo "$line" | grep -oP '"pvc_id":\s*"\K[^"]+') friendly=$(echo "$line" | grep -oP '"friendly_name":\s*"\K[^"]+') if [[ "$pvc_id" == "$search" ]] || [[ "$friendly" == "$search" ]]; then echo "$pvc_id:$friendly" return 0 fi done < <(grep -A6 '"volumes"' "$MANIFEST" | grep -E '"pvc_id"|"friendly_name"') return 1 } VOLUME_INFO=$(find_volume "$SEARCH_NAME") if [[ -z "$VOLUME_INFO" ]]; then echo "Error: Volume '$SEARCH_NAME' not found in manifest." echo "" echo "Available volumes:" grep -oP '"friendly_name":\s*"\K[^"]+' "$MANIFEST" | while read -r name; do echo " - $name" done exit 1 fi PVC_ID="${VOLUME_INFO%%:*}" FRIENDLY_NAME="${VOLUME_INFO#*:}" BACKUP_VOLUME_DIR="$BACKUP_DIR/volumes/$PVC_ID" RESTORE_VOLUME_DIR="$RESTORE_BASE/$PVC_ID" echo "========================================" echo " Restore Longhorn Volume" echo "========================================" echo "" echo "PVC ID: $PVC_ID" echo "Name: $FRIENDLY_NAME" echo "Source: $BACKUP_VOLUME_DIR" echo "Destination: $RESTORE_VOLUME_DIR" echo "Dry run: $DRY_RUN" echo "" if [[ "$DRY_RUN" == "true" ]]; then echo "[DRY RUN] Would copy:" du -sh "$BACKUP_VOLUME_DIR" 2>/dev/null || echo " (size unknown)" echo "" echo "Files to copy:" find "$BACKUP_VOLUME_DIR" -type f | head -20 exit 0 fi if [[ -d "$RESTORE_VOLUME_DIR" ]]; then echo "WARNING: Destination already exists!" echo "" read -p "Overwrite existing data? [y/N] " -n 1 -r echo "" if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Aborted." exit 1 fi echo "" echo "Removing existing data..." sudo rm -rf "$RESTORE_VOLUME_DIR" fi echo "Creating destination directory..." sudo mkdir -p "$RESTORE_VOLUME_DIR" echo "Copying volume data..." sudo rsync -a --no-owner --no-group --info=progress2 \ "$BACKUP_VOLUME_DIR/" \ "$RESTORE_VOLUME_DIR/" echo "" echo "Setting permissions..." sudo chmod 700 "$RESTORE_VOLUME_DIR" echo "" echo "========================================" echo " Restore Complete!" echo "========================================" echo "" echo "Restored to: $RESTORE_VOLUME_DIR" echo "" echo "Size:" sudo du -sh "$RESTORE_VOLUME_DIR" echo "" echo "Next steps:" echo "1. Ensure Longhorn is configured to use $RESTORE_BASE" echo "2. Restart Longhorn or the affected pod" echo "3. Verify data integrity"