Last active
August 29, 2015 14:18
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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