#!/bin/bash # Script to list available snapshots from Restic repository # Usage: ./list-snapshots [service_name] set -e # Configuration should be sourced before running: source backup.env # Configuration BACKUP_DIR="$BACKUP_BASE_DIR" CONFIG_FILE="$RESTIC_CONFIG_FILE" # Colors for output BLUE='\033[0;34m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color show_help() { echo "Usage: $0 [service_name]" echo "" echo "List available snapshots from Restic repository" echo "" echo "Examples:" echo " $0 # List all snapshots grouped by service" echo " $0 paperless # List snapshots for paperless service only" echo "" } log() { echo -e "${BLUE}[INFO]${NC} $1" } list_all_snapshots() { log "All available snapshots:" echo "" local snapshots=$(restic snapshots --json 2>/dev/null) if [ -z "$snapshots" ] || [ "$snapshots" = "null" ] || [ "$snapshots" = "[]" ]; then echo "No snapshots found in repository." return fi # Filter out timestamp tags (like paperless-20250609-115655) and retention tags local services=$(echo "$snapshots" | jq -r '.[].tags[]' | grep -v -E '^(daily|weekly|monthly|yearly)$' | grep -v -E '^.*-[0-9]{8}-[0-9]{6}$' | sort -u) for service in $services; do echo -e "${GREEN}=== $service ===${NC}" # Display snapshots for this service echo "$snapshots" | jq -r ".[] | select(.tags[] == \"$service\") | \"\(.short_id) \(.time[:19]) \(.summary.total_files_processed) \((.summary.total_bytes_processed / 1024 / 1024 / 1024 * 100 | floor) / 100)\"" | \ awk 'BEGIN {printf "%-10s %-20s %-10s %s\n", "ID", "DATE", "FILES", "SIZE(GB)"; print "-------------------------------------------------------"} {printf "%-10s %-20s %-10s %.2f\n", $1, $2, $3, $4}' echo "" done } list_service_snapshots() { local service="$1" log "Snapshots for service: $service" echo "" local snapshots=$(restic snapshots --tag "$service" --json 2>/dev/null) if [ -z "$snapshots" ] || [ "$snapshots" = "null" ] || [ "$snapshots" = "[]" ]; then echo "No snapshots found for service: $service" return fi # Display snapshots in a readable format echo "$snapshots" | jq -r '.[] | "\(.short_id) \(.time[:19]) \(.tags | join(",")) \(.summary.total_files_processed) \((.summary.total_bytes_processed / 1024 / 1024 / 1024 * 100 | floor) / 100)"' | \ awk 'BEGIN {printf "%-10s %-20s %-35s %-10s %s\n", "ID", "DATE", "TAGS", "FILES", "SIZE(GB)"; print "-------------------------------------------------------------------------------------"} {printf "%-10s %-20s %-35s %-10s %.2f\n", $1, $2, $3, $4, $5}' echo "" # Show summary local count=$(echo "$snapshots" | jq length) local total_size=$(echo "$snapshots" | jq -r '.[].summary.total_bytes_processed' | awk '{sum+=$1} END {printf "%.2f", sum/1024/1024/1024}') local oldest=$(echo "$snapshots" | jq -r '.[0].time[:19]' 2>/dev/null) local newest=$(echo "$snapshots" | jq -r '.[-1].time[:19]' 2>/dev/null) echo -e "${YELLOW}Summary:${NC}" echo " Total snapshots: $count" echo " Total size: ${total_size}GB" if [ "$oldest" != "$newest" ]; then echo " Date range: $oldest to $newest" else echo " Date: $oldest" fi } show_repository_info() { log "Repository information:" echo "" # Repository stats restic stats --mode raw-data 2>/dev/null | head -10 echo "" log "Repository status:" restic check --read-data-subset=1% 2>/dev/null && echo "✅ Repository is healthy" || echo "⚠️ Repository check failed or not available" } # Main script logic main() { local service="${1:-}" if [ "$service" = "--help" ] || [ "$service" = "-h" ] || [ "$service" = "help" ]; then show_help exit 0 fi # Check if we're in the backup directory or config exists if [ ! -f "$CONFIG_FILE" ]; then echo "Error: Configuration file not found: $CONFIG_FILE" echo "Make sure you're running this from the backup directory or have valid restic.conf" exit 1 fi # Source Restic configuration source "$CONFIG_FILE" # Test repository access if ! restic snapshots >/dev/null 2>&1; then echo "Error: Cannot access Restic repository" echo "Check your configuration and repository password" exit 1 fi # List snapshots if [ -n "$service" ]; then list_service_snapshots "$service" else list_all_snapshots fi # Show repository info echo "" show_repository_info } # Check for required tools if ! command -v restic &> /dev/null; then echo "Error: restic is not installed or not in PATH" exit 1 fi if ! command -v jq &> /dev/null; then echo "Error: jq is not installed (required for JSON parsing)" exit 1 fi # Run main function main "$@"