You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2016/11/23 09:30:54 UTC

[1/2] git commit: updated refs/heads/master to feaeed7

Repository: cloudstack
Updated Branches:
  refs/heads/master 97f9ef52a -> feaeed7b1


CLOUDSTACK-9379: Support nested virtualization at VM level on VMware Hypervisor


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/cebee7cb
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/cebee7cb
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/cebee7cb

Branch: refs/heads/master
Commit: cebee7cbda62eb7967b4dacaa3911e669cb05560
Parents: 4c15cfc
Author: nvazquez <ni...@gmail.com>
Authored: Mon May 9 17:06:02 2016 -0300
Committer: nvazquez <ni...@gmail.com>
Committed: Thu Nov 17 17:51:50 2016 -0300

----------------------------------------------------------------------
 .../com/cloud/hypervisor/guru/VMwareGuru.java   |  65 ++++++--
 .../vmware/resource/VmwareResource.java         |   2 +-
 .../cloud/hypervisor/guru/VMwareGuruTest.java   | 157 +++++++++++++++++++
 .../vmware/resource/VmwareResourceTest.java     |  56 +++++++
 server/src/com/cloud/configuration/Config.java  |   8 -
 .../smoke/test_nested_virtualization.py         | 152 ++++++++++++++++++
 6 files changed, 419 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cebee7cb/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
index 986000a..64ca406 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java
@@ -31,13 +31,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.framework.config.ConfigKey;
 import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.storage.command.CopyCommand;
 import org.apache.cloudstack.storage.command.DeleteCommand;
 import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.commons.lang.BooleanUtils;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.api.BackupSnapshotCommand;
@@ -57,7 +57,6 @@ import com.cloud.agent.api.to.DiskTO;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.cluster.ClusterManager;
-import com.cloud.configuration.Config;
 import com.cloud.exception.InsufficientAddressCapacityException;
 import com.cloud.host.Host;
 import com.cloud.host.HostVO;
@@ -127,8 +126,6 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
     @Inject
     private NetworkModel _networkMgr;
     @Inject
-    private ConfigurationDao _configDao;
-    @Inject
     private NicDao _nicDao;
     @Inject
     private PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
@@ -155,6 +152,12 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
         "Specify whether or not to reserve memory when not overprovisioning, In case of memory overprovisioning we will always reserve memory.", true,
         ConfigKey.Scope.Cluster, null);
 
+    protected ConfigKey<Boolean> VmwareEnableNestedVirtualization = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization", "Advanced", "false",
+            "When set to true this will enable nested virtualization when this is supported by the hypervisor", true, ConfigKey.Scope.Global, null);
+
+    protected ConfigKey<Boolean> VmwareEnableNestedVirtualizationPerVM = new ConfigKey<Boolean>(Boolean.class, "vmware.nested.virtualization.perVM", "Advanced", "false",
+            "When set to true this will enable nested virtualization per vm", true, ConfigKey.Scope.Global, null);
+
     @Override
     public HypervisorType getHypervisorType() {
         return HypervisorType.VMware;
@@ -306,13 +309,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
         // Don't do this if the virtual machine is one of the special types
         // Should only be done on user machines
         if (userVm) {
-            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);
-
-            }
+            configureNestedVirtualization(details, to);
         }
         // Determine the VM's OS description
         GuestOSVO guestOS = _guestOsDao.findByIdIncludingRemoved(vm.getVirtualMachine().getGuestOSId());
@@ -331,6 +328,50 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
         return to;
     }
 
+    /**
+     * Decide in which cases nested virtualization should be enabled based on (1){@code globalNestedV}, (2){@code globalNestedVPerVM}, (3){@code localNestedV}<br/>
+     * Nested virtualization should be enabled when one of this cases:
+     * <ul>
+     * <li>(1)=TRUE, (2)=TRUE, (3) is NULL (missing)</li>
+     * <li>(1)=TRUE, (2)=TRUE, (3)=TRUE</li>
+     * <li>(1)=TRUE, (2)=FALSE</li>
+     * <li>(1)=FALSE, (2)=TRUE, (3)=TRUE</li>
+     * </ul>
+     * In any other case, it shouldn't be enabled
+     * @param globalNestedV value of {@code 'vmware.nested.virtualization'} global config
+     * @param globalNestedVPerVM value of {@code 'vmware.nested.virtualization.perVM'} global config
+     * @param localNestedV value of {@code 'nestedVirtualizationFlag'} key in vm details if present, null if not present
+     * @return "true" for cases in which nested virtualization is enabled, "false" if not
+     */
+    protected Boolean shouldEnableNestedVirtualization(Boolean globalNestedV, Boolean globalNestedVPerVM, String localNestedV){
+        if (globalNestedV == null || globalNestedVPerVM == null) {
+            return false;
+        }
+        boolean globalNV = globalNestedV.booleanValue();
+        boolean globalNVPVM = globalNestedVPerVM.booleanValue();
+
+        if (globalNVPVM){
+            return (localNestedV == null && globalNV) || BooleanUtils.toBoolean(localNestedV);
+        }
+        return globalNV;
+    }
+
+    /**
+     * Adds {@code 'nestedVirtualizationFlag'} value to {@code details} due to if it should be enabled or not
+     * @param details vm details
+     * @param to vm to
+     */
+    protected void configureNestedVirtualization(Map<String, String> details, VirtualMachineTO to) {
+        Boolean globalNestedV = VmwareEnableNestedVirtualization.value();
+        Boolean globalNestedVPerVM = VmwareEnableNestedVirtualizationPerVM.value();
+        String localNestedV = details.get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG);
+
+        Boolean shouldEnableNestedVirtualization = shouldEnableNestedVirtualization(globalNestedV, globalNestedVPerVM, localNestedV);
+        s_logger.debug("Nested virtualization requested, adding flag to vm configuration");
+        details.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, Boolean.toString(shouldEnableNestedVirtualization));
+        to.setDetails(details);
+    }
+
     private long getClusterId(long vmId) {
         long clusterId;
         Long hostId;
@@ -525,7 +566,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru, Co
 
     @Override
     public ConfigKey<?>[] getConfigKeys() {
-        return new ConfigKey<?>[] {VmwareReserveCpu, VmwareReserveMemory};
+        return new ConfigKey<?>[] {VmwareReserveCpu, VmwareReserveMemory, VmwareEnableNestedVirtualization, VmwareEnableNestedVirtualizationPerVM};
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cebee7cb/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
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 522b8ae..9f38cae 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
@@ -2208,7 +2208,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
         return new Pair<String, String>(vmInternalCSName, vmNameOnVcenter);
     }
 
-    private static void configNestedHVSupport(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, VirtualMachineConfigSpec vmConfigSpec) throws Exception {
+    protected void configNestedHVSupport(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, VirtualMachineConfigSpec vmConfigSpec) throws Exception {
 
         VmwareContext context = vmMo.getContext();
         if ("true".equals(vmSpec.getDetails().get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG))) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cebee7cb/plugins/hypervisors/vmware/test/com/cloud/hypervisor/guru/VMwareGuruTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/guru/VMwareGuruTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/guru/VMwareGuruTest.java
new file mode 100755
index 0000000..77042fd
--- /dev/null
+++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/guru/VMwareGuruTest.java
@@ -0,0 +1,157 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.hypervisor.guru;
+
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.inOrder;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.support.AnnotationConfigContextLoader;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.vm.VmDetailConstants;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ConfigKey.class, VMwareGuru.class})
+@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
+public class VMwareGuruTest {
+
+    @Mock(name="VmwareEnableNestedVirtualization")
+    private ConfigKey<Boolean> vmwareNestedVirtualizationConfig;
+
+    @Mock(name="VmwareEnableNestedVirtualizationPerVM")
+    private ConfigKey<Boolean> vmwareNestedVirtualizationPerVmConfig;
+
+    @Spy
+    @InjectMocks
+    private VMwareGuru _guru = new VMwareGuru();
+
+    @Mock
+    VirtualMachineTO vmTO;
+
+    private Map<String,String> vmDetails = new HashMap<String, String>();
+
+    @Before
+    public void testSetUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    private void setConfigValues(Boolean globalNV, Boolean globalNVPVM, String localNV){
+        when(vmwareNestedVirtualizationConfig.value()).thenReturn(globalNV);
+        when(vmwareNestedVirtualizationPerVmConfig.value()).thenReturn(globalNVPVM);
+        if (localNV != null) {
+            vmDetails.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, localNV);
+        }
+    }
+
+    private void executeAndVerifyTest(Boolean globalNV, Boolean globalNVPVM, String localNV, Boolean expectedResult){
+        Boolean result = _guru.shouldEnableNestedVirtualization(globalNV, globalNVPVM, localNV);
+        assertEquals(expectedResult, result);
+    }
+
+    @Test
+    public void testConfigureNestedVirtualization(){
+        setConfigValues(true, true, null);
+        _guru.configureNestedVirtualization(vmDetails, vmTO);
+
+        InOrder inOrder = inOrder(_guru, vmTO);
+        inOrder.verify(_guru).shouldEnableNestedVirtualization(true, true, null);
+        inOrder.verify(vmTO).setDetails(vmDetails);
+
+        assertTrue(vmDetails.containsKey(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG));
+        assertEquals(Boolean.toString(true), vmDetails.get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG));
+
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVTrueGlobalNVPVMTrueLocalNVNull(){
+        executeAndVerifyTest(true, true, null, true);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVTrueGlobalNVPVMTrueLocalNVTrue(){
+        executeAndVerifyTest(true, true, "true", true);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVTrueGlobalNVPVMTrueLocalNVFalse(){
+        executeAndVerifyTest(true, true, "false", false);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVTrueGlobalNVPVMFalseLocalNVNull(){
+        executeAndVerifyTest(true, false, null, true);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVTrueGlobalNVPVMFalseLocalNVTrue(){
+        executeAndVerifyTest(true, false, "true", true);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVTrueGlobalNVPVMFalseLocalNVNFalse(){
+        executeAndVerifyTest(true, false, "false", true);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVFalseGlobalNVPVMTrueLocalNVNull(){
+        executeAndVerifyTest(false, true, null, false);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVFalseGlobalNVPVMTrueLocalNVTrue(){
+        executeAndVerifyTest(false, true, "true", true);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVFalseGlobalNVPVMTrueLocalNVFalse(){
+        executeAndVerifyTest(false, true, "false", false);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVFalseGlobalNVPVMFalseLocalNVNull(){
+        executeAndVerifyTest(false, false, null, false);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVFalseGlobalNVPVMFalseLocalNVTrue(){
+        executeAndVerifyTest(false, false, "true", false);
+    }
+
+    @Test
+    public void testEnableNestedVirtualizationCaseGlobalNVFalseGlobalNVPVMFalseLocalNVFalse(){
+        executeAndVerifyTest(false, false, "false", false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cebee7cb/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
index 6f411dc..744c93a 100644
--- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
+++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java
@@ -51,7 +51,9 @@ import org.powermock.api.mockito.PowerMockito;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
+import com.vmware.vim25.HostCapability;
 import com.vmware.vim25.ManagedObjectReference;
+import com.vmware.vim25.VimPortType;
 import com.vmware.vim25.VirtualDevice;
 import com.vmware.vim25.VirtualDeviceConfigSpec;
 import com.vmware.vim25.VirtualMachineConfigSpec;
@@ -65,9 +67,12 @@ import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.hypervisor.vmware.mo.DatacenterMO;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.vmware.mo.HostMO;
 import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
 import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
+import com.cloud.hypervisor.vmware.util.VmwareClient;
 import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.vm.VmDetailConstants;
 import com.cloud.storage.resource.VmwareStorageProcessor;
 import com.cloud.storage.resource.VmwareStorageSubsystemCommandHandler;
 import com.cloud.storage.resource.VmwareStorageProcessor.VmwareStorageProcessorConfigurableFields;
@@ -135,6 +140,20 @@ public class VmwareResourceTest {
     DataTO destDataTO;
     @Mock
     PrimaryDataStoreTO destDataStoreTO;
+    @Mock
+    HostMO host;
+    @Mock
+    ManagedObjectReference hostRef;
+    @Mock
+    ManagedObjectReference computeRef;
+    @Mock
+    ManagedObjectReference envRef;
+    @Mock
+    VmwareClient client;
+    @Mock
+    VimPortType vimService;
+    @Mock
+    HostCapability hostCapability;
 
     CopyCommand storageCmd;
     EnumMap<VmwareStorageProcessorConfigurableFields, Object> params = new EnumMap<VmwareStorageProcessorConfigurableFields,Object>(VmwareStorageProcessorConfigurableFields.class);
@@ -145,6 +164,8 @@ public class VmwareResourceTest {
     private static final long VIDEO_CARD_MEMORY_SIZE = 65536l;
     private static final Boolean FULL_CLONE_FLAG = true;
 
+    private Map<String,String> specsArray = new HashMap<String,String>();
+
     @Before
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -163,6 +184,17 @@ public class VmwareResourceTest {
         when(destDataTO.getDataStore()).thenReturn(destDataStoreTO);
         when(destDataStoreTO.isFullCloneFlag()).thenReturn(FULL_CLONE_FLAG);
         when(volume.getPath()).thenReturn(VOLUME_PATH);
+        when(vmSpec.getDetails()).thenReturn(specsArray);
+
+        when(vmMo.getContext()).thenReturn(context);
+        when(vmMo.getRunningHost()).thenReturn(host);
+        when(host.getMor()).thenReturn(hostRef);
+        when(context.getVimClient()).thenReturn(client);
+        when(client.getMoRefProp(hostRef, "parent")).thenReturn(computeRef);
+        when(client.getMoRefProp(computeRef, "environmentBrowser")).thenReturn(envRef);
+        when(context.getService()).thenReturn(vimService);
+        when(vimService.queryTargetCapabilities(envRef, hostRef)).thenReturn(hostCapability);
+        when(hostCapability.isNestedHVSupported()).thenReturn(true);
     }
 
     //Test successful scaling up the vm
@@ -348,4 +380,28 @@ public class VmwareResourceTest {
         VirtualMachineMO result = _resource.findVmOnDatacenter(context, hyperHost, volume);
         assertEquals(vmMo, result);
     }
+
+    @Test
+    public void testConfigNestedHVSupportFlagTrue() throws Exception{
+        specsArray.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, "true");
+        _resource.configNestedHVSupport(vmMo, vmSpec, vmConfigSpec);
+        verify(vmMo).getRunningHost();
+        verify(host).getMor();
+        verify(context, times(2)).getVimClient();
+        verify(client).getMoRefProp(hostRef, "parent");
+        verify(client).getMoRefProp(computeRef, "environmentBrowser");
+        verify(context).getService();
+        verify(vimService).queryTargetCapabilities(envRef, hostRef);
+        verify(hostCapability).isNestedHVSupported();
+
+        verify(vmConfigSpec).setNestedHVEnabled(true);
+    }
+
+    @Test
+    public void testConfigNestedHVSupportFlagFalse() throws Exception{
+        specsArray.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, "false");
+        _resource.configNestedHVSupport(vmMo, vmSpec, vmConfigSpec);
+        verify(vmMo, never()).getRunningHost();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cebee7cb/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index ed7f161..851b868 100644
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -1220,14 +1220,6 @@ public enum Config {
             "Specify whether or not to recycle hung worker VMs",
             null),
     VmwareHungWorkerTimeout("Advanced", ManagementServer.class, Long.class, "vmware.hung.wokervm.timeout", "7200", "Worker VM timeout in seconds", 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),
     VmwareVcenterSessionTimeout("Advanced", ManagementServer.class, Long.class, "vmware.vcenter.session.timeout", "1200", "VMware client timeout in seconds", null),
 
     // Midonet

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cebee7cb/test/integration/smoke/test_nested_virtualization.py
----------------------------------------------------------------------
diff --git a/test/integration/smoke/test_nested_virtualization.py b/test/integration/smoke/test_nested_virtualization.py
new file mode 100755
index 0000000..3b03f77
--- /dev/null
+++ b/test/integration/smoke/test_nested_virtualization.py
@@ -0,0 +1,152 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+""" Tests for Nested Virtualization
+"""
+#Import Local Modules
+from marvin.codes import FAILED
+from marvin.cloudstackTestCase import cloudstackTestCase
+from marvin.lib.utils import (cleanup_resources,
+                              get_hypervisor_type,
+                              get_process_status)
+from marvin.lib.base import (Account,
+                             ServiceOffering,
+                             NetworkOffering,
+                             Configurations,
+                             VirtualMachine,
+                             Network)
+from marvin.lib.common import (get_zone,
+                               get_domain,
+                               get_template)
+from nose.plugins.attrib import attr
+from marvin.sshClient import SshClient
+import logging
+
+class TestNestedVirtualization(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        testClient = super(TestNestedVirtualization, cls).getClsTestClient()
+        cls.apiclient = testClient.getApiClient()
+        cls.services = testClient.getParsedTestDataConfig()
+        
+        cls.logger = logging.getLogger('TestNestedVirtualization')
+        cls.stream_handler = logging.StreamHandler()
+        cls.logger.setLevel(logging.DEBUG)
+        cls.logger.addHandler(cls.stream_handler)
+
+        cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
+        cls.services['mode'] = cls.zone.networktype
+        cls.services["isolated_network"]["zoneid"] = cls.zone.id
+        cls.domain = get_domain(cls.apiclient)
+        cls.service_offering = ServiceOffering.create(
+            cls.apiclient,
+            cls.services["service_offerings"]["tiny"]
+        )
+        cls.account = Account.create(cls.apiclient, services=cls.services["account"])
+        cls.template = get_template(
+            cls.apiclient,
+            cls.zone.id,
+            cls.services["ostype"]
+        )
+        cls.hypervisor = get_hypervisor_type(cls.apiclient)
+        
+        cls.isolated_network_offering = NetworkOffering.create(
+                                                cls.apiclient,
+                                                cls.services["isolated_network_offering"])
+        # Enable Isolated Network offering
+        cls.isolated_network_offering.update(cls.apiclient, state='Enabled')
+        
+        if cls.template == FAILED:
+            assert False, "get_template() failed to return template with description %s" % cls.services["ostype"]
+            
+        cls.services["small"]["zoneid"] = cls.zone.id
+        cls.services["small"]["template"] = cls.template.id
+
+        cls.cleanup = [cls.account]
+
+    @attr(tags=["advanced"], required_hardware="true")
+    def test_nested_virtualization_vmware(self):
+        """Test nested virtualization on Vmware hypervisor"""
+        if self.hypervisor.lower() not in ["vmware"]:
+             self.skipTest("Skipping test because suitable hypervisor/host not present")
+             
+        # 1) Update nested virtualization configurations, if needed
+        configs = Configurations.list(self.apiclient, name="vmware.nested.virtualization")
+        rollback_nv = False
+        rollback_nv_per_vm = False
+        for conf in configs:
+            if (conf.name == "vmware.nested.virtualization" and conf.value == "false"):
+                config_update = Configurations.update(self.apiclient, "vmware.nested.virtualization", "true")
+                self.logger.debug("Updated global setting vmware.nested.virtualization to true")
+                rollback_nv = True
+            elif (conf.name == "vmware.nested.virtualization.perVM" and conf.value == "false"):
+                config_update = Configurations.update(self.apiclient, "vmware.nested.virtualization.perVM", "true")
+                self.logger.debug("Updated global setting vmware.nested.virtualization.perVM to true")
+                rollback_nv_per_vm = True
+                
+        # 2) Deploy a vm
+        virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.services["small"],
+            accountid=self.account.name,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            mode=self.services['mode']
+        )
+        self.assert_(virtual_machine is not None, "VM failed to deploy")
+        self.assert_(virtual_machine.state == 'Running', "VM is not running")
+        self.logger.debug("Deployed vm: %s" % virtual_machine.id)
+        
+        isolated_network = Network.create(
+            self.apiclient,
+            self.services["isolated_network"],
+            self.account.name,
+            self.account.domainid,
+            networkofferingid=self.isolated_network_offering.id)
+
+        virtual_machine.add_nic(self.apiclient, isolated_network.id)
+        
+        # 3) SSH into vm
+        ssh_client = virtual_machine.get_ssh_client()
+
+        if ssh_client:
+            # run ping test
+            result = ssh_client.execute("cat /proc/cpuinfo | grep flags")
+            self.logger.debug(result)
+        else:
+            self.fail("Failed to setup ssh connection to %s" % virtual_machine.public_ip)
+            
+        # 4) Revert configurations, if needed
+        if rollback_nv:
+            config_update = Configurations.update(self.apiclient, "vmware.nested.virtualization", "false")
+            self.logger.debug("Reverted global setting vmware.nested.virtualization back to false")
+        if rollback_nv_per_vm:
+            config_update = Configurations.update(self.apiclient, "vmware.nested.virtualization", "false")
+            self.logger.debug("Reverted global setting vmware.nested.virtualization.perVM back to false")
+            
+        #5) Check for CPU flags: vmx for Intel and svm for AMD indicates nested virtualization is enabled
+        self.assert_(result is not None, "Empty result for CPU flags")
+        res = str(result)
+        self.assertTrue('vmx' in res or 'svm' in res)
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            cleanup_resources(cls.apiclient, cls.cleanup)
+        except Exception, e:
+            raise Exception("Cleanup failed with %s" % e)
+    
\ No newline at end of file


[2/2] git commit: updated refs/heads/master to feaeed7

Posted by bh...@apache.org.
Merge pull request #1542 from nvazquez/nestedv

CLOUDSTACK-9379: Support nested virtualization at VM level on VMware Hypervisor## Introduction

[JIRA TICKET](https://issues.apache.org/jira/browse/CLOUDSTACK-9379)

It is desired to support nested virtualization at VM level for VMware hypervisor. Current behaviour supports enabling/desabling global nested virtualization by modifying global config `'vmware.nested.virtualization'`. It is wished to improve this feature, having control at VM level instead of a global control only.

A new global configuration is added, to enable/disable VM nested virtualization control: `'vmware.nested.virtualization.perVM'`. Default value=false

After a vm deployment or start command, vm params include `'nestedVirtualizationFlag'` key and its value is:
- true -> nested virtualization enabled
- false -> nested virtualization disabled

**We will determinate nested virtualization enabled/disabled by examining this 3 values:**
- **(1)** global configuration `'vmware.nested.virtualization'` value
- **(2)** global configuration `'vmware.nested.virtualization.perVM'` value
- **(3)** `'nestedVirtualizationFlag'` value in `user_vm_details` if present, `null` if not.

Using this 3 values, there are different use cases:
- **(1)** = TRUE, **(2)** = TRUE, **(3)** is null -> _ENABLED_
- **(1)** = TRUE, **(2)** = TRUE, **(3)** = TRUE -> _ENABLED_
- **(1)** = TRUE, **(2)** = TRUE, **(3)** = FALSE -> _DISABLED_
- **(1)** = TRUE, **(2)** = FALSE, **(3)** indifferent  -> _ENABLED_
- **(1)** = FALSE, **(2)** = TRUE, **(3)** is null -> _DISABLED_
- **(1)** = FALSE, **(2)** = TRUE, **(3)** = TRUE -> _ENABLED_
- **(1)** = FALSE, **(2)** = TRUE, **(3)** = FALSE -> _DISABLED_
- **(1)** = FALSE, **(2)** = FALSE, **(3)** indifferent -> _DISABLED_

* pr/1542:
  CLOUDSTACK-9379: Support nested virtualization at VM level on VMware Hypervisor

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/feaeed7b
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/feaeed7b
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/feaeed7b

Branch: refs/heads/master
Commit: feaeed7b1665c8851d7762ef95a37a5fc70756e3
Parents: 97f9ef5 cebee7c
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Wed Nov 23 14:59:35 2016 +0530
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Wed Nov 23 15:00:36 2016 +0530

----------------------------------------------------------------------
 .../com/cloud/hypervisor/guru/VMwareGuru.java   |  65 ++++++--
 .../vmware/resource/VmwareResource.java         |   2 +-
 .../cloud/hypervisor/guru/VMwareGuruTest.java   | 157 +++++++++++++++++++
 .../vmware/resource/VmwareResourceTest.java     |  56 +++++++
 server/src/com/cloud/configuration/Config.java  |   8 -
 .../smoke/test_nested_virtualization.py         | 152 ++++++++++++++++++
 6 files changed, 419 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/feaeed7b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------