Merge pull request #1879 from Accelerite/CLOUDSTACK-9719

CLOUDSTACK-9719: [VMware] VR loses DHCP settings and VMs cannot obtain IP after HA recovery - Set high restart priority for the VR.
This commit is contained in:
Rajani Karuturi 2017-04-22 21:10:26 +05:30 committed by GitHub
commit 6cba86dd5e
5 changed files with 155 additions and 8 deletions

View File

@ -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);
}

View File

@ -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<String, String> 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");
}
}

View File

@ -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<ClusterDasVmConfigInfo> 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

View File

@ -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<HostIpRouteEntry> entries = getHostIpRouteEntries();

View File

@ -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;