#!/usr/bin/bash function usage { echo "Usage: vmclone -s|--source -t|--target -o|--scriptonly" echo " o| --scriptonly, only clone script is generated, the clone command will not be executed" } ######## # MAIN # ######## typeset SOURCE_VM typeset TARGET_VM typeset SCRIPTONLY typeset CLONESCRIPT="/tmp/kvmclone.sh" typeset -i DISK_COUNT_SOURCE typeset -i I typeset RC typeset REPLACE # parameter processing while [ "$1" != "" ]; do case $1 in -s | --source ) shift SOURCE_VM="$1" ;; -t | --target ) shift TARGET_VM="$1" ;; -o | --scriptonly ) SCRIPTONLY=true ;; -r | --replace ) REPLACE=true ;; -h | --help ) usage exit ;; * ) usage exit 1 esac shift done if [ -z "$SOURCE_VM" ] || [ -z "$TARGET_VM" ]; then usage exit fi # check if source VM exists I=$(virsh list --all | grep $SOURCE_VM | wc -l) if (( I == 0 )); then echo "Source VM ($SOURCE_VM) does not exists" exit 1 fi # check if source VM is shut off RC=$(virsh domstate $SOURCE_VM) if [ "$RC" != "shut off" ]; then echo "Source VM ($SOURCE_VM) is $RC, please shut it down first" exit 1 fi # check if target VM exists I=$(virsh list --all | grep $TARGET_VM | wc -l) if (( I > 0 )); then # -r|--replace option was used if [ "$REPLACE" == true ] ; then # destroy the VM and the underlayng storage echo "Shutdown VM $TARGET_VM" virsh destroy $TARGET_VM > /dev/null 2>&1 echo "Remove VM $TARGET_VM" virsh undefine $TARGET_VM --remove-all-storage > /dev/null 2>&1 else echo "Target VM ($TARGET_VM) already exists, use -r|--replace option to replace it" exit 1 fi fi # generate KVM clone shell rm -rf $CLONESCRIPT echo -e "#!/usr/bin/bash"'\n' >> $CLONESCRIPT chmod +x $CLONESCRIPT echo "virt-clone \\" >> $CLONESCRIPT echo " --original $SOURCE_VM \\" >> $CLONESCRIPT echo " --name $TARGET_VM \\" >> $CLONESCRIPT DISK_COUNT_SOURCE=$(virsh domblklist ${SOURCE_VM} --details | grep -v cdrom | grep "file" | wc -l) I=0 for DISK in $(virsh domblklist ${SOURCE_VM} --details | grep -v cdrom | grep "file" | awk -F " " '{ print $4}') do I=$((I+1)) NEWDISK=${DISK/$SOURCE_VM/$TARGET_VM} if (( I < DISK_COUNT_SOURCE )); then echo " --file $NEWDISK \\" >> $CLONESCRIPT else echo " --file $NEWDISK" >> $CLONESCRIPT fi done echo "KVM clone script [$SOURCE_VM -> $TARGET_VM] has been generated: $CLONESCRIPT" if [ "$SCRIPTONLY" != true ] ; then # recreate VM storage directories cat $CLONESCRIPT | grep '\-\-file' | xargs -I{} echo {} | sed "s/--file//g" | sed 's/ //g' | xargs -I{} dirname {} | sort -u | xargs -I{} rm -rf {} cat $CLONESCRIPT | grep '\-\-file' | xargs -I{} echo {} | sed "s/--file//g" | sed 's/ //g' | xargs -I{} dirname {} | sort -u | xargs -I{} mkdir -p {} # Run generated KVM clone shell echo "Executing $CLONESCRIPT.." $CLONESCRIPT fi