Skip to content

Instantly share code, notes, and snippets.

@nohtyp
Last active August 29, 2015 14:18
Show Gist options
  • Save nohtyp/befaf312e670cad38c25 to your computer and use it in GitHub Desktop.
Save nohtyp/befaf312e670cad38c25 to your computer and use it in GitHub Desktop.
This is a gist (not finished) that will migrate vm's for KVM to a different host with shared lvm's. This is currently a proof of concept for a VRTX system.
#!/bin/bash
#####################################
# Written By: Thomas Foster #
# Date: 04/02/2015 #
#####################################
#This script will automate the process of moving a vm from
#one host to the other using saved states. I don't know how
#useful the script can be for larger vm's but I am writing this
#as a proof of concept for moving vms between hosts. I am still
#refactoring
function usage() {
cat << USAGE
This is the help menu
"-h Display this help menu"
"-l Lists the systems on this kvm host"
"-g This option is to overwrite an existing ssh key or create a new one (valid values: y|n) (required)"
"-s The server where to transfer the guest (required)"
"-f The file used for the kvm guest's statefile (required)"
"-d The KVM domain you want to migrate (ex: <id> or <vmname>) (required)"
USAGE
}
function listguests {
VCOMM='/usr/bin/virsh list'
GUESTNAME=`$VCOMM |awk 'NR>2' |tr -s [:space:] |awk -F ' ' '{print $2}'`
HOSTLIST=`$VCOMM |awk 'NR>2' |tr -s [:space:] |awk -F ' ' '{print $1,$2,$3}'`
echo "The following states are for the guests on this machine: "
for i in $GUESTNAME;do
GUESTID=$(echo "$HOSTLIST" | grep $i | awk -F ' ' '{print $1}')
GUESTSTATE=$(echo "$HOSTLIST" | grep $i | awk -F ' ' '{print $3}')
echo "Guest $i has an id of $GUESTID and is in a $GUESTSTATE state."
done
echo
}
function gentempsshkey() {
echo "Generating temporary ssh key in ~/.ssh/id_rsa to transfer guest saved state."
echo "$1" | /usr/bin/ssh-keygen -N '' -t rsa -q -f ~/.ssh/id_rsa
}
function movekeytoserver() {
echo "SSH'ing file to $1"
/usr/bin/ssh-copy-id -i ~/.ssh/id_rsa.pub "$1"
}
function savevmstatefile() {
GUESTNAME=`/usr/bin/virsh list |awk 'NR>2' |tr -s [:space:] |awk -F ' ' '{print $2}'|grep $1`
SAVEDIR="/root/kvmsavestate"
if [ -z "$GUESTNAME" ];then
echo "Server $1 does not exist on this system."
exit 1
elif [ ! -d "$SAVEDIR" ];then
echo "$SAVEDIR directory is not created..Creating!"
/bin/mkdir -p "$SAVEDIR"
echo "Saving $2 file to $SAVEDIR"
/usr/bin/virsh save "$GUESTNAME" "$SAVEDIR/$2"
else
if [ -f "$SAVEDIR/$2" ];then
echo "You already have a statefile called $SAVEDIR/$2"
exit 1
else
echo "Saving vm statefile to $SAVEDIR/$2"
/usr/bin/virsh save "$GUESTNAME" "$SAVEDIR/$2"
fi
fi
}
function movestatefiletoserver() {
SAVEDIR="/root/kvmsavestate"
/usr/bin/scp "$SAVEDIR/$1" "$2:$SAVEDIR/$1"
}
function verifylocallvmdisk() {
VMID=`/usr/bin/virsh list | awk 'NR>2' |grep $1| awk -F ' ' '{print $1}'`
VMBLKD=`virsh domblklist "$VMID" | awk 'NR>2'|grep /dev | awk -F ' ' '{print $2}'`
echo "The lvm disk for domain $1 is $VMBLKD"
}
function verifyremotelvmdisk() {
VMID=`/usr/bin/virsh list | awk 'NR>2' |grep $1| awk -F ' ' '{print $1}'`
VMBLKD=`virsh domblklist "$VMID" | awk 'NR>2'|grep /dev | awk -F ' ' '{print $2}'`
echo "The lvm disk for domain $1 is $VMBLKD"
}
function restorelocalstate() {
VMID=`/usr/bin/virsh list | awk 'NR>2' |grep $1| awk -F ' ' '{print $1}'`
VMBLKD=`virsh domblklist "$VMID" | awk 'NR>2'|grep /dev | awk -F ' ' '{print $2}'`
echo "The lvm disk for domain $1 is $VMBLKD"
}
function verifyrestorefile() {
SAVEDIR="/root/kvmsavestate"
VMFILESIZE=`ls -s "$SAVEDIR/$1" |awk -F ' ' '{print $1}'`
echo "The file $1 on `hostname -s` is $VMFILESIZE kilobytes"
}
function verifyremotestate() {
SAVEDIR="/root/kvmsavestate"
#check remote filesize
export RVMFILESIZE=`ssh "$1" ls -s "$SAVEDIR/$2" |awk -F ' ' '{print $1}'`
echo "The file $2 on the remote server $1 is $RVMFILESIZE kilobytes"
}
function restoreremotestate() {
SAVEDIR="/root/kvmsavestate"
#check remote filesize
COMMANDOUTPUT=`ssh "$1" virsh restore "$SAVEDIR/$2"`
echo "The output from restoring the guest on $1 was $COMMANDOUTPUT"
}
while getopts g:s:f:d:vlh option
do
case "${option}" in
h) usage
exit 1;;
l) listguests
exit 0;;
g) SSHKEY=${OPTARG};;
s) SERVER=${OPTARG};;
f) STATEFILE=${OPTARG};;
d) VMDOMAIN=${OPTARG};;
esac
done
if [ -z "$SERVER" ] || [ -z "$STATEFILE" ] || [ -z "$VMDOMAIN" ] || [ -z "$SSHKEY" ];then
usage
exit 1
elif [ "$SSHKEY" == 'y' ];then
echo "Overwriting existing ssh key in ~/.ssh"
gentempsshkey "$SSHKEY"
movekeytoserver "$SERVER"
savevmstatefile "$VMDOMAIN" "$STATEFILE"
verifyrestorefile "$STATEFILE"
movestatefiletoserver "$STATEFILE" "$SERVER"
verifyremotestate "$SERVER" "$STATEFILE"
restoreremotestate "$SERVER" "$STATEFILE"
else
echo "Not overwriting existing key. ~/.ssh/id_rsa.pub will be used for an ssh connection"
movekeytoserver "$SERVER"
savevmstatefile "$VMDOMAIN" "$STATEFILE"
verifyrestorefile "$STATEFILE"
movestatefiletoserver "$STATEFILE" "$SERVER"
verifyremotestate "$SERVER" "$STATEFILE"
restoreremotestate "$SERVER" "$STATEFILE"
fi
#Examples of using the functions
#listhosts
#gentempsshkey
#movekeytoserver kvmhost2
#savevmstatefile guest1 guest1.vmstate
#verifyrestorefile guest1.vmstate
#restorelocalstate guest1
#movestatefiletoserver guest1.vmstate kvmhost2
#verifyremotestate kvmhost2 guest1.vmstate
#restoreremotestate kvmhost2 guest1.vmstate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment