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.
This commit is contained in:
David Mabry 2016-04-18 15:40:36 -05:00
parent 48ce763440
commit 0b7cc087f8
3 changed files with 135 additions and 4 deletions

View File

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

View File

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

View File

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