#!/bin/bash helpFunction() { echo "" echo "Usage: $0 -v VmName -t TargetHost -d TargetDataset" echo -e "\t-v Name of the vm to backup" echo -e "\t-t Backup target host name" echo -e "\t-s VM source zfs dataset" echo -e "\t-d Backup target zfs dataset" exit 1 # Exit script after printing help } while getopts "v:t:s:d:" opt do case "$opt" in v ) VM="$OPTARG" ;; t ) DESTHOST="$OPTARG" ;; s ) SRCZFS="$OPTARG" ;; d ) DESTZFS="$OPTARG" ;; ? ) helpFunction ;; # Print helpFunction in case parameter is non-existent esac done # Print helpFunction in case parameters are empty if [ -z "$VM" ] || [ -z "$DESTHOST" ] || [ -z "$DESTZFS" ] || [ -z "$SRCZFS" ] then echo "Some or all of the parameters are empty"; helpFunction fi DATE=$(date "+%Y%m%d%H%M") DATE30=$(date -d "-30day" "+%Y%m%d") SNAPNAME="backup_$DATE" VMDISKS=$(virsh domblklist $VM | egrep -o vd.) DISKSPEC="" for disk in $VMDISKS do DISKSPEC+="--diskspec $disk,file=/srv/snapshots/$VM/$VM-$disk-$SNAPNAME.qcow2,snapshot=external " done # create snapshot dataset zfs create tank/snapshots/$VM virsh snapshot-create-as --domain $VM --name $SNAPNAME --quiesce --atomic --disk-only $DISKSPEC >/dev/null 2>&1 if [ $? -ne 0 ] then virsh snapshot-create-as --domain $VM --name $SNAPNAME --disk-only $DISKSPEC >/dev/null 2>&1 if [ $? -ne 0 ] then echo "VM snapshot creation failed" >&2 exit 1 else echo "Snapshot created without --quiesce" fi fi zfs snapshot "$SRCZFS"@"$SNAPNAME" if [ $? -ne 0 ] then echo "ZFS snapshot creation failed" >&2 exit 1 fi for disk in $VMDISKS do virsh blockcommit $VM $disk --pivot --active >/dev/null done VMDISKS=$(virsh domblklist $VM | egrep vd.) for disk in $VMDISKS do if [[ $disk == *"snapshot"* ]] then echo "Snapshot deletion failed for $disk" >&2 fi done virsh snapshot-delete $VM $SNAPNAME --metadata SUCCESS=$(zfs get backup:success -H -o value $SRCZFS) if [[ $SUCCESS == "true" ]] then LASTBACKUP=$(zfs get backup:date -H -o value $SRCZFS) LASTSNAP="backup_$LASTBACKUP" zfs send -i "$SRCZFS"@"$LASTSNAP" "$SRCZFS"@"$SNAPNAME" | pv -L 500M | ssh $DESTHOST sudo zfs recv -F $DESTZFS else zfs send "$SRCZFS"@"$SNAPNAME" | pv -L 500M | ssh $DESTHOST sudo zfs recv -F $DESTZFS fi if [ $? -eq 0 ] then zfs set backup:success="true" $SRCZFS zfs set backup:date="$DATE" $SRCZFS else zfs set backup:success="false" $SRCZFS zfs set backup:failed="$DATE" $SRCZFS fi zfs destroy tank/snapshots/$VM