136 lines
3.4 KiB
Bash
Executable File
136 lines
3.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
BACKUP_DIR="${BACKUP_DIR:-/mnt2/homey-backup}"
|
|
RESTORE_BASE="${RESTORE_BASE:-/mnt/replicas}"
|
|
|
|
usage() {
|
|
echo "Usage: $0 <pvc-name-or-friendly-name> [--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"
|