mirror of
https://github.com/uprightbass360/AzerothCore-RealmMaster.git
synced 2026-01-13 09:07:20 +00:00
refactoring and adding automations
This commit is contained in:
@@ -1,6 +1,49 @@
|
||||
#!/bin/bash
|
||||
# ac-compose
|
||||
set -e
|
||||
|
||||
print_help() {
|
||||
cat <<'EOF'
|
||||
Usage: db-import-conditional.sh [options]
|
||||
|
||||
Description:
|
||||
Conditionally restores AzerothCore databases from backups if available;
|
||||
otherwise creates fresh databases and runs the dbimport tool to populate
|
||||
schemas. Uses status markers to prevent overwriting restored data.
|
||||
|
||||
Options:
|
||||
-h, --help Show this help message and exit
|
||||
|
||||
Environment variables:
|
||||
CONTAINER_MYSQL Hostname of the MySQL container (default: ac-mysql)
|
||||
MYSQL_PORT MySQL port (default: 3306)
|
||||
MYSQL_USER MySQL user (default: root)
|
||||
MYSQL_ROOT_PASSWORD MySQL password for the user above
|
||||
DB_AUTH_NAME Auth DB name (default: acore_auth)
|
||||
DB_WORLD_NAME World DB name (default: acore_world)
|
||||
DB_CHARACTERS_NAME Characters DB name (default: acore_characters)
|
||||
BACKUP DIRS Uses /backups/{daily,timestamped} if present
|
||||
STATUS MARKERS Uses /var/lib/mysql-persistent/.restore-*
|
||||
|
||||
Notes:
|
||||
- If a valid backup is detected and successfully restored, schema import is skipped.
|
||||
- On fresh setups, the script creates databases and runs dbimport.
|
||||
EOF
|
||||
}
|
||||
|
||||
case "${1:-}" in
|
||||
-h|--help)
|
||||
print_help
|
||||
exit 0
|
||||
;;
|
||||
"") ;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
print_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "🔧 Conditional AzerothCore Database Import"
|
||||
echo "========================================"
|
||||
|
||||
@@ -12,7 +55,6 @@ RESTORE_FAILED_MARKER="$RESTORE_STATUS_DIR/.restore-failed"
|
||||
RESTORE_SUCCESS_MARKER_TMP="$MARKER_STATUS_DIR/.restore-completed"
|
||||
RESTORE_FAILED_MARKER_TMP="$MARKER_STATUS_DIR/.restore-failed"
|
||||
|
||||
# Ensure we can write to the status directory, fallback to tmp
|
||||
mkdir -p "$RESTORE_STATUS_DIR" 2>/dev/null || true
|
||||
if ! touch "$RESTORE_STATUS_DIR/.test-write" 2>/dev/null; then
|
||||
echo "⚠️ Cannot write to $RESTORE_STATUS_DIR, using $MARKER_STATUS_DIR for markers"
|
||||
@@ -24,23 +66,16 @@ fi
|
||||
|
||||
echo "🔍 Checking restoration status..."
|
||||
|
||||
# Check if backup was successfully restored
|
||||
if [ -f "$RESTORE_SUCCESS_MARKER" ]; then
|
||||
echo "✅ Backup restoration completed successfully"
|
||||
echo "📄 Restoration details:"
|
||||
cat "$RESTORE_SUCCESS_MARKER"
|
||||
echo ""
|
||||
cat "$RESTORE_SUCCESS_MARKER" || true
|
||||
echo "🚫 Skipping database import - data already restored from backup"
|
||||
echo "💡 This prevents overwriting restored data with fresh schema"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Check if restoration failed (fresh databases created)
|
||||
if [ -f "$RESTORE_FAILED_MARKER" ]; then
|
||||
echo "ℹ️ No backup was restored - fresh databases detected"
|
||||
echo "📄 Database creation details:"
|
||||
cat "$RESTORE_FAILED_MARKER"
|
||||
echo ""
|
||||
cat "$RESTORE_FAILED_MARKER" || true
|
||||
echo "▶️ Proceeding with database import to populate fresh databases"
|
||||
else
|
||||
echo "⚠️ No restoration status found - assuming fresh installation"
|
||||
@@ -50,66 +85,11 @@ fi
|
||||
echo ""
|
||||
echo "🔧 Starting database import process..."
|
||||
|
||||
# First attempt backup restoration
|
||||
echo "🔍 Checking for backups to restore..."
|
||||
|
||||
BACKUP_DIRS="/backups"
|
||||
|
||||
|
||||
# Function to restore from backup (directory or single file)
|
||||
restore_from_directory() {
|
||||
local backup_path="$1"
|
||||
echo "🔄 Restoring from backup: $backup_path"
|
||||
|
||||
local restore_success=true
|
||||
|
||||
# Handle single .sql file (legacy backup)
|
||||
if [ -f "$backup_path" ] && [[ "$backup_path" == *.sql ]]; then
|
||||
echo "📥 Restoring legacy backup file: $(basename "$backup_path")"
|
||||
if timeout 300 mysql -h ${CONTAINER_MYSQL} -u${MYSQL_USER} -p${MYSQL_ROOT_PASSWORD} < "$backup_path"; then
|
||||
echo "✅ Successfully restored legacy backup"
|
||||
return 0
|
||||
else
|
||||
echo "❌ Failed to restore legacy backup"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Handle directory with .sql.gz files (modern timestamped backups)
|
||||
if [ -d "$backup_path" ]; then
|
||||
echo "🔄 Restoring from backup directory: $backup_path"
|
||||
# Restore each database backup
|
||||
for backup_file in "$backup_path"/*.sql.gz; do
|
||||
if [ -f "$backup_file" ]; then
|
||||
local db_name=$(basename "$backup_file" .sql.gz)
|
||||
echo "📥 Restoring database: $db_name"
|
||||
|
||||
if timeout 300 zcat "$backup_file" | mysql -h ${CONTAINER_MYSQL} -u${MYSQL_USER} -p${MYSQL_ROOT_PASSWORD}; then
|
||||
echo "✅ Successfully restored $db_name"
|
||||
else
|
||||
echo "❌ Failed to restore $db_name"
|
||||
restore_success=false
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$restore_success" = true ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# If we get here, backup_path is neither a valid .sql file nor a directory
|
||||
echo "❌ Invalid backup path: $backup_path (not a .sql file or directory)"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Attempt backup restoration with full functionality restored
|
||||
echo "🔄 Checking for backups..."
|
||||
backup_path=""
|
||||
|
||||
# Priority 1: Legacy single backup file with content validation
|
||||
echo "🔍 Checking for legacy backup file..."
|
||||
if [ -f "/var/lib/mysql-persistent/backup.sql" ]; then
|
||||
echo "📄 Found legacy backup file, validating content..."
|
||||
@@ -123,52 +103,40 @@ else
|
||||
echo "🔍 No legacy backup found"
|
||||
fi
|
||||
|
||||
# Priority 2: Modern timestamped backups (only if no legacy backup found)
|
||||
if [ -z "$backup_path" ] && [ -d "$BACKUP_DIRS" ]; then
|
||||
echo "📁 Backup directory exists, checking for timestamped backups..."
|
||||
if [ "$(ls -A $BACKUP_DIRS 2>/dev/null | wc -l)" -gt 0 ]; then
|
||||
# Check daily backups first
|
||||
if [ -d "$BACKUP_DIRS/daily" ] && [ "$(ls -A $BACKUP_DIRS/daily 2>/dev/null | wc -l)" -gt 0 ]; then
|
||||
echo "📅 Found daily backup directory, finding latest..."
|
||||
latest_daily=$(ls -1t $BACKUP_DIRS/daily 2>/dev/null | head -n 1)
|
||||
if [ -n "$(ls -A "$BACKUP_DIRS" 2>/dev/null)" ]; then
|
||||
if [ -d "$BACKUP_DIRS/daily" ]; then
|
||||
echo "🔍 Checking for daily backups..."
|
||||
latest_daily=$(ls -1t "$BACKUP_DIRS/daily" 2>/dev/null | head -n 1)
|
||||
if [ -n "$latest_daily" ] && [ -d "$BACKUP_DIRS/daily/$latest_daily" ]; then
|
||||
echo "📦 Checking backup directory: $latest_daily"
|
||||
# Check if directory has .sql.gz files
|
||||
if ls "$BACKUP_DIRS/daily/$latest_daily"/*.sql.gz >/dev/null 2>&1; then
|
||||
# Validate at least one backup file has content
|
||||
echo "🔍 Validating backup content..."
|
||||
for backup_file in "$BACKUP_DIRS/daily/$latest_daily"/*.sql.gz; do
|
||||
if [ -f "$backup_file" ] && [ -s "$backup_file" ]; then
|
||||
# Use timeout to prevent hanging on zcat
|
||||
if timeout 10 zcat "$backup_file" 2>/dev/null | head -20 | grep -q "CREATE DATABASE\|INSERT INTO\|CREATE TABLE"; then
|
||||
echo "✅ Valid backup found: $(basename $backup_file)"
|
||||
backup_path="$BACKUP_DIRS/daily/$latest_daily"
|
||||
break
|
||||
fi
|
||||
echo "📦 Latest daily backup found: $latest_daily"
|
||||
for backup_file in "$BACKUP_DIRS/daily/$latest_daily"/*.sql.gz; do
|
||||
if [ -f "$backup_file" ] && [ -s "$backup_file" ]; then
|
||||
if timeout 10 zcat "$backup_file" 2>/dev/null | head -20 | grep -q "CREATE DATABASE\|INSERT INTO\|CREATE TABLE"; then
|
||||
echo "✅ Valid daily backup file: $(basename "$backup_file")"
|
||||
backup_path="$BACKUP_DIRS/daily/$latest_daily"
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "⚠️ No .sql.gz files found in backup directory"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "📅 No daily backup directory found"
|
||||
fi
|
||||
else
|
||||
echo "📅 No daily backup directory found"
|
||||
# Check for timestamped backup directories (legacy format: YYYYMMDD_HHMMSS)
|
||||
echo "🔍 Checking for timestamped backup directories..."
|
||||
timestamped_backups=$(ls -1t $BACKUP_DIRS 2>/dev/null | grep -E '^[0-9]{8}_[0-9]{6}$' | head -n 1)
|
||||
if [ -n "$timestamped_backups" ]; then
|
||||
latest_timestamped="$timestamped_backups"
|
||||
echo "📦 Found timestamped backup: $latest_timestamped"
|
||||
if [ -d "$BACKUP_DIRS/$latest_timestamped" ]; then
|
||||
# Check if directory has .sql.gz files
|
||||
if ls "$BACKUP_DIRS/$latest_timestamped"/*.sql.gz >/dev/null 2>&1; then
|
||||
# Validate at least one backup file has content
|
||||
echo "🔍 Validating timestamped backup content..."
|
||||
for backup_file in "$BACKUP_DIRS/$latest_timestamped"/*.sql.gz; do
|
||||
if [ -f "$backup_file" ] && [ -s "$backup_file" ]; then
|
||||
# Use timeout to prevent hanging on zcat
|
||||
if timeout 10 zcat "$backup_file" 2>/dev/null | head -20 | grep -q "CREATE DATABASE\|INSERT INTO\|CREATE TABLE"; then
|
||||
echo "✅ Valid timestamped backup found: $(basename $backup_file)"
|
||||
echo "✅ Valid timestamped backup found: $(basename "$backup_file")"
|
||||
backup_path="$BACKUP_DIRS/$latest_timestamped"
|
||||
break
|
||||
fi
|
||||
@@ -191,71 +159,47 @@ fi
|
||||
|
||||
echo "🔄 Final backup path result: '$backup_path'"
|
||||
if [ -n "$backup_path" ]; then
|
||||
echo "📦 Found backup: $(basename $backup_path)"
|
||||
if restore_from_directory "$backup_path"; then
|
||||
echo "✅ Database restoration completed successfully!"
|
||||
echo "$(date): Backup successfully restored from $backup_path" > "$RESTORE_SUCCESS_MARKER"
|
||||
echo "🚫 Skipping schema import - data already restored from backup"
|
||||
exit 0
|
||||
else
|
||||
echo "❌ Backup restoration failed - proceeding with fresh setup"
|
||||
echo "$(date): Backup restoration failed - proceeding with fresh setup" > "$RESTORE_FAILED_MARKER"
|
||||
echo "📦 Found backup: $(basename "$backup_path")"
|
||||
if [ -d "$backup_path" ]; then
|
||||
echo "🔄 Restoring from backup directory: $backup_path"
|
||||
restore_success=true
|
||||
for backup_file in "$backup_path"/*.sql.gz; do
|
||||
if [ -f "$backup_file" ]; then
|
||||
if timeout 300 zcat "$backup_file" | mysql -h ${CONTAINER_MYSQL} -u${MYSQL_USER} -p${MYSQL_ROOT_PASSWORD}; then
|
||||
echo "✅ Restored $(basename "$backup_file")"
|
||||
else
|
||||
echo "❌ Failed to restore $(basename "$backup_file")"; restore_success=false
|
||||
fi
|
||||
fi
|
||||
done
|
||||
if [ "$restore_success" = true ]; then
|
||||
echo "$(date): Backup successfully restored from $backup_path" > "$RESTORE_SUCCESS_MARKER"
|
||||
exit 0
|
||||
else
|
||||
echo "$(date): Backup restoration failed - proceeding with fresh setup" > "$RESTORE_FAILED_MARKER"
|
||||
fi
|
||||
elif [ -f "$backup_path" ]; then
|
||||
echo "🔄 Restoring from backup file: $backup_path"
|
||||
if timeout 300 mysql -h ${CONTAINER_MYSQL} -u${MYSQL_USER} -p${MYSQL_ROOT_PASSWORD} < "$backup_path"; then
|
||||
echo "$(date): Backup successfully restored from $backup_path" > "$RESTORE_SUCCESS_MARKER"
|
||||
exit 0
|
||||
else
|
||||
echo "$(date): Backup restoration failed - proceeding with fresh setup" > "$RESTORE_FAILED_MARKER"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "ℹ️ No valid backups found - proceeding with fresh setup"
|
||||
echo "$(date): No backup found - fresh setup needed" > "$RESTORE_FAILED_MARKER"
|
||||
fi
|
||||
|
||||
# Create fresh databases if restoration didn't happen
|
||||
echo "🗄️ Creating fresh AzerothCore databases..."
|
||||
mysql -h ${CONTAINER_MYSQL} -u${MYSQL_USER} -p${MYSQL_ROOT_PASSWORD} -e "
|
||||
CREATE DATABASE IF NOT EXISTS ${DB_AUTH_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE DATABASE IF NOT EXISTS ${DB_WORLD_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE DATABASE IF NOT EXISTS ${DB_CHARACTERS_NAME} DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
SHOW DATABASES;" || {
|
||||
echo "❌ Failed to create databases"
|
||||
exit 1
|
||||
}
|
||||
SHOW DATABASES;" || { echo "❌ Failed to create databases"; exit 1; }
|
||||
echo "✅ Fresh databases created - proceeding with schema import"
|
||||
|
||||
# Wait for databases to be ready (they should exist now)
|
||||
echo "⏳ Verifying databases are accessible..."
|
||||
for i in $(seq 1 10); do
|
||||
if mysql -h ${CONTAINER_MYSQL} -u${MYSQL_USER} -p${MYSQL_ROOT_PASSWORD} -e "USE ${DB_AUTH_NAME}; USE ${DB_WORLD_NAME}; USE ${DB_CHARACTERS_NAME};" >/dev/null 2>&1; then
|
||||
echo "✅ All databases accessible"
|
||||
break
|
||||
fi
|
||||
echo "⏳ Waiting for databases... attempt $i/10"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
# Verify databases are actually empty before importing
|
||||
echo "🔍 Verifying databases are empty before import..."
|
||||
check_table_count() {
|
||||
local db_name="$1"
|
||||
local count=$(mysql -h ${CONTAINER_MYSQL} -u${MYSQL_USER} -p${MYSQL_ROOT_PASSWORD} -e "
|
||||
SELECT COUNT(*) FROM information_schema.tables
|
||||
WHERE table_schema='$db_name' AND table_type='BASE TABLE';" -s -N 2>/dev/null || echo "0")
|
||||
echo "$count"
|
||||
}
|
||||
|
||||
auth_tables=$(check_table_count "${DB_AUTH_NAME}")
|
||||
world_tables=$(check_table_count "${DB_WORLD_NAME}")
|
||||
char_tables=$(check_table_count "${DB_CHARACTERS_NAME}")
|
||||
|
||||
echo "📊 Current table counts:"
|
||||
echo " ${DB_AUTH_NAME}: $auth_tables tables"
|
||||
echo " ${DB_WORLD_NAME}: $world_tables tables"
|
||||
echo " ${DB_CHARACTERS_NAME}: $char_tables tables"
|
||||
|
||||
# Warn if databases appear to have data
|
||||
if [ "$auth_tables" -gt 5 ] || [ "$world_tables" -gt 50 ] || [ "$char_tables" -gt 5 ]; then
|
||||
echo "⚠️ WARNING: Databases appear to contain data!"
|
||||
echo "⚠️ Import may overwrite existing data. Consider backing up first."
|
||||
echo "⚠️ Continuing in 10 seconds... (Ctrl+C to cancel)"
|
||||
sleep 10
|
||||
fi
|
||||
|
||||
echo "📝 Creating dbimport configuration..."
|
||||
mkdir -p /azerothcore/env/dist/etc
|
||||
cat > /azerothcore/env/dist/etc/dbimport.conf <<EOF
|
||||
@@ -264,68 +208,17 @@ WorldDatabaseInfo = "${CONTAINER_MYSQL};${MYSQL_PORT};${MYSQL_USER};${MYSQL_ROOT
|
||||
CharacterDatabaseInfo = "${CONTAINER_MYSQL};${MYSQL_PORT};${MYSQL_USER};${MYSQL_ROOT_PASSWORD};${DB_CHARACTERS_NAME}"
|
||||
Updates.EnableDatabases = 7
|
||||
Updates.AutoSetup = 1
|
||||
|
||||
# Required configuration properties
|
||||
MySQLExecutable = ""
|
||||
TempDir = ""
|
||||
SourceDirectory = ""
|
||||
Updates.AllowedModules = "all"
|
||||
LoginDatabase.WorkerThreads = 1
|
||||
LoginDatabase.SynchThreads = 1
|
||||
WorldDatabase.WorkerThreads = 1
|
||||
WorldDatabase.SynchThreads = 1
|
||||
CharacterDatabase.WorkerThreads = 1
|
||||
CharacterDatabase.SynchThreads = 1
|
||||
Updates.Redundancy = 1
|
||||
Updates.AllowRehash = 1
|
||||
Updates.ArchivedRedundancy = 0
|
||||
Updates.CleanDeadRefMaxCount = 3
|
||||
|
||||
# Logging configuration
|
||||
Appender.Console=1,3,6
|
||||
Logger.root=3,Console
|
||||
EOF
|
||||
|
||||
echo "🚀 Running database import..."
|
||||
cd /azerothcore/env/dist/bin
|
||||
|
||||
# Run dbimport with error handling
|
||||
if ./dbimport; then
|
||||
echo "✅ Database import completed successfully!"
|
||||
|
||||
# Create import completion marker
|
||||
if touch "$RESTORE_STATUS_DIR/.import-completed" 2>/dev/null; then
|
||||
echo "$(date): Database import completed successfully" > "$RESTORE_STATUS_DIR/.import-completed"
|
||||
else
|
||||
echo "$(date): Database import completed successfully" > "$MARKER_STATUS_DIR/.import-completed"
|
||||
echo "⚠️ Using temporary location for completion marker"
|
||||
fi
|
||||
|
||||
# Verify import was successful
|
||||
echo "🔍 Verifying import results..."
|
||||
auth_tables_after=$(check_table_count "${DB_AUTH_NAME}")
|
||||
world_tables_after=$(check_table_count "${DB_WORLD_NAME}")
|
||||
char_tables_after=$(check_table_count "${DB_CHARACTERS_NAME}")
|
||||
|
||||
echo "📊 Post-import table counts:"
|
||||
echo " ${DB_AUTH_NAME}: $auth_tables_after tables"
|
||||
echo " ${DB_WORLD_NAME}: $world_tables_after tables"
|
||||
echo " ${DB_CHARACTERS_NAME}: $char_tables_after tables"
|
||||
|
||||
if [ "$auth_tables_after" -gt 0 ] && [ "$world_tables_after" -gt 0 ]; then
|
||||
echo "✅ Import verification successful - databases populated"
|
||||
else
|
||||
echo "⚠️ Import verification failed - databases may be empty"
|
||||
fi
|
||||
echo "$(date): Database import completed successfully" > "$RESTORE_STATUS_DIR/.import-completed" || echo "$(date): Database import completed successfully" > "$MARKER_STATUS_DIR/.import-completed"
|
||||
else
|
||||
echo "❌ Database import failed!"
|
||||
if touch "$RESTORE_STATUS_DIR/.import-failed" 2>/dev/null; then
|
||||
echo "$(date): Database import failed" > "$RESTORE_STATUS_DIR/.import-failed"
|
||||
else
|
||||
echo "$(date): Database import failed" > "$MARKER_STATUS_DIR/.import-failed"
|
||||
echo "⚠️ Using temporary location for failed marker"
|
||||
fi
|
||||
echo "$(date): Database import failed" > "$RESTORE_STATUS_DIR/.import-failed" || echo "$(date): Database import failed" > "$MARKER_STATUS_DIR/.import-failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🎉 Database import process complete!"
|
||||
echo "🎉 Database import process complete!"
|
||||
|
||||
Reference in New Issue
Block a user