|
Linux bash script for VMware: automated backup vm's |
|
|
|
|
Thursday, 16 November 2006 00:33 |
|
Page 1 of 3 Here is a script that I use to create backups of all of my VM's. There has been some evolution over time so I posted three versions. You can run these script after some adjustments on your VMware host server. For every VM the same routine is followed: stop, copy, start. To complete the backup procedure the backup that just was created is copied to a remote VMware server. So in case of a hardware failure you can start your VM's again on the remote machine. Be aware that this is not a hot backup, the VM's will be switched off.
What you have to know and do before starting this script? - This script is a Linux bash script so the VMware host should be a linux os, not Windows. If you're running Windows then you can use the concept and program in DOS or VB or so. And you can use blat as a simple smtp email tool.
- I use the VMware server version. I don't know if this script works with other versions of VMware but I guess there shouldn't be any problems.
- Create a ssh key of the host server you are running the vm's on and install it on the backup server. This is very usefull so you don't have to use passwords in your scripts to log in when using ssh for backing up the vm files.
- Install the VMware tools on all VM's so they can be shut down using the command line tools on the vmware host server.
- Adjust the script to your situation. Change the variables in the script. And add your own email address and emailserver. If you don't receive the email try to send an email on the command line yourself or check your servers smtp settings.
I got three versions of the script and you can find them on these three pages. (new stuff: vm_list="`vmware-cmd -l`" OLD_IFS="$IFS" IFS=\" \" for vm in "$vm_list"; do ... done ) #! /bin/bash # Roderick Derks # www.r71.nl # 20070227 # # backup vmware's virtual machines to a remote computer # 1. check if backupserver is running # Actions 2, 3 and 4 are per vm: # 2. stop the vm if it is running # 3. local copy the vm files # 4. start the vm if it was running # 5. remote copy of the backups created in step 3 ###################################################################
### day and hour DAY=$(date | cut -d" " -f1) HOUR=$(date|tr -s " "|cut -d" " -f4| cut -d":" -f1) ### logfile export LOGFILE="/var/log/backup_vmware_servers.log" if [ ! -e "${LOGFILE}" ] then touch "$LOGFILE" # create a new logfile if not present fi ### variables VM_HOST_SRC="alpedhuez.r71.nl" VM_HOST_REMOTE_DEST="bonette.r71.nl" VM_ROOT_SRC="/DATA/vmware/vmmachines" VM_LOCAL_BACKUP_DEST="/mnt/usbdrive01/Backup/vmware/vmmachines" VM_ROOT_REMOTE_DEST="/DATA/vmware/vmmachines" VM_REMOTE_DEST="${VM_HOST_REMOTE_DEST}:${VM_ROOT_REMOTE_DEST}" MAILSERVER="yourmailserver.yourmail.com" EMAILADDRESS="
This e-mail address is being protected from spambots. You need JavaScript enabled to view it
"
################################################################### ### check local machine name if [ $HOSTNAME != "${VM_HOST_SRC}" ]; then echo Hostname=${HOSTNAME}: echo "Dit script will only run on ${VM_HOST_SRC}" exit fi
echo $HOSTNAME > ${LOGFILE} # flush logfile and add data date >> ${LOGFILE} echo >> ${LOGFILE}
###################################################################
IFS=$'\n' # needed to prevent problems with filenames containing spaces in arrays for VM_PATH_FILE in $(find ${VM_ROOT_SRC} -type f -name *.vmx) do
echo VM: ${VM_PATH_FILE} | tee -a ${LOGFILE} echo | tee -a ${LOGFILE}
## ## stop vm's if they are running ##
vmware-cmd ${VM_PATH_FILE} getstate|grep -q "getstate() = on" if [ $? -eq 0 ]; then echo "Shutting down VM at `date`." | tee -a ${LOGFILE} #array0=( "${array0[@]}" "${VM_PATH_FILE}" ) # add to array, these vm's will be started later on BOOT="1" #### vmware-cmd ${VM_PATH_FILE} stop soft >> ${LOGFILE} else echo "VM is not running." >> ${LOGFILE}; echo "VM is not running." BOOT="0" fi
## ## start backup ##
VM_PATH=`echo ${VM_PATH_FILE}|rev|cut -d"/" -f2-|rev` # remove last field (using rev to remove first field, is easier) echo VM_PATH: $VM_PATH
echo "Starting local backup at `date`. (This is going to take a while...)" | tee -a ${LOGFILE}
# Local rsync copy command (to a local disk) VM_ROOT_SRC_VMDIR=`echo ${VM_PATH}|awk -F "${VM_ROOT_SRC}" '{ print $2 }'` #echo rsync -avu ${VM_PATH}/ ${VM_LOCAL_BACKUP_DEST}${VM_ROOT_SRC_VMDIR} #### rsync -avu ${VM_PATH}/ ${VM_LOCAL_BACKUP_DEST}${VM_ROOT_SRC_VMDIR} >> ${LOGFILE}
echo Local backup finished at `date`. | tee -a ${LOGFILE}
## ## start VM if it was running ##
if [ $BOOT -eq 1 ]; then echo "Starting VM" | tee -a ${LOGFILE} #### vmware-cmd "${VM_PATH_FILE}" start >> ${LOGFILE} fi if [ $BOOT -eq 0 ]; then echo "VM wasn't running so it will not be started." | tee -a ${LOGFILE} fi
echo | tee -a ${LOGFILE}
echo "------------------------------------------------------------" | tee -a ${LOGFILE} done
date >> ${LOGFILE} echo "All VM's have been backed up and started at `date`." | tee -a ${LOGFILE}
###################################################################
# check if remote server is up using return value: 1 is failed (down), 0 is success (up) echo | tee -a ${LOGFILE} echo Starting remote backup procedure. | tee -a ${LOGFILE}
ping ${VM_HOST_REMOTE_DEST} -c2|grep -q " 0% packet loss" if [ $? -eq 0 ]; then echo echo ${VM_HOST_REMOTE_DEST} is up, ping test succeeded. | tee -a ${LOGFILE}
# Copy local backup to a remote server. echo Remote backup started at `date`.. | tee -a ${LOGFILE} #### rsync -avu -e ssh ${VM_LOCAL_BACKUP_DEST}/ ${VM_REMOTE_DEST} >> ${LOGFILE} echo Remote backup finished at `date`. | tee -a ${LOGFILE}
else echo echo ${VM_HOST_REMOTE_DEST} unreachable, ping failed: no remote backup. | tee -a ${LOGFILE} fi
echo | tee -a ${LOGFILE}
###################################################################
## ## Mail ##
ping ${MAILSERVER} -c2|grep -q " 0% packet loss" if [ $? -eq 0 ]; then echo echo ${MAILSERVER} is up, ping test succeeded. | tee -a ${LOGFILE}
else echo echo ${MAILSERVER} unreachable, ping failed: waiting for 90 seconds to give it some time to boot. | tee -a ${LOGFILE}
sleep 90 # my mailserver is probably booting now so wait a little bit #exit 1 fi
echo "Sending e-mail to ${EMAILADDRESS}" >> ${LOGFILE} date >> ${LOGFILE} # logfile aanvullen mail -s "VMWare backupscipt finished" ${EMAILADDRESS} <${LOGFILE}
exit 0
|
|