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):