Pass requested_destination in filter_properties

When we added the requested_destination field for the RequestSpec object
in Newton, we forgot to pass it to the legacy dictionary when wanting to
use scheduler methods not yet supporting the NovaObject.
As a consequence, when we were transforming the RequestSpec object into a
tuple of (request_spec, filter_props) dicts and then rehydrating a new
RequestSpec object using those dicts, the newly created object was not
keeping that requested_destination field from the original.

Conflicts:
      nova/tests/unit/objects/test_request_spec.py

NOTE(mriedem): Conflict is due to d288132dca
not being in Ocata, but it's not needed either.

Change-Id: Iba0b88172e9a3bfd4f216dd364d70f7e01c60ee2
Closes-Bug: #1702454
(cherry picked from commit 69bef428bd)
(cherry picked from commit bceb176fb0)
This commit is contained in:
Sylvain Bauza 2017-07-06 17:17:31 +02:00 committed by Matt Riedemann
parent 0b672420bc
commit fe8acf003e
3 changed files with 25 additions and 5 deletions

View File

@ -258,6 +258,8 @@ class RequestSpec(base.NovaObject):
spec._populate_group_info(filter_properties)
scheduler_hints = filter_properties.get('scheduler_hints', {})
spec._from_hints(scheduler_hints)
spec.requested_destination = filter_properties.get(
'requested_destination')
# NOTE(sbauza): Default the other fields that are not part of the
# original contract
@ -365,6 +367,9 @@ class RequestSpec(base.NovaObject):
# we had to hydrate the field by putting a single item into a list.
filt_props['scheduler_hints'] = {hint: self.get_scheduler_hint(
hint) for hint in self.scheduler_hints}
if self.obj_attr_is_set('requested_destination'
) and self.requested_destination:
filt_props['requested_destination'] = self.requested_destination
return filt_props
@classmethod
@ -410,6 +415,8 @@ class RequestSpec(base.NovaObject):
spec_obj.availability_zone = availability_zone
if security_groups is not None:
spec_obj.security_groups = security_groups
spec_obj.requested_destination = filter_properties.get(
'requested_destination')
# NOTE(sbauza): Default the other fields that are not part of the
# original contract

View File

@ -153,5 +153,5 @@ class SchedulerOnlyChecksTargetTest(test.TestCase,
self._wait_for_state_change(self.api, server, 'ACTIVE')
server = self.admin_api.get_server(server_id)
# Unfortunately, the requested host isn't respected.
self.assertEqual('host3', server['OS-EXT-SRV-ATTR:host'])
# Yeepee, that works!
self.assertEqual('host2', server['OS-EXT-SRV-ATTR:host'])

View File

@ -299,13 +299,22 @@ class _TestRequestSpecObject(object):
# just making sure that the context is set by the method
self.assertEqual(ctxt, spec._context)
def test_from_primitives_with_requested_destination(self):
destination = objects.Destination(host='foo')
spec_dict = {}
filt_props = {'requested_destination': destination}
ctxt = context.RequestContext('fake', 'fake')
spec = objects.RequestSpec.from_primitives(ctxt, spec_dict, filt_props)
self.assertEqual(destination, spec.requested_destination)
def test_from_components(self):
ctxt = context.RequestContext('fake-user', 'fake-project')
destination = objects.Destination(host='foo')
instance = fake_instance.fake_instance_obj(ctxt)
image = {'id': uuids.image_id, 'properties': {'mappings': []},
'status': 'fake-status', 'location': 'far-away'}
flavor = fake_flavor.fake_flavor_obj(ctxt)
filter_properties = {}
filter_properties = {'requested_destination': destination}
instance_group = None
spec = objects.RequestSpec.from_components(ctxt, instance.uuid, image,
@ -318,6 +327,7 @@ class _TestRequestSpecObject(object):
'Field: %s is not set' % field)
# just making sure that the context is set by the method
self.assertEqual(ctxt, spec._context)
self.assertEqual(destination, spec.requested_destination)
@mock.patch('nova.objects.RequestSpec._populate_group_info')
def test_from_components_with_instance_group(self, mock_pgi):
@ -436,6 +446,7 @@ class _TestRequestSpecObject(object):
fake_computes_obj = objects.ComputeNodeList(
objects=[objects.ComputeNode(host='fake1',
hypervisor_hostname='node1')])
fake_dest = objects.Destination(host='fakehost')
spec = objects.RequestSpec(
ignore_hosts=['ignoredhost'],
force_hosts=['fakehost'],
@ -448,7 +459,8 @@ class _TestRequestSpecObject(object):
memory_mb=8192.0),
instance_group=objects.InstanceGroup(hosts=['fake1'],
policies=['affinity']),
scheduler_hints={'foo': ['bar']})
scheduler_hints={'foo': ['bar']},
requested_destination=fake_dest)
expected = {'ignore_hosts': ['ignoredhost'],
'force_hosts': ['fakehost'],
'force_nodes': ['fakenode'],
@ -461,7 +473,8 @@ class _TestRequestSpecObject(object):
'group_updated': True,
'group_hosts': set(['fake1']),
'group_policies': set(['affinity']),
'scheduler_hints': {'foo': 'bar'}}
'scheduler_hints': {'foo': 'bar'},
'requested_destination': fake_dest}
self.assertEqual(expected, spec.to_legacy_filter_properties_dict())
def test_to_legacy_filter_properties_dict_with_nullable_values(self):