Make servers api view load instance fault from proper cell
Right now with CellsV2 the servers api will fail to load the fault for an instance because it does not target it to a particular cell. This makes us look up the instance mapping and use it to target loading of the fault. Change-Id: Ic2df2c3cfa66a91bd20437f534287e770b85f51d
This commit is contained in:
@@ -23,7 +23,10 @@ from nova.api.openstack import common
|
||||
from nova.api.openstack.compute.views import addresses as views_addresses
|
||||
from nova.api.openstack.compute.views import flavors as views_flavors
|
||||
from nova.api.openstack.compute.views import images as views_images
|
||||
from nova import context as nova_context
|
||||
from nova import exception
|
||||
from nova.i18n import _LW
|
||||
from nova import objects
|
||||
from nova.objects import base as obj_base
|
||||
from nova import utils
|
||||
|
||||
@@ -260,9 +263,26 @@ class ViewBuilder(common.ViewBuilder):
|
||||
}],
|
||||
}
|
||||
|
||||
def _load_fault(self, request, instance):
|
||||
try:
|
||||
mapping = objects.InstanceMapping.get_by_instance_uuid(
|
||||
request.environ['nova.context'], instance.uuid)
|
||||
if mapping.cell_mapping is not None:
|
||||
with nova_context.target_cell(instance._context,
|
||||
mapping.cell_mapping):
|
||||
return instance.fault
|
||||
except exception.InstanceMappingNotFound:
|
||||
pass
|
||||
|
||||
# NOTE(danms): No instance mapping at all, or a mapping with no cell,
|
||||
# which means a legacy environment or instance.
|
||||
return instance.fault
|
||||
|
||||
def _get_fault(self, request, instance):
|
||||
# This can result in a lazy load of the fault information
|
||||
fault = instance.fault
|
||||
if 'fault' in instance:
|
||||
fault = instance.fault
|
||||
else:
|
||||
fault = self._load_fault(request, instance)
|
||||
|
||||
if not fault:
|
||||
return None
|
||||
|
||||
@@ -4049,6 +4049,29 @@ class ServersViewBuilderTest(test.TestCase):
|
||||
self.assertThat(output['server']['fault'],
|
||||
matchers.DictMatches(expected_fault))
|
||||
|
||||
@mock.patch('nova.objects.InstanceMapping.get_by_instance_uuid')
|
||||
def test_build_server_detail_with_fault_no_instance_mapping(self,
|
||||
mock_im):
|
||||
self.instance['vm_state'] = vm_states.ERROR
|
||||
|
||||
mock_im.side_effect = exception.InstanceMappingNotFound(uuid='foo')
|
||||
|
||||
self.request.context = context.RequestContext('fake', 'fake')
|
||||
self.view_builder.show(self.request, self.instance)
|
||||
mock_im.assert_called_once_with(mock.ANY, self.uuid)
|
||||
|
||||
@mock.patch('nova.objects.InstanceMapping.get_by_instance_uuid')
|
||||
def test_build_server_detail_with_fault_loaded(self, mock_im):
|
||||
self.instance['vm_state'] = vm_states.ERROR
|
||||
fault = fake_instance.fake_fault_obj(self.request.context,
|
||||
self.uuid, code=500,
|
||||
message="No valid host was found")
|
||||
self.instance['fault'] = fault
|
||||
|
||||
self.request.context = context.RequestContext('fake', 'fake')
|
||||
self.view_builder.show(self.request, self.instance)
|
||||
self.assertFalse(mock_im.called)
|
||||
|
||||
def test_build_server_detail_with_fault_no_details_not_admin(self):
|
||||
self.instance['vm_state'] = vm_states.ERROR
|
||||
self.instance['fault'] = fake_instance.fake_fault_obj(
|
||||
|
||||
Reference in New Issue
Block a user