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