forcedtobeonline

FTP incremental backup

Sep 7th, 2025
71
0
94 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 4.00 KB | Source Code | 0 0
  1. #!/bin/bash
  2.  
  3. # ========== CONFIGURATION ==========
  4. FTP_HOST="serverIP"
  5. FTP_USER="FTPuser"
  6. FTP_PASS="password"
  7.  
  8. # Local backup paths
  9. BASE_BACKUP_DIR="/volume/BackupServer/GameServer_Backup"
  10. STORAGE_BACKUP_DIR="$BASE_BACKUP_DIR/storage"
  11. VIRTUAL_BACKUP_DIR="$BASE_BACKUP_DIR/virtual"
  12. LOG_DIR="$BASE_BACKUP_DIR/logs"
  13.  
  14. # Max backup versions to keep
  15. MAX_ROTATIONS=120
  16.  
  17. # Timestamp
  18. NOW=$(date +"%Y-%m-%d_%H-%M")
  19.  
  20. # Log file
  21. mkdir -p "$LOG_DIR"
  22. LOGFILE="$LOG_DIR/backup_$NOW.log"
  23.  
  24. # Lockfile to prevent concurrent execution
  25. LOCKFILE="$BASE_BACKUP_DIR/backup_script.lock"
  26.  
  27. # ========== PREVENT MULTIPLE INSTANCES ==========
  28. if [ -e "$LOCKFILE" ]; then
  29.     echo "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: Script is already running." | tee -a "$LOGFILE"
  30.     exit 1
  31. fi
  32.  
  33. touch "$LOCKFILE"
  34. trap 'rm -f "$LOCKFILE"; exit' INT TERM EXIT
  35.  
  36. # ========== FUNCTIONS ==========
  37.  
  38. rotate_backups() {
  39.     local dir=$1
  40.     cd "$dir" || exit 1
  41.     local backups=( $(ls -1d 20* 2>/dev/null | sort) )
  42.     local count=${#backups[@]}
  43.  
  44.     if (( count >= MAX_ROTATIONS )); then
  45.         local to_delete=$((count - MAX_ROTATIONS + 1))
  46.         for ((i=0; i<to_delete; i++)); do
  47.             echo "Deleting old backup: ${backups[$i]}" | tee -a "$LOGFILE"
  48.             rm -rf "${backups[$i]}"
  49.         done
  50.     fi
  51. }
  52.  
  53. cleanup_old_logs() {
  54.     echo "[*] Cleaning up log files older than 15 days..." | tee -a "$LOGFILE"
  55.     find "$LOG_DIR" -type f -name "backup_*.log" -mtime +15 -exec rm -f {} \;
  56. }
  57.  
  58. backup_storage() {
  59.     echo "[*] Backing up /storage/backup/011" | tee -a "$LOGFILE"
  60.     local dest_dir="$STORAGE_BACKUP_DIR/$NOW"
  61.     mkdir -p "$dest_dir"
  62.  
  63.     timeout 7200 lftp -u "$FTP_USER","$FTP_PASS" "$FTP_HOST" <<EOF 2>&1 | tee -a "$LOGFILE"
  64. set ftp:passive-mode true
  65. set net:timeout 300
  66. set net:max-retries 2
  67. mirror --verbose /ftpServer/main/folder/to/storage/011 "$dest_dir/011"
  68. quit
  69. EOF
  70.  
  71.     rotate_backups "$STORAGE_BACKUP_DIR"
  72. }
  73.  
  74. backup_virtual_incremental() {
  75.     echo "[*] Backing up /storage/virtual (incremental)" | tee -a "$LOGFILE"
  76.     local dest_dir="$VIRTUAL_BACKUP_DIR/$NOW"
  77.     mkdir -p "$dest_dir"
  78.  
  79.     # === STEP 1: Copy entire content from previous backup before download ===
  80.     local last_backup=$(ls -1d "$VIRTUAL_BACKUP_DIR"/20* 2>/dev/null | sort | tail -n 1)
  81.     if [ -d "$last_backup" ]; then
  82.         echo "[*] Copying previous backup from $last_backup to $dest_dir..." | tee -a "$LOGFILE"
  83.        
  84.         # Copy folder structure first
  85.         rsync -a --include='*/' --exclude='*' "$last_backup/" "$dest_dir/" | tee -a "$LOGFILE"
  86.        
  87.         # Then copy files that don't exist yet
  88.         rsync -a --ignore-existing "$last_backup/" "$dest_dir/" | tee -a "$LOGFILE"
  89.        
  90.         echo "[*] Copy from previous backup complete." | tee -a "$LOGFILE"
  91.     else
  92.         echo "[!] No previous backup found. Starting fresh." | tee -a "$LOGFILE"
  93.     fi
  94.  
  95.     # === STEP 2: FTP mirror with only-newer logic ===
  96.     echo "[*] Downloading updated and new files from FTP..." | tee -a "$LOGFILE"
  97.     local lftp_log="/tmp/lftp_virtual_$$.log"
  98.     > "$lftp_log"
  99.  
  100.     timeout 7200 lftp -u "$FTP_USER","$FTP_PASS" "$FTP_HOST" <<EOF > "$lftp_log" 2>&1
  101. set ftp:passive-mode true
  102. set net:timeout 300
  103. set net:max-retries 2
  104. mirror --only-newer --parallel=4 /ftpServer/main/folder/to/storage/virtual "$dest_dir"
  105. quit
  106. EOF
  107.  
  108.     local changed_files_count
  109.     changed_files_count=$(grep -E '^Transferring|^=>|^<=|^Removing' "$lftp_log" | wc -l)
  110.     echo "[*] FTP sync complete. Files changed or added: $changed_files_count" | tee -a "$LOGFILE"
  111.     cat "$lftp_log" >> "$LOGFILE"
  112.     rm -f "$lftp_log"
  113.  
  114.     rotate_backups "$VIRTUAL_BACKUP_DIR"
  115. }
  116.  
  117. # ========== MAIN ==========
  118. echo "===== Backup started at $NOW =====" | tee -a "$LOGFILE"
  119.  
  120. mkdir -p "$STORAGE_BACKUP_DIR"
  121. mkdir -p "$VIRTUAL_BACKUP_DIR"
  122.  
  123. backup_storage
  124. backup_virtual_incremental
  125. cleanup_old_logs
  126.  
  127. echo "===== Backup finished at $(date +"%Y-%m-%d %H:%M:%S") =====" | tee -a "$LOGFILE"
  128.  
  129. # Cleanup
  130. rm -f "$LOCKFILE"
  131. trap - INT TERM EXIT
Advertisement
Add Comment
Please, Sign In to add comment