IT & + si affinités

Encore un blog de sysadmin … mais pas uniquement ;-)

Backup de VM Qemu/KVM

Ce script effectue une sauvegarde des VM (Configuration et disque), attention, les VMs sont killées si elles ne répondent pas à la commande d’arrêt dans le temps imparti. 

Note : il existe de meilleurs moyens de faire des sauvegarde, par exemple avec des snapshots si votre format de stockage le permet.

#!/bin/bash
# Name : backup_vm.sh
# Author : @Markhor75 
# Last Mod : 2014 10 20
# Backup VM (disk and config)

DESTINATION="/home/backup/vm"
DATE="$(date +"%Y%m%d_%H%M")"
RETENTIONDAYS="2"	# Days to keep backups 
KILLTIME=60		# Seconds to wait after excute shutdown VM and before destroying it
THISVMDEST=""
DOM=""
debug=1

if [ $debug -eq 1 ]; then
	echo "****************************************"
	echo "* Backup destination is "$DESTINATION
	echo "* Date is "$DATE
	echo "* Retention is "$RETENTIONDAYS" days"
	echo "* Killtime is "$KILLTIME"s"
	echo "* Debug is active"
	echo "****************************************"
fi	

for DOM in `virsh list --all | tail -n +3 | awk '{print $2}' | sort -u`
do 
        if [ $debug -eq 1 ]; then
		echo "*** Starting Backup $DOM ***"
	fi

	STATE=`virsh domstate $DOM`
	THISVMDEST=$DESTINATION"/"$DOM

	if [ ! -d $THISVMDEST ]; then
		if [ $debug -eq 1 ]; then 
			echo " Creating dir $THISVMDEST"
		fi
		mkdir $THISVMDEST
	fi

	virsh dumpxml $DOM >$THISVMDEST"/"$DATE"_"$DOM".xml"

	if [ "$STATE" == "running" ]; then
		if [ $debug -eq 1 ]; then
			echo " VM state is running, shutting down"
		fi
		virsh shutdown $DOM
		sleeping=0
		while [ $sleeping -lt $KILLTIME ]
		do
			if [ "`virsh domstate $DOM`" != "shut off" ]; then
				sleep 5
                        	sleeping=$(( $sleeping + 5))
			else
				sleeping=0
				break
			fi
		done

		#Destoying domain if not stopped after 60 seconds
		if [ "$sleeping" != "0" ]; then
                	if [ $debug -eq 1 ]; then
                        	echo " VM always running after $KILLTIME s, Destoying it"
                	fi
			virsh destroy $DOM
		fi
		
	fi
	
	for DISK in `virsh dumpxml $DOM |grep "source file" |cut -d "'" -f 2`
	do
		DISKNAME=`echo $DISK |awk -F"/" '{print $NF}'`
		if [ $debug -eq 1 ]; then
			echo " making cp $DISK $THISVMDEST\"/\"$DATE\"_\"$DISKNAME"
		fi
		#cp $DISK $THISVMDEST"/"$DATE"_"$DISKNAME
	done

        if [ "$STATE" == "running" ]; then
		if [ $debug -eq 1 ]; then
			echo " VM restarting"
		fi
		virsh start $DOM
	fi
        if [ $debug -eq 1 ]; then
                echo "*** Ending backup $DOM ***"
        fi
done

if [ $debug -eq 1 ]; then
	echo "Deleting old backups"
fi

find $DESTINATION -maxdepth 1 -ctime +$RETENTIONDAYS -type f -exec rm {} \;

if [ $debug -eq 1 ]; then
        echo "Script ending"
	echo""
fi

 

Script de backup

Voici un petit script qui permet de  « sauvegarder » un répertoire et de gérer la rotation :

#!/bin/bash
# 
# Name : backup_dir.sh
# Author : @Markhor75 
# Last Mod : 2012 10 28
export name=`basename "$0"`

RETENTIONDAYS="7"
MAKEARCHIVE="1"
SOURCE="&&&"
DESTINATION="/var/backups"
DATE="$(date +"%Y%m%d_%H%M")"

if [ $MAKEARCHIVE -eq "1" ]; then
        ARCHIVESTATUS="enabled"
else
        ARCHIVESTATUS="disabled"
fi

usage()
{
   echo "> Make a tar.gz of \"Source dir\" directory in "$DESTINATION" or other specified dir." 
   echo "> Delete archives older than "$RETENTIONDAYS" days."
   echo "> You can change this value with option -r ( 0 won't delete files)."
   echo "> Optionaly make mensual permanent copy, this option is currently "$ARCHIVESTATUS
   echo ">"
   echo "> Usage:"
   echo ">    $name -h                      Show this help."
   echo ">    $name -s Source dir [-d Destination dir] [-r 7]"
   echo "> Default Destination dir is "$DESTINATION
}

if [ "$1" != "-s" ]; then
   usage
   exit
fi
while getopts s:d:hr: opt
do
   case "$opt" in
      s) SOURCE=$OPTARG;;
      d) DESTINATION=$OPTARG;;
      r) ((RETENTIONDAYS=OPTARG+0));;
      h)
        usage
        exit
        ;;
      \?)
        usage
        exit
         ;;
   esac
done

if [ ! -d $SOURCE ]; then
        usage
        exit
fi

# Creating destination dir if needed
if [ ! -d $DESTINATION ]; then
        mkdir $DESTINATION
fi

CURRENT_DIR=`pwd`
cd $SOURCE
ARCHIVENAME=${PWD##*/}"_"$DATE".tar.gz"

tar -cvzf $DESTINATION"/"$ARCHIVENAME $SOURCE 2>&1 1>/dev/null

if [ "$MAKEARCHIVE" == "1" ]; then
        ARCHIVEMENSUEL=$DESTINATION"/mensuel"
        if [ ! -d $ARCHIVEMENSUEL ]; then
                mkdir $ARCHIVEMENSUEL
        fi
fi

# If RETENTIONDAYS value is greater than 1, we delete older files
if [ "$RETENTIONDAYS" -gt "1" ] ; then
        find $DESTINATION -maxdepth 1 -ctime +$RETENTIONDAYS -type f -exec rm {} \;
fi

cd $CURRENT_DIR
exit 0;