How to Import and Export OVF Packages

This article is based on a similar one at vSphere Java API home page. At that time, one of VMware community members sent me an email for samples of using OvfManager APIs. Then I went to office on a Saturday writing two samples, which have been validated by several folks as “working” samples.

The purpose of the samples are to illustrate the vSphere APIs. Let’s take a look at them one by one.

Lost VMs or Containers? Too Many Consoles? Too Slow GUI? Time to learn how to "Google" and manage your VMware and clouds in a fast and secure HTML5 App.

First, ExportOvfToLocal.java. This sample shows how to download either a VM or vApp to your local machine. The typical flow is:

  • Find the VM or vApp
  • Call their exportVm() or exportVApp() methods and get HttpNfcLease
  • Set lease time out
  • Wait for HttpNfcLease until it’s ready
  • From the HttpNfcLease.info property, find the all URLs from which you download the vmdk files
  • Call OvfManager.createDescriptor() API to create the content of ovf and save it to a file along with downloaded vmdk files.
  • Release the lease by calling httpNfcLeaseComplete() method
/*================================================================================
Copyright (c) 2008 VMware, Inc. All Rights Reserved.
<pre>Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

 * Neither the name of VMware, Inc. nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior
written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
================================================================================*/
package com.vmware.vim25.mo.samples.ovf;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import com.vmware.vim25.HttpNfcLeaseDeviceUrl;
import com.vmware.vim25.HttpNfcLeaseInfo;
import com.vmware.vim25.HttpNfcLeaseState;
import com.vmware.vim25.OvfCreateDescriptorParams;
import com.vmware.vim25.OvfCreateDescriptorResult;
import com.vmware.vim25.OvfFile;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.HttpNfcLease;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.VirtualApp;
import com.vmware.vim25.mo.VirtualMachine;

/**
 * Exports VMDK(s) and OVF Descriptor for a VM or a vApp.
 * http://vijava.sf.net
 * @author Steve Jin (sjin at vmware.com)
 */

public class ExportOvfToLocal
{
   public static LeaseProgressUpdater leaseProgUpdater;

	 public static void main(String[] args) throws Exception
	  {
	    if (args.length != 7)
	    {
	      System.out.println("java ExportOvfToLocal <SdkUrl> <username> <password> <VappOrVmName> <hostip> <VirtualMachine|VirtualApp> <localDir>");
	      System.out.println("java ExportOvfToLocal https://10.20.152.74/sdk root password NewVM1 10.20.152.74 VirtualMachine C:\\Temp\\ovf\\");
	      return;
	    }

	    ServiceInstance si = new ServiceInstance(new URL(args[0]), args[1], args[2], true);

	    String vAppOrVmName = args[3];
	    String hostip = args[4];
	    String entityType = args[5];
	    String targetDir = args[6];

	    HostSystem host = (HostSystem) si.getSearchIndex().findByIp(null, hostip, false);

	    System.out.println("Host Name : " + host.getName());
	    System.out.println("Network : " + host.getNetworks()[0].getName());
	    System.out.println("Datastore : " + host.getDatastores()[0].getName());

	    InventoryNavigator iv = new InventoryNavigator(si.getRootFolder());

	    HttpNfcLease hnLease = null;

	    ManagedEntity me = null;
	    if (entityType.equals("VirtualApp"))
	    {
	      me = iv.searchManagedEntity("VirtualApp", vAppOrVmName);
	      hnLease = ((VirtualApp)me).exportVApp();
	    }
	    else
	    {
	      me = iv.searchManagedEntity("VirtualMachine", vAppOrVmName);
	      hnLease = ((VirtualMachine)me).exportVm();
	    }

	    // Wait until the HttpNfcLeaseState is ready
	    HttpNfcLeaseState hls;
	    for(;;)
	    {
	      hls = hnLease.getState();
	      if(hls == HttpNfcLeaseState.ready)
	      {
	        break;
	      }
	      if(hls == HttpNfcLeaseState.error)
	      {
	        si.getServerConnection().logout();
	        return;
	      }
	    }

	    System.out.println("HttpNfcLeaseState: ready ");
	    HttpNfcLeaseInfo httpNfcLeaseInfo = hnLease.getInfo();
	    httpNfcLeaseInfo.setLeaseTimeout(300*1000*1000);
	    printHttpNfcLeaseInfo(httpNfcLeaseInfo);

	    //Note: the diskCapacityInByte could be many time bigger than
	    //the total size of VMDK files downloaded.
	    //As a result, the progress calculated could be much less than reality.
	    long diskCapacityInByte = (httpNfcLeaseInfo.getTotalDiskCapacityInKB()) * 1024;

	    leaseProgUpdater = new LeaseProgressUpdater(hnLease, 5000);
	    leaseProgUpdater.start();

	    long alredyWrittenBytes = 0;
	    HttpNfcLeaseDeviceUrl[] deviceUrls = httpNfcLeaseInfo.getDeviceUrl();
	    if (deviceUrls != null)
	    {
	      OvfFile[] ovfFiles = new OvfFile[deviceUrls.length];
	      System.out.println("Downloading Files:");
	      for (int i = 0; i < deviceUrls.length; i++)
	      {
	        String deviceId = deviceUrls[i].getKey();
	        String deviceUrlStr = deviceUrls[i].getUrl();
	        String diskFileName = deviceUrlStr.substring(deviceUrlStr.lastIndexOf("/") + 1);
	        String diskUrlStr = deviceUrlStr.replace("*", hostip);
	        String diskLocalPath = targetDir + diskFileName;
	        System.out.println("File Name: " + diskFileName);
	        System.out.println("VMDK URL: " + diskUrlStr);
	        String cookie = si.getServerConnection().getVimService().getWsc().getCookie();
	        long lengthOfDiskFile = writeVMDKFile(diskLocalPath, diskUrlStr, cookie, alredyWrittenBytes, diskCapacityInByte);
	        alredyWrittenBytes += lengthOfDiskFile;
	        OvfFile ovfFile = new OvfFile();
	        ovfFile.setPath(diskFileName);
	        ovfFile.setDeviceId(deviceId);
	        ovfFile.setSize(lengthOfDiskFile);
	        ovfFiles[i] = ovfFile;
	      }

	      OvfCreateDescriptorParams ovfDescParams = new OvfCreateDescriptorParams();
	      ovfDescParams.setOvfFiles(ovfFiles);
	      OvfCreateDescriptorResult ovfCreateDescriptorResult =
	        si.getOvfManager().createDescriptor(me, ovfDescParams);

	      String ovfPath = targetDir + vAppOrVmName + ".ovf";
	      FileWriter out = new FileWriter(ovfPath);
	      out.write(ovfCreateDescriptorResult.getOvfDescriptor());
	      out.close();
	      System.out.println("OVF Desriptor Written to file: " + ovfPath);
	    }

	    System.out.println("Completed Downloading the files");
	    leaseProgUpdater.interrupt();
	    hnLease.httpNfcLeaseProgress(100);
	    hnLease.httpNfcLeaseComplete();

	    si.getServerConnection().logout();
	  }

	private static void printHttpNfcLeaseInfo(HttpNfcLeaseInfo info)
	{
		System.out.println("########################  HttpNfcLeaseInfo  ###########################");
		System.out.println("Lease Timeout: " + info.getLeaseTimeout());
		System.out.println("Total Disk capacity: "	+ info.getTotalDiskCapacityInKB());
		HttpNfcLeaseDeviceUrl[] deviceUrlArr = info.getDeviceUrl();
		if (deviceUrlArr != null)
		{
			int deviceUrlCount = 1;
			for (HttpNfcLeaseDeviceUrl durl : deviceUrlArr)
			{
				System.out.println("HttpNfcLeaseDeviceUrl : "
						+ deviceUrlCount++);
				System.out.println("	Device URL Import Key: "
						+ durl.getImportKey());
				System.out.println("	Device URL Key: " + durl.getKey());
				System.out.println("	Device URL : " + durl.getUrl());
				System.out.println("	SSL Thumbprint : "	+ durl.getSslThumbprint());
			}
		}
		else
		{
			System.out.println("No Device URLS Found");
		}
	}

	private static long writeVMDKFile(String localFilePath, String diskUrl, String cookie,
			long bytesAlreadyWritten, long totalBytes) throws IOException
	{
		HttpsURLConnection conn = getHTTPConnection(diskUrl, cookie);
		InputStream in = conn.getInputStream();
		OutputStream out = new FileOutputStream(new File(localFilePath));
		byte[] buf = new byte[102400];
		int len = 0;
		long bytesWritten = 0;
		while ((len = in.read(buf)) > 0)
		{
			out.write(buf, 0, len);
			bytesWritten += len;
			int percent = (int)(((bytesAlreadyWritten + bytesWritten) * 100) / totalBytes);
			leaseProgUpdater.setPercent(percent);
			System.out.println("written: " + bytesWritten);
		}
		in.close();
		out.close();
		return bytesWritten;
	}

	private static HttpsURLConnection getHTTPConnection(String urlStr, String cookieStr) throws IOException
	{
		HostnameVerifier hv = new HostnameVerifier()
		{
			public boolean verify(String urlHostName, SSLSession session)
			{
				return true;
			}
		};
		HttpsURLConnection.setDefaultHostnameVerifier(hv);
		URL url = new URL(urlStr);
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setAllowUserInteraction(true);
		conn.setRequestProperty("Cookie",	cookieStr);
		conn.connect();
		return conn;
	}

}

Second, ImportLocalOvfVApp.java. This sample shows how to upload a VM or vApp. The flow is:

  • Read in the *.ovf file and call OvfManager().createImportSpec() method
  • From a ResoucePool, call its importVApp() method() and get HttpNfcLease object
  • Wait until the lease is ready
  • Upload the vmdk files using the URL provided by the lease object
  • Release the lease by calling httpNfcLeaseComplete() method

Note: with VI Java API 5.0 GA, remove the line “ovfDescriptor = escapeSpecialChars(ovfDescriptor);” becuase escaping is added to underlying engine.

/*================================================================================
Copyright (c) 2008 VMware, Inc. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

 * Neither the name of VMware, Inc. nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior
written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
================================================================================*/
package com.vmware.vim25.mo.samples.ovf;

import java.io.*;
import java.net.*;
import javax.net.ssl.*;
import com.vmware.vim25.*;
import com.vmware.vim25.mo.ComputeResource;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.HttpNfcLease;
import com.vmware.vim25.mo.ResourcePool;
import com.vmware.vim25.mo.ServiceInstance;

/**
 * Deploy VM or vApp from local disk to an ESX(i) server
 * http://vijava.sf.net
 * @author Steve Jin (sjin at vmware.com)
 */

public class ImportLocalOvfVApp
{
	private static final int CHUCK_LEN = 64 * 1024;

	public static LeaseProgressUpdater leaseUpdater;

	public static void main(String[] args) throws Exception
	{
		if (args.length < 6)
		{
			System.out.println(
			"java ImportLocalOvfVApp <targetURL> <username> <password> <hostip> <OVFFile LocalPath> <NewVMName>");
			System.out.println(
			"java ImportLocalOvfVApp https://10.20.140.47/sdk Administrator password 10.17.204.115 E:/Downloads/Nostalgia.ovf NewVM");
			return;
		}

		ServiceInstance si = new ServiceInstance(new URL(args[0]), args[1], args[2], true);

		String ovfLocal = args[4];
		String hostip = args[3];
		String newVmName = args[5];

		HostSystem host = (HostSystem) si.getSearchIndex().findByIp(null, hostip, false);

		System.out.println("Host Name : " + host.getName());
		System.out.println("Network : " + host.getNetworks()[0].getName());
		System.out.println("Datastore : " + host.getDatastores()[0].getName());

		Folder vmFolder = (Folder) host.getVms()[0].getParent();

		OvfCreateImportSpecParams importSpecParams = new OvfCreateImportSpecParams();
		importSpecParams.setHostSystem(host.getMOR());
		importSpecParams.setLocale("US");
		importSpecParams.setEntityName(newVmName);
		importSpecParams.setDeploymentOption("");
		OvfNetworkMapping networkMapping = new OvfNetworkMapping();
		networkMapping.setName("Network 1");
		networkMapping.setNetwork(host.getNetworks()[0].getMOR()); // network);
		importSpecParams.setNetworkMapping(new OvfNetworkMapping[] { networkMapping });
		importSpecParams.setPropertyMapping(null);

		String ovfDescriptor = readOvfContent(ovfLocal);
		if (ovfDescriptor == null)
		{
			si.getServerConnection().logout();
			return;
		}

		ovfDescriptor = escapeSpecialChars(ovfDescriptor);
		System.out.println("ovfDesc:" + ovfDescriptor);

		ResourcePool rp = ((ComputeResource)host.getParent()).getResourcePool();

		OvfCreateImportSpecResult ovfImportResult = si.getOvfManager().createImportSpec(
				ovfDescriptor, rp, host.getDatastores()[0], importSpecParams);

		if(ovfImportResult==null)
		{
			si.getServerConnection().logout();
			return;
		}

		long totalBytes = addTotalBytes(ovfImportResult);
		System.out.println("Total bytes: " + totalBytes);

		HttpNfcLease httpNfcLease = null;

		httpNfcLease = rp.importVApp(ovfImportResult.getImportSpec(), vmFolder, host);

		// Wait until the HttpNfcLeaseState is ready
		HttpNfcLeaseState hls;
		for(;;)
		{
			hls = httpNfcLease.getState();
			if(hls == HttpNfcLeaseState.ready || hls == HttpNfcLeaseState.error)
			{
				break;
			}
		}

		if (hls.equals(HttpNfcLeaseState.ready))
		{
			System.out.println("HttpNfcLeaseState: ready ");
			HttpNfcLeaseInfo httpNfcLeaseInfo = (HttpNfcLeaseInfo) httpNfcLease.getInfo();
			printHttpNfcLeaseInfo(httpNfcLeaseInfo);

			leaseUpdater = new LeaseProgressUpdater(httpNfcLease, 5000);
			leaseUpdater.start();

			HttpNfcLeaseDeviceUrl[] deviceUrls = httpNfcLeaseInfo.getDeviceUrl();

			long bytesAlreadyWritten = 0;
			for (HttpNfcLeaseDeviceUrl deviceUrl : deviceUrls)
			{
				String deviceKey = deviceUrl.getImportKey();
				for (OvfFileItem ovfFileItem : ovfImportResult.getFileItem())
				{
					if (deviceKey.equals(ovfFileItem.getDeviceId()))
					{
						System.out.println("Import key==OvfFileItem device id: " + deviceKey);
						String absoluteFile = new File(ovfLocal).getParent() + File.separator + ovfFileItem.getPath();
						String urlToPost = deviceUrl.getUrl().replace("*", hostip);
						uploadVmdkFile(ovfFileItem.isCreate(), absoluteFile, urlToPost, bytesAlreadyWritten, totalBytes);
						bytesAlreadyWritten += ovfFileItem.getSize();
						System.out.println("Completed uploading the VMDK file:" + absoluteFile);
					}
				}
			}

			leaseUpdater.interrupt();
			httpNfcLease.httpNfcLeaseProgress(100);
			httpNfcLease.httpNfcLeaseComplete();
		}
		si.getServerConnection().logout();
	}

	public static long addTotalBytes(OvfCreateImportSpecResult ovfImportResult)
	{
		OvfFileItem[] fileItemArr = ovfImportResult.getFileItem();

		long totalBytes = 0;
		if (fileItemArr != null)
		{
			for (OvfFileItem fi : fileItemArr)
			{
				printOvfFileItem(fi);
				totalBytes += fi.getSize();
			}
		}
		return totalBytes;
	}

	private static void uploadVmdkFile(boolean put, String diskFilePath, String urlStr,
			long bytesAlreadyWritten, long totalBytes) throws IOException
	{
		HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
		{
			public boolean verify(String urlHostName, SSLSession session)
			{
				return true;
			}
		});

		HttpsURLConnection conn = (HttpsURLConnection) new URL(urlStr).openConnection();
		conn.setDoOutput(true);
		conn.setUseCaches(false);
		conn.setChunkedStreamingMode(CHUCK_LEN);
		conn.setRequestMethod(put? "PUT" : "POST"); // Use a post method to write the file.
		conn.setRequestProperty("Connection", "Keep-Alive");
		conn.setRequestProperty("Content-Type",	"application/x-vnd.vmware-streamVmdk");
		conn.setRequestProperty("Content-Length", Long.toString(new File(diskFilePath).length()));

		BufferedOutputStream bos = new BufferedOutputStream(conn.getOutputStream());

		BufferedInputStream diskis = new BufferedInputStream(new FileInputStream(diskFilePath));
		int bytesAvailable = diskis.available();
		int bufferSize = Math.min(bytesAvailable, CHUCK_LEN);
		byte[] buffer = new byte[bufferSize];

		long totalBytesWritten = 0;
		while (true)
		{
			int bytesRead = diskis.read(buffer, 0, bufferSize);
			if (bytesRead == -1)
			{
				System.out.println("Total bytes written: " + totalBytesWritten);
				break;
			}

			totalBytesWritten += bytesRead;
			bos.write(buffer, 0, bufferSize);
			bos.flush();
			System.out.println("Total bytes written: " + totalBytesWritten);
			int progressPercent = (int) (((bytesAlreadyWritten + totalBytesWritten) * 100) / totalBytes);
			leaseUpdater.setPercent(progressPercent);
		}

		diskis.close();
		bos.flush();
		bos.close();
		conn.disconnect();
	}

	public static String readOvfContent(String ovfFilePath)	throws IOException
	{
		StringBuffer strContent = new StringBuffer();
		BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(ovfFilePath)));
		String lineStr;
		while ((lineStr = in.readLine()) != null)
		{
			strContent.append(lineStr);
		}
		in.close();
		return strContent.toString();
	}

	private static void printHttpNfcLeaseInfo(HttpNfcLeaseInfo info)
	{
		System.out.println("================ HttpNfcLeaseInfo ================");
		HttpNfcLeaseDeviceUrl[] deviceUrlArr = info.getDeviceUrl();
		for (HttpNfcLeaseDeviceUrl durl : deviceUrlArr)
		{
			System.out.println("Device URL Import Key: " + durl.getImportKey());
			System.out.println("Device URL Key: " + durl.getKey());
			System.out.println("Device URL : " + durl.getUrl());
			System.out.println("Updated device URL: " + durl.getUrl());
		}
		System.out.println("Lease Timeout: " + info.getLeaseTimeout());
		System.out.println("Total Disk capacity: " + info.getTotalDiskCapacityInKB());
		System.out.println("==================================================");
	}

	private static void printOvfFileItem(OvfFileItem fi)
	{
		System.out.println("================ OvfFileItem ================");
		System.out.println("chunkSize: " + fi.getChunkSize());
		System.out.println("create: " + fi.isCreate());
		System.out.println("deviceId: " + fi.getDeviceId());
		System.out.println("path: " + fi.getPath());
		System.out.println("size: " + fi.getSize());
		System.out.println("==============================================");
	}

	public static String escapeSpecialChars(String str)
	{
		str = str.replaceAll("<", "&lt;");
		return str.replaceAll(">", "&gt;"); // do not escape "&" -> "&amp;", "\"" -> "&quot;"
	}
}

While you are downloading or uploading the files, you would also like to update the progress with the httpNfcLease.httpNfcLeaseProgress() API. This is done periodically in a separate thread with both samples. Note that the size calculation is not accurate, so you may find mismatch there.

/*================================================================================
Copyright (c) 2008 VMware, Inc. All Rights Reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

 * Neither the name of VMware, Inc. nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior
written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
================================================================================*/
package com.vmware.vim25.mo.samples.ovf;

import com.vmware.vim25.mo.HttpNfcLease;

/**
 * http://vijava.sf.net
 * @author Steve Jin (sjin at vmware.com)
 */

public class LeaseProgressUpdater extends Thread
{
	private HttpNfcLease httpNfcLease = null;
	private int progressPercent = 0;
	private int updateInterval;

	public LeaseProgressUpdater(HttpNfcLease httpNfcLease, int updateInterval)
	{
		this.httpNfcLease = httpNfcLease;
		this.updateInterval = updateInterval;
	}

	public void run()
	{
		while (true)
		{
			try
			{
				httpNfcLease.httpNfcLeaseProgress(progressPercent);
				Thread.sleep(updateInterval);
			}
			catch(InterruptedException ie)
			{
				break;
			}
			catch(Exception e)
			{
				throw new RuntimeException(e);
			}
		}
	}

	public void setPercent(int percent)
	{
		this.progressPercent = percent;
	}
}

You can import an OVF package from a URL using vSphere Client. How to implement it using the API? Easy. Instead of reading from a local file, you read from the URL. I leave it to you to try out.

For more details, check out the code repository. I have tested both samples in a round trip: export a VM to a local disk, and then import it back. The imported VM works well.

Marcus Ludvigson from Lawson sent me an email with a fix for unfinished upload disk file issue that happens occasionally. You need to add the following two sections of code into uploadVmdkFile() method.

conn.setDoInput(true);
try
{
  DataInputStream dis = new DataInputStream(conn.getInputStream());
  dis.close();
} catch (Exception e) {}

This entry was posted in vSphere API and tagged , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

103 Comments

  1. Majid
    Posted February 9, 2016 at 3:13 am | Permalink

    I am trying to upload vmdk of size around 1.1G but it is taking too much time. Any idea which portion of code takes care of that?

  2. Alin
    Posted May 26, 2016 at 1:07 am | Permalink

    I am trying to import a OVF with this code and i get the following error:
    Failed to get a HTTP NFC Lease: Invalid configuration for device '7'.
    Here is the for device 7:

    0
    false
    CD/DVD drive 1
    9
    3
    vmware.cdrom.atapi
    15


    If i remove this item i can successfully import the ovf. How can this be fixed?
    Note that i can import it via vSphere client without any errors.

  3. Alin
    Posted May 26, 2016 at 1:10 am | Permalink

    <Item ovf:required=”false”>
    <rasd:AddressOnParent>0</rasd:AddressOnParent>
    <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
    <rasd:ElementName>CD/DVD drive 1</rasd:ElementName>
    <rasd:InstanceID>9</rasd:InstanceID>
    <rasd:Parent>3</rasd:Parent>
    <rasd:ResourceSubType>vmware.cdrom.atapi</rasd:ResourceSubType>
    <rasd:ResourceType>15</rasd:ResourceType>
    </Item>

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  • NEED HELP?


    My company has created products like vSearch ("Super vCenter"), vijavaNG APIs, EAM APIs, ICE tool. We also help clients with virtualization and cloud computing on customized development, training. Should you, or someone you know, need these products and services, please feel free to contact me: steve __AT__ doublecloud.org.

    Me: Steve Jin, VMware vExpert who authored the VMware VI and vSphere SDK by Prentice Hall, and created the de factor open source vSphere Java API while working at VMware engineering. Companies like Cisco, EMC, NetApp, HP, Dell, VMware, are among the users of the API and other tools I developed for their products, internal IT orchestration, and test automation.