#!/bin/bash # Borg backup script for /mnt/services # This script creates incremental backups of the services directory # Set environment variables export BORG_REPO="{{ borg_repo_dir }}" export BORG_PASSPHRASE="{{ borg_passphrase }}" export BORG_CACHE_DIR="{{ borg_config_dir }}/cache" export BORG_CONFIG_DIR="{{ borg_config_dir }}/config" export BORG_SECURITY_DIR="{{ borg_config_dir }}/security" export BORG_KEYS_DIR="{{ borg_config_dir }}/keys" # Telegram notification variables export TELEGRAM_BOT_TOKEN="{{ lookup('community.general.onepassword', 'Telegram Home Server Bot', vault='Dotfiles', field='password') }}" export TELEGRAM_CHAT_ID="{{ lookup('community.general.onepassword', 'Telegram Home Server Bot', vault='Dotfiles', field='chat_id') }}" # Backup name with timestamp BACKUP_NAME="services-$(date +%Y%m%d-%H%M%S)" # Log function log() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a /var/log/borg-backup.log } # Telegram notification function send_telegram() { local message="$1" local silent="${2:-false}" if [ -z "$TELEGRAM_BOT_TOKEN" ] || [ -z "$TELEGRAM_CHAT_ID" ]; then log "Telegram credentials not configured, skipping notification" return fi local payload=$(cat < /dev/null 2>&1 if [ $? -eq 0 ]; then log "Telegram notification sent successfully" else log "Failed to send Telegram notification" fi } # Ensure all Borg directories exist mkdir -p "$BORG_CACHE_DIR" mkdir -p "$BORG_CONFIG_DIR" mkdir -p "$BORG_SECURITY_DIR" mkdir -p "$BORG_KEYS_DIR" # Start backup log "Starting Borg backup: $BACKUP_NAME" # Create backup borg create \ --verbose \ --filter AME \ --list \ --stats \ --show-rc \ --compression lz4 \ --exclude-caches \ --exclude '*.tmp' \ --exclude '*.temp' \ --exclude '*.log' \ --exclude '*/.cache' \ --exclude '*/cache' \ --exclude '*/logs' \ --exclude '*/tmp' \ --exclude '*/node_modules' \ --exclude '*/__pycache__' \ "::$BACKUP_NAME" \ {{ borg_backup_dir }} backup_exit=$? log "Backup finished with exit code: $backup_exit" # Prune old backups (keep last 7 daily, 4 weekly, 6 monthly) log "Pruning old backups" # Check if there are any archives to prune first archive_count=$(borg list --short --prefix 'services-' 2>/dev/null | wc -l) if [ "$archive_count" -gt 1 ]; then borg prune \ --list \ --prefix 'services-' \ --show-rc \ --keep-daily 7 \ --keep-weekly 4 \ --keep-monthly 6 prune_exit=$? else log "Only one or no archives found, skipping prune" prune_exit=0 fi log "Prune finished with exit code: $prune_exit" # Compact repository log "Compacting repository" borg compact compact_exit=$? log "Compact finished with exit code: $compact_exit" # Global exit status global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit )) if [ $global_exit -eq 0 ]; then log "Backup completed successfully" send_telegram "🔒 Borg Backup Success ✅ Backup: $BACKUP_NAME completed successfully 📊 Repository: {{ borg_repo_dir }} 🕐 Completed: $(date '+%Y-%m-%d %H:%M:%S') All operations completed without errors." "true" elif [ $global_exit -eq 1 ]; then log "Backup completed with warnings (exit code: $global_exit)" send_telegram "⚠️ Borg Backup Warning ⚠️ Backup: $BACKUP_NAME completed with warnings 📊 Repository: {{ borg_repo_dir }} 🕐 Completed: $(date '+%Y-%m-%d %H:%M:%S') Exit code: $global_exit Check logs for details: /var/log/borg-backup.log" else log "Backup completed with warnings or errors (exit code: $global_exit)" send_telegram "❌ Borg Backup Failed ❌ Backup: $BACKUP_NAME failed 📊 Repository: {{ borg_repo_dir }} 🕐 Failed: $(date '+%Y-%m-%d %H:%M:%S') Exit code: $global_exit Check logs immediately: /var/log/borg-backup.log" fi exit $global_exit