Browse Source

Merge "virt: Provide block_device_info during rescue"

tags/21.0.0.0rc1
Zuul 2 months ago
committed by Gerrit Code Review
parent
commit
b6f3d393aa
14 changed files with 61 additions and 30 deletions
  1. +8
    -3
      nova/compute/manager.py
  2. +21
    -8
      nova/tests/unit/compute/test_compute.py
  3. +12
    -3
      nova/tests/unit/compute/test_compute_mgr.py
  4. +4
    -4
      nova/tests/unit/virt/ironic/test_driver.py
  5. +1
    -1
      nova/tests/unit/virt/libvirt/test_driver.py
  6. +2
    -2
      nova/tests/unit/virt/test_virt_drivers.py
  7. +2
    -2
      nova/tests/unit/virt/xenapi/test_xenapi.py
  8. +3
    -1
      nova/virt/driver.py
  9. +1
    -1
      nova/virt/fake.py
  10. +1
    -1
      nova/virt/hyperv/driver.py
  11. +3
    -1
      nova/virt/ironic/driver.py
  12. +1
    -1
      nova/virt/libvirt/driver.py
  13. +1
    -1
      nova/virt/vmwareapi/driver.py
  14. +1
    -1
      nova/virt/xenapi/driver.py

+ 8
- 3
nova/compute/manager.py View File

@@ -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)


+ 21
- 8
nova/tests/unit/compute/test_compute.py View File

@@ -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):


+ 12
- 3
nova/tests/unit/compute/test_compute_mgr.py View File

@@ -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)


+ 4
- 4
nova/tests/unit/virt/ironic/test_driver.py View File

@@ -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')


+ 1
- 1
nova/tests/unit/virt/libvirt/test_driver.py View File

@@ -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)



+ 2
- 2
nova/tests/unit/virt/test_virt_drivers.py View File

@@ -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


+ 2
- 2
nova/tests/unit/virt/xenapi/test_xenapi.py View File

@@ -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,


+ 3
- 1
nova/virt/driver.py View File

@@ -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()



+ 1
- 1
nova/virt/fake.py View File

@@ -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):


+ 1
- 1
nova/virt/hyperv/driver.py View File

@@ -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)



+ 3
- 1
nova/virt/ironic/driver.py View File

@@ -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)


+ 1
- 1
nova/virt/libvirt/driver.py View File

@@ -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


+ 1
- 1
nova/virt/vmwareapi/driver.py View File

@@ -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)



+ 1
- 1
nova/virt/xenapi/driver.py View File

@@ -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…
Cancel
Save