diff --git a/scripts/imports/view_snapshots.sh b/scripts/imports/view_snapshots.sh index 5d5db9f..7f76fbf 100644 --- a/scripts/imports/view_snapshots.sh +++ b/scripts/imports/view_snapshots.sh @@ -1,80 +1,167 @@ #!/bin/bash -# Exit immediately on error -set -e - # Configuration backupPath='/mnt/backups' password_file="/etc/restic-password" -LOG_FILE="/var/log/restic_snapshot.log" +LOG_DIR="$HOME/mb-backups/logs" +LOG_FILE="${LOG_DIR}/restic_snapshot.log" +ERROR_LOG_FILE="${LOG_DIR}/restic_snapshot_error.log" + +# Ensure log directory exists +mkdir -p "$LOG_DIR" # Logging function log_message() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } -# Function: Display usage +# Error logging function +log_error() { + echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1" | tee -a "$ERROR_LOG_FILE" +} + +# Function: Display usage and tags display_usage() { + local tags + tags=$(fetch_available_tags) echo "Usage: $0 " echo "Available tags:" - restic -r "$RESTIC_REPOSITORY" snapshots --json 2>/dev/null | jq -r '.[].tags[]' | sort -u || echo "main_backup, wordpress_db, core_files, media_themes, full_backup" + if [ -z "$tags" ]; then + echo " (No tags found or repository inaccessible)" + else + echo " all" + echo "$tags" | sed 's/^/ /' + fi exit 1 } -# Ensure dependencies are installed -validate_dependencies() { - for cmd in restic jq; do - if ! command -v "$cmd" &>/dev/null; then - log_message "ERROR: Required command '$cmd' not found. Please install it." - exit 1 - fi - done +# Function: Fetch available tags +fetch_available_tags() { + log_message "Fetching available tags..." + local snapshot_json + + # Retrieve JSON snapshot data + snapshot_json=$(RESTIC_PASSWORD=$(cat "$password_file") restic -r "$backupPath" snapshots --json 2>/dev/null) + if [ $? -ne 0 ]; then + log_error "Failed to retrieve snapshots. Check repository path or password." + return 1 + fi + + # Extract unique tags from JSON data + local tags + tags=$(echo "$snapshot_json" | jq -r '.[].tags[]' 2>/dev/null | sort -u | uniq) + if [ -z "$tags" ]; then + log_message "No tags found in repository snapshots." + fi + + echo "$tags" + return 0 } -# Validate environment +# Function: Validate repository access +# Function: Validate repository access +validate_repository() { + log_message "Validating repository access..." + + # Check if repository path exists + if [ ! -d "$backupPath" ]; then + log_error "Backup path '$backupPath' does not exist or is not accessible." + echo "Restic repository path not found. Please verify that the path exists and is mounted." + exit 1 + fi + + # Check if Restic can access the repository + if ! RESTIC_PASSWORD=$(cat "$password_file") restic -r "$backupPath" snapshots &>/dev/null; then + # Attempt to fix permissions automatically + log_message "Attempting to fix permissions for '$backupPath'..." + sudo chown -R $(whoami):$(whoami) "$backupPath" + sudo chmod -R u+rw "$backupPath" + + # Retry repository validation + if ! RESTIC_PASSWORD=$(cat "$password_file") restic -r "$backupPath" snapshots &>/dev/null; then + log_error "Unable to access Restic repository at '$backupPath'." + echo "Restic repository is inaccessible. Please check the path, permissions, or mount status." + exit 1 + fi + fi + + log_message "Repository access validated successfully." +} + +# Function: Fix permissions if necessary +fix_permissions() { + log_message "Checking permissions for '$backupPath'..." + if [ ! -r "$backupPath" ] || [ ! -w "$backupPath" ]; then + log_message "Fixing permissions for '$backupPath'..." + sudo chown -R $(whoami):$(whoami) "$backupPath" + sudo chmod -R u+rw "$backupPath" + fi +} + +# Function: Display all snapshots +display_all_snapshots() { + log_message "Retrieving all snapshots..." + if RESTIC_PASSWORD=$(cat "$password_file") restic -r "$backupPath" snapshots --json | jq -r '.[] | "\(.short_id) \(.time) \(.tags | join(", "))"' 2>/dev/null; then + log_message "All snapshots displayed successfully." + else + log_error "Unable to retrieve all snapshots." + exit 1 + fi +} + +# Function: Validate environment validate_environment() { if [ ! -f "$password_file" ]; then - log_message "ERROR: Password file not found at $password_file" + log_error "Password file not found at $password_file" exit 1 fi if [ ! -d "$backupPath" ]; then - log_message "ERROR: Backup path '$backupPath' does not exist or is not accessible." + log_error "Backup path '$backupPath' does not exist or is not accessible." exit 1 fi + + validate_repository + fix_permissions } # Main script logic main() { - # Ensure a tag is provided - if [ "$#" -ne 1 ]; then + # If no arguments are provided, display usage + if [ "$#" -eq 0 ]; then display_usage fi # Assign input argument TAG=$1 - # Set Restic environment variables - export RESTIC_REPOSITORY="$backupPath" - export RESTIC_PASSWORD=$(cat "$password_file") + # Validate environment and dependencies + validate_environment + + # Handle the special case for "all" + if [ "$TAG" == "all" ]; then + display_all_snapshots + exit 0 + fi # Validate the tag - if ! restic -r "$RESTIC_REPOSITORY" snapshots --json 2>/dev/null | jq -e ".[] | select(.tags[] == \"$TAG\")" &>/dev/null; then - log_message "ERROR: Unknown or unused tag '$TAG'." + log_message "Validating tag '$TAG'..." + local available_tags + available_tags=$(fetch_available_tags) + if ! echo "$available_tags" | grep -qw "$TAG"; then + log_error "Unknown or unused tag '$TAG'." display_usage fi # Display snapshots for the provided tag log_message "Retrieving snapshots for tag '$TAG'..." - if restic -r "$RESTIC_REPOSITORY" snapshots --tag "$TAG" --json | jq -r '.[] | "\(.short_id) \(.time) \(.tags | join(", "))"' 2>/dev/null; then + if RESTIC_PASSWORD=$(cat "$password_file") restic -r "$backupPath" snapshots --tag "$TAG" --json | jq -r '.[] | "\(.short_id) \(.time) \(.tags | join(", "))"' 2>/dev/null; then log_message "Snapshots for tag '$TAG' displayed successfully." else - log_message "ERROR: Unable to display snapshots for tag '$TAG'." + log_error "Unable to display snapshots for tag '$TAG'." exit 1 fi } -# Run validations and execute the main function -validate_dependencies -validate_environment +# Run main function main "$@"