initial commital

This commit is contained in:
2026-09-02 14:47:08 -06:00
commit 3c80aef53b
23 changed files with 1648 additions and 0 deletions

View 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