mirror of https://github.com/apache/cloudstack.git
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:
parent
48ce763440
commit
0b7cc087f8
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Reference in New Issue