Merge "VMware: treat deletion exception with attached volumes"

This commit is contained in:
Jenkins
2015-08-18 00:03:14 +00:00
committed by Gerrit Code Review
2 changed files with 51 additions and 23 deletions
@@ -680,6 +680,25 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
connection_info, self.instance, 'fake-name')
mock_destroy.assert_called_once_with(self.instance, True)
@mock.patch.object(vmops.VMwareVMOps, 'power_off',
side_effect=vexc.ManagedObjectNotFoundException())
@mock.patch.object(vmops.VMwareVMOps, 'destroy')
def test_destroy_with_attached_volumes_missing(self,
mock_destroy,
mock_power_off):
self._create_vm()
connection_info = {'data': 'fake-data', 'serial': 'volume-fake-id'}
bdm = [{'connection_info': connection_info,
'disk_bus': 'fake-bus',
'device_name': 'fake-name',
'mount_device': '/dev/sdb'}]
bdi = {'block_device_mapping': bdm, 'root_device_name': '/dev/sda'}
self.assertNotEqual(vm_states.STOPPED, self.instance.vm_state)
self.conn.destroy(self.context, self.instance, self.network_info,
block_device_info=bdi)
mock_power_off.assert_called_once_with(self.instance)
mock_destroy.assert_called_once_with(self.instance, True)
@mock.patch.object(driver.VMwareVCDriver, 'detach_volume',
side_effect=exception.StorageError(reason='oh man'))
@mock.patch.object(vmops.VMwareVMOps, 'destroy')
+32 -23
View File
@@ -27,6 +27,7 @@ from oslo_log import versionutils
from oslo_serialization import jsonutils
from oslo_utils import excutils
from oslo_vmware import api
from oslo_vmware import exceptions as vexc
from oslo_vmware import pbm
from oslo_vmware import vim
from oslo_vmware import vim_util
@@ -573,6 +574,31 @@ class VMwareVCDriver(driver.ComputeDriver):
"""Reboot VM instance."""
self._vmops.reboot(instance, network_info, reboot_type)
def _detach_instance_volumes(self, instance, block_device_info):
# We need to detach attached volumes
block_device_mapping = driver.block_device_info_get_mapping(
block_device_info)
if block_device_mapping:
# Certain disk types, for example 'IDE' do not support hot
# plugging. Hence we need to power off the instance and update
# the instance state.
self._vmops.power_off(instance)
# TODO(garyk): update the volumeops to read the state form the
# VM instead of relying on a instance flag
instance.vm_state = vm_states.STOPPED
for disk in block_device_mapping:
connection_info = disk['connection_info']
try:
self.detach_volume(connection_info, instance,
disk.get('device_name'))
except Exception as e:
with excutils.save_and_reraise_exception():
LOG.error(_LE("Failed to detach %(device_name)s. "
"Exception: %(exc)s"),
{'device_name': disk.get('device_name'),
'exc': e},
instance=instance)
def destroy(self, context, instance, network_info, block_device_info=None,
destroy_disks=True, migrate_data=None):
"""Destroy VM instance."""
@@ -590,29 +616,12 @@ class VMwareVCDriver(driver.ComputeDriver):
# We need to detach attached volumes
if block_device_info is not None:
block_device_mapping = driver.block_device_info_get_mapping(
block_device_info)
if block_device_mapping:
# Certain disk types, for example 'IDE' do not support hot
# plugging. Hence we need to power off the instance and update
# the instance state.
self._vmops.power_off(instance)
# TODO(garyk): update the volumeops to read the state form the
# VM instead of relying on a instance flag
instance.vm_state = vm_states.STOPPED
for disk in block_device_mapping:
connection_info = disk['connection_info']
try:
self.detach_volume(connection_info, instance,
disk.get('device_name'))
except Exception as e:
with excutils.save_and_reraise_exception():
LOG.error(_LE("Failed to detach %(device_name)s. "
"Exception: %(exc)s"),
{'device_name': disk.get('device_name'),
'exc': e},
instance=instance)
try:
self._detach_instance_volumes(instance, block_device_info)
except vexc.ManagedObjectNotFoundException:
LOG.warning(_LW('Instance does not exists. Proceeding to '
'delete instance properties on datastore'),
instance=instance)
self._vmops.destroy(instance, destroy_disks)
def pause(self, instance):