Reusable RequestGroup.add_{resource|trait}

This simply refactors the (minimal) logic to add a resource or
(required/forbidden) trait to a RequestGroup into RequestGroup itself.
It didn't make sense for it to be in ResourceRequest.

This will make the logic reusable for e.g. assembling
RequestSpec.requested_resources for accelerator requests.

This is a straight refactor, thoroughly covered by existing tests.

Change-Id: Ied2047a6bd22d194b3c33dca44bf81e7eebc6c86
This commit is contained in:
Eric Fried 2019-11-27 12:12:55 -06:00
parent e0eb0a520f
commit a576de8f76
3 changed files with 37 additions and 34 deletions

View File

@ -15,6 +15,7 @@
import copy
import itertools
import os_resource_classes as orc
from oslo_log import log as logging
from oslo_serialization import jsonutils
from oslo_utils import versionutils
@ -1119,3 +1120,36 @@ class RequestGroup(base.NovaObject):
del primitive['requester_id']
if 'provider_uuids' in primitive:
del primitive['provider_uuids']
def add_resource(self, rclass, amount):
# Validate the class.
if not (rclass.startswith(orc.CUSTOM_NAMESPACE) or
rclass in orc.STANDARDS):
LOG.warning(
"Received an invalid ResourceClass '%(key)s' in extra_specs.",
{"key": rclass})
return
# val represents the amount. Convert to int, or warn and skip.
try:
amount = int(amount)
if amount < 0:
raise ValueError()
except ValueError:
LOG.warning(
"Resource amounts must be nonnegative integers. Received '%s'",
amount)
return
self.resources[rclass] = amount
def add_trait(self, trait_name, trait_type):
# Currently the only valid values for a trait entry are 'required'
# and 'forbidden'
trait_vals = ('required', 'forbidden')
if trait_type == 'required':
self.required_traits.add(trait_name)
elif trait_type == 'forbidden':
self.forbidden_traits.add(trait_name)
else:
LOG.warning(
"Only (%(tvals)s) traits are supported. Received '%(val)s'.",
{"tvals": ', '.join(trait_vals), "val": trait_type})

View File

@ -309,41 +309,10 @@ class ResourceRequest(object):
self._rg_by_id[ident] = request_group
def _add_resource(self, groupid, rclass, amount):
# Validate the class.
if not (rclass.startswith(orc.CUSTOM_NAMESPACE) or
rclass in orc.STANDARDS):
LOG.warning(
"Received an invalid ResourceClass '%(key)s' in extra_specs.",
{"key": rclass})
return
# val represents the amount. Convert to int, or warn and skip.
try:
amount = int(amount)
if amount < 0:
raise ValueError()
except ValueError:
LOG.warning(
"Resource amounts must be nonnegative integers. Received "
"'%(val)s' for key resources%(groupid)s.",
{"groupid": groupid or '', "val": amount})
return
self.get_request_group(groupid).resources[rclass] = amount
self.get_request_group(groupid).add_resource(rclass, amount)
def _add_trait(self, groupid, trait_name, trait_type):
# Currently the only valid values for a trait entry are 'required'
# and 'forbidden'
trait_vals = ('required', 'forbidden')
if trait_type == 'required':
self.get_request_group(groupid).required_traits.add(trait_name)
elif trait_type == 'forbidden':
self.get_request_group(groupid).forbidden_traits.add(trait_name)
else:
LOG.warning(
"Only (%(tvals)s) traits are supported. Received '%(val)s' "
"for key trait%(groupid)s.",
{"tvals": ', '.join(trait_vals), "groupid": groupid or '',
"val": trait_type})
return
self.get_request_group(groupid).add_trait(trait_name, trait_type)
def _add_group_policy(self, policy):
# The only valid values for group_policy are 'none' and 'isolate'.

View File

@ -266,7 +266,7 @@ class TestUtils(TestUtilsBase):
extra_specs={
"resources:DOESNT_EXIST": 0})
fake_spec = objects.RequestSpec(flavor=flavor)
with mock.patch("nova.scheduler.utils.LOG.warning") as mock_log:
with mock.patch("nova.objects.request_spec.LOG.warning") as mock_log:
utils.resources_from_request_spec(
self.context, fake_spec, self.mock_host_manager)
mock_log.assert_called_once()