Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # ========== CONFIGURATION ==========
- FTP_HOST="serverIP"
- FTP_USER="FTPuser"
- FTP_PASS="password"
- # Local backup paths
- BASE_BACKUP_DIR="/volume/BackupServer/GameServer_Backup"
- STORAGE_BACKUP_DIR="$BASE_BACKUP_DIR/storage"
- VIRTUAL_BACKUP_DIR="$BASE_BACKUP_DIR/virtual"
- LOG_DIR="$BASE_BACKUP_DIR/logs"
- # Max backup versions to keep
- MAX_ROTATIONS=120
- # Timestamp
- NOW=$(date +"%Y-%m-%d_%H-%M")
- # Log file
- mkdir -p "$LOG_DIR"
- LOGFILE="$LOG_DIR/backup_$NOW.log"
- # Lockfile to prevent concurrent execution
- LOCKFILE="$BASE_BACKUP_DIR/backup_script.lock"
- # ========== PREVENT MULTIPLE INSTANCES ==========
- if [ -e "$LOCKFILE" ]; then
- echo "[$(date +"%Y-%m-%d %H:%M:%S")] ERROR: Script is already running." | tee -a "$LOGFILE"
- exit 1
- fi
- touch "$LOCKFILE"
- trap 'rm -f "$LOCKFILE"; exit' INT TERM EXIT
- # ========== FUNCTIONS ==========
- rotate_backups() {
- local dir=$1
- cd "$dir" || exit 1
- local backups=( $(ls -1d 20* 2>/dev/null | sort) )
- local count=${#backups[@]}
- if (( count >= MAX_ROTATIONS )); then
- local to_delete=$((count - MAX_ROTATIONS + 1))
- for ((i=0; i<to_delete; i++)); do
- echo "Deleting old backup: ${backups[$i]}" | tee -a "$LOGFILE"
- rm -rf "${backups[$i]}"
- done
- fi
- }
- cleanup_old_logs() {
- echo "[*] Cleaning up log files older than 15 days..." | tee -a "$LOGFILE"
- find "$LOG_DIR" -type f -name "backup_*.log" -mtime +15 -exec rm -f {} \;
- }
- backup_storage() {
- echo "[*] Backing up /storage/backup/011" | tee -a "$LOGFILE"
- local dest_dir="$STORAGE_BACKUP_DIR/$NOW"
- mkdir -p "$dest_dir"
- timeout 7200 lftp -u "$FTP_USER","$FTP_PASS" "$FTP_HOST" <<EOF 2>&1 | tee -a "$LOGFILE"
- set ftp:passive-mode true
- set net:timeout 300
- set net:max-retries 2
- mirror --verbose /ftpServer/main/folder/to/storage/011 "$dest_dir/011"
- quit
- EOF
- rotate_backups "$STORAGE_BACKUP_DIR"
- }
- backup_virtual_incremental() {
- echo "[*] Backing up /storage/virtual (incremental)" | tee -a "$LOGFILE"
- local dest_dir="$VIRTUAL_BACKUP_DIR/$NOW"
- mkdir -p "$dest_dir"
- # === STEP 1: Copy entire content from previous backup before download ===
- local last_backup=$(ls -1d "$VIRTUAL_BACKUP_DIR"/20* 2>/dev/null | sort | tail -n 1)
- if [ -d "$last_backup" ]; then
- echo "[*] Copying previous backup from $last_backup to $dest_dir..." | tee -a "$LOGFILE"
- # Copy folder structure first
- rsync -a --include='*/' --exclude='*' "$last_backup/" "$dest_dir/" | tee -a "$LOGFILE"
- # Then copy files that don't exist yet
- rsync -a --ignore-existing "$last_backup/" "$dest_dir/" | tee -a "$LOGFILE"
- echo "[*] Copy from previous backup complete." | tee -a "$LOGFILE"
- else
- echo "[!] No previous backup found. Starting fresh." | tee -a "$LOGFILE"
- fi
- # === STEP 2: FTP mirror with only-newer logic ===
- echo "[*] Downloading updated and new files from FTP..." | tee -a "$LOGFILE"
- local lftp_log="/tmp/lftp_virtual_$$.log"
- > "$lftp_log"
- timeout 7200 lftp -u "$FTP_USER","$FTP_PASS" "$FTP_HOST" <<EOF > "$lftp_log" 2>&1
- set ftp:passive-mode true
- set net:timeout 300
- set net:max-retries 2
- mirror --only-newer --parallel=4 /ftpServer/main/folder/to/storage/virtual "$dest_dir"
- quit
- EOF
- local changed_files_count
- changed_files_count=$(grep -E '^Transferring|^=>|^<=|^Removing' "$lftp_log" | wc -l)
- echo "[*] FTP sync complete. Files changed or added: $changed_files_count" | tee -a "$LOGFILE"
- cat "$lftp_log" >> "$LOGFILE"
- rm -f "$lftp_log"
- rotate_backups "$VIRTUAL_BACKUP_DIR"
- }
- # ========== MAIN ==========
- echo "===== Backup started at $NOW =====" | tee -a "$LOGFILE"
- mkdir -p "$STORAGE_BACKUP_DIR"
- mkdir -p "$VIRTUAL_BACKUP_DIR"
- backup_storage
- backup_virtual_incremental
- cleanup_old_logs
- echo "===== Backup finished at $(date +"%Y-%m-%d %H:%M:%S") =====" | tee -a "$LOGFILE"
- # Cleanup
- rm -f "$LOCKFILE"
- trap - INT TERM EXIT
Advertisement
Add Comment
Please, Sign In to add comment