svMotion vCloud Director VM’s using the vCloud REST API and cURL

Because I had to clear out 2 LUN’s I ran into the problem that moving vCloud Director VM’s through vSphere is a bad idea.

Luckily I remembered a blog post made by the brilliant William Lam not so long ago: Performing A Storage vMotion in vCloud Director Using vCloud REST API. This will be the basis of the solution. Please note I’m using vCloud Director 1.5.

In preperation of this, I did the usual:

  1. Create new LUN’s
  2. Present them to the ESXi hosts
  3. Create new datastores

The next thing to do is to add the datastores to vCloud Director. I was trying to add them in the vSphere Resources section, but couldn’t find the functionality there

The correct place is do this is in the Provider vDC:

Now it’s time to call the REST API’s. First, download cURL. Since I’m using Windows, I got the from the Win32 section.

Before issuing the commands, you need to get a session key. You need to provide credentials to get one. I don’t know what permissions you need to perform the svMotion, so I’ll just take the vCloud Administrator account. Execute the following command in a Command Prompt to get the session key:

curl -i -k -H “Accept:application/*+xml;version=1.5” -u Administrator@system:[vCloud Administrator password] -X POST https://%5BYour vCloud Server FQDN]/api/sessions

Your reply should look something like this. The session key is highlighted in bold:

HTTP/1.1 200 OK
Date: Fri, 18 May 2012 10:22:51 GMT
x-vcloud-authorization: y27xZ3cYNlmmtMkR9oXhHwca2+U8pb3pIxWlFCXIn78=

Now to get all the VM’s in your vCloud Director environment, execute the following command. Please note I use the session key I just retrieved :

curl -i -k -H “Accept:application/*+xml;version=1.5” -H “x-vcloud-authorization: y27xZ3cYNlmmtMkR9oXhHwca2+U8pb3pIxWlFCXIn78=” -X GET https://%5BYour vCloud Server FQDN]/api/query?type=adminVM

This command differs from what is posted on William Lam’s blog. When I specify the ‘&fields=name,vCloud’ parameter, I receive the error ”fields’ is not recognized as an internal or external command, operable program or batch file.’, so I left that out.

You will get another HTTP/1.1 200 OK response followed by alot of XML code. Look for the <AdminVMRecord tag. This will indicate the start a code block for a VM.

<AdminVMRecord vmToolsVersion=”8290″ vdc=”https://%5BYour vCloud Server FQDN]/api/vdc/acace623-5973-4c1f-9b81-f6f5bf
88aaa7″ vc=”https://%5BYour vCloud Server FQDN]/api/admin/extension/vimServer/9d57c5dc-6e58-4514-9e6e-a3cf2f4cddfb” stat
us=”POWERED_OFF” org=”https://%5BYour vCloud Server FQDN]/api/org/21749a1d-5b02-4228-ba9b-2b0db996b629″ numberOfCpus=”1″
networkName=”vApp Intern” name=”WinXP” moref=”vm-682″ memoryMB=”2048″ isVdcEnabled=”true” isVAppTemplate=”false” isPubl
ished=”false” isDeployed=”false” isDeleted=”false” hostName=”[ESXi host]” hardwareVersion=”8″ guestOs=
“Microsoft Windows XP Professional (32-bit)” datastoreName=”[Your datastore name]” containerName=”[Your vApp name]” contain
er=”https://%5BYour vCloud Server FQDN]/api/vApp/vapp-ad1fcab3-fa67-4e87-9f9d-7db9e7d1f3eb” href=”https://%5BYour vCloud Server FQDN]/api/vApp/vm-0302a63d-b749-4c10-9fb3-019ab1e2ef09″ pvdcHighestSupportedHardwareVersion=”8″ containerStatus=

Look for the value href and copy the URL. Do this for all <AdminVMRecord blocks and you’ll end up with a list of VM’s with their href URL’s:

name=”WinXP1″ href=”https://%5BYour vCloud Server FQDN]/api/vApp/vm-0302a63d-b749-4c10-9fb3-019ab1e2ef09″
name=”Linux1″ href=”https://%5BYour vCloud Server FQDN]/api/vApp/vm-55bc30b8-738f-4388-8165-59caa61bfd63″
name=”WinXP2″ href=”https://%5BYour vCloud Server FQDN]/api/vApp/vm-6aa01bf8-3ae8-48d9-bb39-0de7fad9850c”
name=”Linux2″ href=”https://%5BYour vCloud Server FQDN]/api/vApp/vm-7b653086-1f89-4d86-9802-d37f61922c79″
name=”Linux3″ href=”https://%5BYour vCloud Server FQDN]/api/vApp/vm-bb28fd62-65b1-4474-af55-86621d791558″

Now do something similar to get your datastore href’s:

curl -i -k -H “Accept:application/*+xml;version=1.5” -H “x-vcloud-authorization: y27xZ3cYNlmmtMkR9oXhHwca2+U8pb3pIxWlFCXIn78=” -X GET https://%5BYour vCloud Server FQDN]/api/query?type=datastore

Look for the <DatastoreRecord tag in the XML output and copy the corresponding href values:

<DatastoreRecord vcName=”[Your VC name]” vc=”https://%5BYour vCloud Server FQDN]/api/admin/extension/vimServer/9d57c5dc-6e
58-4514-9e6e-a3cf2f4cddfb” storageUsedMB=”200149″ storageMB=”767744″ requestedStorageMB=”246784″ provisionedStorageMB=”5
03169″ numberOfProviderVdcs=”1″ name=”[Your datastore name]” moref=”datastore-689″ isEnabled=”true” isDeleted=”false” datas
toreType=”VMFS5″ href=”https://%5BYour vCloud Server FQDN]/api/admin/extension/datastore/6f16b43f-3c6d-433e-b4a2-55d0976
dda9c” taskStatus=”success” task=”https://%5BYour vCloud Server FQDN]/api/task/36e286f1-d6bc-42ed-9a43-01b5e663e1ac” tas

Again, you will end up with a list similar to this:

name=”vCloud-SourceDisk01″ href=”https://%5BYour vCloud Server FQDN]/api/admin/extension/datastore/10f678c7-9a9f-4b2d-907d-c129d9d0119d”
name=”vCloud-SourceDisk02″ href=”https://%5BYour vCloud Server FQDN]/api/admin/extension/datastore/855a6cf8-1cf3-4e1e-ba63-9863f1607402″
name=”vCloud-DestinationDisk01″ href=”https://%5BYour vCloud Server FQDN]/api/admin/extension/datastore/80816ef7-80fe-4084-88eb-d58ead85e7d5″
name=”vCloud-DestinationDisk02″ href=”https://%5BYour vCloud Server FQDN]/api/admin/extension/datastore/6f16b43f-3c6d-433e-b4a2-55d0976dda9c”

You’ll now have to create a text document for every destination datastore for the vCloud VM’s. In my case I had 2 destination datastores, so I made 2 files, relocate-response-destinationdisk01.txt and relocate-response-destinationdisk02.txt with the following info:

<RelocateParams xmlns=”″&gt;
<Datastore href=”https://%5BYour vCloud Server FQDN]/api/admin/extension/datastore/80816ef7-80fe-4084-88eb-d58ead85e7d5″/>


<RelocateParams xmlns=”″&gt;
<Datastore href=”https://%5BYour vCloud Server FQDN]/api/admin/extension/datastore/6f16b43f-3c6d-433e-b4a2-55d0976dda9c”/>

These are, of course, the destination datastore href values. Now you’re ready to give the actual svMotion command:

curl -i -k -H “Accept:application/*+xml;version=1.5” -H “x-vcloud-authorization: y27xZ3cYNlmmtMkR9oXhHwca2+U8pb3pIxWlFCXIn78=” -H “Content-Type:application/vnd.vmware.vcloud.relocateVmParams+xml” -X POST https://%5BYour vCloud Server FQDN]/api/vApp/vm-0302a63d-b749-4c10-9fb3-019ab1e2ef09/action/relocate -d @relocate-response-destinationdisk01.txt

You’ll have to do this for every VM, note the href ID’s of your list of VM’s. Please change the relocate file accordingly. You can see the vMotion execute  in the vSphere client:

On several occasions I saw the vCloud Director server issue a consolidate command on a VM before it executed the svMotion. Exactely the reason why you can’t do this through vSphere.

Because some of the svMotions took a long time, I had to get new a session key several times. Just execute the first curl command and replace the returned session key in your svMotion command.

Good luck and I want to give another shout out to William Lam for publishing his solutions to difficult, highly technical problems. Follow his blog here.


About Yuri de Jager
Technology Addict

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: