#!/bin/bash # Laravel Timebank Backup Setup Script # Initializes the backup system and performs initial configuration # Usage: ./setup-backups.sh set -e # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_status() { local level="$1" local message="$2" case "$level" in "INFO") echo -e "${BLUE}[INFO]${NC} $message" ;; "SUCCESS") echo -e "${GREEN}[SUCCESS]${NC} $message" ;; "WARNING") echo -e "${YELLOW}[WARNING]${NC} $message" ;; "ERROR") echo -e "${RED}[ERROR]${NC} $message" ;; esac } # Function to check prerequisites check_prerequisites() { print_status "INFO" "Checking prerequisites..." local missing_tools=() # Check required commands local required_commands=("mysqldump" "mysql" "rsync" "tar" "gzip" "find" "awk") for cmd in "${required_commands[@]}"; do if ! command -v "$cmd" >/dev/null 2>&1; then missing_tools+=("$cmd") fi done if [ ${#missing_tools[@]} -gt 0 ]; then print_status "ERROR" "Missing required tools: ${missing_tools[*]}" print_status "INFO" "Please install missing tools and try again" return 1 fi print_status "SUCCESS" "All required tools are available" return 0 } # Function to verify environment configuration check_environment() { print_status "INFO" "Checking environment configuration..." if [ ! -f "$PROJECT_ROOT/.env" ]; then print_status "ERROR" ".env file not found in $PROJECT_ROOT" return 1 fi # Load environment loader source "$SCRIPT_DIR/load-env.sh" # Load environment variables if ! load_env "$PROJECT_ROOT/.env"; then return 1 fi # Check required database variables local missing_vars=() if [ -z "$DB_DATABASE" ]; then missing_vars+=("DB_DATABASE"); fi if [ -z "$DB_USERNAME" ]; then missing_vars+=("DB_USERNAME"); fi if [ -z "$DB_HOST" ]; then missing_vars+=("DB_HOST"); fi if [ ${#missing_vars[@]} -gt 0 ]; then print_status "ERROR" "Missing required environment variables: ${missing_vars[*]}" return 1 fi print_status "SUCCESS" "Environment configuration is valid" return 0 } # Function to test database connection test_database_connection() { print_status "INFO" "Testing database connection..." # Create MySQL configuration file for secure password handling local mysql_cnf_file="/tmp/mysql_test_$$.cnf" cat > "$mysql_cnf_file" </dev/null 2>&1; then print_status "SUCCESS" "Database connection successful" rm -f "$mysql_cnf_file" return 0 else print_status "ERROR" "Database connection failed" rm -f "$mysql_cnf_file" return 1 fi } # Function to set up backup directories setup_directories() { print_status "INFO" "Setting up backup directories..." local backup_dirs=( "$PROJECT_ROOT/backups" "$PROJECT_ROOT/backups/database/daily" "$PROJECT_ROOT/backups/database/weekly" "$PROJECT_ROOT/backups/database/monthly" "$PROJECT_ROOT/backups/database/pre-restore" "$PROJECT_ROOT/backups/storage/daily" "$PROJECT_ROOT/backups/storage/weekly" "$PROJECT_ROOT/backups/storage/monthly" "$PROJECT_ROOT/backups/storage/snapshots" "$PROJECT_ROOT/backups/storage/pre-restore" "$PROJECT_ROOT/backups/logs" ) for dir in "${backup_dirs[@]}"; do if [ ! -d "$dir" ]; then mkdir -p "$dir" print_status "INFO" "Created directory: $dir" fi done # Set appropriate permissions chmod 755 "$PROJECT_ROOT/backups" chmod -R 750 "$PROJECT_ROOT/backups"/{database,storage} chmod 755 "$PROJECT_ROOT/backups/logs" print_status "SUCCESS" "Backup directories created successfully" } # Function to make scripts executable setup_script_permissions() { print_status "INFO" "Setting up script permissions..." local scripts=( "$SCRIPT_DIR/backup-database.sh" "$SCRIPT_DIR/backup-storage.sh" "$SCRIPT_DIR/backup-all.sh" "$SCRIPT_DIR/restore-database.sh" "$SCRIPT_DIR/restore-storage.sh" "$SCRIPT_DIR/cleanup-backups.sh" ) for script in "${scripts[@]}"; do if [ -f "$script" ]; then chmod +x "$script" print_status "INFO" "Made executable: $(basename "$script")" else print_status "WARNING" "Script not found: $(basename "$script")" fi done print_status "SUCCESS" "Script permissions configured" } # Function to run initial test backup run_test_backup() { print_status "INFO" "Running initial test backup..." # Test database backup if [ -x "$SCRIPT_DIR/backup-database.sh" ]; then print_status "INFO" "Testing database backup..." if "$SCRIPT_DIR/backup-database.sh" daily; then print_status "SUCCESS" "Database backup test successful" else print_status "ERROR" "Database backup test failed" return 1 fi fi # Test storage backup if [ -x "$SCRIPT_DIR/backup-storage.sh" ]; then print_status "INFO" "Testing storage backup..." if "$SCRIPT_DIR/backup-storage.sh" daily; then print_status "SUCCESS" "Storage backup test successful" else print_status "ERROR" "Storage backup test failed" return 1 fi fi return 0 } # Function to show next steps show_next_steps() { print_status "SUCCESS" "Backup system setup completed successfully!" echo "" print_status "INFO" "Next steps:" echo " 1. Review the backup configuration in BACKUP_GUIDE.md" echo " 2. Set up automated backups using cron:" echo " sudo cp scripts/cron-backup.conf /etc/cron.d/timebank-backup" echo " sudo nano /etc/cron.d/timebank-backup # Edit paths and email" echo " 3. Test the complete backup system:" echo " ./scripts/backup-all.sh daily --verify" echo " 4. Test restore procedures:" echo " ./scripts/restore-database.sh --list-backups" echo " 5. Set up monitoring and notifications" echo "" print_status "INFO" "Available commands:" echo " ./scripts/backup-all.sh daily # Daily backup" echo " ./scripts/backup-all.sh weekly # Weekly backup" echo " ./scripts/backup-all.sh monthly # Monthly backup" echo " ./scripts/restore-database.sh --latest # Restore database" echo " ./scripts/restore-storage.sh --latest # Restore storage" echo " ./scripts/cleanup-backups.sh --dry-run # Check cleanup" echo "" } # Function to display backup status show_backup_status() { print_status "INFO" "Current backup status:" local backup_dir="$PROJECT_ROOT/backups" if [ -d "$backup_dir" ]; then # Count backups local db_backups=$(find "$backup_dir/database" -name "*.sql.gz" 2>/dev/null | wc -l) local storage_backups=$(find "$backup_dir/storage" -name "*.tar.gz" 2>/dev/null | wc -l) echo " Database backups: $db_backups" echo " Storage backups: $storage_backups" if [ -d "$backup_dir" ]; then local total_size=$(du -sh "$backup_dir" 2>/dev/null | cut -f1) echo " Total backup size: $total_size" fi # Show recent backups local recent_db=$(find "$backup_dir/database" -name "*.sql.gz" -mtime -1 2>/dev/null | head -n 1) local recent_storage=$(find "$backup_dir/storage" -name "*.tar.gz" -mtime -1 2>/dev/null | head -n 1) if [ -n "$recent_db" ]; then echo " Latest database backup: $(basename "$recent_db") ($(date -r "$recent_db" '+%Y-%m-%d %H:%M:%S'))" fi if [ -n "$recent_storage" ]; then echo " Latest storage backup: $(basename "$recent_storage") ($(date -r "$recent_storage" '+%Y-%m-%d %H:%M:%S'))" fi else echo " No backups found" fi echo "" } # Main execution main() { echo "============================================" echo " Laravel Timebank Backup System Setup " echo "============================================" echo "" # Check if already set up if [ -d "$PROJECT_ROOT/backups" ] && [ -f "$PROJECT_ROOT/backups/backup.log" ]; then print_status "INFO" "Backup system appears to already be configured" show_backup_status read -p "Do you want to re-run the setup? [y/N]: " -n 1 -r echo "" if [[ ! $REPLY =~ ^[Yy]$ ]]; then print_status "INFO" "Setup cancelled" exit 0 fi echo "" fi # Run setup steps if ! check_prerequisites; then exit 1 fi if ! check_environment; then print_status "INFO" "Please configure your .env file with proper database credentials" exit 1 fi if ! test_database_connection; then print_status "INFO" "Please check your database configuration and connection" exit 1 fi setup_directories setup_script_permissions # Ask if user wants to run test backup echo "" read -p "Do you want to run an initial test backup? [Y/n]: " -n 1 -r echo "" if [[ ! $REPLY =~ ^[Nn]$ ]]; then if run_test_backup; then print_status "SUCCESS" "Test backup completed successfully" else print_status "WARNING" "Test backup had issues, but setup is complete" fi fi echo "" show_next_steps } # Check if running from correct directory if [ ! -f "$PROJECT_ROOT/composer.json" ] || [ ! -f "$PROJECT_ROOT/.env.example" ]; then print_status "ERROR" "This script must be run from the Laravel project root directory" exit 1 fi # Run main function main