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:
		@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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])
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user