initial commital
This commit is contained in:
96
roles/minecraft-podman/templates/backup.sh.j2
Normal file
96
roles/minecraft-podman/templates/backup.sh.j2
Normal file
@@ -0,0 +1,96 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Minecraft Server Backup Script
|
||||
# Deployed by Ansible - {{ ansible_date_time.iso8601 if ansible_date_time is defined else 'managed' }}
|
||||
#
|
||||
# Creates rolling backups of the Minecraft world and data directories.
|
||||
# Prunes old backups based on retention count.
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Configuration
|
||||
DATA_DIR="{{ paths.data_dir }}"
|
||||
BACKUP_DIR="{{ paths.backup_dir }}"
|
||||
RETENTION_COUNT="{{ backup.retention_count | default(10) }}"
|
||||
COMPRESS="{{ backup.compress | default('true') }}"
|
||||
SERVER_NAME="{{ minecraft.server_name }}"
|
||||
|
||||
# Timestamp for this backup
|
||||
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
# Log function
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
||||
}
|
||||
|
||||
# Safety checks
|
||||
if [ ! -d "$DATA_DIR" ]; then
|
||||
log "ERROR: Data directory $DATA_DIR does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$BACKUP_DIR" ]; then
|
||||
log "Creating backup directory: $BACKUP_DIR"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
fi
|
||||
|
||||
# Create backup using tar
|
||||
BACKUP_FILE="${BACKUP_DIR}/${SERVER_NAME}_${TIMESTAMP}"
|
||||
|
||||
log "Starting backup of $DATA_DIR..."
|
||||
|
||||
# Use atomic save if RCON is enabled
|
||||
USE_RCON="{{ minecraft.rcon_enabled | default('false') }}"
|
||||
if [ "$USE_RCON" = "true" ]; then
|
||||
log "Using RCON for world save..."
|
||||
# Send save-all command via rcon-cli or telnet
|
||||
# This is a best-effort operation - fall back to tar if it fails
|
||||
if command -v rcon-cli >/dev/null 2>&1; then
|
||||
rcon-cli -a localhost -p {{ minecraft.rcon_port }} -P {{ minecraft.rcon_password }} save-all || true
|
||||
sleep 5
|
||||
elif command -v mcrcon >/dev/null 2>&1; then
|
||||
mcrcon -H localhost -P {{ minecraft.rcon_port }} -p {{ minecraft.rcon_password }} "save-all" || true
|
||||
sleep 5
|
||||
else
|
||||
log "RCON client not found, skipping save-all command (backup may be inconsistent)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Deterministic backup using tar
|
||||
if [ "$COMPRESS" = "true" ]; then
|
||||
BACKUP_FILE="${BACKUP_FILE}.tar.gz"
|
||||
log "Creating compressed backup: $BACKUP_FILE"
|
||||
tar --warning=no-file-changed -czf "$BACKUP_FILE" \
|
||||
--exclude="$DATA_DIR/logs/*.gz" \
|
||||
-C "$(dirname $DATA_DIR)" "$(basename $DATA_DIR)"
|
||||
else
|
||||
BACKUP_FILE="${BACKUP_FILE}.tar"
|
||||
log "Creating uncompressed backup: $BACKUP_FILE"
|
||||
tar --warning=no-file-changed -cf "$BACKUP_FILE" \
|
||||
--exclude="$DATA_DIR/logs/*.gz" \
|
||||
-C "$(dirname $DATA_DIR)" "$(basename $DATA_DIR)"
|
||||
fi
|
||||
|
||||
log "Backup created successfully: $BACKUP_FILE"
|
||||
|
||||
# Prune old backups, retaining the most recent N
|
||||
log "Pruning old backups (keeping $RETENTION_COUNT)..."
|
||||
|
||||
# Count backups (whether .tar or .tar.gz)
|
||||
BACKUP_COUNT=$(ls "${BACKUP_DIR}/"${SERVER_NAME}_*.tar* 2>/dev/null | wc -l)
|
||||
OVERFLOW=$((BACKUP_COUNT - RETENTION_COUNT))
|
||||
|
||||
if [ "$OVERFLOW" -gt 0 ]; then
|
||||
# Remove oldest backups
|
||||
ls -t "${BACKUP_DIR}/"${SERVER_NAME}_*.tar* 2>/dev/null | tail -n "$OVERFLOW" | while read -r old_backup; do
|
||||
log "Removing old backup: $old_backup"
|
||||
rm -f "$old_backup"
|
||||
done
|
||||
else
|
||||
log "Backup count ($BACKUP_COUNT) is within retention limit ($RETENTION_COUNT)"
|
||||
fi
|
||||
|
||||
log "Backup completed at $(date '+%Y-%m-%d %H:%M:%S')"
|
||||
log "Current backups:"
|
||||
ls -lh "${BACKUP_DIR}/" 2>/dev/null || true
|
||||
Reference in New Issue
Block a user