Merge "VMware: Handle missing vmdk during volume detach"
This commit is contained in:
commit
65381d6a42
|
@ -15,6 +15,7 @@
|
|||
import contextlib
|
||||
|
||||
import mock
|
||||
from oslo_vmware import exceptions as oslo_vmw_exceptions
|
||||
|
||||
from nova.compute import vm_states
|
||||
from nova import context
|
||||
|
@ -322,3 +323,52 @@ class VMwareVolumeOpsTestCase(test.NoDBTestCase):
|
|||
attach_disk_to_vm.assert_called_once_with(
|
||||
volume_ref, instance, adapter_type, disk_type,
|
||||
vmdk_path=new_file_name)
|
||||
|
||||
@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_missing_vmdk(
|
||||
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
|
||||
|
||||
relocate_vmdk_volume.side_effect = [
|
||||
oslo_vmw_exceptions.FileNotFoundException, None]
|
||||
|
||||
instance = mock.sentinel.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_calls = [mock.call(volume_ref, rp, datastore, host),
|
||||
mock.call(volume_ref, rp, datastore, host)]
|
||||
self.assertEqual(relocate_calls, relocate_vmdk_volume.call_args_list)
|
||||
detach_disk_from_vm.assert_called_once_with(
|
||||
volume_ref, instance, original_device)
|
||||
attach_disk_to_vm.assert_called_once_with(
|
||||
volume_ref, instance, adapter_type, disk_type,
|
||||
vmdk_path=new_file_name)
|
||||
|
|
|
@ -19,11 +19,12 @@ Management class for Storage-related functions (attach, detach, etc).
|
|||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_vmware import exceptions as oslo_vmw_exceptions
|
||||
from oslo_vmware import vim_util as vutil
|
||||
|
||||
from nova.compute import vm_states
|
||||
from nova import exception
|
||||
from nova.i18n import _, _LI
|
||||
from nova.i18n import _, _LI, _LW
|
||||
from nova.virt.vmwareapi import constants
|
||||
from nova.virt.vmwareapi import vim_util
|
||||
from nova.virt.vmwareapi import vm_util
|
||||
|
@ -459,11 +460,29 @@ class VMwareVolumeOps(object):
|
|||
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, host)
|
||||
detached = False
|
||||
LOG.debug("Relocating volume's backing: %(backing)s to resource "
|
||||
"pool: %(rp)s, datastore: %(ds)s, host: %(host)s.",
|
||||
{'backing': volume_ref, 'rp': res_pool, 'ds': datastore,
|
||||
'host': host})
|
||||
try:
|
||||
self._relocate_vmdk_volume(volume_ref, res_pool, datastore, host)
|
||||
except oslo_vmw_exceptions.FileNotFoundException:
|
||||
# Volume's vmdk was moved; remove the device so that we can
|
||||
# relocate the volume.
|
||||
LOG.warn(_LW("Virtual disk: %s of volume's backing not found."),
|
||||
original_device_path, exc_info=True)
|
||||
LOG.debug("Removing disk device of volume's backing and "
|
||||
"reattempting relocate.")
|
||||
self.detach_disk_from_vm(volume_ref, instance, original_device)
|
||||
detached = True
|
||||
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,
|
||||
destroy_disk=True)
|
||||
# Volume's backing is relocated now; detach the old vmdk if not done
|
||||
# already.
|
||||
if not detached:
|
||||
self.detach_disk_from_vm(volume_ref, instance, original_device,
|
||||
destroy_disk=True)
|
||||
|
||||
# Attach the current volume to the volume_ref
|
||||
self.attach_disk_to_vm(volume_ref, instance,
|
||||
|
|
Loading…
Reference in New Issue