From 6b4f89ab59a9ed68211e1250d9fa6ab5da3c7366 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Fri, 31 May 2019 15:26:24 -0400 Subject: [PATCH] Set/get group uuid when transforming RequestSpec to/from filter_properties As a follow up to change I20981c987549eec40ad9762e74b0db16e54f4e63 we can avoid having an incomplete InstanceGroup by updating the _to_legacy_group_info and _populate_group_info methods to set/get the group uuid to/from the filter_properties. Change-Id: I164a6dee1e92a65fcf6e89525ee194bb482e9920 Related-Bug: #1830747 --- nova/objects/request_spec.py | 9 +++++--- .../regressions/test_bug_1830747.py | 3 +++ nova/tests/unit/objects/test_request_spec.py | 23 ++++++++++++------- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/nova/objects/request_spec.py b/nova/objects/request_spec.py index 415183dc56e9..67d7b39b81f2 100644 --- a/nova/objects/request_spec.py +++ b/nova/objects/request_spec.py @@ -242,11 +242,13 @@ class RequestSpec(base.NovaObject): policies = list(filter_properties.get('group_policies')) hosts = list(filter_properties.get('group_hosts')) members = list(filter_properties.get('group_members')) - # TODO(mriedem): We could try to get the group uuid from the - # group hint in the filter_properties. self.instance_group = objects.InstanceGroup(policy=policies[0], hosts=hosts, members=members) + # InstanceGroup.uuid is not nullable so only set it if we got it. + group_uuid = filter_properties.get('group_uuid') + if group_uuid: + self.instance_group.uuid = group_uuid # hosts has to be not part of the updates for saving the object self.instance_group.obj_reset_changes(['hosts']) else: @@ -369,7 +371,8 @@ class RequestSpec(base.NovaObject): return {'group_updated': True, 'group_hosts': set(self.instance_group.hosts), 'group_policies': set([self.instance_group.policy]), - 'group_members': set(self.instance_group.members)} + 'group_members': set(self.instance_group.members), + 'group_uuid': self.instance_group.uuid} def to_legacy_request_spec_dict(self): """Returns a legacy request_spec dict from the RequestSpec object. diff --git a/nova/tests/functional/regressions/test_bug_1830747.py b/nova/tests/functional/regressions/test_bug_1830747.py index 1e22df6caf66..c93e67977264 100644 --- a/nova/tests/functional/regressions/test_bug_1830747.py +++ b/nova/tests/functional/regressions/test_bug_1830747.py @@ -124,6 +124,9 @@ class MissingReqSpecInstanceGroupUUIDTestCase( # which we can determine from the filter_properties retry dict. filter_properties = scheduler_hint['filter_properties'] if filter_properties.get('retry', {}).get('exc'): + # Assert the group_uuid is passed through the filter properties + self.assertIn('group_uuid', filter_properties) + self.assertEqual(group_id, filter_properties['group_uuid']) kwargs.pop('request_spec', None) return original_resize_instance( _self, context, instance, extra_instance_updates, diff --git a/nova/tests/unit/objects/test_request_spec.py b/nova/tests/unit/objects/test_request_spec.py index c288997f75a2..794acf35b668 100644 --- a/nova/tests/unit/objects/test_request_spec.py +++ b/nova/tests/unit/objects/test_request_spec.py @@ -232,13 +232,18 @@ class _TestRequestSpecObject(object): filt_props['group_policies'] = set(['affinity']) filt_props['group_hosts'] = set(['fake1']) filt_props['group_members'] = set(['fake-instance1']) - - spec = objects.RequestSpec() - spec._populate_group_info(filt_props) - self.assertIsInstance(spec.instance_group, objects.InstanceGroup) - self.assertEqual('affinity', spec.instance_group.policy) - self.assertEqual(['fake1'], spec.instance_group.hosts) - self.assertEqual(['fake-instance1'], spec.instance_group.members) + # Make sure it can handle group uuid not being present. + for group_uuid in (None, uuids.group_uuid): + if group_uuid: + filt_props['group_uuid'] = group_uuid + spec = objects.RequestSpec() + spec._populate_group_info(filt_props) + self.assertIsInstance(spec.instance_group, objects.InstanceGroup) + self.assertEqual('affinity', spec.instance_group.policy) + self.assertEqual(['fake1'], spec.instance_group.hosts) + self.assertEqual(['fake-instance1'], spec.instance_group.members) + if group_uuid: + self.assertEqual(uuids.group_uuid, spec.instance_group.uuid) def test_populate_group_info_missing_values(self): filt_props = {} @@ -489,7 +494,8 @@ class _TestRequestSpecObject(object): memory_mb=8192.0), instance_group=objects.InstanceGroup(hosts=['fake1'], policy='affinity', - members=['inst1', 'inst2']), + members=['inst1', 'inst2'], + uuid=uuids.group_uuid), scheduler_hints={'foo': ['bar']}, requested_destination=fake_dest) expected = {'ignore_hosts': ['ignoredhost'], @@ -505,6 +511,7 @@ class _TestRequestSpecObject(object): 'group_hosts': set(['fake1']), 'group_policies': set(['affinity']), 'group_members': set(['inst1', 'inst2']), + 'group_uuid': uuids.group_uuid, 'scheduler_hints': {'foo': 'bar'}, 'requested_destination': fake_dest} self.assertEqual(expected, spec.to_legacy_filter_properties_dict())