Merge "Ensure instance files are deleted when using multiple CSVs" into stable/ocata
This commit is contained in:
commit
cef16d8db8
|
@ -740,7 +740,7 @@ class VMOps(object):
|
|||
self._pathutils.remove(configdrive_path)
|
||||
|
||||
@serialconsoleops.instance_synchronized
|
||||
def _delete_disk_files(self, instance_name):
|
||||
def _delete_disk_files(self, instance_name, instance_path=None):
|
||||
# We want to avoid the situation in which serial console workers
|
||||
# are started while we perform this operation, preventing us from
|
||||
# deleting the instance log files (bug #1556189). This can happen
|
||||
|
@ -748,14 +748,23 @@ class VMOps(object):
|
|||
#
|
||||
# The unsynchronized method is being used to avoid a deadlock.
|
||||
self._serial_console_ops.stop_console_handler_unsync(instance_name)
|
||||
self._pathutils.get_instance_dir(instance_name,
|
||||
create_dir=False,
|
||||
remove_dir=True)
|
||||
|
||||
# This may be a 'non-default' location.
|
||||
if not instance_path:
|
||||
instance_path = self._pathutils.get_instance_dir(instance_name)
|
||||
|
||||
self._pathutils.check_remove_dir(instance_path)
|
||||
|
||||
def destroy(self, instance, network_info=None, block_device_info=None,
|
||||
destroy_disks=True):
|
||||
instance_name = instance.name
|
||||
LOG.info(_LI("Got request to destroy instance"), instance=instance)
|
||||
|
||||
# Get the instance folder before destroying it. In some cases,
|
||||
# we won't be able to retrieve it otherwise.
|
||||
instance_path = self._pathutils.get_instance_dir(instance.name,
|
||||
create_dir=False)
|
||||
|
||||
try:
|
||||
if self._vmutils.vm_exists(instance_name):
|
||||
|
||||
|
@ -770,7 +779,7 @@ class VMOps(object):
|
|||
LOG.debug("Instance not found", instance=instance)
|
||||
|
||||
if destroy_disks:
|
||||
self._delete_disk_files(instance_name)
|
||||
self._delete_disk_files(instance_name, instance_path)
|
||||
except Exception:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.exception(_LE('Failed to destroy instance: %s'),
|
||||
|
|
|
@ -76,6 +76,7 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
|||
self._vmops._serial_console_ops = mock.MagicMock()
|
||||
self._vmops._block_dev_man = mock.MagicMock()
|
||||
self._vmops._vif_driver = mock.MagicMock()
|
||||
self._pathutils = self._vmops._pathutils
|
||||
|
||||
def test_list_instances(self):
|
||||
mock_instance = mock.MagicMock()
|
||||
|
@ -1139,15 +1140,27 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
|||
self._vmops._pathutils.remove.assert_called_once_with(
|
||||
mock.sentinel.configdrive_path)
|
||||
|
||||
def test_delete_disk_files(self):
|
||||
@ddt.data(None, mock.sentinel.instance_path)
|
||||
def test_delete_disk_files(self, passed_instance_path):
|
||||
mock_instance = fake_instance.fake_instance_obj(self.context)
|
||||
self._vmops._delete_disk_files(mock_instance.name)
|
||||
self._vmops._delete_disk_files(mock_instance.name,
|
||||
passed_instance_path)
|
||||
|
||||
stop_console_handler = (
|
||||
self._vmops._serial_console_ops.stop_console_handler_unsync)
|
||||
stop_console_handler.assert_called_once_with(mock_instance.name)
|
||||
self._vmops._pathutils.get_instance_dir.assert_called_once_with(
|
||||
mock_instance.name, create_dir=False, remove_dir=True)
|
||||
|
||||
if passed_instance_path:
|
||||
self.assertFalse(self._vmops._pathutils.get_instance_dir.called)
|
||||
else:
|
||||
self._pathutils.get_instance_dir.assert_called_once_with(
|
||||
mock_instance.name)
|
||||
|
||||
exp_inst_path = (passed_instance_path or
|
||||
self._pathutils.get_instance_dir.return_value)
|
||||
|
||||
self._pathutils.check_remove_dir.assert_called_once_with(
|
||||
exp_inst_path)
|
||||
|
||||
@mock.patch('hyperv.nova.volumeops.VolumeOps.disconnect_volumes')
|
||||
@mock.patch('hyperv.nova.vmops.VMOps._delete_disk_files')
|
||||
|
@ -1162,6 +1175,9 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
|||
block_device_info=mock.sentinel.FAKE_BD_INFO,
|
||||
network_info=mock.sentinel.fake_network_info)
|
||||
|
||||
self._pathutils.get_instance_dir.assert_called_once_with(
|
||||
mock_instance.name,
|
||||
create_dir=False)
|
||||
self._vmops._vmutils.vm_exists.assert_called_with(
|
||||
mock_instance.name)
|
||||
mock_power_off.assert_called_once_with(mock_instance)
|
||||
|
@ -1172,7 +1188,8 @@ class VMOpsTestCase(test_base.HyperVBaseTestCase):
|
|||
mock_disconnect_volumes.assert_called_once_with(
|
||||
mock.sentinel.FAKE_BD_INFO)
|
||||
mock_delete_disk_files.assert_called_once_with(
|
||||
mock_instance.name)
|
||||
mock_instance.name,
|
||||
self._pathutils.get_instance_dir.return_value)
|
||||
|
||||
def test_destroy_inexistent_instance(self):
|
||||
mock_instance = fake_instance.fake_instance_obj(self.context)
|
||||
|
|
Loading…
Reference in New Issue