Merge "Fix getting instance bdms in multiple cells"

This commit is contained in:
Jenkins 2017-08-04 20:17:18 +00:00 committed by Gerrit Code Review
commit 5971dde5d9
2 changed files with 44 additions and 4 deletions

View File

@ -15,6 +15,7 @@
"""The Extended Volumes API extension."""
from nova.api.openstack import api_version_request
from nova.api.openstack import wsgi
from nova import context
from nova import objects
from nova.policies import extended_volumes as ev_policies
@ -45,14 +46,34 @@ class ExtendedVolumesController(wsgi.Controller):
instance_bdms = self._get_instance_bdms(bdms, server)
self._extend_server(context, server, req, instance_bdms)
@staticmethod
def _get_instance_bdms_in_multiple_cells(ctxt, servers):
instance_uuids = [server['id'] for server in servers]
inst_maps = objects.InstanceMappingList.get_by_instance_uuids(
ctxt, instance_uuids)
cell_mappings = {}
for inst_map in inst_maps:
if (inst_map.cell_mapping is not None and
inst_map.cell_mapping.uuid not in cell_mappings):
cell_mappings.update(
{inst_map.cell_mapping.uuid: inst_map.cell_mapping})
bdms = {}
for cell_mapping in cell_mappings.values():
with context.target_cell(ctxt, cell_mapping) as cctxt:
bdms.update(
objects.BlockDeviceMappingList.bdms_by_instance_uuid(
cctxt, instance_uuids))
return bdms
@wsgi.extends
def detail(self, req, resp_obj):
context = req.environ['nova.context']
if context.can(ev_policies.BASE_POLICY_NAME, fatal=False):
servers = list(resp_obj.obj['servers'])
instance_uuids = [server['id'] for server in servers]
bdms = objects.BlockDeviceMappingList.bdms_by_instance_uuid(
context, instance_uuids)
bdms = self._get_instance_bdms_in_multiple_cells(context, servers)
for server in servers:
instance_bdms = self._get_instance_bdms(bdms, server)
self._extend_server(context, server, req, instance_bdms)

View File

@ -20,12 +20,14 @@ from nova.api.openstack.compute import (extended_volumes
as extended_volumes_v21)
from nova.api.openstack import wsgi as os_wsgi
from nova import compute
from nova import context as nova_context
from nova import objects
from nova.objects import instance as instance_obj
from nova import test
from nova.tests.unit.api.openstack import fakes
from nova.tests.unit import fake_block_device
from nova.tests.unit import fake_instance
from nova.tests import uuidsentinel as uuids
from nova import volume
UUID1 = '00000000-0000-0000-0000-000000000001'
@ -138,8 +140,25 @@ class ExtendedVolumesTestV21(test.TestCase):
actual = server.get('%svolumes_attached' % self.prefix)
self.assertEqual(self.exp_volumes_show, actual)
def test_detail(self):
@mock.patch.object(objects.InstanceMappingList, 'get_by_instance_uuids')
def test_detail(self, mock_get_by_instance_uuids):
mock_get_by_instance_uuids.return_value = [
objects.InstanceMapping(
instance_uuid=UUID1,
cell_mapping=objects.CellMapping(
uuid=uuids.cell1,
transport_url='fake://nowhere/',
database_connection=uuids.cell1)),
objects.InstanceMapping(
instance_uuid=UUID2,
cell_mapping=objects.CellMapping(
uuid=uuids.cell1,
transport_url='fake://nowhere/',
database_connection=uuids.cell1))]
res = self._make_request('/detail')
mock_get_by_instance_uuids.assert_called_once_with(
test.MatchType(nova_context.RequestContext), [UUID1, UUID2])
self.assertEqual(200, res.status_int)
for i, server in enumerate(self._get_servers(res.body)):