Fix recent regression filling in flavor extra_specs

In commit cb338cb769, we dropped an extra
DB query to fill in flavor extra_specs because the object should already
have those set. However, if we pulled the flavor from the instance,
extra_specs are mostly not stored, which means we effectively cut off
the scheduler filters from access to those things.

This adds that back in for that case, but only temporarily. Soon we will
be merging a change to stash real flavor objects with the instance, which
will make this moot. However, that may take a while to merge and this is
broken now.

Change-Id: Ia728025345b09687da9744004f0f47ad73ce196c
Closes-Bug: #1403547
This commit is contained in:
Dan Smith
2014-12-17 08:41:25 -08:00
committed by Dan Smith
parent fec5ff1294
commit 41cb43d5a5
3 changed files with 37 additions and 4 deletions

View File

@@ -59,6 +59,11 @@ def build_request_spec(ctxt, image, instances, instance_type=None):
if instance_type is None:
instance_type = flavors.extract_flavor(instance)
# NOTE(danms): This won't have extra_specs, so fill in the gaps
_instance_type = objects.Flavor.get_by_flavor_id(
ctxt, instance_type['flavorid'])
instance_type.extra_specs = instance_type.get('extra_specs', {})
instance_type.extra_specs.update(_instance_type.extra_specs)
if isinstance(instance_type, objects.Flavor):
instance_type = obj_base.obj_to_primitive(instance_type)

View File

@@ -1248,6 +1248,7 @@ class _BaseTaskTestCase(object):
system_metadata=system_metadata,
expected_attrs=['system_metadata']) for i in xrange(2)]
instance_type = flavors.extract_flavor(instances[0])
instance_type['extra_specs'] = {}
instance_type_p = jsonutils.to_primitive(instance_type)
instance_properties = jsonutils.to_primitive(instances[0])

View File

@@ -32,6 +32,7 @@ from nova import rpc
from nova.scheduler import utils as scheduler_utils
from nova import test
from nova.tests.unit import fake_instance
from nova.tests.unit.objects import test_flavor
CONF = cfg.CONF
@@ -42,10 +43,33 @@ class SchedulerUtilsTestCase(test.NoDBTestCase):
super(SchedulerUtilsTestCase, self).setUp()
self.context = 'fake-context'
def test_build_request_spec_without_image(self):
@mock.patch('nova.objects.Flavor.get_by_flavor_id')
def test_build_request_spec_requeries_extra_specs(self, mock_get):
flavor = objects.Flavor(**test_flavor.fake_flavor)
flavor.extra_specs = {'hw:numa_cpus.1': '1985'}
instance = objects.Instance(id=0, uuid=uuid.uuid4().hex,
system_metadata={})
with mock.patch.object(instance, 'save'):
instance.set_flavor(flavor.obj_clone())
flavor.extra_specs = {'second': '2015', 'third': '1885'}
mock_get.return_value = flavor
request_spec = scheduler_utils.build_request_spec(self.context,
None,
[instance])
mock_get.assert_called_once_with(self.context,
flavor.flavorid)
self.assertEqual({'hw:numa_cpus.1': '1985',
'second': '2015',
'third': '1885'},
request_spec['instance_type']['extra_specs'])
@mock.patch('nova.objects.Flavor.get_by_flavor_id')
def test_build_request_spec_without_image(self, mock_get):
image = None
instance = {'uuid': 'fake-uuid'}
instance_type = {'flavorid': 'fake-id'}
instance_type = objects.Flavor(**test_flavor.fake_flavor)
mock_get.return_value = objects.Flavor(extra_specs={})
self.mox.StubOutWithMock(flavors, 'extract_flavor')
flavors.extract_flavor(mox.IgnoreArg()).AndReturn(instance_type)
@@ -56,10 +80,13 @@ class SchedulerUtilsTestCase(test.NoDBTestCase):
self.assertEqual({}, request_spec['image'])
@mock.patch.object(flavors, 'extract_flavor')
def test_build_request_spec_with_object(self, extract_flavor):
instance_type = {'flavorid': 'fake-id'}
@mock.patch('nova.objects.Flavor.get_by_flavor_id')
def test_build_request_spec_with_object(self, mock_get, extract_flavor):
instance_type = objects.Flavor(**test_flavor.fake_flavor)
instance = fake_instance.fake_instance_obj(self.context)
mock_get.return_value = objects.Flavor(extra_specs={})
extract_flavor.return_value = instance_type
request_spec = scheduler_utils.build_request_spec(self.context, None,