338 lines
10 KiB
Bash
Executable File
338 lines
10 KiB
Bash
Executable File
#!/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" <<EOF
|
|
[mysql]
|
|
host=${DB_HOST:-127.0.0.1}
|
|
port=${DB_PORT:-3306}
|
|
user=$DB_USERNAME
|
|
password=$DB_PASSWORD
|
|
EOF
|
|
|
|
# Set secure permissions on the config file
|
|
chmod 600 "$mysql_cnf_file"
|
|
|
|
if mysql --defaults-extra-file="$mysql_cnf_file" -e "SELECT 1;" >/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 |