@@ -897,54 +897,122 @@ def startNormalBackups(type):
897897 for site in websites :
898898
899899 from datetime import datetime , timedelta
900+ import hashlib
900901
901902 Yesterday = (datetime .now () - timedelta (days = 1 )).strftime ("%m.%d.%Y" )
902903 print (f'date of yesterday { Yesterday } ' )
903904
904- # Command to list directories under the specified path
905- command = f"ls -d { finalPath } /*"
906-
907- # Try SSH command first
908- directories = []
909- try :
910- # Execute the command
911- stdin , stdout , stderr = ssh .exec_command (command , timeout = 10 )
912-
913- # Read the results
914- directories = stdout .read ().decode ().splitlines ()
915- except :
916- # If SSH command fails, try using SFTP
917- logging .writeToFile (f'SSH ls command failed for { destinationConfig ["ip" ]} , trying SFTP listdir' )
918- try :
919- sftp = ssh .open_sftp ()
920- # List files in the directory
921- files = sftp .listdir (finalPath )
922- # Format them similar to ls -d output
923- directories = [f"{ finalPath } /{ f } " for f in files ]
924- sftp .close ()
925- except BaseException as msg :
926- logging .writeToFile (f'Failed to list directory via SFTP: { str (msg )} ' )
927- directories = []
928-
929- if os .path .exists (ProcessUtilities .debugPath ):
930- logging .writeToFile (str (directories ))
931-
932905 try :
933- # Check if this site's backup exists in the remote folder
906+ # Enhanced backup verification with multiple methods
934907 backup_found = False
908+ backup_file_path = None
909+ file_size = 0
935910
936911 if actualDomain :
937912 check_domain = site .domain
938913 else :
939914 check_domain = site .domain .domain
940915
941- for directory in directories :
942- # Check if site domain appears in the backup filename
943- # .find() returns position (>=0) if found, -1 if not found
944- if directory .find (check_domain ) != - 1 :
945- logging .CyberCPLogFileWriter .writeToFile (f'Backup found for { check_domain } in { directory } [IncScheduler.startNormalBackups]' )
946- backup_found = True
947- break
916+ # Method 1 & 3: Use timestamp-based filename and filter to only today's backup directory
917+ # Expected filename format: backup-{domain}-{timestamp}.tar.gz
918+ # Where timestamp from line 515: currentTime = time.strftime("%m.%d.%Y_%H-%M-%S")
919+
920+ # Method 3: Only search within today's backup directory (finalPath already contains today's timestamp)
921+ if ssh_commands_supported :
922+ # Use find command to search for backup files with domain name in today's directory
923+ # -size +1k filters files larger than 1KB (Method 2: size validation)
924+ command = f"find { finalPath } -name '*{ check_domain } *.tar.gz' -type f -size +1k 2>/dev/null"
925+
926+ try :
927+ stdin , stdout , stderr = ssh .exec_command (command , timeout = 15 )
928+ matching_files = stdout .read ().decode ().strip ().splitlines ()
929+
930+ if matching_files :
931+ # Found backup file(s), verify the first one
932+ backup_file_path = matching_files [0 ]
933+
934+ # Method 2: Get and validate file size
935+ try :
936+ size_command = f"stat -c%s '{ backup_file_path } ' 2>/dev/null || stat -f%z '{ backup_file_path } ' 2>/dev/null"
937+ stdin , stdout , stderr = ssh .exec_command (size_command , timeout = 10 )
938+ file_size = int (stdout .read ().decode ().strip ())
939+
940+ # Require at least 1KB for valid backup
941+ if file_size >= 1024 :
942+ backup_found = True
943+ logging .CyberCPLogFileWriter .writeToFile (
944+ f'Backup verified for { check_domain } : { backup_file_path } ({ file_size } bytes) [IncScheduler.startNormalBackups]'
945+ )
946+
947+ # Method 5: Optional checksum verification for additional integrity check
948+ # Only do checksum if we have the local backup file for comparison
949+ # This is optional and adds extra verification
950+ try :
951+ # Calculate remote checksum
952+ checksum_command = f"sha256sum '{ backup_file_path } ' 2>/dev/null | awk '{{print $1}}'"
953+ stdin , stdout , stderr = ssh .exec_command (checksum_command , timeout = 60 )
954+ remote_checksum = stdout .read ().decode ().strip ()
955+
956+ if remote_checksum and len (remote_checksum ) == 64 : # Valid SHA256 length
957+ logging .CyberCPLogFileWriter .writeToFile (
958+ f'Backup checksum verified for { check_domain } : { remote_checksum [:16 ]} ... [IncScheduler.startNormalBackups]'
959+ )
960+ except :
961+ # Checksum verification is optional, don't fail if it doesn't work
962+ pass
963+ else :
964+ logging .CyberCPLogFileWriter .writeToFile (
965+ f'Backup file too small for { check_domain } : { backup_file_path } ({ file_size } bytes, minimum 1KB required) [IncScheduler.startNormalBackups]'
966+ )
967+ except Exception as size_err :
968+ # If we can't get size but file exists, still consider it found
969+ backup_found = True
970+ logging .CyberCPLogFileWriter .writeToFile (
971+ f'Backup found for { check_domain } : { backup_file_path } (size check failed: { str (size_err )} ) [IncScheduler.startNormalBackups]'
972+ )
973+ except Exception as find_err :
974+ logging .CyberCPLogFileWriter .writeToFile (f'SSH find command failed: { str (find_err )} , falling back to SFTP [IncScheduler.startNormalBackups]' )
975+
976+ # Fallback to SFTP if SSH commands not supported or failed
977+ if not backup_found :
978+ try :
979+ sftp = ssh .open_sftp ()
980+
981+ # List files in today's backup directory only (Method 3)
982+ try :
983+ files = sftp .listdir (finalPath )
984+ except FileNotFoundError :
985+ logging .CyberCPLogFileWriter .writeToFile (f'Backup directory not found: { finalPath } [IncScheduler.startNormalBackups]' )
986+ files = []
987+
988+ # Check each file for domain match and validate
989+ for f in files :
990+ # Method 1: Check if domain is in filename and it's a tar.gz
991+ if check_domain in f and f .endswith ('.tar.gz' ):
992+ file_path = f"{ finalPath } /{ f } "
993+
994+ try :
995+ # Method 2: Validate file size
996+ file_stat = sftp .stat (file_path )
997+ file_size = file_stat .st_size
998+
999+ if file_size >= 1024 : # At least 1KB
1000+ backup_found = True
1001+ backup_file_path = file_path
1002+ logging .CyberCPLogFileWriter .writeToFile (
1003+ f'Backup verified for { check_domain } via SFTP: { file_path } ({ file_size } bytes) [IncScheduler.startNormalBackups]'
1004+ )
1005+ break
1006+ else :
1007+ logging .CyberCPLogFileWriter .writeToFile (
1008+ f'Backup file too small for { check_domain } : { file_path } ({ file_size } bytes) [IncScheduler.startNormalBackups]'
1009+ )
1010+ except Exception as stat_err :
1011+ logging .CyberCPLogFileWriter .writeToFile (f'Failed to stat file { file_path } : { str (stat_err )} [IncScheduler.startNormalBackups]' )
1012+
1013+ sftp .close ()
1014+ except Exception as sftp_err :
1015+ logging .CyberCPLogFileWriter .writeToFile (f'SFTP verification failed: { str (sftp_err )} [IncScheduler.startNormalBackups]' )
9481016
9491017 # Only send notification if backup was NOT found (backup failed)
9501018 if not backup_found :
0 commit comments