Merge "virt: Provide block_device_info during rescue"
This commit is contained in:
commit
b6f3d393aa
@ -4150,6 +4150,11 @@ class ComputeManager(manager.Manager):
|
||||
rescue_image_meta = self._get_rescue_image(context, instance,
|
||||
rescue_image_ref)
|
||||
|
||||
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
|
||||
context, instance.uuid)
|
||||
block_device_info = self._get_instance_block_device_info(
|
||||
context, instance, bdms=bdms)
|
||||
|
||||
extra_usage_info = {'rescue_image_name':
|
||||
self._get_image_name(rescue_image_meta)}
|
||||
self._notify_about_instance_usage(context, instance,
|
||||
@ -4162,9 +4167,9 @@ class ComputeManager(manager.Manager):
|
||||
try:
|
||||
self._power_off_instance(context, instance, clean_shutdown)
|
||||
|
||||
self.driver.rescue(context, instance,
|
||||
network_info,
|
||||
rescue_image_meta, admin_password)
|
||||
self.driver.rescue(context, instance, network_info,
|
||||
rescue_image_meta, admin_password,
|
||||
block_device_info)
|
||||
except Exception as e:
|
||||
LOG.exception("Error trying to Rescue Instance",
|
||||
instance=instance)
|
||||
|
@ -2277,7 +2277,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
'unrescued': False}
|
||||
|
||||
def fake_rescue(self, context, instance_ref, network_info, image_meta,
|
||||
rescue_password):
|
||||
rescue_password, block_device_info):
|
||||
called['rescued'] = True
|
||||
|
||||
self.stub_out('nova.virt.fake.FakeDriver.rescue', fake_rescue)
|
||||
@ -2309,7 +2309,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
def test_rescue_notifications(self, mock_context, mock_notify):
|
||||
# Ensure notifications on instance rescue.
|
||||
def fake_rescue(self, context, instance_ref, network_info, image_meta,
|
||||
rescue_password):
|
||||
rescue_password, block_device_info):
|
||||
pass
|
||||
self.stub_out('nova.virt.fake.FakeDriver.rescue', fake_rescue)
|
||||
|
||||
@ -2406,14 +2406,18 @@ class ComputeTestCase(BaseTestCase,
|
||||
|
||||
self.compute.terminate_instance(self.context, instance, [])
|
||||
|
||||
@mock.patch.object(nova.compute.manager.ComputeManager,
|
||||
'_get_instance_block_device_info')
|
||||
@mock.patch.object(fake.FakeDriver, 'power_off')
|
||||
@mock.patch.object(fake.FakeDriver, 'rescue')
|
||||
@mock.patch.object(compute_manager.ComputeManager, '_get_rescue_image')
|
||||
def test_rescue_handle_err(self, mock_get, mock_rescue, mock_power_off):
|
||||
def test_rescue_handle_err(self, mock_get, mock_rescue, mock_power_off,
|
||||
mock_get_block_info):
|
||||
# If the driver fails to rescue, instance state should got to ERROR
|
||||
# and the exception should be converted to InstanceNotRescuable
|
||||
inst_obj = self._create_fake_instance_obj()
|
||||
mock_get.return_value = objects.ImageMeta.from_dict({})
|
||||
mock_get_block_info.return_value = mock.sentinel.block_device_info
|
||||
mock_rescue.side_effect = RuntimeError("Try again later")
|
||||
|
||||
expected_message = ('Instance %s cannot be rescued: '
|
||||
@ -2429,13 +2433,16 @@ class ComputeTestCase(BaseTestCase,
|
||||
self.assertEqual(vm_states.ERROR, inst_obj.vm_state)
|
||||
mock_get.assert_called_once_with(mock.ANY, inst_obj, mock.ANY)
|
||||
mock_rescue.assert_called_once_with(mock.ANY, inst_obj, [],
|
||||
mock.ANY, 'password')
|
||||
mock.ANY, 'password',
|
||||
mock.sentinel.block_device_info)
|
||||
|
||||
@mock.patch.object(nova.compute.manager.ComputeManager,
|
||||
'_get_instance_block_device_info')
|
||||
@mock.patch.object(image_api.API, "get")
|
||||
@mock.patch.object(fake.FakeDriver, 'power_off')
|
||||
@mock.patch.object(nova.virt.fake.FakeDriver, "rescue")
|
||||
def test_rescue_with_image_specified(self, mock_rescue, mock_power_off,
|
||||
mock_image_get):
|
||||
mock_image_get, mock_get_block_info):
|
||||
image_ref = uuids.image_instance
|
||||
rescue_image_meta = {}
|
||||
params = {"task_state": task_states.RESCUING}
|
||||
@ -2445,6 +2452,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
mock_context = mock.Mock()
|
||||
mock_context.elevated.return_value = ctxt
|
||||
|
||||
mock_get_block_info.return_value = mock.sentinel.block_device_info
|
||||
mock_image_get.return_value = rescue_image_meta
|
||||
|
||||
self.compute.rescue_instance(mock_context, instance=instance,
|
||||
@ -2454,14 +2462,17 @@ class ComputeTestCase(BaseTestCase,
|
||||
mock_image_get.assert_called_with(ctxt, image_ref)
|
||||
mock_rescue.assert_called_with(ctxt, instance, [],
|
||||
test.MatchType(objects.ImageMeta),
|
||||
'password')
|
||||
'password',
|
||||
mock.sentinel.block_device_info)
|
||||
self.compute.terminate_instance(ctxt, instance, [])
|
||||
|
||||
@mock.patch.object(nova.compute.manager.ComputeManager,
|
||||
'_get_instance_block_device_info')
|
||||
@mock.patch.object(image_api.API, "get")
|
||||
@mock.patch.object(fake.FakeDriver, 'power_off')
|
||||
@mock.patch.object(nova.virt.fake.FakeDriver, "rescue")
|
||||
def test_rescue_with_base_image_when_image_not_specified(self,
|
||||
mock_rescue, mock_power_off, mock_image_get):
|
||||
mock_rescue, mock_power_off, mock_image_get, mock_get_block_info):
|
||||
image_ref = FAKE_IMAGE_REF
|
||||
system_meta = {"image_base_image_ref": image_ref}
|
||||
rescue_image_meta = {}
|
||||
@ -2473,6 +2484,7 @@ class ComputeTestCase(BaseTestCase,
|
||||
mock_context = mock.Mock()
|
||||
mock_context.elevated.return_value = ctxt
|
||||
|
||||
mock_get_block_info.return_value = mock.sentinel.block_device_info
|
||||
mock_image_get.return_value = rescue_image_meta
|
||||
|
||||
self.compute.rescue_instance(mock_context, instance=instance,
|
||||
@ -2484,7 +2496,8 @@ class ComputeTestCase(BaseTestCase,
|
||||
|
||||
mock_rescue.assert_called_with(ctxt, instance, [],
|
||||
test.MatchType(objects.ImageMeta),
|
||||
'password')
|
||||
'password',
|
||||
mock.sentinel.block_device_info)
|
||||
self.compute.terminate_instance(self.context, instance, [])
|
||||
|
||||
def test_power_on(self):
|
||||
|
@ -4301,6 +4301,11 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
||||
return_value=fake_nw_info),
|
||||
mock.patch.object(self.compute, '_get_rescue_image',
|
||||
return_value=rescue_image_meta),
|
||||
mock.patch.object(objects.BlockDeviceMappingList,
|
||||
'get_by_instance_uuid',
|
||||
return_value=mock.sentinel.bdms),
|
||||
mock.patch.object(self.compute, '_get_instance_block_device_info',
|
||||
return_value=mock.sentinel.block_device_info),
|
||||
mock.patch.object(self.compute, '_notify_about_instance_usage'),
|
||||
mock.patch.object(self.compute, '_power_off_instance'),
|
||||
mock.patch.object(self.compute.driver, 'rescue'),
|
||||
@ -4310,8 +4315,9 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
||||
mock.patch.object(instance, 'save')
|
||||
) as (
|
||||
elevated_context, get_nw_info, get_rescue_image,
|
||||
notify_instance_usage, power_off_instance, driver_rescue,
|
||||
notify_usage_exists, get_power_state, instance_save
|
||||
get_bdm_list, get_block_info, notify_instance_usage,
|
||||
power_off_instance, driver_rescue, notify_usage_exists,
|
||||
get_power_state, instance_save
|
||||
):
|
||||
self.compute.rescue_instance(
|
||||
self.context, instance, rescue_password='verybadpass',
|
||||
@ -4327,6 +4333,9 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
||||
get_nw_info.assert_called_once_with(self.context, instance)
|
||||
get_rescue_image.assert_called_once_with(
|
||||
self.context, instance, None)
|
||||
get_bdm_list.assert_called_once_with(self.context, instance.uuid)
|
||||
get_block_info.assert_called_once_with(self.context, instance,
|
||||
bdms=mock.sentinel.bdms)
|
||||
|
||||
extra_usage_info = {'rescue_image_name': uuids.image_name}
|
||||
notify_calls = [
|
||||
@ -4344,7 +4353,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
||||
|
||||
driver_rescue.assert_called_once_with(
|
||||
self.context, instance, fake_nw_info, rescue_image_meta,
|
||||
'verybadpass')
|
||||
'verybadpass', mock.sentinel.block_device_info)
|
||||
|
||||
notify_usage_exists.assert_called_once_with(self.compute.notifier,
|
||||
self.context, instance, 'fake-mini', current_period=True)
|
||||
|
@ -3004,7 +3004,7 @@ class IronicDriverSyncTestCase(IronicDriverTestCase):
|
||||
instance = fake_instance.fake_instance_obj(self.ctx,
|
||||
node=node.uuid)
|
||||
|
||||
self.driver.rescue(self.ctx, instance, None, None, 'xyz')
|
||||
self.driver.rescue(self.ctx, instance, None, None, 'xyz', None)
|
||||
mock_sps.assert_called_once_with(node.uuid, 'rescue',
|
||||
rescue_password='xyz')
|
||||
|
||||
@ -3021,7 +3021,7 @@ class IronicDriverSyncTestCase(IronicDriverTestCase):
|
||||
|
||||
self.assertRaises(exception.InstanceRescueFailure,
|
||||
self.driver.rescue,
|
||||
self.ctx, instance, None, None, 'xyz')
|
||||
self.ctx, instance, None, None, 'xyz', None)
|
||||
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_validate_instance_and_node')
|
||||
@ -3035,7 +3035,7 @@ class IronicDriverSyncTestCase(IronicDriverTestCase):
|
||||
|
||||
self.assertRaises(exception.InstanceRescueFailure,
|
||||
self.driver.rescue,
|
||||
self.ctx, instance, None, None, 'xyz')
|
||||
self.ctx, instance, None, None, 'xyz', None)
|
||||
|
||||
@mock.patch.object(ironic_driver.IronicDriver,
|
||||
'_validate_instance_and_node')
|
||||
@ -3051,7 +3051,7 @@ class IronicDriverSyncTestCase(IronicDriverTestCase):
|
||||
|
||||
self.assertRaises(exception.InstanceRescueFailure,
|
||||
self.driver.rescue,
|
||||
self.ctx, instance, None, None, 'xyz')
|
||||
self.ctx, instance, None, None, 'xyz', None)
|
||||
|
||||
@mock.patch.object(loopingcall, 'FixedIntervalLoopingCall')
|
||||
@mock.patch.object(FAKE_CLIENT.node, 'set_provision_state')
|
||||
|
@ -22576,7 +22576,7 @@ class LibvirtDriverTestCase(test.NoDBTestCase, TraitsComparisonMixin):
|
||||
self.drvr, '_create_domain',
|
||||
side_effect=fake_create_domain) as mock_create_domain:
|
||||
self.drvr.rescue(self.context, instance,
|
||||
network_info, image_meta, rescue_password)
|
||||
network_info, image_meta, rescue_password, None)
|
||||
|
||||
self.assertTrue(mock_create_domain.called)
|
||||
|
||||
|
@ -298,7 +298,7 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
|
||||
image_meta = objects.ImageMeta.from_dict({})
|
||||
instance_ref, network_info = self._get_running_instance()
|
||||
self.connection.rescue(self.ctxt, instance_ref, network_info,
|
||||
image_meta, '')
|
||||
image_meta, '', None)
|
||||
|
||||
@catch_notimplementederror
|
||||
@mock.patch('os.unlink')
|
||||
@ -313,7 +313,7 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
|
||||
image_meta = objects.ImageMeta.from_dict({})
|
||||
instance_ref, network_info = self._get_running_instance()
|
||||
self.connection.rescue(self.ctxt, instance_ref, network_info,
|
||||
image_meta, '')
|
||||
image_meta, '', None)
|
||||
self.connection.unrescue(instance_ref, network_info)
|
||||
|
||||
@catch_notimplementederror
|
||||
|
@ -1315,7 +1315,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase,
|
||||
{'id': IMAGE_VHD,
|
||||
'disk_format': 'vhd',
|
||||
'properties': {'vm_mode': 'xen'}})
|
||||
conn.rescue(self.context, instance, [], image_meta, '')
|
||||
conn.rescue(self.context, instance, [], image_meta, '', None)
|
||||
|
||||
vm = xenapi_fake.get_record('VM', vm_ref)
|
||||
rescue_name = "%s-rescue" % vm["name_label"]
|
||||
@ -1351,7 +1351,7 @@ class XenAPIVMTestCase(stubs.XenAPITestBase,
|
||||
self.conn._vmops, '_start',
|
||||
side_effect=test.TestingException('Start Error')):
|
||||
self.assertRaises(test.TestingException, self.conn.rescue,
|
||||
self.context, instance, [], image_meta, '')
|
||||
self.context, instance, [], image_meta, '', [])
|
||||
|
||||
# confirm original disk still exists:
|
||||
vdi_ref2, vdi_rec2 = vm_utils.get_vdi_for_vm_safely(session,
|
||||
|
@ -850,7 +850,7 @@ class ComputeDriver(object):
|
||||
raise NotImplementedError()
|
||||
|
||||
def rescue(self, context, instance, network_info, image_meta,
|
||||
rescue_password):
|
||||
rescue_password, block_device_info):
|
||||
"""Rescue the specified instance.
|
||||
|
||||
:param nova.context.RequestContext context:
|
||||
@ -862,6 +862,8 @@ class ComputeDriver(object):
|
||||
:param nova.objects.ImageMeta image_meta:
|
||||
The metadata of the image of the instance.
|
||||
:param rescue_password: new root password to set for rescue.
|
||||
:param dict block_device_info:
|
||||
The block device mapping of the instance.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
@ -238,7 +238,7 @@ class FakeDriver(driver.ComputeDriver):
|
||||
pass
|
||||
|
||||
def rescue(self, context, instance, network_info, image_meta,
|
||||
rescue_password):
|
||||
rescue_password, block_device_info):
|
||||
pass
|
||||
|
||||
def unrescue(self, instance, network_info):
|
||||
|
@ -357,7 +357,7 @@ class HyperVDriver(driver.ComputeDriver):
|
||||
return self._vmops.detach_interface(instance, vif)
|
||||
|
||||
def rescue(self, context, instance, network_info, image_meta,
|
||||
rescue_password):
|
||||
rescue_password, block_device_info):
|
||||
self._vmops.rescue_instance(context, instance, network_info,
|
||||
image_meta, rescue_password)
|
||||
|
||||
|
@ -2120,7 +2120,7 @@ class IronicDriver(virt_driver.ComputeDriver):
|
||||
version=max_version)
|
||||
|
||||
def rescue(self, context, instance, network_info, image_meta,
|
||||
rescue_password):
|
||||
rescue_password, block_device_info):
|
||||
"""Rescue the specified instance.
|
||||
|
||||
:param nova.context.RequestContext context:
|
||||
@ -2133,6 +2133,8 @@ class IronicDriver(virt_driver.ComputeDriver):
|
||||
:param nova.objects.ImageMeta image_meta:
|
||||
The metadata of the image of the instance. Ignored by this driver.
|
||||
:param rescue_password: new root password to set for rescue.
|
||||
:param dict block_device_info:
|
||||
The block device mapping of the instance.
|
||||
:raise InstanceRescueFailure if rescue fails.
|
||||
"""
|
||||
LOG.debug('Rescue called for instance', instance=instance)
|
||||
|
@ -3409,7 +3409,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
self._hard_reboot(context, instance, network_info, block_device_info)
|
||||
|
||||
def rescue(self, context, instance, network_info, image_meta,
|
||||
rescue_password):
|
||||
rescue_password, block_device_info):
|
||||
"""Loads a VM using rescue images.
|
||||
|
||||
A rescue is normally performed when something goes wrong with the
|
||||
|
@ -646,7 +646,7 @@ class VMwareVCDriver(driver.ComputeDriver):
|
||||
self._vmops.resume(instance)
|
||||
|
||||
def rescue(self, context, instance, network_info, image_meta,
|
||||
rescue_password):
|
||||
rescue_password, block_device_info):
|
||||
"""Rescue the specified instance."""
|
||||
self._vmops.rescue(context, instance, network_info, image_meta)
|
||||
|
||||
|
@ -313,7 +313,7 @@ class XenAPIDriver(driver.ComputeDriver):
|
||||
self._vmops.resume(instance)
|
||||
|
||||
def rescue(self, context, instance, network_info, image_meta,
|
||||
rescue_password):
|
||||
rescue_password, block_device_info):
|
||||
"""Rescue the specified instance."""
|
||||
self._vmops.rescue(context, instance, network_info, image_meta,
|
||||
rescue_password)
|
||||
|
Loading…
x
Reference in New Issue
Block a user