#!/bin/bash
# Interactive script to backup a VM or Container on one Proxmox host and restore it on another
# Default configuration variables
SOURCE_HOST="srv78"
TARGET_HOST="srv141"
BACKUP_PATH="/var/lib/vz/dump"
SSH_USER="root"
TARGET_STORAGE="local"
# Function to validate numeric input
validate_number() {
if [[ ! $1 =~ ^[0-9]+$ ]]; then
echo "Error: '$1' is not a valid number."
return 1
fi
return 0
}
# Ask for Proxmox hosts information
read -p "Enter source Proxmox host [${SOURCE_HOST}]: " input_source_host
SOURCE_HOST=${input_source_host:-$SOURCE_HOST}
read -p "Enter target Proxmox host [${TARGET_HOST}]: " input_target_host
TARGET_HOST=${input_target_host:-$TARGET_HOST}
read -p "Enter SSH user [${SSH_USER}]: " input_ssh_user
SSH_USER=${input_ssh_user:-$SSH_USER}
# Ask for VM/CT ID and validate
while true; do
read -p "Enter source VM/CT ID: " VM_ID
if validate_number "$VM_ID"; then
break
fi
done
while true; do
read -p "Enter target VM/CT ID [${VM_ID}]: " input_new_vm_id
NEW_VM_ID=${input_new_vm_id:-$VM_ID}
if validate_number "$NEW_VM_ID"; then
break
fi
done
# Ask for container/VM type
while true; do
read -p "Is this a VM (qemu) or Container (lxc)? [qemu/lxc]: " VM_TYPE
VM_TYPE=$(echo "$VM_TYPE" | tr '[:upper:]' '[:lower:]')
if [[ "$VM_TYPE" == "qemu" || "$VM_TYPE" == "lxc" ]]; then
break
else
echo "Error: Please enter either 'qemu' or 'lxc'."
fi
done
read -p "Enter target storage location [${TARGET_STORAGE}]: " input_target_storage
TARGET_STORAGE=${input_target_storage:-$TARGET_STORAGE}
# Confirm the details before proceeding
echo ""
echo "Migration Details:"
echo "-------------------"
echo "Source Host: $SOURCE_HOST"
echo "Target Host: $TARGET_HOST"
echo "Source ID: $VM_ID"
echo "Target ID: $NEW_VM_ID"
echo "Type: $VM_TYPE"
echo "Target Storage: $TARGET_STORAGE"
echo ""
read -p "Are these details correct? [y/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
echo "Operation cancelled."
exit 1
fi
# Stop the VM/CT on source host
echo "Stopping $VM_TYPE $VM_ID on $SOURCE_HOST..."
if [[ "$VM_TYPE" == "qemu" ]]; then
ssh $SSH_USER@$SOURCE_HOST "qm stop $VM_ID" || { echo "Failed to stop VM"; exit 1; }
else
ssh $SSH_USER@$SOURCE_HOST "pct stop $VM_ID" || { echo "Failed to stop Container"; exit 1; }
fi
# Wait for VM/CT to stop
echo "Waiting for $VM_TYPE to stop completely..."
sleep 10
# Create backup on source host
echo "Creating backup of $VM_TYPE $VM_ID..."
ssh $SSH_USER@$SOURCE_HOST "vzdump $VM_ID --compress zstd" || { echo "Backup failed"; exit 1; }
# Get the newest backup file for this VM/CT
if [[ "$VM_TYPE" == "qemu" ]]; then
BACKUP_FILE=$(ssh $SSH_USER@$SOURCE_HOST "ls -t $BACKUP_PATH/vzdump-qemu-$VM_ID-*.vma.zst | head -1")
else
BACKUP_FILE=$(ssh $SSH_USER@$SOURCE_HOST "ls -t $BACKUP_PATH/vzdump-lxc-$VM_ID-*.tar.zst | head -1")
fi
BACKUP_FILENAME=$(basename "$BACKUP_FILE")
if [[ -z "$BACKUP_FILE" ]]; then
echo "Error: Backup file not found!"
exit 1
fi
echo "Backup created: $BACKUP_FILENAME"
# Transfer the backup file to target host
echo "Transferring backup to $TARGET_HOST..."
ssh $SSH_USER@$SOURCE_HOST "rsync --progress -a $BACKUP_FILE $SSH_USER@$TARGET_HOST:$BACKUP_PATH/" || { echo "Transfer failed"; exit 1; }
# Import the backup on target host
echo "Importing backup on $TARGET_HOST..."
if [[ "$VM_TYPE" == "qemu" ]]; then
ssh $SSH_USER@$TARGET_HOST "qmrestore $BACKUP_PATH/$BACKUP_FILENAME $NEW_VM_ID --storage $TARGET_STORAGE" || { echo "Restore failed"; exit 1; }
else
ssh $SSH_USER@$TARGET_HOST "pct restore $NEW_VM_ID $BACKUP_PATH/$BACKUP_FILENAME --storage $TARGET_STORAGE" || { echo "Restore failed"; exit 1; }
fi
# Start the VM/CT on target host
echo "Starting $VM_TYPE $NEW_VM_ID on $TARGET_HOST..."
if [[ "$VM_TYPE" == "qemu" ]]; then
ssh $SSH_USER@$TARGET_HOST "qm start $NEW_VM_ID" || { echo "Failed to start VM"; exit 1; }
else
ssh $SSH_USER@$TARGET_HOST "pct start $NEW_VM_ID" || { echo "Failed to start Container"; exit 1; }
fi
# Ask if backup files should be removed
read -p "Do you want to remove the backup files to save space? [y/N]: " CLEANUP
if [[ "$CLEANUP" =~ ^[Yy]$ ]]; then
echo "Cleaning up backup files..."
ssh $SSH_USER@$SOURCE_HOST "rm $BACKUP_FILE"
ssh $SSH_USER@$TARGET_HOST "rm $BACKUP_PATH/$BACKUP_FILENAME"
echo "Backup files removed."
fi
echo "Migration complete! $VM_TYPE $VM_ID from $SOURCE_HOST is now running as $VM_TYPE $NEW_VM_ID on $TARGET_HOST"