2026-03-12 20:51:59
This commit is contained in:
111
bash/vmclone.sh
Normal file
111
bash/vmclone.sh
Normal file
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
function usage {
|
||||
echo "Usage: vmclone -s|--source <SOURCE_VM> -t|--target <TARGET_VM> -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
|
||||
Reference in New Issue
Block a user