/*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is available at http://www.abiquo.com/.....
*
* The Initial Developer of the Original Code is Soluciones Grid, S.L. (www.abiquo.com),
* Consell de Cent 296 principal 2�, 08007 Barcelona, Spain.
* No portions of the Code have been created by third parties.
* All Rights Reserved.
*
* Contributor(s): ______________________________________.
*
* Graphical User Interface of this software may be used under the terms
* of the Common Public Attribution License Version 1.0 (the "CPAL License",
* available at http://cpal.abiquo.com), in which case the provisions of CPAL
* License are applicable instead of those above. In relation of this portions
* of the Code, a Legal Notice according to Exhibits A and B of CPAL Licence
* should be provided in any distribution of the corresponding Code to Graphical
* User Interface.
*/
package com.abiquo.abicloud.machine.impl;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.abiquo.abicloud.exception.VirtualMachineException;
import com.abiquo.abicloud.hypervisor.impl.VmwareHypervisor;
import com.abiquo.abicloud.model.AbiCloudModel;
import com.abiquo.abicloud.model.AbsVirtualMachine;
import com.abiquo.abicloud.model.VirtualDisk;
import com.abiquo.abicloud.model.config.Configuration;
import com.abiquo.abicloud.model.config.VirtualMachineConfiguration;
import com.abiquo.abicloud.model.config.VmwareHypervisorConfiguration;
import com.vmware.apputils.version.ExtendedAppUtil;
import com.vmware.apputils.vim25.VMUtils;
import com.vmware.vim25.DynamicProperty;
import com.vmware.vim25.InvalidPowerState;
import com.vmware.vim25.InvalidState;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.ObjectContent;
import com.vmware.vim25.OptionValue;
import com.vmware.vim25.ResourceAllocationInfo;
import com.vmware.vim25.SharesInfo;
import com.vmware.vim25.SharesLevel;
import com.vmware.vim25.TaskInfo;
import com.vmware.vim25.ToolsUnavailable;
import com.vmware.vim25.VirtualDevice;
import com.vmware.vim25.VirtualDeviceConfigSpec;
import com.vmware.vim25.VirtualDeviceConfigSpecFileOperation;
import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo;
import com.vmware.vim25.VirtualMachineConfigInfo;
import com.vmware.vim25.VirtualMachineConfigSpec;
/**
* The vmware virtual machine representation
*
* @author pnavarro
*/
public class VmwareMachine extends AbsVirtualMachine
{
/**
* The machine name
*/
private String machineName;
/**
* The machine id
*/
private UUID machineId;
/**
* The vmware hypervisor
*/
private VmwareHypervisor vmwareHyper;
// private String dcName;
// private String hostName;
/**
* Apputil from the SDK
*/
private ExtendedAppUtil apputil;
/**
* The remote desktop port
*/
private int rdPort;
/**
* The virtual disk
*/
private VirtualDisk virtualDisk;
/**
* The virtual machine managed object reference
*/
private ManagedObjectReference _virtualMachine;
/**
* The virtual machine configuration
*/
private VirtualMachineConfiguration vmConfig;
/** The logger */
private static final Logger logger = LoggerFactory.getLogger(VmwareMachine.class);
/**
* This label is for extended disk detection
*/
private static final String extended_Disk_Label = "Hard Disk 2";
/**
* Vmwware hypervisor configuration
*/
private VmwareHypervisorConfiguration vmwareConfig;
/**
* The standard constructor
*
* @param configuration the virtual machine configuration
* @throws VirtualMachineException
*/
public VmwareMachine(VirtualMachineConfiguration configuration) throws VirtualMachineException
{
super(configuration);
if (config.getHyper() == null)
{
logger.error("THE HYPERVISOR IS NULL");
}
if (config.isSetHypervisor() & config.getHyper() instanceof VmwareHypervisor)
{
vmwareHyper = (VmwareHypervisor) config.getHyper();
}
else
{
throw new VirtualMachineException("Vmware machine requires a Vmware Hypervisor "
+ "on VirtualMachineConfiguration, not a "
+ config.getHyper().getClass().getCanonicalName());
}
String machineNameUUID = config.getMachineName();
// The 4 last characters of the machine name are erased because are
// omitted by the ESXi
int machineNameLength = machineNameUUID.length();
this.machineName = machineNameUUID.substring(0, machineNameLength - 4);
virtualDisk = config.getVirtualDiskBase();
machineId = config.getMachineId();
rdPort = config.getRdPort();
vmConfig = configuration;
vmwareConfig =
AbiCloudModel.getInstance().getConfigManager().getConfiguration()
.getVmwareHyperConfig();
apputil = vmwareHyper.getAppUtil();
try
{
// Deploy the virtual machine if it's required
if (config.canDeployVirtualMachine())
deployMachine();
}
catch (Exception e)
{
throw new VirtualMachineException(e);
}
logger.info("Created vmware machine name:" + config.getMachineName() + "\t ID:"
+ config.getMachineId().toString() + "\t " + "using hypervisor connection at "
+ config.getHyper().getAddress().toString());
}
@Override
public void deleteMachine() throws Exception
{
reconnect();
ArrayList vmList = getVms();
for (int i = 0; i < vmList.size(); i++)
{
String vmName =
(String) apputil.getServiceUtil3().getDynamicProperty(
(ManagedObjectReference) vmList.get(i), "name");
ManagedObjectReference vmMOR = (ManagedObjectReference) vmList.get(i);
ManagedObjectReference taskmor = null;
logger.info("Powering off virtualmachine '" + vmName + "'");
taskmor = apputil.getServiceConnection3().getService().destroy_Task(vmMOR);
boolean result = getTaskInfo(taskmor);
if (result)
{
logger.info("" + vmName + " powered off successfuly");
}
}
vmwareHyper.logout();
}
@Override
protected void deployMachine() throws Exception
{
reconnect();
// if (!apputil.getServiceConnection3().isConnected())
// Create the template vdestPathirtual machine
createVirtualMachine();
// Copy from the NAS to the template virtual machine
cloneVirtualDisk();
vmwareHyper.logout();
}
/**
* Private helper to clone a virtual disk from the repository one
*
* @throws Exception
*/
private void cloneVirtualDisk() throws Exception
{
String dcName = vmwareConfig.getDatacenterName();
ManagedObjectReference dcmor =
apputil.getServiceUtil3().getDecendentMoRef(null, "Datacenter", dcName);
ManagedObjectReference fileManager =
apputil.getServiceConnection3().getServiceContent().getFileManager();
String virtualDiskPath = virtualDisk.getLocation();
String fileName = null;
String separator = File.separator;
int pos = virtualDiskPath.lastIndexOf(separator);
int pos2 = virtualDiskPath.lastIndexOf(".");
if (pos2 > -1)
fileName = virtualDiskPath.substring(pos + 1, pos2);
else
fileName = virtualDiskPath.substring(pos + 1);
String sourcePath =
"[" + vmwareConfig.getDatastoreSanName() + "] " + fileName + "/" + fileName
+ "-flat.vmdk";
logger.info("The source datastore path is: {}", sourcePath);
String destPath =
"[" + vmwareConfig.getDatastoreVmfsName() + "] " + this.machineName + "/"
+ this.machineName + "-flat.vmdk";
// logger.info("The datastore destination name is : {}",
// vmwareConfig.getDatastoreVmfsName());
logger.info("The destination datastore path is: {}", destPath);
ManagedObjectReference taskCopyMor =
apputil.getServiceConnection3().getService().copyDatastoreFile_Task(fileManager,
sourcePath, dcmor, destPath, dcmor, true);
String res = apputil.getServiceUtil3().waitForTask(taskCopyMor);
if (res.equalsIgnoreCase("sucess"))
{
logger.info("Virtual Machine cloned Sucessfully");
}
else
{
String message = "Virtual Machine could not be cloned. " + res;
logger.error(message);
throw new VirtualMachineException(message);
}
}
/**
* Private helper to create a virtual machine template from the open virtualization format
* parameters
*
* @throws Exception
*/
private void createVirtualMachine() throws Exception
{
VMUtils vmUtils = new VMUtils(apputil);
String dcName = apputil.get_option("datacentername");
ManagedObjectReference dcmor =
apputil.getServiceUtil3().getDecendentMoRef(null, "Datacenter", dcName);
if (dcmor == null)
{
String message = "Datacenter " + dcName + " not found.";
logger.error(message);
throw new VirtualMachineException(message);
}
ManagedObjectReference hfmor = apputil.getServiceUtil3().getMoRefProp(dcmor, "hostFolder");
ArrayList crmors = apputil.getServiceUtil3().getDecendentMoRefs(hfmor, "ComputeResource");
String hostName = apputil.get_option("hostname");
ManagedObjectReference hostmor;
if (hostName != null)
{
hostmor = apputil.getServiceUtil3().getDecendentMoRef(hfmor, "HostSystem", hostName);
if (hostmor == null)
{
String message = "Host " + hostName + " not found";
logger.error(message);
throw new VirtualMachineException(message);
}
}
else
{
hostmor = apputil.getServiceUtil3().getFirstDecendentMoRef(dcmor, "HostSystem");
}
ManagedObjectReference crmor = null;
hostName = (String) apputil.getServiceUtil3().getDynamicProperty(hostmor, "name");
for (int i = 0; i < crmors.size(); i++)
{
ManagedObjectReference[] hrmors =
(ManagedObjectReference[]) apputil.getServiceUtil3().getDynamicProperty(
(ManagedObjectReference) crmors.get(i), "host");
if (hrmors != null && hrmors.length > 0)
{
for (int j = 0; j < hrmors.length; j++)
{
String hname =
(String) apputil.getServiceUtil3().getDynamicProperty(hrmors[j], "name");
if (hname.equalsIgnoreCase(hostName))
{
crmor = (ManagedObjectReference) crmors.get(i);
i = crmors.size() + 1;
j = hrmors.length + 1;
}
}
}
}
if (crmor == null)
{
String message = "No Compute Resource Found On Specified Host";
logger.error(message);
throw new VirtualMachineException(message);
}
ManagedObjectReference resourcePool =
apputil.getServiceUtil3().getMoRefProp(crmor, "resourcePool");
ManagedObjectReference vmFolderMor =
apputil.getServiceUtil3().getMoRefProp(dcmor, "vmFolder");
// TODO #createVMConfigSpec defines not convenient default data, change
// this
VirtualMachineConfigSpec vmConfigSpec =
vmUtils.createVmConfigSpec(this.machineName, vmwareConfig.getDatastoreVmfsName(),
this.virtualDisk.getCapacity(), crmor, hostmor);
vmConfigSpec.setName(this.machineName);
vmConfigSpec.setAnnotation("VirtualMachine Annotation");
vmConfigSpec.setMemoryMB(new Long(Integer.parseInt(apputil.get_option("memorysize"))));
vmConfigSpec.setNumCPUs(Integer.parseInt(apputil.get_option("cpucount")));
vmConfigSpec.setGuestId(apputil.get_option("guestosid"));
OptionValue[] values = new OptionValue[2];
values[0] = new OptionValue(null, null, "RemoteDisplay.vnc.enabled", "true");
values[1] = new OptionValue(null, null, "RemoteDisplay.vnc.port", rdPort);
vmConfigSpec.setExtraConfig(values);
logger.info("Machine name :{} Machine ID: {} ready to be created", this.machineName,
this.machineId);
ManagedObjectReference taskmor =
apputil.getServiceConnection3().getService().createVM_Task(vmFolderMor, vmConfigSpec,
resourcePool, hostmor);
String res = apputil.getServiceUtil3().waitForTask(taskmor);
if (res.equalsIgnoreCase("sucess"))
{
logger.info("Virtual Machine Created Sucessfully");
}
else
{
String message = "Virtual Machine could not be created. " + res;
logger.error(message);
throw new VirtualMachineException(message);
}
}
@Override
public void findSnapshot(String name)
{
String msg = "This method is not implemented for this hypervisor plugin";
logger.error(msg);
}
@Override
public void pauseMachine() throws Exception
{
reconnect();
ArrayList vmList = getVms();
if (vmList == null)
{
throw new VirtualMachineException("Error pausing the machine: tha virtual machine was not found");
}
for (int i = 0; i < vmList.size(); i++)
{
String vmName =
(String) apputil.getServiceUtil3().getDynamicProperty(
(ManagedObjectReference) vmList.get(i), "name");
ManagedObjectReference vmMOR = (ManagedObjectReference) vmList.get(i);
ManagedObjectReference taskmor = null;
logger.info("Suspending virtualmachine '" + vmName + "'");
taskmor = apputil.getServiceConnection3().getService().suspendVM_Task(vmMOR);
boolean result = getTaskInfo(taskmor);
if (result)
{
logger.info("" + vmName + " suspended successfuly");
}
else
{
throw new VirtualMachineException("Error pausing the machine");
}
}
vmwareHyper.logout();
}
@Override
public void populateEvent()
{
String msg = "This method is not implemented for this hypervisor plugin";
logger.error(msg);
}
@Override
public void powerOffMachine() throws Exception
{
reconnect();
ArrayList vmList = getVms();
if (vmList == null)
{
throw new VirtualMachineException("Error powering off the machine: tha virtual machine was not found");
}
for (int i = 0; i < vmList.size(); i++)
{
String vmName =
(String) apputil.getServiceUtil3().getDynamicProperty(
(ManagedObjectReference) vmList.get(i), "name");
ManagedObjectReference vmMOR = (ManagedObjectReference) vmList.get(i);
ManagedObjectReference taskmor = null;
logger.info("Powering off virtualmachine '" + vmName + "'");
taskmor = apputil.getServiceConnection3().getService().powerOffVM_Task(vmMOR);
boolean result = getTaskInfo(taskmor);
if (result)
{
logger.info("" + vmName + " powered off successfuly");
}
else
{
throw new VirtualMachineException("Error powering off the machine");
}
}
vmwareHyper.logout();
}
@Override
public void powerOnMachine() throws Exception
{
reconnect();
ArrayList vmList = getVms();
if (vmList == null)
{
throw new VirtualMachineException("Error powering on the machine: tha virtual machine was not found");
}
for (int i = 0; i < vmList.size(); i++)
{
String vmName =
(String) apputil.getServiceUtil3().getDynamicProperty(
(ManagedObjectReference) vmList.get(i), "name");
ManagedObjectReference vmMOR = (ManagedObjectReference) vmList.get(i);
ManagedObjectReference taskmor = null;
logger.info("Powering on virtualmachine '" + vmName + "'");
taskmor = apputil.getServiceConnection3().getService().powerOnVM_Task(vmMOR, null);
boolean result = getTaskInfo(taskmor);
if (result)
{
logger.info("" + vmName + " powered on successfuly");
}
else
{
throw new VirtualMachineException("Error powering on the machine");
}
}
vmwareHyper.logout();
}
/**
* Private helper to choose the virtual machine managed object reference
*
* @return a list of virtual machine managed object references
* @throws Exception
*/
private ArrayList getVms() throws Exception
{
String vmname = null;
String operation = null;
String host = null;
String folder = null;
String datacenter = null;
String pool = null;
String guestid = null;
String ipaddress = null;
String[][] filter = null;
ExtendedAppUtil cb = vmwareHyper.getAppUtil();
ArrayList vmList = new ArrayList();
if (cb.option_is_set("host"))
{
host = cb.get_option("host");
}
if (cb.option_is_set("folder"))
{
folder = cb.get_option("folder");
}
if (cb.option_is_set("datacenter"))
{
datacenter = cb.get_option("datacenter");
}
if (cb.option_is_set("vmname"))
{
vmname = cb.get_option("vmname");
}
if (cb.option_is_set("pool"))
{
pool = cb.get_option("pool");
}
if (cb.option_is_set("ipaddress"))
{
ipaddress = cb.get_option("ipaddress");
}
if (cb.option_is_set("guestid"))
{
guestid = cb.get_option("guestid");
}
// filter = new String[][] { new String[] { "summary.config.guestId",
// "winXPProGuest",},};
vmname = this.machineName;
filter =
new String[][] {new String[] {"guest.ipAddress", ipaddress,},
new String[] {"summary.config.guestId", guestid,}};
vmList = getVMs("VirtualMachine", datacenter, folder, pool, vmname, host, filter);
return vmList;
}
/**
* Private helper to get a list of virtual machine managed object references
*
* @param entity
* @param datacenter
* @param folder
* @param pool
* @param vmname
* @param host
* @param filter
* @return a list of virtual machine managed object references
* @throws Exception
*/
public ArrayList getVMs(String entity, String datacenter, String folder, String pool,
String vmname, String host, String[][] filter) throws Exception
{
ManagedObjectReference dsMOR = null;
ManagedObjectReference hostMOR = null;
ManagedObjectReference poolMOR = null;
ManagedObjectReference vmMOR = null;
ManagedObjectReference folderMOR = null;
ManagedObjectReference tempMOR = null;
ArrayList vmList = new ArrayList();
String[][] filterData = null;
if (datacenter != null)
{
dsMOR = apputil.getServiceUtil3().getDecendentMoRef(null, "Datacenter", datacenter);
if (dsMOR == null)
{
logger.info("Datacenter Not found");
return null;
}
else
{
tempMOR = dsMOR;
}
}
if (folder != null)
{
folderMOR = apputil.getServiceUtil3().getDecendentMoRef(tempMOR, "Folder", folder);
if (folderMOR == null)
{
logger.info("Folder Not found");
return null;
}
else
{
tempMOR = folderMOR;
}
}
if (pool != null)
{
poolMOR = apputil.getServiceUtil3().getDecendentMoRef(tempMOR, "ResourcePool", pool);
if (poolMOR == null)
{
logger.info("Resource pool Not found");
return null;
}
else
{
tempMOR = poolMOR;
}
}
if (host != null)
{
hostMOR = apputil.getServiceUtil3().getDecendentMoRef(tempMOR, "HostSystem", host);
if (hostMOR == null)
{
logger.info("Host Not found");
return null;
}
else
{
tempMOR = hostMOR;
}
}
if (vmname != null)
{
int i = 0;
filterData = new String[filter.length + 1][2];
for (i = 0; i < filter.length; i++)
{
filterData[i][0] = filter[i][0];
filterData[i][1] = filter[i][1];
}
// Adding the vmname in the filter
filterData[i][0] = "name";
filterData[i][1] = vmname;
}
else if (vmname == null)
{
int i = 0;
filterData = new String[filter.length + 1][2];
for (i = 0; i < filter.length; i++)
{
filterData[i][0] = filter[i][0];
filterData[i][1] = filter[i][1];
}
}
vmList =
apputil.getServiceUtil3().getDecendentMoRefs(tempMOR, "VirtualMachine", filterData);
if ((vmList == null) || (vmList.size() == 0))
{
logger.error("NO Virtual Machine found");
return null;
}
return vmList;
}
@Override
public void resetMachine() throws Exception
{
reconnect();
ArrayList vmList = getVms();
if (vmList == null)
{
throw new VirtualMachineException("Error reseting the machine: tha virtual machine was not found");
}
for (int i = 0; i < vmList.size(); i++)
{
String vmName =
(String) apputil.getServiceUtil3().getDynamicProperty(
(ManagedObjectReference) vmList.get(i), "name");
ManagedObjectReference vmMOR = (ManagedObjectReference) vmList.get(i);
ManagedObjectReference taskmor = null;
logger.info("Reseting virtualmachine '" + vmName + "'");
taskmor = apputil.getServiceConnection3().getService().resetVM_Task(vmMOR);
boolean result = getTaskInfo(taskmor);
if (result)
{
logger.info("Virtual Machine " + vmName + " reset successfuly");
}
else
{
throw new VirtualMachineException("Error reseting the machine");
}
}
vmwareHyper.logout();
}
@Override
public void resumeMachine() throws Exception
{
reconnect();
ArrayList vmList = getVms();
if (vmList == null)
{
throw new VirtualMachineException("Error resuming the machine: tha virtual machine was not found");
}
for (int i = 0; i < vmList.size(); i++)
{
String vmName =
(String) apputil.getServiceUtil3().getDynamicProperty(
(ManagedObjectReference) vmList.get(i), "name");
ManagedObjectReference vmMOR = (ManagedObjectReference) vmList.get(i);
logger.info("Putting the guestOs of vm '" + vmName + "' in standby mode");
ManagedObjectReference taskmor =
apputil.getServiceConnection3().getService().powerOnVM_Task(vmMOR, null);
logger.info("GuestOs of vm '" + vmName + "' put in standby mode");
boolean result = getTaskInfo(taskmor);
if (result)
{
logger.info("" + vmName + " resumed successfuly done");
}
else
{
throw new VirtualMachineException("Error resuming the machine");
}
}
vmwareHyper.logout();
}
@Override
public void setCurrentSnapshot(UUID id)
{
String msg = "This method is not implemented for this hypervisor plugin";
logger.error(msg);
}
@Override
public void takeSnapshot(String name)
{
String msg = "This method is not implemented for this hypervisor plugin";
logger.error(msg);
}
/**
* Private helper to get the task information
*
* @param taskmor the MOR to get the info from
* @return
* @throws Exception
*/
private boolean getTaskInfo(ManagedObjectReference taskmor) throws Exception
{
boolean valid = false;
DynamicProperty[] scsiArry = getDynamicProarray(taskmor, "info");
TaskInfo tinfo = ((TaskInfo) (scsiArry[0]).getVal());
String res = apputil.getServiceUtil3().waitForTask(taskmor);
if (res.equalsIgnoreCase("sucess"))
{
valid = true;
}
else
{
valid = false;
}
/*
* if (tinfo.getState().getValue().equalsIgnoreCase("error")) {
* logger.info("Error "+tinfo.getError().getLocalizedMessage()); valid = true; } else{ valid
* = false; }
*/
return valid;
}
/**
* Private helper to get an array dinamic property
*
* @param MOR the Managed Object Referented
* @param pName the property name
* @return the array dinamy property
* @throws Exception
*/
private DynamicProperty[] getDynamicProarray(ManagedObjectReference MOR, String pName)
throws Exception
{
ObjectContent[] objContent =
apputil.getServiceUtil3().getObjectProperties(null, MOR, new String[] {pName});
ObjectContent contentObj = objContent[0];
DynamicProperty[] objArr = contentObj.getPropSet();
return objArr;
}
@Override
public void reconfigVM(VirtualMachineConfiguration newConfiguration)
throws VirtualMachineException
{
try
{
reconnect();
getVmMor(this.machineName);
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
// Setting the new Ram value
logger.info("Reconfiguring The Virtual Machine For Memory Update " + this.machineName);
if (newConfiguration.isRam_set())
vmConfigSpec.setMemoryAllocation(getShares(String.valueOf(newConfiguration
.getRamAllocationUnits())));
logger.info("Reconfiguring The Virtual Machine For CPU Update " + this.machineName);
// Setting the number cpu value
if (newConfiguration.isCpu_number_set())
vmConfigSpec.setCpuAllocation(getShares(String.valueOf(newConfiguration
.getCpuNumber())));
// Setting the disk cpu value
logger.info("Reconfiguring The Virtual Machine For disk Update " + this.machineName);
VirtualDeviceConfigSpec vdiskSpec = getDiskDeviceConfigSpec(newConfiguration);
if (vdiskSpec != null)
{
VirtualDeviceConfigSpec[] vdiskSpecArray = {vdiskSpec};
vmConfigSpec.setDeviceChange(vdiskSpecArray);
}
ManagedObjectReference tmor =
apputil.getServiceConnection3().getService().reconfigVM_Task(_virtualMachine,
vmConfigSpec);
monitorTask(tmor);
// Updating configuration
this.vmConfig = newConfiguration;
vmwareHyper.logout();
}
catch (Exception e)
{
e.printStackTrace();
throw new VirtualMachineException(e);
}
}
/**
* Private helper to monitor the task launched
*
* @param tmor the task managed object reference
* @throws Exception
*/
private void monitorTask(ManagedObjectReference tmor) throws Exception
{
if (tmor != null)
{
String result = apputil.getServiceUtil3().waitForTask(tmor);
if (result.equalsIgnoreCase("sucess"))
{
logger.info("Task Completed Sucessfully");
}
else
{
logger.error("Failure " + result);
throw new Exception("The task could not be performed");
}
}
}
/**
* Gets the management object reference from the virtual machine name
*
* @param vmName the virtual machine name
* @throws Exception
*/
private void getVmMor(String vmName) throws Exception
{
_virtualMachine =
apputil.getServiceUtil3().getDecendentMoRef(null, "VirtualMachine", vmName);
}
/**
* Gets the device config information
*
* @param newConfiguration the new virtual disk
* @return
* @throws Exception
*/
private VirtualDeviceConfigSpec getDiskDeviceConfigSpec(
VirtualMachineConfiguration newConfiguration) throws Exception
{
// Compares the two lists and adds or remove the disks
List<VirtualDisk> newExtendedDiskList = newConfiguration.getExtendedVirtualDiskList();
List<VirtualDisk> oldExtendedDiskList = vmConfig.getExtendedVirtualDiskList();
VirtualDeviceConfigSpec diskSpec = new VirtualDeviceConfigSpec();
// If there are no more extended disks, I remove the existent ones
if ((newExtendedDiskList.size() == 0) && (oldExtendedDiskList.size() == 0))
{
return null;
}
else if ((newExtendedDiskList.size() == 0) && (oldExtendedDiskList.size() > 0))
{
removeVirtualDiskFromConfig(oldExtendedDiskList.get(0), diskSpec);
return diskSpec;
}
if ((newExtendedDiskList.size() > 0) && (oldExtendedDiskList.size() == 0))
{
for (VirtualDisk newVirtualDisk : newExtendedDiskList)
{
String location = addVirtualDiskToConfig(newVirtualDisk, diskSpec);
newVirtualDisk.setLocation(location);
}
return diskSpec;
}
else if ((newExtendedDiskList.get(0).getCapacity() > oldExtendedDiskList.get(0)
.getCapacity()))
{
long diffSize = newExtendedDiskList.get(0).getCapacity();
String diskLocation = oldExtendedDiskList.get(0).getLocation();
newExtendedDiskList.get(0).setLocation(diskLocation);
logger.info("Extending to {} bytes in the disk location: {}", diffSize, diskLocation);
// The new extended disk capacity is larger than the old one
extendVirtualDisk(diskLocation, diffSize);
return null;
}
else if ((newExtendedDiskList.get(0).getCapacity() < oldExtendedDiskList.get(0)
.getCapacity()))
{
// EXPERIMENTAL !
long diffSize = newExtendedDiskList.get(0).getCapacity();
String diskLocation = oldExtendedDiskList.get(0).getLocation();
newExtendedDiskList.get(0).setLocation(diskLocation);
logger.info("Shrinking the disk location: {}", diffSize, diskLocation);
shrinkVirtualDisk(diskLocation, diffSize);
// reduceVirtualDisk(newExtendedDiskList.get(0),diskSpec);
return null;
}
else if ((newExtendedDiskList.get(0).getCapacity() == oldExtendedDiskList.get(0)
.getCapacity()))
{
return null;
}
// List<VirtualDisk> disksToAdd = new ArrayList<VirtualDisk>(newExtendedDiskList);
// List<VirtualDisk> disksToDelete = new ArrayList<VirtualDisk>(oldExtendedDiskList);
/*
* // Adding the new virtual disk lists if ((disksToAdd.removeAll(oldExtendedDiskList)) ||
* (oldExtendedDiskList.size() == 0)) { for (VirtualDisk newVirtualDisk : disksToAdd) {
* addVirtualDiskToConfig(newVirtualDisk, diskSpec); } } //Removing disks if
* (disksToDelete.removeAll(newExtendedDiskList)) { for (VirtualDisk oldVirtualDisk :
* disksToDelete) { removeVirtualDiskFromConfig(oldVirtualDisk, diskSpec); } }
*/
return diskSpec;
}
/**
* Adds the virtual Disk to the virtual device configuration
*
* @param newVirtualDisk the new virtual disk to add
* @param diskSpec the virtual disk device configuration
* @throws Exception
*/
private String reduceVirtualDisk(VirtualDisk newVirtualDisk, VirtualDeviceConfigSpec diskSpec)
throws Exception
{
VirtualMachineConfigInfo vmConfigInfo =
(VirtualMachineConfigInfo) apputil.getServiceUtil3().getDynamicProperty(
_virtualMachine, "config");
com.vmware.vim25.VirtualDisk disk = new com.vmware.vim25.VirtualDisk();
VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo();
String dsName = vmwareConfig.getDatastoreVmfsName();
int ckey = 0;
int unitNumber = 0;
VirtualDevice[] test = vmConfigInfo.getHardware().getDevice();
for (int k = 0; k < test.length; k++)
{
if (test[k].getDeviceInfo().getLabel().equalsIgnoreCase("SCSI Controller 0"))
{
ckey = test[k].getKey();
}
}
unitNumber = test.length + 1;
String fileName =
"[" + dsName + "] " + this.machineName + "/" + newVirtualDisk.getId() + ".vmdk";
diskfileBacking.setFileName(fileName);
// Provisioning with thin provisioning
diskfileBacking.setThinProvisioned(true);
diskfileBacking.setDiskMode("persistent");
disk.setControllerKey(ckey);
disk.setUnitNumber(unitNumber);
disk.setBacking(diskfileBacking);
int size = (int) (newVirtualDisk.getCapacity() / 1024);
disk.setCapacityInKB(size);
disk.setKey(-1);
diskSpec.setOperation(VirtualDeviceConfigSpecOperation.edit);
diskSpec.setDevice(disk);
return fileName;
}
private void shrinkVirtualDisk(String virtualDiskLocation, long diffSize) throws Exception
{
ManagedObjectReference virtualDiskManager =
apputil.getServiceConnection3().getServiceContent().getVirtualDiskManager();
String dcName = apputil.get_option("datacentername");
ManagedObjectReference dcmor =
apputil.getServiceUtil3().getDecendentMoRef(null, "Datacenter", dcName);
if (dcmor == null)
{
String message = "Datacenter " + dcName + " not found.";
logger.error(message);
throw new VirtualMachineException(message);
}
// TODO Defragment the disk
ManagedObjectReference tmor =
apputil.getServiceConnection3().getService().shrinkVirtualDisk_Task(virtualDiskManager,
virtualDiskLocation, dcmor, false);
monitorTask(tmor);
}
private void extendVirtualDisk(String virtualDiskLocation, long diffSize) throws Exception
{
ManagedObjectReference virtualDiskManager =
apputil.getServiceConnection3().getServiceContent().getVirtualDiskManager();
String dcName = apputil.get_option("datacentername");
ManagedObjectReference dcmor =
apputil.getServiceUtil3().getDecendentMoRef(null, "Datacenter", dcName);
if (dcmor == null)
{
String message = "Datacenter " + dcName + " not found.";
logger.error(message);
throw new VirtualMachineException(message);
}
ManagedObjectReference tmor =
apputil.getServiceConnection3().getService().extendVirtualDisk_Task(virtualDiskManager,
virtualDiskLocation, dcmor, diffSize / 1024);
monitorTask(tmor);
}
/**
* Removes the virtual disk configuration from the virtual disk device configuration
*
* @param oldVirtualDisk the virtual disk to remove
* @param diskSpec the virtual disk configuration specifications
* @throws Exception
*/
private void removeVirtualDiskFromConfig(VirtualDisk oldVirtualDisk,
VirtualDeviceConfigSpec diskSpec) throws Exception
{
VirtualMachineConfigInfo vmConfigInfo =
(VirtualMachineConfigInfo) apputil.getServiceUtil3().getDynamicProperty(
_virtualMachine, "config");
com.vmware.vim25.VirtualDisk disk = null;
VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo();
VirtualDevice[] test = vmConfigInfo.getHardware().getDevice();
for (int k = 0; k < test.length; k++)
{
if (test[k].getDeviceInfo().getLabel().equalsIgnoreCase(extended_Disk_Label))
{
disk = (com.vmware.vim25.VirtualDisk) test[k];
}
}
if (disk != null)
{
diskSpec.setOperation(VirtualDeviceConfigSpecOperation.remove);
diskSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.destroy);
diskSpec.setDevice(disk);
}
else
{
logger.error("The disk {} was not removed since it was not found", oldVirtualDisk
.getId());
}
}
/**
* Adds the virtual Disk to the virtual device configuration
*
* @param newVirtualDisk the new virtual disk to add
* @param diskSpec the virtual disk device configuration
* @throws Exception
*/
private String addVirtualDiskToConfig(VirtualDisk newVirtualDisk,
VirtualDeviceConfigSpec diskSpec) throws Exception
{
VirtualMachineConfigInfo vmConfigInfo =
(VirtualMachineConfigInfo) apputil.getServiceUtil3().getDynamicProperty(
_virtualMachine, "config");
com.vmware.vim25.VirtualDisk disk = new com.vmware.vim25.VirtualDisk();
VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo();
String dsName = vmwareConfig.getDatastoreVmfsName();
int ckey = 0;
int unitNumber = 0;
VirtualDevice[] test = vmConfigInfo.getHardware().getDevice();
for (int k = 0; k < test.length; k++)
{
if (test[k].getDeviceInfo().getLabel().equalsIgnoreCase("SCSI Controller 0"))
{
ckey = test[k].getKey();
}
}
unitNumber = test.length + 1;
String fileName =
"[" + dsName + "] " + this.machineName + "/" + newVirtualDisk.getId() + ".vmdk";
diskfileBacking.setFileName(fileName);
// Provisioning with thin provisioning
diskfileBacking.setThinProvisioned(true);
diskfileBacking.setDiskMode("persistent");
disk.setControllerKey(ckey);
disk.setUnitNumber(unitNumber);
disk.setBacking(diskfileBacking);
int size = (int) (newVirtualDisk.getCapacity() / 1024);
disk.setCapacityInKB(size);
disk.setKey(-1);
diskSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
diskSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.create);
diskSpec.setDevice(disk);
return fileName;
}
/**
* Gets the resource allocation information from the resource value
*
* @param value the value
* @return the resource allocation information
* @throws Exception
*/
private ResourceAllocationInfo getShares(String value) throws Exception
{
ResourceAllocationInfo raInfo = new ResourceAllocationInfo();
SharesInfo sharesInfo = new SharesInfo();
if (value.equalsIgnoreCase(SharesLevel._high))
{
sharesInfo.setLevel(SharesLevel.high);
}
else if (value.equalsIgnoreCase(SharesLevel._normal))
{
sharesInfo.setLevel(SharesLevel.normal);
}
else if (value.equalsIgnoreCase(SharesLevel._low))
{
sharesInfo.setLevel(SharesLevel.low);
}
else
{
sharesInfo.setLevel(SharesLevel.custom);
sharesInfo.setShares(Integer.parseInt(value));
}
raInfo.setShares(sharesInfo);
return raInfo;
}
private void reconnect()
{
URL address = vmwareHyper.getAddress();
vmwareHyper.init(address);
vmwareHyper.connect(address);
apputil = vmwareHyper.getAppUtil();
}
}