mirror of
https://github.com/acedanger/shell.git
synced 2025-12-06 06:40:13 -08:00
feat: Implement comprehensive Immich backup and restore scripts with validation and notification features
This commit is contained in:
177
immich/validate-immich-backups.sh
Executable file
177
immich/validate-immich-backups.sh
Executable file
@@ -0,0 +1,177 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Immich Backup Validation Script
|
||||
# This script validates Immich backup files for integrity and completeness
|
||||
|
||||
# Set up error handling
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to display usage
|
||||
usage() {
|
||||
echo "Usage: $0 [backup_directory]"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " backup_directory Directory containing backup files (default: ../immich_backups)"
|
||||
echo ""
|
||||
echo "This script validates:"
|
||||
echo " - Database backup file integrity"
|
||||
echo " - Upload archive integrity"
|
||||
echo " - File sizes and timestamps"
|
||||
echo " - Backup completeness"
|
||||
}
|
||||
|
||||
# Parse command line arguments
|
||||
BACKUP_DIR="${1:-$(dirname "$0")/../immich_backups}"
|
||||
|
||||
# Set up logging to central logs directory
|
||||
LOG_DIR="$(dirname "$0")/../logs"
|
||||
mkdir -p "$LOG_DIR"
|
||||
LOG_FILE="${LOG_DIR}/immich-validation.log"
|
||||
|
||||
# Function to log validation results
|
||||
log_validation() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Verify backup directory exists
|
||||
if [ ! -d "$BACKUP_DIR" ]; then
|
||||
echo -e "${RED}Error: Backup directory not found: $BACKUP_DIR${NC}"
|
||||
log_validation "Error: Backup directory not found: $BACKUP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_validation "Starting backup validation for directory: $BACKUP_DIR"
|
||||
echo "=== IMMICH BACKUP VALIDATION ==="
|
||||
echo "Backup directory: $BACKUP_DIR"
|
||||
echo ""
|
||||
|
||||
# Find backup files
|
||||
DB_BACKUPS=$(find "$BACKUP_DIR" -name "immich_db_backup_*.sql.gz" -type f | sort -r)
|
||||
UPLOAD_BACKUPS=$(find "$BACKUP_DIR" -name "immich_uploads_*.tar.gz" -type f | sort -r)
|
||||
|
||||
TOTAL_ERRORS=0
|
||||
|
||||
echo "=== DATABASE BACKUPS ==="
|
||||
if [ -z "$DB_BACKUPS" ]; then
|
||||
echo -e "${YELLOW}Warning: No database backup files found${NC}"
|
||||
log_validation "Warning: No database backup files found"
|
||||
((TOTAL_ERRORS++))
|
||||
else
|
||||
for backup in $DB_BACKUPS; do
|
||||
echo "Validating: $(basename "$backup")"
|
||||
|
||||
# Check file size
|
||||
SIZE=$(stat -c%s "$backup" 2>/dev/null || echo "0")
|
||||
if [ "$SIZE" -lt 1024 ]; then
|
||||
echo -e " ${RED}✗ File is too small (${SIZE} bytes)${NC}"
|
||||
log_validation "Error: File is too small (${SIZE} bytes) - $(basename "$backup")"
|
||||
((TOTAL_ERRORS++))
|
||||
else
|
||||
echo -e " ${GREEN}✓ File size OK ($(du -h "$backup" | cut -f1))${NC}"
|
||||
fi
|
||||
|
||||
# Check if it's a valid gzip file
|
||||
if gzip -t "$backup" 2>/dev/null; then
|
||||
echo -e " ${GREEN}✓ Gzip file integrity OK${NC}"
|
||||
else
|
||||
echo -e " ${RED}✗ Gzip file corruption detected${NC}"
|
||||
log_validation "Error: Gzip file corruption detected - $(basename "$backup")"
|
||||
((TOTAL_ERRORS++))
|
||||
fi
|
||||
|
||||
# Check if SQL content looks valid (basic check)
|
||||
if zcat "$backup" 2>/dev/null | head -n 10 | grep -q "PostgreSQL database dump"; then
|
||||
echo -e " ${GREEN}✓ SQL content appears valid${NC}"
|
||||
else
|
||||
echo -e " ${YELLOW}? Cannot verify SQL content format${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
fi
|
||||
|
||||
echo "=== UPLOAD BACKUPS ==="
|
||||
if [ -z "$UPLOAD_BACKUPS" ]; then
|
||||
echo -e "${YELLOW}Warning: No upload backup files found${NC}"
|
||||
log_validation "Warning: No upload backup files found"
|
||||
((TOTAL_ERRORS++))
|
||||
else
|
||||
for backup in $UPLOAD_BACKUPS; do
|
||||
echo "Validating: $(basename "$backup")"
|
||||
|
||||
# Check file size
|
||||
SIZE=$(stat -c%s "$backup" 2>/dev/null || echo "0")
|
||||
if [ "$SIZE" -lt 1024 ]; then
|
||||
echo -e " ${RED}✗ File is too small (${SIZE} bytes)${NC}"
|
||||
log_validation "Error: File is too small (${SIZE} bytes) - $(basename "$backup")"
|
||||
((TOTAL_ERRORS++))
|
||||
else
|
||||
echo -e " ${GREEN}✓ File size OK ($(du -h "$backup" | cut -f1))${NC}"
|
||||
fi
|
||||
|
||||
# Check if it's a valid tar.gz file
|
||||
if tar -tzf "$backup" >/dev/null 2>&1; then
|
||||
echo -e " ${GREEN}✓ Tar.gz file integrity OK${NC}"
|
||||
|
||||
# Count files in archive
|
||||
FILE_COUNT=$(tar -tzf "$backup" 2>/dev/null | wc -l)
|
||||
echo -e " ${GREEN}✓ Archive contains ${FILE_COUNT} files/directories${NC}"
|
||||
else
|
||||
echo -e " ${RED}✗ Tar.gz file corruption detected${NC}"
|
||||
log_validation "Error: Tar.gz file corruption detected - $(basename "$backup")"
|
||||
((TOTAL_ERRORS++))
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
fi
|
||||
|
||||
echo "=== BACKUP PAIRING VALIDATION ==="
|
||||
# Check if we have matching pairs of backups (same timestamp)
|
||||
DB_TIMESTAMPS=$(echo "$DB_BACKUPS" | sed 's/.*immich_db_backup_\([0-9_]*\)\.sql\.gz/\1/' | sort)
|
||||
UPLOAD_TIMESTAMPS=$(echo "$UPLOAD_BACKUPS" | sed 's/.*immich_uploads_\([0-9_]*\)\.tar\.gz/\1/' | sort)
|
||||
|
||||
echo "Database backup timestamps: $(echo "$DB_TIMESTAMPS" | tr '\n' ' ')"
|
||||
echo "Upload backup timestamps: $(echo "$UPLOAD_TIMESTAMPS" | tr '\n' ' ')"
|
||||
|
||||
# Find matching pairs
|
||||
MATCHED_PAIRS=0
|
||||
for db_ts in $DB_TIMESTAMPS; do
|
||||
if echo "$UPLOAD_TIMESTAMPS" | grep -q "^${db_ts}$"; then
|
||||
echo -e "${GREEN}✓ Complete backup set found for timestamp: $db_ts${NC}"
|
||||
((MATCHED_PAIRS++))
|
||||
else
|
||||
echo -e "${YELLOW}? Incomplete backup set for timestamp: $db_ts (missing upload backup)${NC}"
|
||||
log_validation "Warning: Incomplete backup set for timestamp: $db_ts (missing upload backup)"
|
||||
fi
|
||||
done
|
||||
|
||||
for upload_ts in $UPLOAD_TIMESTAMPS; do
|
||||
if ! echo "$DB_TIMESTAMPS" | grep -q "^${upload_ts}$"; then
|
||||
echo -e "${YELLOW}? Incomplete backup set for timestamp: $upload_ts (missing database backup)${NC}"
|
||||
log_validation "Warning: Incomplete backup set for timestamp: $upload_ts (missing database backup)"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== VALIDATION SUMMARY ==="
|
||||
echo "Complete backup pairs: $MATCHED_PAIRS"
|
||||
echo "Total validation errors: $TOTAL_ERRORS"
|
||||
|
||||
log_validation "Validation summary: $MATCHED_PAIRS complete backup pairs, $TOTAL_ERRORS errors"
|
||||
|
||||
if [ "$TOTAL_ERRORS" -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ All backup validations passed${NC}"
|
||||
log_validation "Success: All backup validations passed"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}✗ Backup validation failed with $TOTAL_ERRORS errors${NC}"
|
||||
log_validation "Error: Backup validation failed with $TOTAL_ERRORS errors"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user