Note that this depends on “virsh”, the libvirt client, and “bzip2″.
Basically, what this script does is send a shutdown signal to each of the specified nodes, back up the disk images, and then bzip them in the background while it restarts the node. So having said this, you’ll want to make sure your services on your VM’s are set to shut down and start up gracefully when the OS is shut down / restarted.
#!/bin/bash
#
# This is who we'll back up
#
machines="Dev Test Foobar"
#
# Keep the house clean
#
days_to_keep="7"
#
# Store backups here. NFS to another machine would make sense.
# so that your backups are not local.
#
backup_dir="/VirtualMachines/KVM/backups"
#
# Logs go here.
#
log_dir="/VirtualMachines/KVM/backups/logs"
#
# End parameters
#
#=================================================================
#
# Timestamp for the log file
#
right_now=`date '+%m%d%Y_%H%M%p'`
exec 1>/${log_dir}/backup_vms.${right_now}.log 2>&1
print_date() {
date '+%m%d%Y_%H%M%p'
}
for machine in $machines
do
if [[ ! -d ${backup_dir}/${machine} ]];
then
mkdir -p ${backup_dir}/${machine}
fi
echo "Backing up VM configuration"
virsh dumpxml $machine > ${backup_dir}/${machine}/${machine}.xml
echo "Sending shutdown signal to $machine"
virsh shutdown $machine
echo " Return code: $?"
echo -n "Waiting for machine to shut down "
for i in 1 2 3 4 5
do
echo -n "."
virsh list | grep -v "^$" | grep -v "^ Id" | grep -v "\-\-\-\-\-" | awk '{print $2" "$3}' | grep $machine | while read name state
do
if [[ $state -eq "running" ]]
then
sleep 60
fi
done
done
echo "Copying disk(s)"
virsh domblklist $machine | grep -v "^$" | grep -v "^Target" | grep -v "\-\-\-\-\-" | awk '{print $2}' | while read disk
do
echo " $disk ..."
copy_disk="${backup_dir}/${machine}/`basename ${disk}`.`print_date`"
echo " Copying $disk to $copy_disk"
fuser $disk 1>/dev/null 2>&1
if (( $? == 0 ))
then
echo " Disk $disk is still in use! "
else
echo " Copy started at `print_date`"
cp $disk $copy_disk
echo " Return code: $?"
echo " Copy ended at `print_date`"
echo " Backgrounding bzip of $copy_disk"
nohup bzip2 $copy_disk &
fi
done
echo "Starting machine $machine"
virsh start $machine
echo " Return code: $?"
echo
done
echo "Removing old backups."
find $backup_dir -type f -mtime +$days_to_keep -ls
find $backup_dir -type f -mtime +$days_to_keep -exec rm -f {} \;
Thanks for this script.
I should mention that if you have an ISO attached to the VM image then these will get backed up as well. So unattach any ISO before running it.
Also, to take backup of the VM configuration file add the following to your script:
virsh dumpxml vm_name > /tmp/vm_name.xml
cheers…
Great info Sam, thanks. I’ll update the script.
Thank you, this worked great!
hi
i suggest to use bigsync to copy the image file instead of cp!
http://code.google.com/p/bigsync/
That’s a good idea Toni, thanks!
Worked like a charm on brand new Wheezy 64-bit server.