#!/bin/bash ##################################################################### # # A FOOLISH KVM BACKUP SCRIPT # hacked together by Miguel around mid February 2018 # # untar also needs -S !!! # # TODO: ADD TIMING INFO ? # # TODO: do not make so many assumptions about file names and locations :( # This script should/could be much more universal! # Do some BASIC error checking # # TODO!: # config external backup space # show config and ask if ok # override --all-yes with param # use dash instead bash? # dry run # ##################################################################### VERSION="0.1" # we exit as soon as a single command fails! set -e echo "" echo " 1) Are you running inside a tmux/screen?" echo " 2) Did you cleanup the backuped system (pruning unused stuff)?" echo " 3) Did you remember to perform sync & fstrim?" echo " 4) Are you aware this script runs many commands with sudo?" echo "" echo " Please type 'YES' if you want to continue." echo "" read proceed if [[ "$proceed" != "YES" ]]; then exit fi # script expects exaclty one param (see config_example) if [ "$#" -ne 1 ]; then echo "Usage: $0 [config_file]" exit fi # color helpers (set on terminal only) black= red= green= yellow= blue= magenta= cyan= white= reset= if test -t 1; then black=`tput setaf 0` red=`tput setaf 1` green=`tput setaf 2` yellow=`tput setaf 3` blue=`tput setaf 4` magenta=`tput setaf 5` cyan=`tput setaf 6` white=`tput setaf 7` reset=`tput sgr0` fi # pretty printing funcs / vars cnt=0 all=11 function print_ok { echo [${green}OK$reset] } function print_cnt { printf " [${cyan}%2s${reset}/${all}${reset}] " ${1} } function print_txt { ((++cnt)) print_cnt $cnt printf "%-30s " "${1}..." } # let's do it echo echo "### ${magenta}FOOL LIVE KVM BACKUP ${VERSION}${reset} ###" echo echo " Using config file: ${yellow}${1}${reset}" echo source $1 # some vars TIMESTAMP=`date +"%Y%m%d_%H%M%S"` LOG=${DOMAIN}_${TIMESTAMP}.log DOMAIN_T=${DOMAIN}_${TIMESTAMP} # tell what we gonna do echo " Today we backup: ${yellow}${DISK}$reset on ${yellow}${DOMAIN}${reset} as ${yellow}${USER}${reset}" echo " SOURCE_DIR: ${yellow}${SOURCE}$reset" echo " TARGET_DIR: ${yellow}${TARGET}$reset" echo " LIMIT_RATE for tar: ${yellow}${LIMIT_RATE}${reset}/second" echo " Logging to: ${yellow}${LOG}$reset" echo echo " Keep your fingers crossed!" echo # chande into target dir cd $TARGET print_txt "LOG CURRENT DOMBLK LIST" sudo -u $USER virsh domblklist $DOMAIN > $LOG print_ok print_txt "DUMPING XML" sudo -u $USER virsh dumpxml $DOMAIN > $DOMAIN_T.xml sudo -u $USER virsh dumpxml $DOMAIN | sed "s:$SOURCE/${DOMAIN}.img:$SOURCE/${DOMAIN}.SNAP:" > ${DOMAIN_T}_snapped.xml print_ok print_txt "SAVING VM (RAM)" sudo -u $USER virsh save $DOMAIN $DOMAIN_T.ram >> $LOG print_ok print_txt "SNAPSHOTTING DISK" sudo -u $USER virsh snapshot-create-as $DOMAIN SNAP --disk-only --atomic --no-metadata --quiesce >> $LOG print_ok print_txt "RESTORING VM (RAM)" sudo -u $USER virsh restore $DOMAIN_T.ram --xml ${DOMAIN_T}_snapped.xml >> $LOG print_ok print_txt "LOG CURRENT DOMBLKLIST" sudo -u $USER virsh domblklist $DOMAIN >> $LOG print_ok print_txt "SAVING SNAPSHOT" sudo -u $USER tar -C ${SOURCE} -cSf - $DOMAIN.img 2>>$LOG | pv -L $LIMIT_RATE 2>/dev/null 1> $DOMAIN_T.img.tar print_ok print_txt "BLOCK-COMMITTING DELTAS" sudo -u $USER virsh blockcommit $DOMAIN $DISK --pivot >> $LOG print_ok print_txt "REMOVING DELTAS" sudo -u $USER rm ${SOURCE}/$DOMAIN.SNAP >> $LOG print_ok print_txt "LOG CURRENT DOMBLKLIST" sudo -u $USER virsh domblklist $DOMAIN >> $LOG print_ok print_txt "LOG QCOW2 IMAGE INFO" sudo -u $USER qemu-img info ${SOURCE}/$DOMAIN.img >> $LOG print_ok echo echo "### ${magenta}FINITO${reset} ###" echo