Add same_subtree field to RequestLevelParams
Extend RequestLevelParams o.v.o to store lists of request group name suffixes that later will be used as same_subtree query parameters in the Placement GET /allocation_candidates API calls This patch adds logic to parse the same_subtree field out from the port resource_request as well as additional helpers used later on to combine RequestLevelParams objects coming from different ports. Change-Id: I523737ef88850a4e2646221a52106016c9595847 blueprint: qos-minimum-guaranteed-packet-rate
This commit is contained in:
@@ -1293,16 +1293,55 @@ class RequestLevelParams(base.NovaObject):
|
||||
RequestGroup).
|
||||
"""
|
||||
# Version 1.0: Initial version
|
||||
VERSION = '1.0'
|
||||
# Version 1.1: Add same_subtree field
|
||||
VERSION = '1.1'
|
||||
|
||||
fields = {
|
||||
# Traits required on the root provider
|
||||
'root_required': fields.SetOfStringsField(default=set()),
|
||||
# Traits forbidden on the root provider
|
||||
'root_forbidden': fields.SetOfStringsField(default=set()),
|
||||
# Lists of request group suffixes that needs to be allocated from the
|
||||
# same provider subtree
|
||||
'same_subtree': fields.ListOfListsOfStringsField(default=list()),
|
||||
# NOTE(efried): group_policy would be appropriate to include here, once
|
||||
# we have a use case for it.
|
||||
}
|
||||
|
||||
def obj_load_attr(self, attrname):
|
||||
self.obj_set_defaults(attrname)
|
||||
|
||||
def obj_make_compatible(self, primitive, target_version):
|
||||
super().obj_make_compatible(primitive, target_version)
|
||||
|
||||
target_version = versionutils.convert_version_to_tuple(target_version)
|
||||
if target_version < (1, 1):
|
||||
if 'same_subtree' in primitive:
|
||||
del primitive['same_subtree']
|
||||
|
||||
@classmethod
|
||||
def from_port_request(cls, port_resource_request):
|
||||
"""Extracts request level global parameters from the resource_request
|
||||
of a neutron port.
|
||||
|
||||
Neutron only uses same_subtree at the moment.
|
||||
"""
|
||||
same_subtree = port_resource_request.get('same_subtree')
|
||||
if same_subtree:
|
||||
# NOTE(gibi): A single port only has a single list of groups
|
||||
# requesting same subtree, but the RequestLevelParams maintains a
|
||||
# list of such subtree requests
|
||||
return cls(same_subtree=[same_subtree])
|
||||
|
||||
return cls()
|
||||
|
||||
def extend_with(self, other_req_lvl_params):
|
||||
"""Extends the existing object with parameter values from another
|
||||
RequestLevelParams object. That new set of requirements are connected
|
||||
with the existing ones with a logical AND operation.
|
||||
"""
|
||||
self.root_required = self.root_required.union(
|
||||
other_req_lvl_params.root_required)
|
||||
self.root_forbidden = self.root_forbidden.union(
|
||||
other_req_lvl_params.root_forbidden)
|
||||
self.same_subtree.extend(other_req_lvl_params.same_subtree)
|
||||
|
||||
@@ -1123,7 +1123,7 @@ object_data = {
|
||||
'Quotas': '1.3-3b2b91371f60e788035778fc5f87797d',
|
||||
'QuotasNoOp': '1.3-d1593cf969c81846bc8192255ea95cce',
|
||||
'RequestGroup': '1.3-0458d350a8ec9d0673f9be5640a990ce',
|
||||
'RequestLevelParams': '1.0-1e5c8c18bd44cd233c8b32509c99d06f',
|
||||
'RequestLevelParams': '1.1-3a718a0ae0bfdec669e7108631b3f313',
|
||||
'RequestSpec': '1.14-2cdbda368ca07e10905dc5fe96908a58',
|
||||
'Resource': '1.0-d8a2abbb380da583b995fd118f6a8953',
|
||||
'ResourceList': '1.0-4a53826625cc280e15fae64a575e0879',
|
||||
|
||||
@@ -1692,3 +1692,54 @@ class TestMappingRequestGroupsToProviders(test.NoDBTestCase):
|
||||
allocations, provider_traits)
|
||||
|
||||
self.assertIn('allocations leftover', mock_debug.mock_calls[3][1][0])
|
||||
|
||||
|
||||
class TestRequestLevelParams(test.NoDBTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.user_id = uuids.user_id
|
||||
self.project_id = uuids.project_id
|
||||
self.context = context.RequestContext(uuids.user_id, uuids.project_id)
|
||||
|
||||
def test_obj_make_compatible(self):
|
||||
obj = request_spec.RequestLevelParams(
|
||||
self.context,
|
||||
root_required={"CUSTOM_FOO", "CUSTOM_BAR"},
|
||||
root_forbidden={"CUSTOM_BAZ"},
|
||||
same_subtree=[["group1", "group2"], ["group3", "group4"]])
|
||||
|
||||
manifest = ovo_base.obj_tree_get_versions(obj.obj_name())
|
||||
|
||||
obj_primitive = obj.obj_to_primitive(
|
||||
target_version='1.1',
|
||||
version_manifest=manifest)['nova_object.data']
|
||||
self.assertIn('root_required', obj_primitive)
|
||||
self.assertIn('root_forbidden', obj_primitive)
|
||||
self.assertIn('same_subtree', obj_primitive)
|
||||
|
||||
obj_primitive = obj.obj_to_primitive(
|
||||
target_version='1.0',
|
||||
version_manifest=manifest)['nova_object.data']
|
||||
self.assertIn('root_required', obj_primitive)
|
||||
self.assertIn('root_forbidden', obj_primitive)
|
||||
self.assertNotIn('same_subtree', obj_primitive)
|
||||
|
||||
def test_extend_with(self):
|
||||
obj1 = request_spec.RequestLevelParams(
|
||||
self.context,
|
||||
root_required={"CUSTOM_FOO"},
|
||||
root_forbidden={"CUSTOM_BAZ"},
|
||||
same_subtree=[["group1", "group2"]])
|
||||
obj2 = request_spec.RequestLevelParams(
|
||||
self.context,
|
||||
root_required={"CUSTOM_BAR"},
|
||||
root_forbidden={"CUSTOM_FOOBAR"},
|
||||
same_subtree=[["group3", "group4"]])
|
||||
|
||||
obj1.extend_with(obj2)
|
||||
|
||||
self.assertEqual({"CUSTOM_FOO", "CUSTOM_BAR"}, obj1.root_required)
|
||||
self.assertEqual({"CUSTOM_BAZ", "CUSTOM_FOOBAR"}, obj1.root_forbidden)
|
||||
self.assertEqual(
|
||||
[["group1", "group2"], ["group3", "group4"]],
|
||||
obj1.same_subtree)
|
||||
|
||||
Reference in New Issue
Block a user