#!/bin/bash # Calejo Control Adapter Restore Script # This script restores the database and configuration from backups set -e # Configuration BACKUP_DIR="/backups/calejo" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Logging function log() { echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" } warn() { echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1" } error() { echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" exit 1 } # Function to list available backups list_backups() { echo "Available backups:" echo "==================" for manifest in "$BACKUP_DIR"/backup_manifest_*.txt; do if [ -f "$manifest" ]; then backup_id=$(basename "$manifest" | sed 's/backup_manifest_\\(.*\\).txt/\\1/') echo "Backup ID: $backup_id" grep -E "Backup Date:|Backup Size Summary:" "$manifest" | head -2 echo "---" fi done } # Function to validate backup files validate_backup() { local backup_id="$1" local db_backup="$BACKUP_DIR/calejo_db_backup_${backup_id}.sql.gz" local config_backup="$BACKUP_DIR/calejo_config_backup_${backup_id}.tar.gz" local manifest="$BACKUP_DIR/backup_manifest_${backup_id}.txt" if [ ! -f "$db_backup" ]; then error "Database backup file not found: $db_backup" fi if [ ! -f "$config_backup" ]; then error "Configuration backup file not found: $config_backup" fi if [ ! -f "$manifest" ]; then warn "Backup manifest not found: $manifest" fi log "Backup validation passed for ID: $backup_id" } # Function to restore database restore_database() { local backup_id="$1" local db_backup="$BACKUP_DIR/calejo_db_backup_${backup_id}.sql.gz" log "Restoring database from: $db_backup" # Stop application if running if command -v docker-compose &> /dev/null && docker-compose ps | grep -q "calejo-control-adapter"; then log "Stopping Calejo Control Adapter..." docker-compose stop calejo-control-adapter fi if command -v docker-compose &> /dev/null; then # Using Docker Compose log "Dropping and recreating database..." docker-compose exec -T postgres psql -U calejo -c "DROP DATABASE IF EXISTS calejo;" docker-compose exec -T postgres psql -U calejo -c "CREATE DATABASE calejo;" log "Restoring database data..." gunzip -c "$db_backup" | docker-compose exec -T postgres psql -U calejo calejo else # Direct PostgreSQL connection if [ -z "$DATABASE_URL" ]; then error "DATABASE_URL environment variable not set" fi # Extract connection details from DATABASE_URL DB_HOST=$(echo "$DATABASE_URL" | sed -n 's/.*@\\([^:]*\\):.*/\\1/p') DB_PORT=$(echo "$DATABASE_URL" | sed -n 's/.*:\\\([0-9]*\\\)\\/.*/\\1/p') DB_NAME=$(echo "$DATABASE_URL" | sed -n 's/.*\\/\\\([^?]*\\\)/\\1/p') DB_USER=$(echo "$DATABASE_URL" | sed -n 's/.*:\\\([^:]*\\\):.*/\\1/p') DB_PASS=$(echo "$DATABASE_URL" | sed -n 's/.*:\\\([^@]*\\\)@.*/\\1/p') log "Dropping and recreating database..." PGPASSWORD="$DB_PASS" dropdb -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" "$DB_NAME" --if-exists PGPASSWORD="$DB_PASS" createdb -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" "$DB_NAME" log "Restoring database data..." gunzip -c "$db_backup" | PGPASSWORD="$DB_PASS" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" "$DB_NAME" fi log "Database restore completed successfully" } # Function to restore configuration restore_configuration() { local backup_id="$1" local config_backup="$BACKUP_DIR/calejo_config_backup_${backup_id}.tar.gz" log "Restoring configuration from: $config_backup" # Backup current configuration if [ -d "config" ] || [ -d "logs" ]; then local current_backup="$BACKUP_DIR/current_config_backup_$(date +%Y%m%d_%H%M%S).tar.gz" log "Backing up current configuration to: $current_backup" tar -czf "$current_backup" config/ logs/ 2>/dev/null || warn "Some files might not have been backed up" fi # Extract configuration backup tar -xzf "$config_backup" -C . log "Configuration restore completed successfully" } # Function to start application start_application() { log "Starting Calejo Control Adapter..." if command -v docker-compose &> /dev/null; then docker-compose start calejo-control-adapter # Wait for application to be healthy log "Waiting for application to be healthy..." for i in {1..30}; do if curl -f http://localhost:8080/health >/dev/null 2>&1; then log "Application is healthy" break fi sleep 2 done else log "Please start the application manually" fi } # Main restore function main_restore() { local backup_id="$1" if [ -z "$backup_id" ]; then error "Backup ID is required. Use --list to see available backups." fi log "Starting restore process for backup ID: $backup_id" # Validate backup validate_backup "$backup_id" # Show backup details local manifest="$BACKUP_DIR/backup_manifest_${backup_id}.txt" if [ -f "$manifest" ]; then echo cat "$manifest" echo fi # Confirm restore read -p "Are you sure you want to restore from this backup? This will overwrite current data. (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then log "Restore cancelled" exit 0 fi # Perform restore restore_database "$backup_id" restore_configuration "$backup_id" start_application log "Restore completed successfully!" log "Backup ID: $backup_id" log "Application should now be running with restored data" } # Parse command line arguments case "${1:-}" in --list|-l) list_backups exit 0 ;; --help|-h) echo "Usage: $0 [OPTIONS] [BACKUP_ID]" echo "" echo "Options:" echo " --list, -l List available backups" echo " --help, -h Show this help message" echo "" echo "If BACKUP_ID is provided, restore from that backup" echo "If no arguments provided, list available backups" exit 0 ;; "") list_backups echo "" echo "To restore, run: $0 BACKUP_ID" exit 0 ;; *) main_restore "$1" ;; esac