跳过导航
VMware
7,657 视图 16 回复 最后发帖: 2010-8-11 上午6:22 作者 AntakarDonvar RSS
1 2 上一页 下一页
wila Champion User Moderators vExpert 4,489 发帖自
2006-6-27
当前正在审批

2007-6-19 上午12:17

New Script for moving vm to another storage

Hi Guys/Gals,

 

This week i needed to move a bunch of VMs from local storage to iSCSI so that i can accomodate for more storage. The normal way for me to do this is to either do this by hand or write a 10 lines long script for each VM... as i don't have Virtual Center yet.

 

So i decided that it might be nice to create a general script for this. For details and usage, see in the source. Hope you like it, this is my first attempt at a more advanced bash script, so i'm sure that some things could have been done easier. Robustness (is that a word?) was my priority.

 

The source might also need a bit cleanup of commented out things, but alas.. no more time now. It seems to work fine for me.

More updates/cleanup when i get the time.

 

New Script for moving vm to another storage

#!/bin/bash

#

\# vm-relocate.sh

#

\# Script for Virtual Infrastructure 3.x to migrate an existing VM to

\# another VMFS storage. An example of this would be to move a VM from

\# local storage to iSCSI storage.

\# In short, what the script does is; unregister the VM passed by its name.

\# Then copy all disks using vmkfstools, copy all other files, update

\# the configuration file for the changed location, and register the VM again.

\# order and details are a little different, but you get the idea.

#

\# Features:

\# - Only VMs that are powered down will be relocated.

\# - Only connected disks are migrated, making it easier to intentially skip a disk

\# - All target disks will be moved to the new location, even if your machine now

\#   has disks over separate lun's

\# - You should pass it the vmname, this can be different from the display name,

\#   the parameter is case insensitive.

\# - The original VM is not removed at all ONLY unregistered, so you can

\#   always go back by unregistering/deleting the clone and registering the original .vmx

\#   again.

#

\# Note:

\# - This is NOT a backup script, this is not the intention and never will be.

#

\# Example usage:

\#   ./vm-relocate browserappliance /vmfs/volumes/lun-x/browse

\# This will relocate the vm "browserappliance.vmx" to a new folder called

\# "browse" on the volume with name "lun-x"

#

#

\# Author: Wil van Antwerpen

\# Date: June 15, 2007

\# License: GPL

\# Version: 0.2

#

\# Bugreports & suggestions can be send via PM to wila in VMTN

\# or you can leave them in this thread.

#

 

 

\# declare some global variables to work with

strVMname=""      # short VM filename without path or file extension (.vmx)

strDisplayName="" # Display Name of the VM

strVMX=""         # full location of the vmx file to move in UUID style

strVMXpath=""     # The default path of where our source vmx (and disks) is stored

strVMDK=""        # List of vmdk source disks to move, full path UUID again

strVMDKname=""    # List of vmdk disks without the path

strVMDKdevice=""  # List of scsi devices

strTarget=""      # path where you are moving the VM towards

verbose_state=0

LOGFILE="vm-relocate.log"

 

#

\# Return the complete file location for the strVMname passed and store

\# that in strVMX

#

function vmxfileForVMname ()

{

local vm

echo -e -n $"Searching for vm \"$strVMname\" on our host...             "

for vm in `vmware-cmd -l`

do

   if echo "$vm.vmx" | grep -i -q "$strVMname" ; then

     echo "Ok"

     logOutput "Found VM:\n $vm"

     strVMX=$vm

     strVMXpath=$\{vm%/*}

     logOutput "Source path = $\{strVMXpath}"  

   fi

done

if \[ -z "$strVMX" ]; then

   verbose_state=1

   logOutput "$strVMname not found, unable to comply with the request, exiting...."

   exit 3

fi

} # vmxfileForVMname

 

 

#

\# Are the minimal required parameters passed?

#

#

function testParams ()

{

if \[ -z "$strVMname" ]; then

verbose_state=1

logOutput "No VM to relocate has been provided in the command line. Exiting."

showHelp

exit 3

fi

if \[ -z "$strTarget" ]; then

verbose_state=1

logOutput "No target folder to move the VM towards is passed on the command line. Exiting."

showHelp

exit 3

fi

}

 

 

#

\# Checks the preconditions that must be met for the script to

\# work properly

\#  - did we find an existing vm?

\#  - is it still running?

\#  - does the target folder already exist?

\#  - if not can we create it?

#

function checkConditions ()

{

local currentState=""

local displayName=""

 

if \[ -z "$strVMX" ]; then # How many times can one check the same thing

verbose_state=1

logOutput "No VM to relocate has been provided in the command line. Exiting."

logOutput ""

exit 3

fi

 

echo -n $"Checking to make sure the VM is not running....            "

currentState=`vmware-cmd "$strVMX" getstate -q`

strDisplayName=`vmware-cmd "$strVMX" getconfig displayName -q`

if echo $currentState | grep -i -q "on" ; then

verbose_state=1

logOutput "Running state = $currentState"

logOutput "The vm $strDisplayName is still running, this is not supported, aborting.."

exit 4

fi

echo "Ok"

echo -n $"Checking to make sure the target doesn't exist....         "

if \[ -d $strTarget ]; then

  verbose_state=1

  logOutput "The folder $\{strTarget} already exists. Exiting."

  exit 5

fi

echo "Ok"

} # checkConditions

 

 

 

function showHelp ()

{

        echo ""

     echo "Usage:"

     echo "      vm-relocate.sh \[options] $\{LOGFILE}

}

 

 

 

function processArguments ()

{

while test "$1" != "" ; do

  case $1 in

     --help|-h)

          showHelp

          exit 0

     ;;

     --version|V)

          echo "vm-relocate.sh version 0.2"

          exit 0

     ;;

     --verbose|v)

          verbose_state=1

     ;;

     -*)

          echo "Error: Unknown option $1"

          showHelp

          exit 1

     ;;

        *)

          strVMname=$1

          shift

          strTarget=$1

          shift

        ;;

  esac

  shift

done

testParams

} # processArguments

 

 

#

\# Searches the vmx file for lines with vmdk files and extracts those along with

\# the relevant parameters for a later query.

#

function getVirtualDisks ()

{

local vmdk=""

IFS=$'\n'

logOutput "Find all disks in VM"

strVMDK=`cat $strVMX | grep -i ".vmdk"`

logOutput "Disks in vmx:\n$strVMDK"

 

for word in $strVMDK

do

word=$\{word#*=}

word=${word#*\"}

word=${word%*\"}

vmdk=`echo -e "$word\n$vmdk"`

word=$\{word##*/}

strVMDKname=`echo -e "$\{word}\n$strVMDKname"`

done

for word in $strVMDK

do

word=$\{word%=*}

word=$\{word%.fileName*}

strVMDKdevice=`echo -e "$\{word}\n$strVMDKdevice"`

done

strVMDK=$\{vmdk}

logOutput "\nDone:\n$\{strVMDK}\nDisks:\n$\{strVMDKname}\nDevices:\n$\{strVMDKdevice}"

} # getVirtualDisks

 

#

\# Removes the disks from our result that are marked as NOT present

\# in the vmx config file.

#

function removeNonpresentDisks ()

{

local n=0

local connected=0

local device=""

local devices=""

local svmdk=""

local vmdks=""

local vmdk_path=""

local vmdk_path_list=""

IFS=$'\n'

\# checking if the vmdk's are connected

 

devices=""

for device in $strVMDKdevice

do

  ((n += 1))

  connected=`vmware-cmd "$vmx" getconfig "$\{device}.present" -q`

  echo "connected $device = $connected"

  if \[ $connected == "1" ]; then

 

     

  1. create a new devices list with only the devices marked as present.

    svmdk=`echo "$\{strVMDKname}" | sed -n "$\{n}p"`

    vmdk_path=`echo "$\{strVMDK}" | sed -n "$\{n}p"`

    logOutput "Adding connected disk: $\{svmdk} at $\{vmdk_path}"

    if \[ -z $devices ]; then

      devices=$\{device}

      vmdk_path_list=$\{vmdk_path}

      vmdks=$\{svmdk}

    else

      devices=`echo -e "$\{devices}\n$\{device}"`

      vmdk_path_list=`echo -e "$\{vmdk_path_list}\n$\{vmdk_path}"`

      vmdks=`echo -e "$\{vmdks}\n$\{svmdk}"`

    fi

  fi

done

strVMDKdevice=$\{devices}

strVMDKname=$\{vmdks}

strVMDK=$\{vmdk_path_list}

} # removeNonpresentDisks

 

 

#

\# Last chance!

\# Display the devices that the script will copy and ask for a confirmation.

#

function confirmMigration ()

{

local n=0

local svmdk=""

local confirmation=""

 

echo -e "----


"

echo -e "The details of the VM that is to be migrated are:"

echo -e "Display Name: $\{strDisplayName}"

echo -e "VM          : $\{strVMX##*/}"

echo -e "Source Path : $\{strVMXpath}"

echo -e "Target Path : $\{strTarget}"

echo -e "With the following disks:"

for device in $strVMDKdevice

do

((n += 1))

svmdk=`echo "$\{strVMDKname}" | sed -n "$\{n}p"`

echo -e "$\{device} = $svmdk"

done

echo -e "----


"

echo -e "Do you want to continue (Y)es/(N)o New Script for moving vm to another storage?"

read confirmation

if \[ -z $confirmation ]; then

  confirmation="N"

fi

if ! `echo "$confirmation" | grep -i -q "Y"` ; then

  verbose_state=1

  logOutput "Cancelled by user request."

  exit 7

fi

logOutput "Confirmation accepted."

}

 

#

\# performs the actual copying of the disks

#

#

function copyDisks ()

{

local vmx=""

local svmdk=""

local target=""

local diskDevice=""

local n=0

IFS=$'\n'

vmx=$\{strVMX}

target=$\{strTarget}

 

removeNonpresentDisks

 

\# Confirmation on the copy

confirmMigration

 

echo -n $"Creating folder $strTarget ....                 "

mkdir $strTarget

if \[ ! -d $strTarget ]; then

  verbose_state=1

  logOutput "Unable to create target folder $\{strTarget}. Exiting."

  exit 6

fi

echo "Ok"

 

\# The actual copy of the disks

for sourceDisk in $strVMDK

do

   

  ((n += 1))

  svmdk=`echo "$\{strVMDKname}" | sed -n "$\{n}p"`

  if echo "$sourceDisk" | grep -i -q "/" ; then

    logOutput "vmkfstools -i $\{sourceDisk} $\{target}/$\{svmdk}"

    vmkfstools -i "$\{sourceDisk}" "$\{target}/$\{svmdk}"

  else

    logOutput "vmkfstools -i $\{strVMXpath}/$\{sourceDisk} $\{target}/$\{svmdk}"

    vmkfstools -i "$\{strVMXpath}/$\{sourceDisk}" "$\{target}/$\{svmdk}"

  fi

done

#echo "cd $\{target}"

#logOutput `"cp $\{strVMXpath}/*.vmx $\{target}/"`

logOutput `cp $\{strVMXpath}/*.vmx $\{target}/`

#cp "$\{strVMXpath}/*.vmx" "$\{target}/" 1>>$\{LOGFILE}

logOutput `cp $\{strVMXpath}/*.vmxf $\{target}/`

#cp "$\{strVMXpath}/*.vmxf" "$\{target}/" 1>>$\{LOGFILE}

logOutput `cp $\{strVMXpath}/*.nvram $\{target}/`

#cp "$\{strVMXpath}/*.nvram" "$\{target}/" 1>>$\{LOGFILE}

} # copyDisks

 

 

#

\# unregister old, register new, update disks so that no old disks are accidentily

\# referenced by path.

#

function finalizeMigration ()

{

local VMXtarget

local svmdk

echo -e "\nAll disks migrated, now updating the host to finalize the change"

 

#VMXtarget="$\{strTarget}/$\{strVMname}.vmx"

VMXtarget="$\{strTarget}/$\{strVMX##*/}"

verbose_state=1

logOutput "vmware-cmd -s unregister $\{strVMX}"

logOutput `vmware-cmd -s unregister $\{strVMX}`

#vmware-cmd -s unregister \"$\{strVMX}\"

sleep 20

logOutput "vmware-cmd -s register $\{VMXtarget}"

logOutput `vmware-cmd -s register $\{VMXtarget}`

#vmware-cmd -s register \"$\{VMXtarget}\"

\# Update the config file so that all disks ARE local to the target path

for device in $strVMDKdevice

do

   

  ((n += 1))

  svmdk=`echo "$\{strVMDKname}" | sed -n "$\{n}p"`

  logOutput "vmware-cmd \"$\{VMXtarget}\" setconfig $\{device}.fileName \"$svmdk\""

  vmware-cmd $\{VMXtarget} setconfig $\{device}.fileName "$\{strTarget}/$svmdk"

done

}

 

processArguments $@

vmxfileForVMname  # find the vmx config file for the vmname passed

checkConditions   # is VM still running? is the target folder already there? if so QUIT

getVirtualDisks

copyDisks

finalizeMigration

/code

Oczkov Enthusiast 39 发帖自
2006-1-13
当前正在审批
1. 2007-6-29 上午1:27 回复: wila
Re: New Script for moving vm to another storage

Hi Wil,

 

Thanks for sending this on the forum. To the topic of your thread I would add that the script is for copying to another LOCAL VMFS storage ;).

 

Guess what I need? Copying VM's from one VMFS to another, but located on a different ESX machine (in the environemt where where the customer doesn;t have Virtual Center or even if he have I've never seen \[Relocate] option working...) This would surely direct me to the thread on how to do it efficiently:

 

http://www.vmware.com/community/thread.jspa?threadID=29721&tstart=0

 

Combining your product with the knowledge from this thread we should be able to do it.

 

Cheers,

rboussen Lurker 2 发帖自
2004-11-16
当前正在审批
4. 2007-8-9 上午6:38 回复: wila
Re: New Script for moving vm to another storage

Very nice script Wil.

Perhaps you could let the script generate another script

with the unregister/register commands to get back to the old situation very quickly.

espi3030 Expert 540 发帖自
2008-1-3
当前正在审批
6. 2008-5-16 上午7:13 回复: wila
Re: New Script for moving vm to another storage

 

wila,

 

 

 

 

 

I stumbled upon this thread, and glad I did.  Right now I am using a backup script to relocate my VM's (which is fine for now) but it would be nice to implement your script.  I see the last post was in August of 2007, have you made any additional changes/updates to this script?

 

 

 

 

 

Thank you

 

 

espi3030 Expert 540 发帖自
2008-1-3
当前正在审批
7. 2008-5-16 上午8:02 回复: wila
Re: New Script for moving vm to another storage

 

BTW, what is the syntax for the "TARGET"?

 

 

 

 

 

Thank you

 

 

fasteddy Novice 24 发帖自
2008-6-6
当前正在审批
8. 2008-6-6 上午4:26 回复: espi3030
Re: New Script for moving vm to another storage

 

Hi,

 

 

is there another way moving machines from one storage to another?

 

 

I have some Maschines named with some spaces between characters, an these are not processed correctly by the script...

 

 

Thanks in advance.

 

 

Stefan

 

 

espi3030 Expert 540 发帖自
2008-1-3
当前正在审批
9. 2008-6-6 上午5:07 回复: fasteddy
Re: New Script for moving vm to another storage

Have you used VMware converter?

fasteddy Novice 24 发帖自
2008-6-6
当前正在审批
10. 2008-6-6 上午5:33 回复: espi3030
Re: New Script for moving vm to another storage

No, I did not use the converter.

 

I  created some machines using the Windows VMware Infrastructure Client and named them with some spaces... an because ESX creates folders/files named as the initial display name of the machine, I still have these spaces. And the script is not able to process them as arguments coorectly.

 

 

So, when I enter

 

 

 

 

vm-relocate.sh "Windows XP" SNIT-VMS01

 

 

 

 

it SHOULD move the machine "Windows XP" to a new location on the storage SNIT-VMS01, if I understand it right.

 

 

 

 

But instead it wants to move the Machine "Windows" to a new location on "X"...

espi3030 Expert 540 发帖自
2008-1-3
当前正在审批
11. 2008-6-6 上午5:46 回复: fasteddy
Re: New Script for moving vm to another storage

 

I'm sorry, I meant have you tried VMware converter to relocate the machines to new storage.  That is an option if you can't get the script working.

 

 

 

 

 

You are correct with your in assuming the command you mentioned SHOULD move the VM.  All my VM's are named without spaces or contain a - dash or _ underscore, so I really don't know how this script "escapes" the spaces.  In the script when you specify the computer name instead of "Windows XP" (encased in double quotes) try using 'Windows XP' (encased in single quotes).  This has worked in other scripts for me when I have to pass complex passwords that contain "illegal" characters.  It maybe a longshot  worth trying!

 

 

 

 

 

Another thing you can do is email or PM the author of the script, I did to ask him the correct "TARGET" syntax.  It took him a couple of days but he did reply.

 

 

fasteddy Novice 24 发帖自
2008-6-6
当前正在审批
12. 2008-6-6 上午5:57 回复: espi3030
Re: New Script for moving vm to another storage

 

The single quotes do not work, too.

 

 

Trying to use the converter blasted off my Windows-PC resulting in a blue screen an a lot of work repairing it...

 

 

I think I will try the PM-method...

 

 

aerogerm Novice 8 发帖自
2006-2-6
当前正在审批
13. 2008-7-31 上午5:58 回复: wila
Re: New Script for moving vm to another local storage

Hi,

 

 

 

excuse that i drop into this.....i found your script to be very usefull for our purposes and i've authorized myself to edit the script and doing some indentions for better readability......just my half cent...and just to whom it may concern.

 

Find it attached

 

Best regards.

附件:
mcscotty Novice 26 发帖自
2004-6-18
当前正在审批
14. 2008-8-7 下午12:41 回复: wila
Re: New Script for moving vm to another storage

 

I know this is a minor nit, but neither the -v nor the -V options work, due to missing characters in function processArguments.

 

 

Also, do the vmware tools like vmkfstools return any codes upon failure?  I didn't see any testing of the results of these calls; if vmkfstools -i fails (maybe the destination ran out of space) it would be nice if this script would detect and report the problem and maybe even NOT unregister the machine, rather than just silently ignore the problem.

 

 

Thanks for the great tool. I have my virtualcenter running as a VM on the cluster it manages, and migrating the VC to new storage was a lot easier with this tool than it would have been without it.

 

 

书签添加人 (0)

Share This Page

Communities