#!/bin/bash ################################################################################ # Plex Recovery Validation Script ################################################################################ # # Author: Peter Wood # Description: Comprehensive validation script that verifies the success of # Plex database recovery operations. Performs extensive checks # on database integrity, service functionality, and system health # to ensure complete recovery and operational readiness. # # Features: # - Database integrity verification # - Service functionality testing # - Library accessibility checks # - Performance validation # - Web interface connectivity testing # - Comprehensive recovery reporting # - Post-recovery optimization suggestions # # Related Scripts: # - recover-plex-database.sh: Primary recovery script validated by this tool # - icu-aware-recovery.sh: ICU recovery validation # - nuclear-plex-recovery.sh: Nuclear recovery validation # - backup-plex.sh: Backup system that enables recovery # - validate-plex-backups.sh: Backup validation tools # - plex.sh: General Plex service management # # Usage: # ./validate-plex-recovery.sh # Full validation suite # ./validate-plex-recovery.sh --quick # Quick validation checks # ./validate-plex-recovery.sh --detailed # Detailed analysis and reporting # ./validate-plex-recovery.sh --performance # Performance validation only # # Dependencies: # - sqlite3 or Plex SQLite binary # - curl (for web interface testing) # - systemctl (for service status checks) # - Plex Media Server # # Exit Codes: # 0 - Recovery validation successful # 1 - General error # 2 - Database validation failures # 3 - Service functionality issues # 4 - Performance concerns detected # 5 - Partial recovery (requires attention) # ################################################################################ # Final Plex Recovery Validation Script # Comprehensive check to ensure Plex is fully recovered and functional # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color PLEX_DB_DIR="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases" print_status() { local color="$1" local message="$2" echo -e "${color}${message}${NC}" } print_header() { echo print_status "$BLUE" "================================" print_status "$BLUE" "$1" print_status "$BLUE" "================================" } # Check service status check_service_status() { print_header "SERVICE STATUS CHECK" if systemctl is-active --quiet plexmediaserver; then print_status "$GREEN" "✓ Plex Media Server is running" # Get service uptime local uptime=$(systemctl show plexmediaserver --property=ActiveEnterTimestamp --value) print_status "$GREEN" " Started: $uptime" # Get memory usage local memory=$(systemctl show plexmediaserver --property=MemoryCurrent --value) if [[ -n "$memory" && "$memory" != "[not set]" ]]; then local memory_mb=$((memory / 1024 / 1024)) print_status "$GREEN" " Memory usage: ${memory_mb}MB" fi return 0 else print_status "$RED" "✗ Plex Media Server is not running" return 1 fi } # Check database integrity check_database_integrity() { print_header "DATABASE INTEGRITY CHECK" local main_db="${PLEX_DB_DIR}/com.plexapp.plugins.library.db" local blobs_db="${PLEX_DB_DIR}/com.plexapp.plugins.library.blobs.db" local all_good=true # Check main database if [[ -f "$main_db" ]]; then local main_size=$(du -h "$main_db" | cut -f1) print_status "$GREEN" "✓ Main database exists (${main_size})" # Try basic database operations if sqlite3 "$main_db" "SELECT COUNT(*) FROM sqlite_master WHERE type='table';" >/dev/null 2>&1; then local table_count=$(sqlite3 "$main_db" "SELECT COUNT(*) FROM sqlite_master WHERE type='table';" 2>/dev/null) print_status "$GREEN" " Contains $table_count tables" else print_status "$YELLOW" " Warning: Cannot query database tables" all_good=false fi else print_status "$RED" "✗ Main database missing" all_good=false fi # Check blobs database if [[ -f "$blobs_db" ]]; then local blobs_size=$(du -h "$blobs_db" | cut -f1) print_status "$GREEN" "✓ Blobs database exists (${blobs_size})" # Check if it's not empty (previous corruption was 0 bytes) local blobs_bytes=$(stat -c%s "$blobs_db" 2>/dev/null || stat -f%z "$blobs_db" 2>/dev/null) if [[ $blobs_bytes -gt 1000000 ]]; then print_status "$GREEN" " File size is healthy ($(numfmt --to=iec $blobs_bytes))" else print_status "$RED" " Warning: File size is too small ($blobs_bytes bytes)" all_good=false fi else print_status "$RED" "✗ Blobs database missing" all_good=false fi # Check file ownership local main_owner=$(stat -c%U:%G "$main_db" 2>/dev/null) local blobs_owner=$(stat -c%U:%G "$blobs_db" 2>/dev/null) if [[ "$main_owner" == "plex:plex" && "$blobs_owner" == "plex:plex" ]]; then print_status "$GREEN" "✓ Database ownership is correct (plex:plex)" else print_status "$YELLOW" " Warning: Ownership issues detected" print_status "$YELLOW" " Main DB: $main_owner, Blobs DB: $blobs_owner" fi return $([[ "$all_good" == "true" ]] && echo 0 || echo 1) } # Check web interface check_web_interface() { print_header "WEB INTERFACE CHECK" local max_attempts=5 local attempt=1 while [[ $attempt -le $max_attempts ]]; do if curl -s -o /dev/null -w "%{http_code}" "http://localhost:32400/web/index.html" | grep -q "200"; then print_status "$GREEN" "✓ Web interface is accessible" print_status "$GREEN" " URL: http://localhost:32400" return 0 fi print_status "$YELLOW" " Attempt $attempt/$max_attempts: Web interface not ready..." sleep 2 ((attempt++)) done print_status "$RED" "✗ Web interface is not accessible" return 1 } # Check API functionality check_api_functionality() { print_header "API FUNCTIONALITY CHECK" # Test root API endpoint local api_response=$(curl -s "http://localhost:32400/" 2>/dev/null) if echo "$api_response" | grep -q "Unauthorized\|web/index.html"; then print_status "$GREEN" "✓ API is responding (redirect to web interface)" else print_status "$YELLOW" " Warning: Unexpected API response" fi # Try to get server identity (this might work without auth) local identity_response=$(curl -s "http://localhost:32400/identity" 2>/dev/null) if echo "$identity_response" | grep -q "MediaContainer"; then print_status "$GREEN" "✓ Server identity endpoint working" else print_status "$YELLOW" " Note: Server identity requires authentication" fi } # Check recent logs for errors check_recent_logs() { print_header "RECENT LOGS CHECK" # Check for recent errors in systemd logs local recent_errors=$(sudo journalctl -u plexmediaserver --since "5 minutes ago" --no-pager -q 2>/dev/null | grep -i "error\|fail\|exception" | head -3) if [[ -z "$recent_errors" ]]; then print_status "$GREEN" "✓ No recent errors in service logs" else print_status "$YELLOW" " Recent log entries found:" echo "$recent_errors" | while read -r line; do print_status "$YELLOW" " $line" done fi } # Show recovery summary show_recovery_summary() { print_header "RECOVERY SUMMARY" local corrupted_backup_dir="${PLEX_DB_DIR}/corrupted-20250605_060232" if [[ -d "$corrupted_backup_dir" ]]; then print_status "$GREEN" "✓ Corrupted databases backed up to:" print_status "$GREEN" " $corrupted_backup_dir" fi print_status "$GREEN" "✓ Databases restored from: 2025-06-02 backups" print_status "$GREEN" "✓ File ownership corrected to plex:plex" print_status "$GREEN" "✓ Service restarted successfully" echo print_status "$BLUE" "NEXT STEPS:" print_status "$YELLOW" "1. Access Plex at: http://localhost:32400" print_status "$YELLOW" "2. Verify your libraries are intact" print_status "$YELLOW" "3. Consider running a library scan to pick up recent changes" print_status "$YELLOW" "4. Monitor the service for a few days to ensure stability" } # Main function main() { print_status "$BLUE" "PLEX RECOVERY VALIDATION" print_status "$BLUE" "$(date)" echo local overall_status=0 check_service_status || overall_status=1 check_database_integrity || overall_status=1 check_web_interface || overall_status=1 check_api_functionality check_recent_logs show_recovery_summary echo if [[ $overall_status -eq 0 ]]; then print_status "$GREEN" "🎉 RECOVERY SUCCESSFUL! Plex Media Server is fully functional." else print_status "$YELLOW" "⚠️ RECOVERY PARTIALLY SUCCESSFUL - Some issues detected." print_status "$YELLOW" " Plex is running but may need additional attention." fi return $overall_status } # Run the validation main "$@"