diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index 35063b05859..4b2f830a3ee 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -29,7 +29,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import com.vmware.vim25.ClusterDasConfigInfo; import com.vmware.vim25.ManagedObjectReference; import org.apache.cloudstack.api.ApiConstants; @@ -344,8 +343,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer return null; } else { ClusterMO clusterMo = new ClusterMO(context, morCluster); - ClusterDasConfigInfo dasConfig = clusterMo.getDasConfig(); - if (dasConfig != null && dasConfig.isEnabled() != null && dasConfig.isEnabled().booleanValue()) { + if (clusterMo.isHAEnabled()) { clusterDetails.put("NativeHA", "true"); _clusterDetailsDao.persist(clusterId, clusterDetails); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index ad4ae267528..56ca4ea0966 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -48,9 +48,9 @@ import org.apache.log4j.NDC; import com.google.gson.Gson; import com.vmware.vim25.AboutInfo; import com.vmware.vim25.BoolPolicy; -import com.vmware.vim25.ClusterDasConfigInfo; import com.vmware.vim25.ComputeResourceSummary; import com.vmware.vim25.CustomFieldStringValue; +import com.vmware.vim25.DasVmPriority; import com.vmware.vim25.DVPortConfigInfo; import com.vmware.vim25.DVPortConfigSpec; import com.vmware.vim25.DatastoreSummary; @@ -1634,6 +1634,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vmFolderExists && vmxFileFullPath != null) { // VM can be registered only if .vmx is present. registerVm(vmNameOnVcenter, dsRootVolumeIsOn); vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName); + if (vmMo != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found registered vm " + vmInternalCSName + " at host " + hyperHost.getHyperHostName()); + } + } tearDownVm(vmMo); }else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), @@ -1981,6 +1986,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa throw new Exception("Failed to configure VM before start. vmName: " + vmInternalCSName); } + if (vmSpec.getType() == VirtualMachine.Type.DomainRouter) { + hyperHost.setRestartPriorityForVM(vmMo, DasVmPriority.HIGH.value()); + } + // // Post Configuration // @@ -4805,8 +4814,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa private void fillHostDetailsInfo(VmwareContext serviceContext, Map details) throws Exception { VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); - ClusterDasConfigInfo dasConfig = hyperHost.getDasConfig(); - if (dasConfig != null && dasConfig.isEnabled() != null && dasConfig.isEnabled().booleanValue()) { + if (hyperHost.isHAEnabled()) { details.put("NativeHA", "true"); } } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java index b5f0500d391..a6e42850c5e 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java @@ -22,16 +22,20 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.google.gson.Gson; import com.vmware.vim25.ArrayOfHostIpRouteEntry; +import com.vmware.vim25.ArrayUpdateOperation; import com.vmware.vim25.ClusterComputeResourceSummary; import com.vmware.vim25.ClusterConfigInfoEx; import com.vmware.vim25.ClusterDasConfigInfo; +import com.vmware.vim25.ClusterDasVmSettingsRestartPriority; import com.vmware.vim25.ClusterHostRecommendation; import com.vmware.vim25.ComputeResourceSummary; import com.vmware.vim25.CustomFieldStringValue; +import com.vmware.vim25.DasVmPriority; import com.vmware.vim25.DatastoreInfo; import com.vmware.vim25.DynamicProperty; import com.vmware.vim25.GuestOsDescriptor; @@ -49,6 +53,10 @@ import com.vmware.vim25.PropertySpec; import com.vmware.vim25.TraversalSpec; import com.vmware.vim25.VirtualMachineConfigOption; import com.vmware.vim25.VirtualMachineConfigSpec; +import com.vmware.vim25.ClusterDasVmConfigInfo; +import com.vmware.vim25.ClusterDasVmConfigSpec; +import com.vmware.vim25.ClusterDasVmSettings; +import com.vmware.vim25.ClusterConfigSpecEx; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareHelper; @@ -77,9 +85,118 @@ public class ClusterMO extends BaseMO implements VmwareHypervisorHost { @Override public ClusterDasConfigInfo getDasConfig() throws Exception { - // Note getDynamicProperty() with "configurationEx.dasConfig" does not work here because of that dasConfig is a property in subclass + ClusterConfigInfoEx configInfo = getClusterConfigInfo(); + if (configInfo != null) { + // Note getDynamicProperty() with "configurationEx.dasConfig" does not work here because of that dasConfig is a property in subclass + return configInfo.getDasConfig(); + } + + return null; + } + + private ClusterConfigInfoEx getClusterConfigInfo() throws Exception { ClusterConfigInfoEx configInfo = (ClusterConfigInfoEx)_context.getVimClient().getDynamicProperty(_mor, "configurationEx"); - return configInfo.getDasConfig(); + return configInfo; + } + + @Override + public boolean isHAEnabled() throws Exception { + ClusterDasConfigInfo dasConfig = getDasConfig(); + if (dasConfig != null && dasConfig.isEnabled() != null && dasConfig.isEnabled().booleanValue()) { + return true; + } + + return false; + } + + private String getRestartPriorityForVM(VirtualMachineMO vmMo) throws Exception { + if (vmMo == null) { + s_logger.debug("Failed to get restart priority for VM, invalid VM object reference"); + return null; + } + + ManagedObjectReference vmMor = vmMo.getMor(); + if (vmMor == null || !vmMor.getType().equals("VirtualMachine")) { + s_logger.debug("Failed to get restart priority for VM: " + vmMo.getName() + ", invalid VM object reference"); + return null; + } + + ClusterConfigInfoEx configInfo = getClusterConfigInfo(); + if (configInfo == null) { + s_logger.debug("Failed to get restart priority for VM: " + vmMo.getName() + ", no cluster config information"); + return null; + } + + List dasVmConfig = configInfo.getDasVmConfig(); + for (int dasVmConfigIndex = 0; dasVmConfigIndex < dasVmConfig.size(); dasVmConfigIndex++) { + ClusterDasVmConfigInfo dasVmConfigInfo = dasVmConfig.get(dasVmConfigIndex); + if (dasVmConfigInfo != null && dasVmConfigInfo.getKey().getValue().equals(vmMor.getValue())) { + DasVmPriority dasVmPriority = dasVmConfigInfo.getRestartPriority(); + if (dasVmPriority != null) { + return dasVmPriority.value(); + } else { + //VM uses cluster restart priority when DasVmPriority for the VM is null. + return ClusterDasVmSettingsRestartPriority.CLUSTER_RESTART_PRIORITY.value(); + } + } + } + + s_logger.debug("VM: " + vmMo.getName() + " uses default restart priority in the cluster: " + getName()); + return null; + } + + @Override + public void setRestartPriorityForVM(VirtualMachineMO vmMo, String priority) throws Exception { + if (vmMo == null || StringUtils.isBlank(priority)) { + return; + } + + if (!isHAEnabled()) { + s_logger.debug("Couldn't set restart priority for VM: " + vmMo.getName() + ", HA disabled in the cluster"); + return; + } + + ManagedObjectReference vmMor = vmMo.getMor(); + if (vmMor == null || !vmMor.getType().equals("VirtualMachine")) { + s_logger.debug("Failed to set restart priority for VM: " + vmMo.getName() + ", invalid VM object reference"); + return; + } + + String currentVmRestartPriority = getRestartPriorityForVM(vmMo); + if (StringUtils.isNotBlank(currentVmRestartPriority) && currentVmRestartPriority.equalsIgnoreCase(priority)) { + return; + } + + ClusterDasVmSettings clusterDasVmSettings = new ClusterDasVmSettings(); + clusterDasVmSettings.setRestartPriority(priority); + + ClusterDasVmConfigInfo clusterDasVmConfigInfo = new ClusterDasVmConfigInfo(); + clusterDasVmConfigInfo.setKey(vmMor); + clusterDasVmConfigInfo.setDasSettings(clusterDasVmSettings); + + ClusterDasVmConfigSpec clusterDasVmConfigSpec = new ClusterDasVmConfigSpec(); + clusterDasVmConfigSpec.setOperation((StringUtils.isNotBlank(currentVmRestartPriority)) ? ArrayUpdateOperation.EDIT : ArrayUpdateOperation.ADD); + clusterDasVmConfigSpec.setInfo(clusterDasVmConfigInfo); + + ClusterConfigSpecEx clusterConfigSpecEx = new ClusterConfigSpecEx(); + ClusterDasConfigInfo clusterDasConfigInfo = new ClusterDasConfigInfo(); + clusterConfigSpecEx.setDasConfig(clusterDasConfigInfo); + clusterConfigSpecEx.getDasVmConfigSpec().add(clusterDasVmConfigSpec); + + ManagedObjectReference morTask = _context.getService().reconfigureComputeResourceTask(_mor, clusterConfigSpecEx, true); + + boolean result = _context.getVimClient().waitForTask(morTask); + + if (result) { + _context.waitForTaskProgressDone(morTask); + + if (s_logger.isTraceEnabled()) + s_logger.trace("vCenter API trace - setRestartPriority done(successfully)"); + } else { + if (s_logger.isTraceEnabled()) + s_logger.trace("vCenter API trace - setRestartPriority done(failed)"); + s_logger.error("Set restart priority failed for VM: " + vmMo.getName() + " due to " + TaskMO.getTaskFailureInfo(_context, morTask)); + } } @Override diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java index c008e6b01e7..5f64e83c770 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java @@ -143,6 +143,26 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost { return null; } + @Override + public boolean isHAEnabled() throws Exception { + ManagedObjectReference morParent = getParentMor(); + if (morParent.getType().equals("ClusterComputeResource")) { + ClusterMO clusterMo = new ClusterMO(_context, morParent); + return clusterMo.isHAEnabled(); + } + + return false; + } + + @Override + public void setRestartPriorityForVM(VirtualMachineMO vmMo, String priority) throws Exception { + ManagedObjectReference morParent = getParentMor(); + if (morParent.getType().equals("ClusterComputeResource")) { + ClusterMO clusterMo = new ClusterMO(_context, morParent); + clusterMo.setRestartPriorityForVM(vmMo, priority); + } + } + @Override public String getHyperHostDefaultGateway() throws Exception { List entries = getHostIpRouteEntries(); diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java index fdfc254278b..0767ec09f9a 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java @@ -37,6 +37,10 @@ public interface VmwareHypervisorHost { ClusterDasConfigInfo getDasConfig() throws Exception; + boolean isHAEnabled() throws Exception; + + void setRestartPriorityForVM(VirtualMachineMO vmMo, String priority) throws Exception; + ManagedObjectReference getHyperHostDatacenter() throws Exception; ManagedObjectReference getHyperHostOwnerResourcePool() throws Exception;