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

#!/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."