Getting info from your ESX server using the VMware Infrastructure (vSphere) Java API (Part 4)

In the first part, we’ve seen how to get general information about the ESX hosts.

In the second part, we’ve read some information about the virtual machines running on a given host.

In the third part, we’ve seen how to list performance counters and get statistics out of it.

In this part, we’ll be working with snapshots, creating snapshots, listing existing snapshots, selecting an existing snapshot and deleting snapshots.

First let’s create a snapshot:

You need to perform the following steps:

  • Get a new ServiceInstance
  • Search for the virtual machine
  • Create a snapshot task

The created snapshot task will run asynchronously in the background.

Here the code:

package com.benohead.esx;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import com.vmware.vim25.InvalidProperty;
import com.vmware.vim25.RuntimeFault;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.Task;
import com.vmware.vim25.mo.VirtualMachine;

public class CreateVmSnapshot {
	static final String SERVER_NAME = "192.168.190.87";
	static final String USER_NAME = "Administrator";
	static final String PASSWORD = "xxxxxx";
	private static final String VM_NAME = "MyVMName";

	public static void main(String[] args) {
		String url = "https://" + SERVER_NAME + "/sdk/vimService";
		// List host systems
		try {
			ServiceInstance si = new ServiceInstance(new URL(url), USER_NAME, PASSWORD, true);
			VirtualMachine vm = (VirtualMachine) new InventoryNavigator(si.getRootFolder()).searchManagedEntity("VirtualMachine", VM_NAME);
			Task task = vm.createSnapshot_Task("benohead1", "Benohead's first snapshot", false /* memory */, true /* quiesce */);
		} catch (InvalidProperty e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RuntimeFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Using the returned task instance, you can monitor the progress of the task. You will also see in the lower part of the UI of the vSphere client (Recent Tasks) that the task is running.

Now that we can create snapshots let’s see how to get the tree view of the existing snapshots like in the vSphere client snapshot manager. Here are the steps to follow:

  • get the list of Root snapshots
  • go through list and print whatever info you required
  • for each snapshot get the list of child snapshots and process them like the root snapshots

To get the list of Root snapshots:

VirtualMachineSnapshotTree[] rootSnapshotList = vm.getSnapshot().getRootSnapshotList();

We’ll call a method to walk through the tree:

listSnapshotTree(rootSnapshotList, 0, vm.getSnapshot().getCurrentSnapshot());

We provide vm.getSnapshot().getCurrentSnapshot() to the method so that it can write “You are here” next to the snapshot which is the current one.

Here the method:

private static void listSnapshotTree(VirtualMachineSnapshotTree[] rootSnapshotList, int level, ManagedObjectReference currentSnapshot) {
	if (rootSnapshotList != null) {
		for (int i = 0; i < rootSnapshotList.length; i++) {
			VirtualMachineSnapshotTree snapshot = rootSnapshotList[i];
			String name = snapshot.getName();
			for(int j=0;j<level;j++) {
				System.out.print("t");
			}
			String currentString = snapshot.getSnapshot().equals(currentSnapshot) ? " (You are here)" : "";
			System.out.println(name + currentString);
			
			listSnapshotTree(snapshot.childSnapshotList, level+1, currentSnapshot);
		}
	}
}

The level variable is just used to add the appropriate number of tabs so that it looks like a tree (of course if I had a UI, we could actually show a nice tree…).
We need to compare the snapshots with the current snapshot because there is no attribute in the snapshot tree which says “hey ! I’m the current snapshot”.

The complete sample class for listing the snapshots looks this:

package com.benohead.esx;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import com.vmware.vim25.InvalidProperty;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.RuntimeFault;
import com.vmware.vim25.VirtualMachineSnapshotTree;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.VirtualMachine;

public class ListVmSnapshots {
	static final String SERVER_NAME = "192.168.190.87";
	static final String USER_NAME = "Administrator";
	static final String PASSWORD = "xxxxxx";
	private static final String VM_NAME = "MyVMName";

	public static void main(String[] args) {
		String url = "https://" + SERVER_NAME + "/sdk/vimService";
		// List host systems
		try {
			ServiceInstance si = new ServiceInstance(new URL(url), USER_NAME, PASSWORD, true);
			VirtualMachine vm = (VirtualMachine) new InventoryNavigator(si.getRootFolder()).searchManagedEntity("VirtualMachine", VM_NAME);
			VirtualMachineSnapshotTree[] rootSnapshotList = vm.getSnapshot().getRootSnapshotList();
			listSnapshotTree(rootSnapshotList, 0, vm.getSnapshot().getCurrentSnapshot());
		} catch (InvalidProperty e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RuntimeFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static void listSnapshotTree(VirtualMachineSnapshotTree[] rootSnapshotList, int level, ManagedObjectReference currentSnapshot) {
		if (rootSnapshotList != null) {
			for (int i = 0; i < rootSnapshotList.length; i++) {
				VirtualMachineSnapshotTree snapshot = rootSnapshotList[i];
				String name = snapshot.getName();
				for (int j = 0; j < level; j++) {
					System.out.print("t");
				}
				String currentString = snapshot.getSnapshot().equals(currentSnapshot) ? " (You are here)" : "";
				System.out.println(name + currentString);

				listSnapshotTree(snapshot.childSnapshotList, level + 1, currentSnapshot);
			}
		}
	}
}

Now let’s see how to go to (revert to) an existing snapshot (i.e. change the execution state of the VM to the state of this snapshot).

First you have to get an object representing the snapshot you want to revert to. You have to start with the list of root snapshots and walk through the tree until you’ve found the snapshot you’re looking for:

private static VirtualMachineSnapshotTree findInSnapshotTree(String snapshotName, VirtualMachineSnapshotTree[] rootSnapshotList) {
	if (rootSnapshotList != null) {
		for (int i = 0; i < rootSnapshotList.length; i++) {
			VirtualMachineSnapshotTree virtualMachineSnapshotTree = rootSnapshotList[i];
			String name = virtualMachineSnapshotTree.getName();
			System.out.println("checking " + name);
			if (snapshotName.equals(name)) {
				return virtualMachineSnapshotTree;
			} else {
				VirtualMachineSnapshotTree snapshot = findInSnapshotTree(snapshotName, virtualMachineSnapshotTree.childSnapshotList);
				if (snapshot != null) {
					return snapshot;
				}
			}
		}
	}
	return null;
}

Once you have it, you can revert to it:

VirtualMachineSnapshot snapshot = new VirtualMachineSnapshot(si.getServerConnection(), snapshotTree.getSnapshot());
snapshot.revertToSnapshot_Task(null);

The argument null to revertToSnapshot_Task means that if vBalance feature is configured for automatic load balancing, a host is automatically selected otherwise, the VM stays on it’s current host.

Here the complete code of the class:

package com.benohead.esx;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import com.vmware.vim25.InvalidProperty;
import com.vmware.vim25.RuntimeFault;
import com.vmware.vim25.VirtualMachineSnapshotTree;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.mo.VirtualMachineSnapshot;

public class GoToVmSnapshot {
	static final String SERVER_NAME = "192.168.190.87";
	static final String USER_NAME = "Administrator";
	static final String PASSWORD = "xxxxxx";
	private static final String VM_NAME = "MyVMName";
	private static final String SNAPSHOT_NAME = "othersnapshot";

	public static void main(String[] args) {
		String url = "https://" + SERVER_NAME + "/sdk/vimService";
		// List host systems
		try {
			ServiceInstance si = new ServiceInstance(new URL(url), USER_NAME, PASSWORD, true);
			VirtualMachine vm = (VirtualMachine) new InventoryNavigator(si.getRootFolder()).searchManagedEntity("VirtualMachine", VM_NAME);
			VirtualMachineSnapshotTree[] rootSnapshotList = vm.getSnapshot().getRootSnapshotList();
			VirtualMachineSnapshotTree snapshotTree = findInSnapshotTree(SNAPSHOT_NAME, rootSnapshotList);
			VirtualMachineSnapshot snapshot = new VirtualMachineSnapshot(si.getServerConnection(), snapshotTree.getSnapshot());
			snapshot.revertToSnapshot_Task(null);
		} catch (InvalidProperty e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RuntimeFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static VirtualMachineSnapshotTree findInSnapshotTree(String snapshotName, VirtualMachineSnapshotTree[] rootSnapshotList) {
		if (rootSnapshotList != null) {
			for (int i = 0; i < rootSnapshotList.length; i++) {
				VirtualMachineSnapshotTree virtualMachineSnapshotTree = rootSnapshotList[i];
				String name = virtualMachineSnapshotTree.getName();
				System.out.println("checking " + name);
				if (snapshotName.equals(name)) {
					return virtualMachineSnapshotTree;
				} else {
					VirtualMachineSnapshotTree snapshot = findInSnapshotTree(snapshotName, virtualMachineSnapshotTree.childSnapshotList);
					if (snapshot != null) {
						return snapshot;
					}
				}
			}
		}
		return null;
	}
}

Now the only thing left is to delete snapshots. Basically it’s really a lot like reverting to a snapshot:

  • First you need to get an object representing the snapshot
  • Then you need to call the removeSnapshot_Task method to create a background task

Here the code:

package com.benohead.esx;

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import com.vmware.vim25.Description;
import com.vmware.vim25.InvalidProperty;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.RuntimeFault;
import com.vmware.vim25.VirtualDevice;
import com.vmware.vim25.VirtualHardware;
import com.vmware.vim25.VirtualMachineConfigInfo;
import com.vmware.vim25.VirtualMachineSnapshotTree;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.Task;
import com.vmware.vim25.mo.VirtualMachine;
import com.vmware.vim25.mo.VirtualMachineSnapshot;

public class DeleteVmSnapshot {
	static final String SERVER_NAME = "192.168.190.87";
	static final String USER_NAME = "Administrator";
	static final String PASSWORD = "xxxxxx";
	private static final String VM_NAME = "MyVMName";
	private static final String SNAPSHOT_NAME = "benohead1";

	public static void main(String[] args) {
		String url = "https://" + SERVER_NAME + "/sdk/vimService";
		// List host systems
		try {
			ServiceInstance si = new ServiceInstance(new URL(url), USER_NAME, PASSWORD, true);
			VirtualMachine vm = (VirtualMachine) new InventoryNavigator(si.getRootFolder()).searchManagedEntity("VirtualMachine", VM_NAME);
			VirtualMachineSnapshotTree[] rootSnapshotList = vm.getSnapshot().getRootSnapshotList();
			VirtualMachineSnapshotTree snapshotTree = findInSnapshotTree(SNAPSHOT_NAME, rootSnapshotList);
			VirtualMachineSnapshot snapshot = new VirtualMachineSnapshot(si.getServerConnection(), snapshotTree.getSnapshot());
			snapshot.removeSnapshot_Task(false);
		} catch (InvalidProperty e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RuntimeFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static VirtualMachineSnapshotTree findInSnapshotTree(String snapshotName, VirtualMachineSnapshotTree[] rootSnapshotList) {
		if (rootSnapshotList != null) {
			for (int i = 0; i < rootSnapshotList.length; i++) {
				VirtualMachineSnapshotTree virtualMachineSnapshotTree = rootSnapshotList[i];
				String name = virtualMachineSnapshotTree.getName();
				System.out.println("checking " + name);
				if (snapshotName.equals(name)) {
					return virtualMachineSnapshotTree;
				} else {
					VirtualMachineSnapshotTree snapshot = findInSnapshotTree(snapshotName, virtualMachineSnapshotTree.childSnapshotList);
					if (snapshot != null) {
						return snapshot;
					}
				}
			}
		}
		return null;
	}
}

5 thoughts on “Getting info from your ESX server using the VMware Infrastructure (vSphere) Java API (Part 4)

  1. How to get all esx hosts data(info) which are connected to vcenter server(device) from vcenter.
    if anybody have code for this plz send it to my email id

Leave a Reply

Your email address will not be published. Required fields are marked *