XenServer Migration Script Example

There is a very handy migration tool in XenServer that allows you to migrate running VMs (if you've 6.5) or even shutdown VMs (from v7). However, sometimes you need to script that process because ... well a GUI is fine but doesn't scale well. 

Here's a XenServer VM migration script example.

The script below is a bit rough and ready, not a lot of error checking, but I've used it a number of times when migrating from different environments (typically 6.5 to 7 where everyone would be happier using 2 sets of kit that running an inplace upgrade). 

The script assumes that you've a list of VMs in a file  named __vmlist.csv (you can generate such a list using this script Get VM Running Status for an SR) with your VMs to migrate. 

There's some set up to do - work out your UUIDs for storage volumes, specify your network names. The script allows you to accommodate a number of storage resources (in case you've spread a single VM across multiple SRs)  

Essentially, shutdown the VMs; this script will take a copy of the VMs to migrate; then start them up (as in 6.5 VMs need to be running for migration). Then it will migrate the running VMs to the new environment. Obviously, a migration is moving completely, but by taking a clone copy first you have a recovery option if needs be. 

Here is the script,  I look forward to your comments.

=Start of Script================================

#set domigrate to be "yes" to perform the migration, set to any other value to validate process without doing migration

domigrate="yes" srcSR=[uuid] remoteMaster=[insert remote master] remoteUser=[fill remote user] remotePass=[fill remote password] #network to use for the transfer process remoteNet="[storage network name]" #the UUID of the network that the VMs will be connected to remoteVMnet=[remote vm network uuid] dstSR01=[uuid] dstSR02=[uuid] dstSR03=[uuid] remoteStrUUID=[uuid] transfernetwork='[name]' cloneprefiox="clone-" migrate_vm () { mynic0=`xe vif-list vm-uuid=${vminfo[0]} device=0 --minimal` vdilist=`xe vbd-list vm-uuid=${vminfo[0]} type=Disk params=vdi-uuid --minimal` IFS="," read -a vdiarray <<< "${vdilist}" mylayout="" for vdi in "${vdiarray[@]}"; do storeuuid=`xe vdi-list uuid=$vdi params=sr-uuid --minimal` store=`xe sr-list uuid=$storeuuid params=name-label --minimal` if [ "$store" == "YOURSTORE1" ]; then mylayout+=" vdi:"$vdi=$dstSR01 elif [ "$store" == "YOURSTORE2" ]; then mylayout+=" vdi:"$vdi=$dstSR02 else mylayout+=" vdi:"$vdi=$dstSR03 fi done #if we just try and run the xe command it fails as the '=' are skipped/lost #so package the migration command into a script, run the script echo "xe vm-migrate uuid=${vminfo[0]} remote-master=$remoteMaster remote-username=$remoteUser remote-password=$remotePass destination-sr-uuid=$remoteStrUUID vif:$mynic0=$remoteVMnet ${mylayout} remote-network='$transfernetwork' force=true" > /tmp/_mig.sh chmod +x /tmp/_mig.sh /tmp/_mig.sh rm /tmp/_mig.sh } beginswith() { case $2 in "$1"*) true;; *) false;; esac; } IFS=$'\n' for vmn in $(cat _vmlist.csv); do oIFS=$IFS IFS="," vminfo=($vmn) IFS=$oIFS if beginswith $cloneprefix ${vminfo[1]}; then echo "skipping previously created clone " ${vminfo[1]} else #start with no migrate tag xe vm-param-remove uuid=${vminfo[0]} param-name=tags param-key=”migrate” > /dev/null 2>&1 if [ "${vminfo[2]}" == "halted" ]; then if [ -z `xe template-list name-label=${vminfo[1]} --minimal` ] && [ -z `xe snapshot-list name-label=${vminfo[1]} --minimal` ]; then if [ -z `xe vm-list name-label=$cloneprefix${vminfo[1]} --minimal` ]; then echo 'clone ' ${vminfo[1]} xe vm-clone name-label=${vminfo[1]} new-name-label=$cloneprefix${vminfo[1]} else echo "not cloning ${vminfo[1]}, VM clone already exists" fi if [ `xe vm-list name-label=$cloneprefix${vminfo[1]} --minimal` ]; then echo "Clone exists - tag for move" ${vminfo[0]} xe vm-param-add uuid=${vminfo[0]} param-name=tags param-key="migrate" else echo "Clone doesn't exist - remove tag for move" ${vminfo[0]} xe vm-param-remove uuid=${vminfo[0]} param-name=tags param-key="migrate" &> /dev/null fi echo Starting VM to be ready for migration xe vm-start uuid=${vminfo[0]} else echo "disk is template/clone - skipping" fi else if [ -z `xe vm-list name-label=$cloneprefix${vminfo[1]} --minimal` ]; then echo "${vminfo[1]} vm needs to be shutdown - will not copy on running VM" xe vm-param-remove uuid=${vminfo[0]} param-name=tags param-key="migrate" &> /dev/null else echo "Copy of ${vminfo[1]} exists, prepping for migration" xe vm-param-add uuid=${vminfo[0]} param-name=tags param-key="migrate" fi fi fi done # Migrate VMs to the target environment IFS=$'\n' for vmn in $(cat _vmlist.csv); do IFS=$IFS IFS="," vminfo=($vmn) IFS=$oIFS if [ -z `xe vm-list uuid=${vminfo[0]} power-state=running --minimal` ];then if [ -z `xe vm-list uuid=${vminfo[0]} power-state=suspended --minimal` ];then echo " ${vminfo[1]} is not powered on - cannot migrate" else if [ -z `xe vm-list uuid=${vminfo[0]} tags=migrate power-state=suspended --minimal` ];then echo "${vminfo[1]} not tagged for migrate - has clone been taken?" else echo "Migrate suspended VMs" if [ "$domigrate" == "yes" ]; then migrate_vm else echo "skipping actual migrate" fi fi fi else if [ -z `xe vm-list uuid=${vminfo[0]} tags=migrate power-state=running --minimal` ];then echo "${vminfo[1]} not tagged for migrate - has clone been taken?" else echo "Migrate ${vminfo[1]}" if [ "$domigrate" == "yes" ]; then migrate_vm else echo "skipping actual migrate" fi fi fi done

=End of Script================================

Print