citadel/backup/list-snapshots
Nicolas Duhamel f82a913bdd Refactor: Centralize configuration and improve security
- Add centralized configuration system with backup.env
- Move configuration files to proper structure (config/ directory)
- Remove hardcoded paths and make system portable
- Fix security issue: remove password exposure in gen-conf.sh
- Add comprehensive documentation (README.md, CLAUDE.md)
- Create configuration template (backup.env.sample)
- Add .gitignore to protect sensitive files
- Update all scripts to use environment variables
- Implement systemd template variable substitution

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-23 21:13:11 +02:00

158 lines
4.9 KiB
Bash
Executable File

#!/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 "$@"