Merge "Add requested_networks field to RequestSpec object"

This commit is contained in:
Zuul 2021-02-09 23:12:04 +00:00 committed by Gerrit Code Review
commit fec44e5d38
3 changed files with 56 additions and 6 deletions

View File

@ -34,7 +34,8 @@ REQUEST_SPEC_OPTIONAL_ATTRS = ['requested_destination',
'security_groups',
'network_metadata',
'requested_resources',
'request_level_params']
'request_level_params',
'requested_networks']
@base.NovaObjectRegistry.register
@ -53,7 +54,8 @@ class RequestSpec(base.NovaObject):
# Version 1.11: Added is_bfv
# Version 1.12: Added requested_resources
# Version 1.13: Added request_level_params
VERSION = '1.13'
# Version 1.14: Added requested_networks
VERSION = '1.14'
fields = {
'id': fields.IntegerField(),
@ -108,11 +110,15 @@ class RequestSpec(base.NovaObject):
default=None),
# NOTE(efried): This field won't be persisted.
'request_level_params': fields.ObjectField('RequestLevelParams'),
# NOTE(sbauza); This field won't be persisted.
'requested_networks': fields.ObjectField('NetworkRequestList')
}
def obj_make_compatible(self, primitive, target_version):
super(RequestSpec, self).obj_make_compatible(primitive, target_version)
target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 14) and 'requested_networks' in primitive:
del primitive['requested_networks']
if target_version < (1, 13) and 'request_level_params' in primitive:
del primitive['request_level_params']
if target_version < (1, 12):
@ -152,6 +158,10 @@ class RequestSpec(base.NovaObject):
self.request_level_params = RequestLevelParams()
return
if attrname == 'requested_networks':
self.requested_networks = objects.NetworkRequestList(objects=[])
return
# NOTE(sbauza): In case the primitive was not providing that field
# because of a previous RequestSpec version, we want to default
# that field in order to have the same behaviour.
@ -563,7 +573,8 @@ class RequestSpec(base.NovaObject):
if key in ['id', 'instance_uuid']:
setattr(spec, key, db_spec[key])
elif key in ('requested_destination', 'requested_resources',
'network_metadata', 'request_level_params'):
'network_metadata', 'request_level_params',
'requested_networks'):
# Do not override what we already have in the object as this
# field is not persisted. If save() is called after
# one of these fields is populated, it will reset the field to
@ -653,6 +664,10 @@ class RequestSpec(base.NovaObject):
# no need for it after scheduling
if 'network_metadata' in spec and spec.network_metadata:
del spec.network_metadata
# NOTE(sbauza): Don't persist requested_networks since we have
# no need for it after scheduling
if 'requested_networks' in spec and spec.requested_networks:
del spec.requested_networks
db_updates = {'spec': jsonutils.dumps(spec.obj_to_primitive())}
if 'instance_uuid' in updates:

View File

@ -1124,7 +1124,7 @@ object_data = {
'QuotasNoOp': '1.3-d1593cf969c81846bc8192255ea95cce',
'RequestGroup': '1.3-0458d350a8ec9d0673f9be5640a990ce',
'RequestLevelParams': '1.0-1e5c8c18bd44cd233c8b32509c99d06f',
'RequestSpec': '1.13-e1aa38b2bf3f8547474ee9e4c0aa2745',
'RequestSpec': '1.14-2cdbda368ca07e10905dc5fe96908a58',
'Resource': '1.0-d8a2abbb380da583b995fd118f6a8953',
'ResourceList': '1.0-4a53826625cc280e15fae64a575e0879',
'ResourceMetadata': '1.0-77509ea1ea0dd750d5864b9bd87d3f9d',

View File

@ -308,7 +308,7 @@ class _TestRequestSpecObject(object):
mock_limits.assert_called_once_with({})
# Make sure that all fields are set using that helper method
skip = ['id', 'security_groups', 'network_metadata', 'is_bfv',
'request_level_params']
'request_level_params', 'requested_networks']
for field in [f for f in spec.obj_fields if f not in skip]:
self.assertTrue(spec.obj_attr_is_set(field),
'Field: %s is not set' % field)
@ -339,7 +339,8 @@ class _TestRequestSpecObject(object):
filter_properties, instance_group, instance.availability_zone,
objects.SecurityGroupList())
# Make sure that all fields are set using that helper method
skip = ['id', 'network_metadata', 'is_bfv', 'request_level_params']
skip = ['id', 'network_metadata', 'is_bfv', 'request_level_params',
'requested_networks']
for field in [f for f in spec.obj_fields if f not in skip]:
self.assertTrue(spec.obj_attr_is_set(field),
'Field: %s is not set' % field)
@ -664,6 +665,8 @@ class _TestRequestSpecObject(object):
objects.ComputeNode(host='host2', hypervisor_hostname='node2'),
]))
req_obj.retry = expected_retry
nr = objects.NetworkRequest()
req_obj.requested_networks = objects.NetworkRequestList(objects=[nr])
orig_create_in_db = request_spec.RequestSpec._create_in_db
with mock.patch.object(request_spec.RequestSpec, '_create_in_db') \
@ -677,18 +680,21 @@ class _TestRequestSpecObject(object):
# 2. requested_destination
# 3. requested_resources
# 4. retry
# 5. requested_networks
data = jsonutils.loads(updates['spec'])['nova_object.data']
self.assertNotIn('network_metadata', data)
self.assertIsNone(data['requested_destination'])
self.assertIsNone(data['requested_resources'])
self.assertIsNone(data['retry'])
self.assertIsNotNone(data['instance_uuid'])
self.assertNotIn('requested_networks', data)
# also we expect that the following fields are not reset after create
# 1. network_metadata
# 2. requested_destination
# 3. requested_resources
# 4. retry
# 5. requested_networks
self.assertIsNotNone(req_obj.network_metadata)
self.assertJsonEqual(expected_network_metadata.obj_to_primitive(),
req_obj.network_metadata.obj_to_primitive())
@ -701,6 +707,9 @@ class _TestRequestSpecObject(object):
self.assertIsNotNone(req_obj.retry)
self.assertJsonEqual(expected_retry.obj_to_primitive(),
req_obj.retry.obj_to_primitive())
self.assertIsNotNone(req_obj.requested_networks)
self.assertJsonEqual(nr.obj_to_primitive(),
req_obj.requested_networks[0].obj_to_primitive())
def test_save_does_not_persist_requested_fields(self):
req_obj = fake_request_spec.fake_spec_obj(remove_id=True)
@ -722,6 +731,8 @@ class _TestRequestSpecObject(object):
req_obj.retry = expected_retry
req_obj.num_instances = 2
req_obj.ignore_hosts = [uuids.ignored_host]
nr = objects.NetworkRequest()
req_obj.requested_networks = objects.NetworkRequestList(objects=[nr])
orig_save_in_db = request_spec.RequestSpec._save_in_db
with mock.patch.object(request_spec.RequestSpec, '_save_in_db') \
@ -736,6 +747,7 @@ class _TestRequestSpecObject(object):
# 3. requested_resources
# 4. retry
# 5. ignore_hosts
# 6. requested_networks
data = jsonutils.loads(updates['spec'])['nova_object.data']
self.assertNotIn('network_metadata', data)
self.assertIsNone(data['requested_destination'])
@ -743,6 +755,7 @@ class _TestRequestSpecObject(object):
self.assertIsNone(data['retry'])
self.assertIsNone(data['ignore_hosts'])
self.assertIsNotNone(data['instance_uuid'])
self.assertNotIn('requested_networks', data)
# also we expect that the following fields are not reset after save
# 1. network_metadata
@ -750,6 +763,7 @@ class _TestRequestSpecObject(object):
# 3. requested_resources
# 4. retry
# 5. ignore_hosts
# 6. requested_networks
self.assertIsNotNone(req_obj.network_metadata)
self.assertJsonEqual(expected_network_metadata.obj_to_primitive(),
req_obj.network_metadata.obj_to_primitive())
@ -764,6 +778,9 @@ class _TestRequestSpecObject(object):
req_obj.retry.obj_to_primitive())
self.assertIsNotNone(req_obj.ignore_hosts)
self.assertEqual([uuids.ignored_host], req_obj.ignore_hosts)
self.assertIsNotNone(req_obj.requested_networks)
self.assertJsonEqual(nr.obj_to_primitive(),
req_obj.requested_networks[0].obj_to_primitive())
def test_save(self):
req_obj = fake_request_spec.fake_spec_obj()
@ -871,6 +888,17 @@ class _TestRequestSpecObject(object):
self.assertNotIn('requested_resources', primitive)
self.assertIn('instance_uuid', primitive)
def test_compat_requested_networks(self):
req_obj = objects.RequestSpec(
requested_networks=objects.NetworkRequestList(objects=[]),
instance_uuid=uuids.instance)
versions = ovo_base.obj_tree_get_versions('RequestSpec')
primitive = req_obj.obj_to_primitive(target_version='1.13',
version_manifest=versions)
primitive = primitive['nova_object.data']
self.assertNotIn('requested_networks', primitive)
self.assertIn('instance_uuid', primitive)
def test_default_requested_destination(self):
req_obj = objects.RequestSpec()
self.assertIsNone(req_obj.requested_destination)
@ -889,6 +917,13 @@ class _TestRequestSpecObject(object):
objects.NetworkMetadata)
self.assertIn('network_metadata', req_obj)
def test_requested_networks_load(self):
req_obj = objects.RequestSpec()
self.assertNotIn('requested_networks', req_obj)
self.assertIsInstance(req_obj.requested_networks,
objects.NetworkRequestList)
self.assertIn('requested_networks', req_obj)
def test_create_raises_on_unchanged_object(self):
ctxt = context.RequestContext(uuids.user_id, uuids.project_id)
req_obj = request_spec.RequestSpec(context=ctxt)