You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
5.3 KiB
Bash
162 lines
5.3 KiB
Bash
#!/bin/bash
|
|
|
|
# ==============================================================================
|
|
# K3s Snapshot Backup Script
|
|
# Purpose: Archive local snapshots, analyze folder contents, and upload to remote.
|
|
# ==============================================================================
|
|
|
|
# Variables
|
|
SNAPSHOT_DIR="/var/lib/rancher/k3s/server/db/snapshots"
|
|
DEST_PARENT_DIR="/var/lib/rancher/k3s/server/db"
|
|
SSH_KEY_PATH="/root/.ssh/backup-k3os.pem"
|
|
REMOTE_USER="ubuntu"
|
|
REMOTE_DEST_DIR="/home/ubuntu"
|
|
CURRENT_HOSTNAME=$(hostname)
|
|
TAR_FILENAME="snapshots-${CURRENT_HOSTNAME}.tar.gz"
|
|
LOCAL_TAR_PATH="${DEST_PARENT_DIR}/${TAR_FILENAME}"
|
|
|
|
# Ensure the script is running as root
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo "Error: Please run as root."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Starting Backup Routine..."
|
|
echo "------------------------------------------------"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 1. Analyze the Snapshot Directory
|
|
# ------------------------------------------------------------------------------
|
|
if [ -d "$SNAPSHOT_DIR" ]; then
|
|
# Count files
|
|
FILE_COUNT=$(find "$SNAPSHOT_DIR" -maxdepth 1 -type f | wc -l)
|
|
|
|
if [ "$FILE_COUNT" -gt 0 ]; then
|
|
# Find newest file (sort by time, take top)
|
|
NEWEST_FILE=$(ls -t "$SNAPSHOT_DIR" | head -n 1)
|
|
NEWEST_FILE_PATH="$SNAPSHOT_DIR/$NEWEST_FILE"
|
|
NEWEST_DATE=$(date -r "$NEWEST_FILE_PATH" "+%Y-%m-%d %H:%M:%S")
|
|
|
|
# Find oldest file (sort by time reverse, take top)
|
|
OLDEST_FILE=$(ls -tr "$SNAPSHOT_DIR" | head -n 1)
|
|
|
|
echo "Snapshot Directory Analysis:"
|
|
echo "Location: $SNAPSHOT_DIR"
|
|
echo "Total Files: $FILE_COUNT"
|
|
echo "Newest File: $NEWEST_FILE (Date: $NEWEST_DATE)"
|
|
echo "Oldest File: $OLDEST_FILE"
|
|
else
|
|
echo "Warning: Snapshot directory is empty."
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "Error: Snapshot directory $SNAPSHOT_DIR does not exist."
|
|
exit 1
|
|
fi
|
|
|
|
echo "------------------------------------------------"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 2. SSH Key Handling
|
|
# ------------------------------------------------------------------------------
|
|
# Check if key directory exists, create if not
|
|
mkdir -p $(dirname "$SSH_KEY_PATH")
|
|
|
|
if [ ! -f "$SSH_KEY_PATH" ]; then
|
|
echo "SSH Key not found at $SSH_KEY_PATH."
|
|
echo "Please paste the private key content below."
|
|
echo "Press 'Ctrl+D' on a new line when finished:"
|
|
|
|
# Read multi-line input from user
|
|
cat > "$SSH_KEY_PATH"
|
|
|
|
# Verify file was written
|
|
if [ -s "$SSH_KEY_PATH" ]; then
|
|
echo "Key saved."
|
|
else
|
|
echo "Error: Key file is empty."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Set permissions to 0600 (Read/Write for owner only)
|
|
chmod 0600 "$SSH_KEY_PATH"
|
|
echo "SSH Key permissions set to 0600."
|
|
|
|
echo "------------------------------------------------"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 3. Prompt for Remote IP
|
|
# ------------------------------------------------------------------------------
|
|
read -p "Enter the IP address of the backup server: " REMOTE_IP
|
|
|
|
if [ -z "$REMOTE_IP" ]; then
|
|
echo "Error: IP address cannot be empty."
|
|
exit 1
|
|
fi
|
|
|
|
echo "------------------------------------------------"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 4. Create Tarball
|
|
# ------------------------------------------------------------------------------
|
|
echo "Creating archive: $LOCAL_TAR_PATH"
|
|
|
|
# We use -C to change directory before compressing so the archive structure is clean
|
|
# We are archiving the 'snapshots' folder itself
|
|
tar -czf "$LOCAL_TAR_PATH" -C "$DEST_PARENT_DIR" snapshots
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "Archive created successfully."
|
|
else
|
|
echo "Error: Failed to create tarball."
|
|
exit 1
|
|
fi
|
|
|
|
echo "------------------------------------------------"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 5. Upload via SCP
|
|
# ------------------------------------------------------------------------------
|
|
echo "Uploading to $REMOTE_USER@$REMOTE_IP:$REMOTE_DEST_DIR..."
|
|
|
|
scp -i "$SSH_KEY_PATH" "$LOCAL_TAR_PATH" "${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DEST_DIR}"
|
|
|
|
if [ $? -eq 0 ]; then
|
|
echo "SCP upload completed successfully."
|
|
else
|
|
echo "Error: SCP upload failed."
|
|
exit 1
|
|
fi
|
|
|
|
echo "------------------------------------------------"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 6. Verify Upload Integrity
|
|
# ------------------------------------------------------------------------------
|
|
echo "Verifying remote file..."
|
|
|
|
# Get local file size in bytes
|
|
LOCAL_SIZE=$(stat -c%s "$LOCAL_TAR_PATH")
|
|
|
|
# SSH into remote to get remote file size
|
|
# We use StrictHostKeyChecking=no to prevent hanging on yes/no prompts if it's a new host,
|
|
# though standard security usually advises keeping it. Adjust if necessary.
|
|
REMOTE_SIZE=$(ssh -i "$SSH_KEY_PATH" "${REMOTE_USER}@${REMOTE_IP}" "stat -c%s ${REMOTE_DEST_DIR}/${TAR_FILENAME}")
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "Error: Could not connect via SSH to verify file."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Local Size: $LOCAL_SIZE bytes"
|
|
echo "Remote Size: $REMOTE_SIZE bytes"
|
|
|
|
if [ "$LOCAL_SIZE" -eq "$REMOTE_SIZE" ]; then
|
|
echo "SUCCESS: File sizes match. Backup verified."
|
|
else
|
|
echo "FAILURE: File sizes do not match. Integrity check failed."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Done." |