#!/bin/bash # Backup Manager for Mission Control # Run daily via cron # Source: https://git.lemonlink.eu/devmatrix/devmatrix-scripts set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" BACKUP_ROOT="/mnt/truenas/backups/mission-control" DB_SOURCE="/home/devmatrix/mission-control/data/mission-control.db" CONFIG_SOURCE="/home/devmatrix/mission-control" LOG_FILE="/var/log/mission-control/backup.log" RETENTION_DAYS=30 # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log() { echo -e "${BLUE}[$(date +%Y-%m-%d\ %H:%M:%S)]${NC} $1" | tee -a "$LOG_FILE" } success() { echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE" } warning() { echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE" } error() { echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE" exit 1 } # Create backup directories create_directories() { mkdir -p "$BACKUP_ROOT"/{database,configs,logs} } # Backup database backup_database() { log "Backing up database..." local timestamp=$(date +%Y%m%d_%H%M%S) local backup_file="$BACKUP_ROOT/database/mission-control-${timestamp}.db" if [ ! -f "$DB_SOURCE" ]; then warning "Database not found at $DB_SOURCE" return 1 fi # Use SQLite backup command for consistency if sqlite3 "$DB_SOURCE" ".backup '$backup_file'"; then # Compress the backup gzip "$backup_file" success "Database backed up: ${backup_file}.gz" # Verify backup if gunzip -t "${backup_file}.gz" 2>/dev/null; then success "Backup verified successfully" else error "Backup verification failed!" fi else error "Database backup failed!" fi } # Backup configuration files backup_configs() { log "Backing up configuration files..." local timestamp=$(date +%Y%m%d_%H%M%S) local backup_file="$BACKUP_ROOT/configs/mission-control-configs-${timestamp}.tar.gz" # Backup important config files tar -czf "$backup_file" \ -C "$CONFIG_SOURCE" \ package.json \ ecosystem.config.js \ next.config.ts \ tsconfig.json \ .env.local 2>/dev/null || true if [ -f "$backup_file" ]; then success "Configuration files backed up: $backup_file" else warning "No configuration files to backup" fi } # Cleanup old backups cleanup_old_backups() { log "Cleaning up old backups (retention: $RETENTION_DAYS days)..." local deleted_count=0 # Clean database backups while IFS= read -r file; do rm "$file" ((deleted_count++)) done < <(find "$BACKUP_ROOT/database" -name "*.db.gz" -mtime +$RETENTION_DAYS 2>/dev/null) # Clean config backups while IFS= read -r file; do rm "$file" ((deleted_count++)) done < <(find "$BACKUP_ROOT/configs" -name "*.tar.gz" -mtime +$RETENTION_DAYS 2>/dev/null) if [ $deleted_count -gt 0 ]; then success "Cleaned up $deleted_count old backup files" else log "No old backups to clean up" fi } # List available backups list_backups() { log "Available database backups:" ls -lah "$BACKUP_ROOT/database"/*.db.gz 2>/dev/null | tail -10 || echo " No database backups found" log "Available config backups:" ls -lah "$BACKUP_ROOT/configs"/*.tar.gz 2>/dev/null | tail -5 || echo " No config backups found" } # Restore from backup restore_backup() { local backup_file="$1" if [ -z "$backup_file" ]; then error "Please specify a backup file to restore" fi if [ ! -f "$backup_file" ]; then error "Backup file not found: $backup_file" fi log "Restoring from backup: $backup_file" # Create safety backup first local safety_backup="$BACKUP_ROOT/database/pre-restore-$(date +%Y%m%d_%H%M%S).db" if [ -f "$DB_SOURCE" ]; then sqlite3 "$DB_SOURCE" ".backup '$safety_backup'" success "Safety backup created: $safety_backup" fi # Extract and restore if [[ "$backup_file" == *.gz ]]; then gunzip -c "$backup_file" > "$DB_SOURCE" else cp "$backup_file" "$DB_SOURCE" fi success "Database restored successfully!" log "Please restart Mission Control to apply changes" } # Main main() { local command="${1:-backup}" log "================================" log "Mission Control Backup Manager" log "================================" create_directories case "$command" in backup) backup_database backup_configs cleanup_old_backups success "Backup completed successfully!" ;; list) list_backups ;; restore) restore_backup "$2" ;; cleanup) cleanup_old_backups ;; *) echo "Usage: $0 {backup|list|restore|cleanup}" echo "" echo "Commands:" echo " backup - Create new backup" echo " list - List available backups" echo " restore - Restore from backup file" echo " cleanup - Remove old backups" exit 1 ;; esac } main "$@"