Merge "VMware: Fix volume relocate during detach"
This commit is contained in:
commit
e9a21ffda3
|
@ -255,3 +255,68 @@ class VMwareVolumeOpsTestCase(test.NoDBTestCase):
|
|||
constants.ADAPTER_TYPE_LSILOGICSAS,
|
||||
constants.ADAPTER_TYPE_PARAVIRTUAL):
|
||||
self._test_attach_volume_iscsi(adapter_type)
|
||||
|
||||
@mock.patch.object(volumeops.VMwareVolumeOps,
|
||||
'_get_vmdk_base_volume_device')
|
||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_relocate_vmdk_volume')
|
||||
def test_consolidate_vmdk_volume_with_no_relocate(
|
||||
self, relocate_vmdk_volume, get_vmdk_base_volume_device):
|
||||
file_name = mock.sentinel.file_name
|
||||
backing = mock.Mock(fileName=file_name)
|
||||
original_device = mock.Mock(backing=backing)
|
||||
get_vmdk_base_volume_device.return_value = original_device
|
||||
|
||||
device = mock.Mock(backing=backing)
|
||||
|
||||
volume_ref = mock.sentinel.volume_ref
|
||||
vm_ref = mock.sentinel.vm_ref
|
||||
|
||||
self._volumeops._consolidate_vmdk_volume(self._instance, vm_ref,
|
||||
device, volume_ref)
|
||||
|
||||
get_vmdk_base_volume_device.assert_called_once_with(volume_ref)
|
||||
self.assertFalse(relocate_vmdk_volume.called)
|
||||
|
||||
@mock.patch.object(volumeops.VMwareVolumeOps,
|
||||
'_get_vmdk_base_volume_device')
|
||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_relocate_vmdk_volume')
|
||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_host_of_vm')
|
||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_res_pool_of_host')
|
||||
@mock.patch.object(volumeops.VMwareVolumeOps, 'detach_disk_from_vm')
|
||||
@mock.patch.object(volumeops.VMwareVolumeOps, 'attach_disk_to_vm')
|
||||
def test_consolidate_vmdk_volume_with_relocate(
|
||||
self, attach_disk_to_vm, detach_disk_from_vm, get_res_pool_of_host,
|
||||
get_host_of_vm, relocate_vmdk_volume, get_vmdk_base_volume_device):
|
||||
file_name = mock.sentinel.file_name
|
||||
backing = mock.Mock(fileName=file_name)
|
||||
original_device = mock.Mock(backing=backing)
|
||||
get_vmdk_base_volume_device.return_value = original_device
|
||||
|
||||
new_file_name = mock.sentinel.new_file_name
|
||||
datastore = mock.sentinel.datastore
|
||||
new_backing = mock.Mock(fileName=new_file_name, datastore=datastore)
|
||||
device = mock.Mock(backing=new_backing)
|
||||
|
||||
host = mock.sentinel.host
|
||||
get_host_of_vm.return_value = host
|
||||
rp = mock.sentinel.rp
|
||||
get_res_pool_of_host.return_value = rp
|
||||
|
||||
instance = self._instance
|
||||
volume_ref = mock.sentinel.volume_ref
|
||||
vm_ref = mock.sentinel.vm_ref
|
||||
adapter_type = constants.ADAPTER_TYPE_BUSLOGIC
|
||||
disk_type = constants.DISK_TYPE_EAGER_ZEROED_THICK
|
||||
|
||||
self._volumeops._consolidate_vmdk_volume(instance, vm_ref, device,
|
||||
volume_ref, adapter_type,
|
||||
disk_type)
|
||||
|
||||
get_vmdk_base_volume_device.assert_called_once_with(volume_ref)
|
||||
relocate_vmdk_volume.assert_called_once_with(
|
||||
volume_ref, rp, datastore, host)
|
||||
detach_disk_from_vm.assert_called_once_with(
|
||||
volume_ref, instance, original_device, destroy_disk=True)
|
||||
attach_disk_to_vm.assert_called_once_with(
|
||||
volume_ref, instance, adapter_type, disk_type,
|
||||
vmdk_path=new_file_name)
|
||||
|
|
|
@ -374,26 +374,30 @@ class VMwareVolumeOps(object):
|
|||
else:
|
||||
raise exception.VolumeDriverNotFound(driver_type=driver_type)
|
||||
|
||||
def _relocate_vmdk_volume(self, volume_ref, res_pool, datastore):
|
||||
def _relocate_vmdk_volume(self, volume_ref, res_pool, datastore,
|
||||
host=None):
|
||||
"""Relocate the volume.
|
||||
|
||||
The move type will be moveAllDiskBackingsAndAllowSharing.
|
||||
"""
|
||||
client_factory = self._session.vim.client.factory
|
||||
spec = vm_util.relocate_vm_spec(client_factory,
|
||||
datastore=datastore)
|
||||
datastore=datastore,
|
||||
host=host)
|
||||
spec.pool = res_pool
|
||||
task = self._session._call_method(self._session.vim,
|
||||
"RelocateVM_Task", volume_ref,
|
||||
spec=spec)
|
||||
self._session._wait_for_task(task)
|
||||
|
||||
def _get_res_pool_of_vm(self, vm_ref):
|
||||
"""Get resource pool to which the VM belongs."""
|
||||
# Get the host, the VM belongs to
|
||||
host = self._session._call_method(vim_util, 'get_dynamic_property',
|
||||
def _get_host_of_vm(self, vm_ref):
|
||||
"""Get the ESX host of given VM."""
|
||||
return self._session._call_method(vim_util, 'get_dynamic_property',
|
||||
vm_ref, 'VirtualMachine',
|
||||
'runtime').host
|
||||
|
||||
def _get_res_pool_of_host(self, host):
|
||||
"""Get the resource pool of given host's cluster."""
|
||||
# Get the compute resource, the host belongs to
|
||||
compute_res = self._session._call_method(vim_util,
|
||||
'get_dynamic_property',
|
||||
|
@ -404,6 +408,13 @@ class VMwareVolumeOps(object):
|
|||
compute_res, compute_res._type,
|
||||
'resourcePool')
|
||||
|
||||
def _get_res_pool_of_vm(self, vm_ref):
|
||||
"""Get resource pool to which the VM belongs."""
|
||||
# Get the host, the VM belongs to
|
||||
host = self._get_host_of_vm(vm_ref)
|
||||
# Get the resource pool of host's cluster.
|
||||
return self._get_res_pool_of_host(host)
|
||||
|
||||
def _consolidate_vmdk_volume(self, instance, vm_ref, device, volume_ref,
|
||||
adapter_type=None, disk_type=None):
|
||||
"""Consolidate volume backing VMDK files if needed.
|
||||
|
@ -443,11 +454,12 @@ class VMwareVolumeOps(object):
|
|||
LOG.info(_LI("The volume's backing has been relocated to %s. Need to "
|
||||
"consolidate backing disk file."), current_device_path)
|
||||
|
||||
# Pick the resource pool on which the instance resides.
|
||||
# Pick the host and resource pool on which the instance resides.
|
||||
# Move the volume to the datastore where the new VMDK file is present.
|
||||
res_pool = self._get_res_pool_of_vm(vm_ref)
|
||||
host = self._get_host_of_vm(vm_ref)
|
||||
res_pool = self._get_res_pool_of_host(host)
|
||||
datastore = device.backing.datastore
|
||||
self._relocate_vmdk_volume(volume_ref, res_pool, datastore)
|
||||
self._relocate_vmdk_volume(volume_ref, res_pool, datastore, host)
|
||||
|
||||
# Delete the original disk from the volume_ref
|
||||
self.detach_disk_from_vm(volume_ref, instance, original_device,
|
||||
|
|
Loading…
Reference in New Issue