Summary: Add support for nested hypervisors to the VmWare resource.

Add a flag VmDetailConstants.NESTED_VIRTUALIZATION_FLAG
Add an advanced config uption VmwareEnableNestedVirtualization

Depending on the settings of the flags and the capabilities of the target hypervisor the nested virtualization option will be set on guest VMs. It's a global setting intended only for developers to support cloud-in-a-cloud deployments.
This commit is contained in:
Hugo Trippaers 2013-04-12 12:54:57 +02:00
parent c0419791ed
commit accfccd83e
4 changed files with 38 additions and 1 deletions

View File

@ -20,4 +20,5 @@ public interface VmDetailConstants {
public static final String KEYBOARD = "keyboard"; public static final String KEYBOARD = "keyboard";
public static final String NIC_ADAPTER = "nicAdapter"; public static final String NIC_ADAPTER = "nicAdapter";
public static final String ROOK_DISK_CONTROLLER = "rootDiskController"; public static final String ROOK_DISK_CONTROLLER = "rootDiskController";
public static final String NESTED_VIRTUALIZATION_FLAG = "nestedVirtualizationFlag";
} }

View File

@ -27,6 +27,7 @@ import java.util.Map;
import javax.ejb.Local; import javax.ejb.Local;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -40,6 +41,8 @@ import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.cluster.ClusterManager; import com.cloud.cluster.ClusterManager;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
@ -84,6 +87,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
@Inject VmwareManager _vmwareMgr; @Inject VmwareManager _vmwareMgr;
@Inject SecondaryStorageVmManager _secStorageMgr; @Inject SecondaryStorageVmManager _secStorageMgr;
@Inject NetworkModel _networkMgr; @Inject NetworkModel _networkMgr;
@Inject ConfigurationDao _configDao;
protected VMwareGuru() { protected VMwareGuru() {
super(); super();
@ -212,8 +216,21 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
sbMacSequence.deleteCharAt(sbMacSequence.length() - 1); sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
String bootArgs = to.getBootArgs(); String bootArgs = to.getBootArgs();
to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString()); to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
}
// Don't do this if the virtual machine is one of the special types
// Should only be done on user machines
if(!(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO
|| vm.getVirtualMachine() instanceof SecondaryStorageVmVO)) {
String nestedVirt = _configDao.getValue(Config.VmwareEnableNestedVirtualization.key());
if (nestedVirt != null) {
s_logger.debug("Nested virtualization requested, adding flag to vm configuration");
details.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, nestedVirt);
to.setDetails(details);
}
} }
// Determine the VM's OS description // Determine the VM's OS description
GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
to.setOs(guestOS.getDisplayName()); to.setOs(guestOS.getDisplayName());

View File

@ -232,6 +232,7 @@ import com.vmware.vim25.ClusterDasConfigInfo;
import com.vmware.vim25.ComputeResourceSummary; import com.vmware.vim25.ComputeResourceSummary;
import com.vmware.vim25.DatastoreSummary; import com.vmware.vim25.DatastoreSummary;
import com.vmware.vim25.DynamicProperty; import com.vmware.vim25.DynamicProperty;
import com.vmware.vim25.HostCapability;
import com.vmware.vim25.HostFirewallInfo; import com.vmware.vim25.HostFirewallInfo;
import com.vmware.vim25.HostFirewallRuleset; import com.vmware.vim25.HostFirewallRuleset;
import com.vmware.vim25.HostNetworkTrafficShapingPolicy; import com.vmware.vim25.HostNetworkTrafficShapingPolicy;
@ -2147,6 +2148,23 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(),
vmSpec.getMinSpeed(),(int) (vmSpec.getMaxRam()/(1024*1024)), ramMb, vmSpec.getMinSpeed(),(int) (vmSpec.getMaxRam()/(1024*1024)), ramMb,
translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), vmSpec.getLimitCpuUse()); translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), vmSpec.getLimitCpuUse());
if ("true".equals(vmSpec.getDetails().get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG))) {
s_logger.debug("Nested Virtualization enabled in configuration, checking hypervisor capability");
ManagedObjectReference hostMor = vmMo.getRunningHost().getMor();
ManagedObjectReference computeMor = context.getVimClient().getMoRefProp(hostMor, "parent");
ManagedObjectReference environmentBrowser =
context.getVimClient().getMoRefProp(computeMor, "environmentBrowser");
HostCapability hostCapability = context.getService().queryTargetCapabilities(environmentBrowser, hostMor);
if (hostCapability.isNestedHVSupported()) {
s_logger.debug("Hypervisor supports nested virtualization, enabling for VM " + vmSpec.getName());
vmConfigSpec.setNestedHVEnabled(true);
}
else {
s_logger.warn("Hypervisor doesn't support nested virtualization, unable to set config for VM " +vmSpec.getName());
vmConfigSpec.setNestedHVEnabled(false);
}
}
VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices]; VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices];
int i = 0; int i = 0;

View File

@ -276,6 +276,7 @@ public enum Config {
VmwareRootDiskControllerType("Advanced", ManagementServer.class, String.class, "vmware.root.disk.controller", "ide", "Specify the default disk controller for root volumes, valid values are scsi, ide", null), VmwareRootDiskControllerType("Advanced", ManagementServer.class, String.class, "vmware.root.disk.controller", "ide", "Specify the default disk controller for root volumes, valid values are scsi, ide", null),
VmwareSystemVmNicDeviceType("Advanced", ManagementServer.class, String.class, "vmware.systemvm.nic.device.type", "E1000", "Specify the default network device type for system VMs, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3", null), VmwareSystemVmNicDeviceType("Advanced", ManagementServer.class, String.class, "vmware.systemvm.nic.device.type", "E1000", "Specify the default network device type for system VMs, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3", null),
VmwareRecycleHungWorker("Advanced", ManagementServer.class, Boolean.class, "vmware.recycle.hung.wokervm", "false", "Specify whether or not to recycle hung worker VMs", null), VmwareRecycleHungWorker("Advanced", ManagementServer.class, Boolean.class, "vmware.recycle.hung.wokervm", "false", "Specify whether or not to recycle hung worker VMs", null),
VmwareEnableNestedVirtualization("Advanced", ManagementServer.class, Boolean.class, "vmware.nested.virtualization", "false", "When set to true this will enable nested virtualization when this is supported by the hypervisor", null),
// Midonet // Midonet
MidoNetAPIServerAddress("Network", ManagementServer.class, String.class, "midonet.apiserver.address", "http://localhost:8081", "Specify the address at which the Midonet API server can be contacted (if using Midonet)", null), MidoNetAPIServerAddress("Network", ManagementServer.class, String.class, "midonet.apiserver.address", "http://localhost:8081", "Specify the address at which the Midonet API server can be contacted (if using Midonet)", null),