You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by sw...@apache.org on 2016/04/28 22:04:50 UTC

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

Let hypervisor type KVM and Simulator detach root volumes.
Updated test_volumes.py to include a test for detaching and reattaching a root volume from a vm. I also had to update base.py to allow attach_volume to have the parameter deviceid to be passed as needed.


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

Branch: refs/heads/master
Commit: 0b7cc087f81ede19ac9daaaf63aa73f2a2ab789d
Parents: 48ce763
Author: David Mabry <dm...@ena.com>
Authored: Mon Apr 18 15:40:36 2016 -0500
Committer: David Mabry <dm...@ena.com>
Committed: Mon Apr 18 15:40:36 2016 -0500

----------------------------------------------------------------------
 .../com/cloud/storage/VolumeApiServiceImpl.java |   4 +-
 test/integration/component/test_volumes.py      | 129 ++++++++++++++++++-
 tools/marvin/marvin/lib/base.py                 |   6 +-
 3 files changed, 135 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b7cc087/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 5a53f9c..6a59f54 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -1744,8 +1744,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
     }
 
     private void validateRootVolumeDetachAttach(VolumeVO volume, UserVmVO vm) {
-        if (!(vm.getHypervisorType() == HypervisorType.XenServer || vm.getHypervisorType() == HypervisorType.VMware)) {
-            throw new InvalidParameterValueException("Root volume detach is allowed for hypervisor type " + HypervisorType.XenServer + " only");
+        if (!(vm.getHypervisorType() == HypervisorType.XenServer || vm.getHypervisorType() == HypervisorType.VMware || vm.getHypervisorType() == HypervisorType.KVM || vm.getHypervisorType() == HypervisorType.Simulator)) {
+            throw new InvalidParameterValueException("Root volume detach is not supported for hypervisor type " + vm.getHypervisorType() );
         }
         if (!(vm.getState() == State.Stopped) || (vm.getState() == State.Destroyed)) {
             throw new InvalidParameterValueException("Root volume detach can happen only when vm is in states: " + State.Stopped.toString() + " or " + State.Destroyed.toString());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b7cc087/test/integration/component/test_volumes.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_volumes.py b/test/integration/component/test_volumes.py
index 12c8f9d..941e225 100644
--- a/test/integration/component/test_volumes.py
+++ b/test/integration/component/test_volumes.py
@@ -603,7 +603,134 @@ class TestAttachDetachVolume(cloudstackTestCase):
                 "Check the state of VM"
             )
         except Exception as e:
-            self.fail("Exception occuered: %s" % e)
+            self.fail("Exception occurred: %s" % e)
+        return
+    
+    @attr(tags=["advanced", "advancedns"])
+    def test_02_root_volume_attach_detach(self):
+        """Test Root Volume attach/detach to VM
+        """
+
+        # Validate the following
+        # 1. Deploy a VM
+        # 2. Check for root volume
+        # 3. Stop VM
+        # 4. Detach root volume
+        # 5. Verify root volume detached
+        # 6. Attach root volume
+        # 7. Start VM
+        
+        try:
+            # Check for root volume
+            root_volume_response = Volume.list(
+                self.apiclient,
+                virtualmachineid=self.virtual_machine.id,
+                type='ROOT',
+                listall=True
+            )
+            self.assertNotEqual(
+                root_volume_response,
+                None,
+                "Check if root volume exists in ListVolumes"
+            )
+            self.assertEqual(
+                isinstance(root_volume_response, list),
+                True,
+                "Check list volumes response for valid list"
+            )
+            # Grab the root volume for later use
+            root_volume = root_volume_response[0]
+            
+            # Stop VM
+            self.debug("Stopping the VM: %s" % self.virtual_machine.id)
+            self.virtual_machine.stop(self.apiclient)
+            
+            # Ensure VM is stopped before detaching the root volume
+            time.sleep(self.services["sleep"])
+
+            vm_response = VirtualMachine.list(
+                self.apiclient,
+                id=self.virtual_machine.id,
+            )
+            vm = vm_response[0]
+            self.assertEqual(
+                vm.state,
+                'Stopped',
+                "Check the state of VM"
+            )
+            
+            # Detach root volume from VM
+            self.virtual_machine.detach_volume(
+                self.apiclient,
+                root_volume
+            )
+            
+            # Verify that root disk is gone
+            no_root_volume_response = Volume.list(
+                self.apiclient,
+                virtualmachineid=self.virtual_machine.id,
+                type='ROOT',
+                listall=True
+            )
+            self.assertEqual(
+                no_root_volume_response,
+                None,
+                "Check if root volume exists in ListVolumes"
+            )
+            
+            # Attach root volume to VM
+            self.virtual_machine.attach_volume(
+                self.apiclient,
+                root_volume,
+                0
+            )
+            
+            # Check for root volume
+            new_root_volume_response = Volume.list(
+                self.apiclient,
+                virtualmachineid=self.virtual_machine.id,
+                type='ROOT',
+                listall=True
+            )
+            self.assertNotEqual(
+                new_root_volume_response,
+                None,
+                "Check if root volume exists in ListVolumes"
+            )
+            self.assertEqual(
+                isinstance(new_root_volume_response, list),
+                True,
+                "Check list volumes response for valid list"
+            )
+            
+            # Start VM
+            self.virtual_machine.start(self.apiclient)
+            # Sleep to ensure that VM is in ready state
+            time.sleep(self.services["sleep"])
+
+            vm_response = VirtualMachine.list(
+                self.apiclient,
+                id=self.virtual_machine.id,
+            )
+            # Verify VM response to check whether VM deployment was successful
+            self.assertEqual(
+                isinstance(vm_response, list),
+                True,
+                "Check list VM response for valid list"
+            )
+            self.assertNotEqual(
+                len(vm_response),
+                0,
+                "Check VMs available in List VMs response"
+            )
+            vm = vm_response[0]
+            self.assertEqual(
+                vm.state,
+                'Running',
+                "Check the state of VM"
+            )
+        except Exception as e:
+            self.fail("Exception occurred: %s" % e)
         return
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b7cc087/tools/marvin/marvin/lib/base.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index 4e04ba8..5d81e5f 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -667,11 +667,15 @@ class VirtualMachine:
             })
         apiclient.migrateVirtualMachineWithVolume(cmd)
 
-    def attach_volume(self, apiclient, volume):
+    def attach_volume(self, apiclient, volume, deviceid=None):
         """Attach volume to instance"""
         cmd = attachVolume.attachVolumeCmd()
         cmd.id = volume.id
         cmd.virtualmachineid = self.id
+
+        if deviceid is not None:
+            cmd.deviceid = deviceid
+
         return apiclient.attachVolume(cmd)
 
     def detach_volume(self, apiclient, volume):