Merge "VMware: Factor out relocate_vm()"
This commit is contained in:
commit
e9a4f22f45
@ -1121,8 +1121,7 @@ class VMwareAPIVMTestCase(test.NoDBTestCase,
|
|||||||
self._check_vm_info(info, power_state.RUNNING)
|
self._check_vm_info(info, power_state.RUNNING)
|
||||||
self.assertTrue(self.exception)
|
self.assertTrue(self.exception)
|
||||||
|
|
||||||
@mock.patch('nova.virt.vmwareapi.volumeops.VMwareVolumeOps.'
|
@mock.patch.object(vm_util, 'relocate_vm')
|
||||||
'_relocate_vmdk_volume')
|
|
||||||
@mock.patch('nova.virt.vmwareapi.volumeops.VMwareVolumeOps.'
|
@mock.patch('nova.virt.vmwareapi.volumeops.VMwareVolumeOps.'
|
||||||
'attach_volume')
|
'attach_volume')
|
||||||
@mock.patch('nova.virt.vmwareapi.volumeops.VMwareVolumeOps.'
|
@mock.patch('nova.virt.vmwareapi.volumeops.VMwareVolumeOps.'
|
||||||
@ -1133,7 +1132,7 @@ class VMwareAPIVMTestCase(test.NoDBTestCase,
|
|||||||
mock_volume_in_mapping,
|
mock_volume_in_mapping,
|
||||||
mock_get_res_pool_of_vm,
|
mock_get_res_pool_of_vm,
|
||||||
mock_attach_volume,
|
mock_attach_volume,
|
||||||
mock_relocate_vmdk_volume,
|
mock_relocate_vm,
|
||||||
set_image_ref=True):
|
set_image_ref=True):
|
||||||
self._create_instance(set_image_ref=set_image_ref)
|
self._create_instance(set_image_ref=set_image_ref)
|
||||||
|
|
||||||
@ -1152,7 +1151,7 @@ class VMwareAPIVMTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
mock_info_get_mapping.assert_called_once_with(mock.ANY)
|
mock_info_get_mapping.assert_called_once_with(mock.ANY)
|
||||||
mock_get_res_pool_of_vm.assert_called_once_with(mock.ANY)
|
mock_get_res_pool_of_vm.assert_called_once_with(mock.ANY)
|
||||||
mock_relocate_vmdk_volume.assert_called_once_with(mock.ANY,
|
mock_relocate_vm.assert_called_once_with(mock.ANY, mock.ANY,
|
||||||
'fake_res_pool', mock.ANY)
|
'fake_res_pool', mock.ANY)
|
||||||
mock_attach_volume.assert_called_once_with(connection_info,
|
mock_attach_volume.assert_called_once_with(connection_info,
|
||||||
self.instance, constants.DEFAULT_ADAPTER_TYPE)
|
self.instance, constants.DEFAULT_ADAPTER_TYPE)
|
||||||
|
@ -494,9 +494,9 @@ class VMwareVolumeOpsTestCase(test.NoDBTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps,
|
@mock.patch.object(volumeops.VMwareVolumeOps,
|
||||||
'_get_vmdk_base_volume_device')
|
'_get_vmdk_base_volume_device')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_relocate_vmdk_volume')
|
@mock.patch.object(vm_util, 'relocate_vm')
|
||||||
def test_consolidate_vmdk_volume_with_no_relocate(
|
def test_consolidate_vmdk_volume_with_no_relocate(
|
||||||
self, relocate_vmdk_volume, get_vmdk_base_volume_device):
|
self, relocate_vm, get_vmdk_base_volume_device):
|
||||||
file_name = mock.sentinel.file_name
|
file_name = mock.sentinel.file_name
|
||||||
backing = mock.Mock(fileName=file_name)
|
backing = mock.Mock(fileName=file_name)
|
||||||
original_device = mock.Mock(backing=backing)
|
original_device = mock.Mock(backing=backing)
|
||||||
@ -511,18 +511,18 @@ class VMwareVolumeOpsTestCase(test.NoDBTestCase):
|
|||||||
device, volume_ref)
|
device, volume_ref)
|
||||||
|
|
||||||
get_vmdk_base_volume_device.assert_called_once_with(volume_ref)
|
get_vmdk_base_volume_device.assert_called_once_with(volume_ref)
|
||||||
self.assertFalse(relocate_vmdk_volume.called)
|
self.assertFalse(relocate_vm.called)
|
||||||
|
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps,
|
@mock.patch.object(volumeops.VMwareVolumeOps,
|
||||||
'_get_vmdk_base_volume_device')
|
'_get_vmdk_base_volume_device')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_relocate_vmdk_volume')
|
@mock.patch.object(vm_util, 'relocate_vm')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_host_of_vm')
|
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_host_of_vm')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_res_pool_of_host')
|
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_res_pool_of_host')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, 'detach_disk_from_vm')
|
@mock.patch.object(volumeops.VMwareVolumeOps, 'detach_disk_from_vm')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, 'attach_disk_to_vm')
|
@mock.patch.object(volumeops.VMwareVolumeOps, 'attach_disk_to_vm')
|
||||||
def test_consolidate_vmdk_volume_with_relocate(
|
def test_consolidate_vmdk_volume_with_relocate(
|
||||||
self, attach_disk_to_vm, detach_disk_from_vm, get_res_pool_of_host,
|
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):
|
get_host_of_vm, relocate_vm, get_vmdk_base_volume_device):
|
||||||
file_name = mock.sentinel.file_name
|
file_name = mock.sentinel.file_name
|
||||||
backing = mock.Mock(fileName=file_name)
|
backing = mock.Mock(fileName=file_name)
|
||||||
original_device = mock.Mock(backing=backing)
|
original_device = mock.Mock(backing=backing)
|
||||||
@ -551,7 +551,7 @@ class VMwareVolumeOpsTestCase(test.NoDBTestCase):
|
|||||||
disk_type)
|
disk_type)
|
||||||
|
|
||||||
get_vmdk_base_volume_device.assert_called_once_with(volume_ref)
|
get_vmdk_base_volume_device.assert_called_once_with(volume_ref)
|
||||||
relocate_vmdk_volume.assert_called_once_with(
|
relocate_vm.assert_called_once_with(self._session,
|
||||||
volume_ref, rp, datastore, host)
|
volume_ref, rp, datastore, host)
|
||||||
detach_disk_from_vm.assert_called_once_with(
|
detach_disk_from_vm.assert_called_once_with(
|
||||||
volume_ref, instance, original_device, destroy_disk=True)
|
volume_ref, instance, original_device, destroy_disk=True)
|
||||||
@ -561,14 +561,14 @@ class VMwareVolumeOpsTestCase(test.NoDBTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps,
|
@mock.patch.object(volumeops.VMwareVolumeOps,
|
||||||
'_get_vmdk_base_volume_device')
|
'_get_vmdk_base_volume_device')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_relocate_vmdk_volume')
|
@mock.patch.object(vm_util, 'relocate_vm')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_host_of_vm')
|
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_host_of_vm')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_res_pool_of_host')
|
@mock.patch.object(volumeops.VMwareVolumeOps, '_get_res_pool_of_host')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, 'detach_disk_from_vm')
|
@mock.patch.object(volumeops.VMwareVolumeOps, 'detach_disk_from_vm')
|
||||||
@mock.patch.object(volumeops.VMwareVolumeOps, 'attach_disk_to_vm')
|
@mock.patch.object(volumeops.VMwareVolumeOps, 'attach_disk_to_vm')
|
||||||
def test_consolidate_vmdk_volume_with_missing_vmdk(
|
def test_consolidate_vmdk_volume_with_missing_vmdk(
|
||||||
self, attach_disk_to_vm, detach_disk_from_vm, get_res_pool_of_host,
|
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):
|
get_host_of_vm, relocate_vm, get_vmdk_base_volume_device):
|
||||||
file_name = mock.sentinel.file_name
|
file_name = mock.sentinel.file_name
|
||||||
backing = mock.Mock(fileName=file_name)
|
backing = mock.Mock(fileName=file_name)
|
||||||
original_device = mock.Mock(backing=backing)
|
original_device = mock.Mock(backing=backing)
|
||||||
@ -584,7 +584,7 @@ class VMwareVolumeOpsTestCase(test.NoDBTestCase):
|
|||||||
rp = mock.sentinel.rp
|
rp = mock.sentinel.rp
|
||||||
get_res_pool_of_host.return_value = rp
|
get_res_pool_of_host.return_value = rp
|
||||||
|
|
||||||
relocate_vmdk_volume.side_effect = [
|
relocate_vm.side_effect = [
|
||||||
oslo_vmw_exceptions.FileNotFoundException, None]
|
oslo_vmw_exceptions.FileNotFoundException, None]
|
||||||
|
|
||||||
instance = mock.sentinel.instance
|
instance = mock.sentinel.instance
|
||||||
@ -599,9 +599,11 @@ class VMwareVolumeOpsTestCase(test.NoDBTestCase):
|
|||||||
|
|
||||||
get_vmdk_base_volume_device.assert_called_once_with(volume_ref)
|
get_vmdk_base_volume_device.assert_called_once_with(volume_ref)
|
||||||
|
|
||||||
relocate_calls = [mock.call(volume_ref, rp, datastore, host),
|
relocate_calls = [mock.call(self._session, volume_ref, rp, datastore,
|
||||||
mock.call(volume_ref, rp, datastore, host)]
|
host),
|
||||||
self.assertEqual(relocate_calls, relocate_vmdk_volume.call_args_list)
|
mock.call(self._session, volume_ref, rp, datastore,
|
||||||
|
host)]
|
||||||
|
self.assertEqual(relocate_calls, relocate_vm.call_args_list)
|
||||||
detach_disk_from_vm.assert_called_once_with(
|
detach_disk_from_vm.assert_called_once_with(
|
||||||
volume_ref, instance, original_device)
|
volume_ref, instance, original_device)
|
||||||
attach_disk_to_vm.assert_called_once_with(
|
attach_disk_to_vm.assert_called_once_with(
|
||||||
|
@ -933,17 +933,26 @@ def clone_vm_spec(client_factory, location,
|
|||||||
return clone_spec
|
return clone_spec
|
||||||
|
|
||||||
|
|
||||||
def relocate_vm_spec(client_factory, datastore=None, host=None,
|
def relocate_vm_spec(client_factory, res_pool=None, datastore=None, host=None,
|
||||||
disk_move_type="moveAllDiskBackingsAndAllowSharing"):
|
disk_move_type="moveAllDiskBackingsAndAllowSharing"):
|
||||||
"""Builds the VM relocation spec."""
|
|
||||||
rel_spec = client_factory.create('ns0:VirtualMachineRelocateSpec')
|
rel_spec = client_factory.create('ns0:VirtualMachineRelocateSpec')
|
||||||
rel_spec.datastore = datastore
|
rel_spec.datastore = datastore
|
||||||
|
rel_spec.host = host
|
||||||
|
rel_spec.pool = res_pool
|
||||||
rel_spec.diskMoveType = disk_move_type
|
rel_spec.diskMoveType = disk_move_type
|
||||||
if host:
|
|
||||||
rel_spec.host = host
|
|
||||||
return rel_spec
|
return rel_spec
|
||||||
|
|
||||||
|
|
||||||
|
def relocate_vm(session, vm_ref, res_pool=None, datastore=None, host=None,
|
||||||
|
disk_move_type="moveAllDiskBackingsAndAllowSharing"):
|
||||||
|
client_factory = session.vim.client.factory
|
||||||
|
rel_spec = relocate_vm_spec(client_factory, res_pool, datastore, host,
|
||||||
|
disk_move_type)
|
||||||
|
relocate_task = session._call_method(session.vim, "RelocateVM_Task",
|
||||||
|
vm_ref, spec=rel_spec)
|
||||||
|
session._wait_for_task(relocate_task)
|
||||||
|
|
||||||
|
|
||||||
def get_machine_id_change_spec(client_factory, machine_id_str):
|
def get_machine_id_change_spec(client_factory, machine_id_str):
|
||||||
"""Builds the machine id change config spec."""
|
"""Builds the machine id change config spec."""
|
||||||
virtual_machine_config_spec = client_factory.create(
|
virtual_machine_config_spec = client_factory.create(
|
||||||
|
@ -385,22 +385,6 @@ class VMwareVolumeOps(object):
|
|||||||
else:
|
else:
|
||||||
raise exception.VolumeDriverNotFound(driver_type=driver_type)
|
raise exception.VolumeDriverNotFound(driver_type=driver_type)
|
||||||
|
|
||||||
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,
|
|
||||||
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_host_of_vm(self, vm_ref):
|
def _get_host_of_vm(self, vm_ref):
|
||||||
"""Get the ESX host of given VM."""
|
"""Get the ESX host of given VM."""
|
||||||
return self._session._call_method(vutil, 'get_object_property',
|
return self._session._call_method(vutil, 'get_object_property',
|
||||||
@ -476,7 +460,8 @@ class VMwareVolumeOps(object):
|
|||||||
{'backing': volume_ref, 'rp': res_pool, 'ds': datastore,
|
{'backing': volume_ref, 'rp': res_pool, 'ds': datastore,
|
||||||
'host': host})
|
'host': host})
|
||||||
try:
|
try:
|
||||||
self._relocate_vmdk_volume(volume_ref, res_pool, datastore, host)
|
vm_util.relocate_vm(self._session, volume_ref, res_pool, datastore,
|
||||||
|
host)
|
||||||
except oslo_vmw_exceptions.FileNotFoundException:
|
except oslo_vmw_exceptions.FileNotFoundException:
|
||||||
# Volume's vmdk was moved; remove the device so that we can
|
# Volume's vmdk was moved; remove the device so that we can
|
||||||
# relocate the volume.
|
# relocate the volume.
|
||||||
@ -486,7 +471,8 @@ class VMwareVolumeOps(object):
|
|||||||
"reattempting relocate.")
|
"reattempting relocate.")
|
||||||
self.detach_disk_from_vm(volume_ref, instance, original_device)
|
self.detach_disk_from_vm(volume_ref, instance, original_device)
|
||||||
detached = True
|
detached = True
|
||||||
self._relocate_vmdk_volume(volume_ref, res_pool, datastore, host)
|
vm_util.relocate_vm(self._session, volume_ref, res_pool, datastore,
|
||||||
|
host)
|
||||||
|
|
||||||
# Volume's backing is relocated now; detach the old vmdk if not done
|
# Volume's backing is relocated now; detach the old vmdk if not done
|
||||||
# already.
|
# already.
|
||||||
@ -604,6 +590,6 @@ class VMwareVolumeOps(object):
|
|||||||
# Pick the resource pool on which the instance resides. Move the
|
# Pick the resource pool on which the instance resides. Move the
|
||||||
# volume to the datastore of the instance.
|
# volume to the datastore of the instance.
|
||||||
res_pool = self._get_res_pool_of_vm(vm_ref)
|
res_pool = self._get_res_pool_of_vm(vm_ref)
|
||||||
self._relocate_vmdk_volume(volume_ref, res_pool, datastore)
|
vm_util.relocate_vm(self._session, volume_ref, res_pool, datastore)
|
||||||
|
|
||||||
self.attach_volume(connection_info, instance, adapter_type)
|
self.attach_volume(connection_info, instance, adapter_type)
|
||||||
|
Loading…
Reference in New Issue
Block a user