feat: Update backup script to disable interactive mode by default and add command-line option for enabling it

This commit is contained in:
Peter Wood
2025-06-04 08:02:21 -04:00
parent f202301529
commit 780e78f132

View File

@@ -34,7 +34,7 @@ PLEX_SQLITE="/usr/lib/plexmediaserver/Plex SQLite"
# Script options
AUTO_REPAIR=false
INTEGRITY_CHECK_ONLY=false
INTERACTIVE_MODE=true
INTERACTIVE_MODE=false
PARALLEL_VERIFICATION=true
PERFORMANCE_MONITORING=true
WEBHOOK_URL="https://notify.peterwood.rocks/lab"
@@ -56,6 +56,10 @@ while [[ $# -gt 0 ]]; do
INTERACTIVE_MODE=false
shift
;;
--interactive)
INTERACTIVE_MODE=true
shift
;;
--no-parallel)
PARALLEL_VERIFICATION=false
shift
@@ -718,33 +722,30 @@ verify_files_parallel() {
return $verification_errors
}
# Verify backup integrity
# Verify backup integrity with robust checksum handling
verify_backup() {
local src="$1"
local dest="$2"
log_message "Verifying backup integrity: $(basename "$src")"
local src_checksum=$(calculate_checksum "$src")
local src_result=$?
local dest_checksum=$(calculate_checksum "$dest")
# Calculate destination checksum first (this doesn't change)
local dest_checksum
dest_checksum=$(sudo md5sum "$dest" 2>/dev/null | cut -d' ' -f1)
local dest_result=$?
# Handle permission issues gracefully
if [ "$src_checksum" == "PERMISSION_DENIED" ]; then
log_warning "Cannot verify $(basename "$src") - permission denied on source file"
log_warning "Skipping verification for this file"
return 0 # Consider it successful since we can't verify
fi
if [ "$dest_checksum" == "PERMISSION_DENIED" ]; then
log_error "Cannot verify $(basename "$dest") - permission denied on backup file"
if [ $dest_result -ne 0 ] || [[ ! "$dest_checksum" =~ ^[a-f0-9]{32}$ ]]; then
log_error "Failed to calculate destination checksum for $(basename "$dest")"
return 1
fi
if [ $src_result -ne 0 ] || [ $dest_result -ne 0 ]; then
log_error "Failed to calculate checksums for verification"
log_error "Source checksum result: $src_result, Dest checksum result: $dest_result"
# Calculate source checksum (without caching to get current state)
local src_checksum
src_checksum=$(sudo md5sum "$src" 2>/dev/null | cut -d' ' -f1)
local src_result=$?
if [ $src_result -ne 0 ] || [[ ! "$src_checksum" =~ ^[a-f0-9]{32}$ ]]; then
log_error "Failed to calculate source checksum for $(basename "$src")"
return 1
fi
@@ -754,10 +755,48 @@ verify_backup() {
log_info "Backup checksum: $dest_checksum"
return 0
else
log_error "Backup verification failed: $(basename "$src")"
log_error "Source checksum: $src_checksum"
log_error "Backup checksum: $dest_checksum"
return 1
# If checksums don't match, wait a moment and try again (in case of delayed writes)
log_warning "Initial checksum mismatch for $(basename "$src"), retrying in 2 seconds..."
sleep 2
# Recalculate source checksum
src_checksum=$(sudo md5sum "$src" 2>/dev/null | cut -d' ' -f1)
src_result=$?
if [ $src_result -ne 0 ] || [[ ! "$src_checksum" =~ ^[a-f0-9]{32}$ ]]; then
log_error "Failed to recalculate source checksum for $(basename "$src")"
return 1
fi
if [ "$src_checksum" == "$dest_checksum" ]; then
log_success "Backup verification passed on retry: $(basename "$src")"
log_info "Source checksum: $src_checksum"
log_info "Backup checksum: $dest_checksum"
return 0
else
log_error "Backup verification failed: $(basename "$src")"
log_error "Source checksum: $src_checksum"
log_error "Backup checksum: $dest_checksum"
# For database files, this might be normal if Plex processes modified the file
# Let's do a final check - if the backup file is a valid database, we might accept it
if [[ "$(basename "$src")" == *.db ]]; then
log_warning "Database file checksum mismatch might be due to post-backup modifications"
log_warning "Checking if backup database is valid..."
# Basic SQLite validation
if sudo "$PLEX_SQLITE" "$dest" "PRAGMA integrity_check;" 2>/dev/null | grep -q "^ok$"; then
log_warning "Backup database integrity is valid despite checksum mismatch"
log_warning "Accepting backup (source file may have been modified after copy)"
return 0
else
log_error "Backup database integrity check failed"
return 1
fi
fi
return 1
fi
fi
}
@@ -956,10 +995,13 @@ check_integrity_only() {
should_repair=true
log_message "Auto-repair enabled, attempting repair..."
elif [ "$INTERACTIVE_MODE" = true ]; then
read -p "Attempt to repair $(basename "$file")? [y/N]: " -n 1 -r
read -p "Attempt to repair $(basename "$file")? [y/N]: " -n 1 -r -t 30
local read_result=$?
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [ $read_result -eq 0 ] && [[ $REPLY =~ ^[Yy]$ ]]; then
should_repair=true
elif [ $read_result -ne 0 ]; then
log_warning "Read timeout or error, defaulting to no repair"
fi
else
log_warning "Non-interactive mode: skipping repair for $(basename "$file")"
@@ -1010,7 +1052,7 @@ main() {
# Create necessary directories
mkdir -p "${BACKUP_ROOT}"
mkdir -p "${LOG_ROOT}"
mkdir -p "${LOCAL_LOG_ROOT}"
# Initialize logs
initialize_logs
@@ -1065,10 +1107,13 @@ main() {
should_repair=true
log_message "Auto-repair enabled, attempting repair..."
elif [ "$INTERACTIVE_MODE" = true ]; then
read -p "Database $(basename "$file") has integrity issues. Attempt repair before backup? [y/N]: " -n 1 -r
read -p "Database $(basename "$file") has integrity issues. Attempt repair before backup? [y/N]: " -n 1 -r -t 30
local read_result=$?
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
if [ $read_result -eq 0 ] && [[ $REPLY =~ ^[Yy]$ ]]; then
should_repair=true
elif [ $read_result -ne 0 ]; then
log_warning "Read timeout or error, defaulting to no repair"
fi
else
log_warning "Non-interactive mode: backing up database with integrity issues"