Refactor ResourceRequest constructor
This refactor changes ResourceRequest __init__ to make only an empty request and moves the ResourceReqeust creation from a RequestSpec to a static factory method. This is a preparation to introduce another factory method later that will generate a ResourceRequest from a single ResourceGroup instead of a full RequestSpec. Blueprint: support-interface-attach-with-qos-ports Change-Id: Idd58298a6b01775f962b9bf0a0835f762c8e0ed2
This commit is contained in:
parent
e6ff3651e6
commit
c3804efd42
|
@ -66,7 +66,7 @@ def isolate_aggregates(ctxt, request_spec):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Get required traits set in flavor and image
|
# Get required traits set in flavor and image
|
||||||
res_req = utils.ResourceRequest(request_spec)
|
res_req = utils.ResourceRequest.from_request_spec(request_spec)
|
||||||
required_traits = res_req.all_required_traits
|
required_traits = res_req.all_required_traits
|
||||||
|
|
||||||
keys = ['trait:%s' % trait for trait in required_traits]
|
keys = ['trait:%s' % trait for trait in required_traits]
|
||||||
|
|
|
@ -57,7 +57,30 @@ class ResourceRequest(object):
|
||||||
XS_KEYPAT = re.compile(r"^(%s)([a-zA-Z0-9_-]{1,64})?:(.*)$" %
|
XS_KEYPAT = re.compile(r"^(%s)([a-zA-Z0-9_-]{1,64})?:(.*)$" %
|
||||||
'|'.join((XS_RES_PREFIX, XS_TRAIT_PREFIX)))
|
'|'.join((XS_RES_PREFIX, XS_TRAIT_PREFIX)))
|
||||||
|
|
||||||
def __init__(self, request_spec, enable_pinning_translate=True):
|
def __init__(self):
|
||||||
|
"""Create an empty ResourceRequest
|
||||||
|
|
||||||
|
Do not call this directly, use the existing static factory methods
|
||||||
|
from_*()
|
||||||
|
"""
|
||||||
|
self._rg_by_id: ty.Dict[str, objects.RequestGroup] = {}
|
||||||
|
self._group_policy: ty.Optional[str] = None
|
||||||
|
# Default to the configured limit but _limit can be
|
||||||
|
# set to None to indicate "no limit".
|
||||||
|
self._limit = CONF.scheduler.max_placement_results
|
||||||
|
self._root_required: ty.Set[str] = set()
|
||||||
|
self._root_forbidden: ty.Set[str] = set()
|
||||||
|
self.suffixed_groups_from_flavor = 0
|
||||||
|
# TODO(stephenfin): Remove this parameter once we drop support for
|
||||||
|
# 'vcpu_pin_set'
|
||||||
|
self.cpu_pinning_requested = False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_request_spec(
|
||||||
|
cls,
|
||||||
|
request_spec: 'objects.RequestSpec',
|
||||||
|
enable_pinning_translate: bool = True
|
||||||
|
) -> 'ResourceRequest':
|
||||||
"""Create a new instance of ResourceRequest from a RequestSpec.
|
"""Create a new instance of ResourceRequest from a RequestSpec.
|
||||||
|
|
||||||
Examines the flavor, flavor extra specs, (optional) image metadata,
|
Examines the flavor, flavor extra specs, (optional) image metadata,
|
||||||
|
@ -102,17 +125,13 @@ class ResourceRequest(object):
|
||||||
:param request_spec: An instance of ``objects.RequestSpec``.
|
:param request_spec: An instance of ``objects.RequestSpec``.
|
||||||
:param enable_pinning_translate: True if the CPU policy extra specs
|
:param enable_pinning_translate: True if the CPU policy extra specs
|
||||||
should be translated to placement resources and traits.
|
should be translated to placement resources and traits.
|
||||||
|
:return: a ResourceRequest instance
|
||||||
"""
|
"""
|
||||||
# { ident: RequestGroup }
|
res_req = cls()
|
||||||
self._rg_by_id = {}
|
|
||||||
self._group_policy = None
|
|
||||||
# root_required+=these
|
# root_required+=these
|
||||||
self._root_required = request_spec.root_required
|
res_req._root_required = request_spec.root_required
|
||||||
# root_required+=!these
|
# root_required+=!these
|
||||||
self._root_forbidden = request_spec.root_forbidden
|
res_req._root_forbidden = request_spec.root_forbidden
|
||||||
# Default to the configured limit but _limit can be
|
|
||||||
# set to None to indicate "no limit".
|
|
||||||
self._limit = CONF.scheduler.max_placement_results
|
|
||||||
|
|
||||||
# TODO(efried): Handle member_of[$S], which will need to be reconciled
|
# TODO(efried): Handle member_of[$S], which will need to be reconciled
|
||||||
# with destination.aggregates handling in resources_from_request_spec
|
# with destination.aggregates handling in resources_from_request_spec
|
||||||
|
@ -124,36 +143,35 @@ class ResourceRequest(object):
|
||||||
image = objects.ImageMeta(properties=objects.ImageMetaProps())
|
image = objects.ImageMeta(properties=objects.ImageMetaProps())
|
||||||
|
|
||||||
# Parse the flavor extra specs
|
# Parse the flavor extra specs
|
||||||
self._process_extra_specs(request_spec.flavor)
|
res_req._process_extra_specs(request_spec.flavor)
|
||||||
|
|
||||||
self.suffixed_groups_from_flavor = self.get_num_of_suffixed_groups()
|
# NOTE(gibi): this assumes that _process_extra_specs() was already
|
||||||
|
# called but _process_requested_resources() hasn't called it yet.
|
||||||
|
res_req.suffixed_groups_from_flavor = (
|
||||||
|
res_req.get_num_of_suffixed_groups())
|
||||||
|
|
||||||
# Now parse the (optional) image metadata
|
# Now parse the (optional) image metadata
|
||||||
self._process_image_meta(image)
|
res_req._process_image_meta(image)
|
||||||
|
|
||||||
# TODO(stephenfin): Remove this parameter once we drop support for
|
|
||||||
# 'vcpu_pin_set'
|
|
||||||
self.cpu_pinning_requested = False
|
|
||||||
|
|
||||||
if enable_pinning_translate:
|
if enable_pinning_translate:
|
||||||
# Next up, let's handle those pesky CPU pinning policies
|
# Next up, let's handle those pesky CPU pinning policies
|
||||||
self._translate_pinning_policies(request_spec.flavor, image)
|
res_req._translate_pinning_policies(request_spec.flavor, image)
|
||||||
|
|
||||||
# Add on any request groups that came from outside of the flavor/image,
|
# Add on any request groups that came from outside of the flavor/image,
|
||||||
# e.g. from ports or device profiles.
|
# e.g. from ports or device profiles.
|
||||||
self._process_requested_resources(request_spec)
|
res_req._process_requested_resources(request_spec)
|
||||||
|
|
||||||
# Parse the flavor itself, though we'll only use these fields if they
|
# Parse the flavor itself, though we'll only use these fields if they
|
||||||
# don't conflict with something already provided by the flavor extra
|
# don't conflict with something already provided by the flavor extra
|
||||||
# specs. These are all added to the unsuffixed request group.
|
# specs. These are all added to the unsuffixed request group.
|
||||||
merged_resources = self.merged_resources()
|
merged_resources = res_req.merged_resources()
|
||||||
|
|
||||||
if (orc.VCPU not in merged_resources and
|
if (orc.VCPU not in merged_resources and
|
||||||
orc.PCPU not in merged_resources):
|
orc.PCPU not in merged_resources):
|
||||||
self._add_resource(orc.VCPU, request_spec.vcpus)
|
res_req._add_resource(orc.VCPU, request_spec.vcpus)
|
||||||
|
|
||||||
if orc.MEMORY_MB not in merged_resources:
|
if orc.MEMORY_MB not in merged_resources:
|
||||||
self._add_resource(orc.MEMORY_MB, request_spec.memory_mb)
|
res_req._add_resource(orc.MEMORY_MB, request_spec.memory_mb)
|
||||||
|
|
||||||
if orc.DISK_GB not in merged_resources:
|
if orc.DISK_GB not in merged_resources:
|
||||||
disk = request_spec.ephemeral_gb
|
disk = request_spec.ephemeral_gb
|
||||||
|
@ -162,15 +180,17 @@ class ResourceRequest(object):
|
||||||
disk += request_spec.root_gb
|
disk += request_spec.root_gb
|
||||||
|
|
||||||
if disk:
|
if disk:
|
||||||
self._add_resource(orc.DISK_GB, disk)
|
res_req._add_resource(orc.DISK_GB, disk)
|
||||||
|
|
||||||
self._translate_memory_encryption(request_spec.flavor, image)
|
res_req._translate_memory_encryption(request_spec.flavor, image)
|
||||||
|
|
||||||
self._translate_vpmems_request(request_spec.flavor)
|
res_req._translate_vpmems_request(request_spec.flavor)
|
||||||
|
|
||||||
self._translate_vtpm_request(request_spec.flavor, image)
|
res_req._translate_vtpm_request(request_spec.flavor, image)
|
||||||
|
|
||||||
self.strip_zeros()
|
res_req.strip_zeros()
|
||||||
|
|
||||||
|
return res_req
|
||||||
|
|
||||||
def _process_requested_resources(self, request_spec):
|
def _process_requested_resources(self, request_spec):
|
||||||
requested_resources = (request_spec.requested_resources
|
requested_resources = (request_spec.requested_resources
|
||||||
|
@ -554,7 +574,7 @@ def resources_from_flavor(instance, flavor):
|
||||||
# just merge together all the resources specified in the flavor and pass
|
# just merge together all the resources specified in the flavor and pass
|
||||||
# them along. This will need to be adjusted when nested and/or shared RPs
|
# them along. This will need to be adjusted when nested and/or shared RPs
|
||||||
# are in play.
|
# are in play.
|
||||||
res_req = ResourceRequest(req_spec)
|
res_req = ResourceRequest.from_request_spec(req_spec)
|
||||||
|
|
||||||
return res_req.merged_resources()
|
return res_req.merged_resources()
|
||||||
|
|
||||||
|
@ -573,7 +593,8 @@ def resources_from_request_spec(ctxt, spec_obj, host_manager,
|
||||||
:return: A ResourceRequest object.
|
:return: A ResourceRequest object.
|
||||||
:raises NoValidHost: If the specified host/node is not found in the DB.
|
:raises NoValidHost: If the specified host/node is not found in the DB.
|
||||||
"""
|
"""
|
||||||
res_req = ResourceRequest(spec_obj, enable_pinning_translate)
|
res_req = ResourceRequest.from_request_spec(
|
||||||
|
spec_obj, enable_pinning_translate)
|
||||||
|
|
||||||
# values to get the destination target compute uuid
|
# values to get the destination target compute uuid
|
||||||
target_host = None
|
target_host = None
|
||||||
|
|
|
@ -1006,7 +1006,7 @@ class SchedulerReportClientTests(test.TestCase):
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
||||||
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
self.client.get_allocation_candidates(
|
self.client.get_allocation_candidates(
|
||||||
self.context, utils.ResourceRequest(req_spec))
|
self.context, utils.ResourceRequest.from_request_spec(req_spec))
|
||||||
|
|
||||||
def _set_up_provider_tree(self):
|
def _set_up_provider_tree(self):
|
||||||
r"""Create two compute nodes in placement ("this" one, and another one)
|
r"""Create two compute nodes in placement ("this" one, and another one)
|
||||||
|
@ -1221,7 +1221,7 @@ class SchedulerReportClientTests(test.TestCase):
|
||||||
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
self._set_up_provider_tree()
|
self._set_up_provider_tree()
|
||||||
acs = self.client.get_allocation_candidates(
|
acs = self.client.get_allocation_candidates(
|
||||||
self.context, utils.ResourceRequest(req_spec))[0]
|
self.context, utils.ResourceRequest.from_request_spec(req_spec))[0]
|
||||||
# We're not going to validate all the allocations - Placement has
|
# We're not going to validate all the allocations - Placement has
|
||||||
# tests for that - just make sure they're there.
|
# tests for that - just make sure they're there.
|
||||||
self.assertEqual(3, len(acs))
|
self.assertEqual(3, len(acs))
|
||||||
|
@ -1284,7 +1284,7 @@ class SchedulerReportClientTests(test.TestCase):
|
||||||
(ot.COMPUTE_STATUS_DISABLED, ot.COMPUTE_VOLUME_EXTEND,
|
(ot.COMPUTE_STATUS_DISABLED, ot.COMPUTE_VOLUME_EXTEND,
|
||||||
'CUSTOM_FOO'))
|
'CUSTOM_FOO'))
|
||||||
acs, _, ver = self.client.get_allocation_candidates(
|
acs, _, ver = self.client.get_allocation_candidates(
|
||||||
self.context, utils.ResourceRequest(req_spec))
|
self.context, utils.ResourceRequest.from_request_spec(req_spec))
|
||||||
self.assertEqual('1.35', ver)
|
self.assertEqual('1.35', ver)
|
||||||
# This prints which ddt permutation we're using if it fails.
|
# This prints which ddt permutation we're using if it fails.
|
||||||
self.assertEqual(data['expected_acs'], len(acs), data)
|
self.assertEqual(data['expected_acs'], len(acs), data)
|
||||||
|
|
|
@ -2087,7 +2087,7 @@ class TestProviderOperations(SchedulerReportClientTestCase):
|
||||||
'group_policy3': 'none',
|
'group_policy3': 'none',
|
||||||
})
|
})
|
||||||
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
resources = scheduler_utils.ResourceRequest(req_spec)
|
resources = scheduler_utils.ResourceRequest.from_request_spec(req_spec)
|
||||||
resources.get_request_group(None).aggregates = [
|
resources.get_request_group(None).aggregates = [
|
||||||
['agg1', 'agg2', 'agg3'], ['agg1', 'agg2']]
|
['agg1', 'agg2', 'agg3'], ['agg1', 'agg2']]
|
||||||
forbidden_aggs = set(['agg1', 'agg5', 'agg6'])
|
forbidden_aggs = set(['agg1', 'agg5', 'agg6'])
|
||||||
|
@ -2145,7 +2145,7 @@ class TestProviderOperations(SchedulerReportClientTestCase):
|
||||||
'group_policy': 'bogus',
|
'group_policy': 'bogus',
|
||||||
})
|
})
|
||||||
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
resources = scheduler_utils.ResourceRequest(req_spec)
|
resources = scheduler_utils.ResourceRequest.from_request_spec(req_spec)
|
||||||
expected_path = '/allocation_candidates'
|
expected_path = '/allocation_candidates'
|
||||||
expected_query = [
|
expected_query = [
|
||||||
('limit', '42'),
|
('limit', '42'),
|
||||||
|
@ -2189,7 +2189,7 @@ class TestProviderOperations(SchedulerReportClientTestCase):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
||||||
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
req_spec = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
resources = scheduler_utils.ResourceRequest(req_spec)
|
resources = scheduler_utils.ResourceRequest.from_request_spec(req_spec)
|
||||||
|
|
||||||
res = self.client.get_allocation_candidates(self.context, resources)
|
res = self.client.get_allocation_candidates(self.context, resources)
|
||||||
|
|
||||||
|
|
|
@ -834,7 +834,7 @@ class TestUtils(TestUtilsBase):
|
||||||
actual = utils.resources_from_flavor(instance, flavor)
|
actual = utils.resources_from_flavor(instance, flavor)
|
||||||
self.assertEqual(expected, actual)
|
self.assertEqual(expected, actual)
|
||||||
|
|
||||||
def test_resource_request_init(self):
|
def test_resource_request_from_request_spec(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
||||||
|
|
||||||
|
@ -848,10 +848,10 @@ class TestUtils(TestUtilsBase):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
|
|
||||||
def test_resource_request_init_with_extra_specs(self):
|
def test_resource_request_from_request_spec_with_extra_specs(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||||
extra_specs={
|
extra_specs={
|
||||||
|
@ -934,7 +934,7 @@ class TestUtils(TestUtilsBase):
|
||||||
)
|
)
|
||||||
|
|
||||||
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
expected_querystring = (
|
expected_querystring = (
|
||||||
'group_policy=isolate&'
|
'group_policy=isolate&'
|
||||||
|
@ -949,7 +949,7 @@ class TestUtils(TestUtilsBase):
|
||||||
)
|
)
|
||||||
self.assertEqual(expected_querystring, rr.to_querystring())
|
self.assertEqual(expected_querystring, rr.to_querystring())
|
||||||
|
|
||||||
def _test_resource_request_init_with_legacy_extra_specs(self):
|
def _test_resource_request_from_rs_with_legacy_extra_specs(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||||
extra_specs={
|
extra_specs={
|
||||||
|
@ -960,7 +960,7 @@ class TestUtils(TestUtilsBase):
|
||||||
|
|
||||||
return objects.RequestSpec(flavor=flavor, is_bfv=False)
|
return objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
|
|
||||||
def test_resource_request_init_with_legacy_extra_specs(self):
|
def test_resource_request_from_request_spec_with_legacy_extra_specs(self):
|
||||||
expected = FakeResourceRequest()
|
expected = FakeResourceRequest()
|
||||||
expected._rg_by_id[None] = objects.RequestGroup(
|
expected._rg_by_id[None] = objects.RequestGroup(
|
||||||
use_same_provider=False,
|
use_same_provider=False,
|
||||||
|
@ -976,12 +976,14 @@ class TestUtils(TestUtilsBase):
|
||||||
'HW_CPU_HYPERTHREADING',
|
'HW_CPU_HYPERTHREADING',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
rs = self._test_resource_request_init_with_legacy_extra_specs()
|
rs = self._test_resource_request_from_rs_with_legacy_extra_specs()
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
self.assertTrue(rr.cpu_pinning_requested)
|
self.assertTrue(rr.cpu_pinning_requested)
|
||||||
|
|
||||||
def test_resource_request_init_with_legacy_extra_specs_no_translate(self):
|
def test_resource_request_from_rs_with_legacy_extra_specs_no_translate(
|
||||||
|
self
|
||||||
|
):
|
||||||
expected = FakeResourceRequest()
|
expected = FakeResourceRequest()
|
||||||
expected._rg_by_id[None] = objects.RequestGroup(
|
expected._rg_by_id[None] = objects.RequestGroup(
|
||||||
use_same_provider=False,
|
use_same_provider=False,
|
||||||
|
@ -996,12 +998,13 @@ class TestUtils(TestUtilsBase):
|
||||||
# because enable_pinning_translate=False
|
# because enable_pinning_translate=False
|
||||||
forbidden_traits=set(),
|
forbidden_traits=set(),
|
||||||
)
|
)
|
||||||
rs = self._test_resource_request_init_with_legacy_extra_specs()
|
rs = self._test_resource_request_from_rs_with_legacy_extra_specs()
|
||||||
rr = utils.ResourceRequest(rs, enable_pinning_translate=False)
|
rr = utils.ResourceRequest.from_request_spec(
|
||||||
|
rs, enable_pinning_translate=False)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
self.assertFalse(rr.cpu_pinning_requested)
|
self.assertFalse(rr.cpu_pinning_requested)
|
||||||
|
|
||||||
def test_resource_request_init_with_image_props(self):
|
def test_resource_request_from_request_spec_with_image_props(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
||||||
image = objects.ImageMeta.from_dict({
|
image = objects.ImageMeta.from_dict({
|
||||||
|
@ -1024,10 +1027,10 @@ class TestUtils(TestUtilsBase):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
rs = objects.RequestSpec(flavor=flavor, image=image, is_bfv=False)
|
rs = objects.RequestSpec(flavor=flavor, image=image, is_bfv=False)
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
|
|
||||||
def _test_resource_request_init_with_legacy_image_props(self):
|
def _test_resource_request_from_rs_with_legacy_image_props(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
||||||
image = objects.ImageMeta.from_dict({
|
image = objects.ImageMeta.from_dict({
|
||||||
|
@ -1039,7 +1042,7 @@ class TestUtils(TestUtilsBase):
|
||||||
})
|
})
|
||||||
return objects.RequestSpec(flavor=flavor, image=image, is_bfv=False)
|
return objects.RequestSpec(flavor=flavor, image=image, is_bfv=False)
|
||||||
|
|
||||||
def test_resource_request_init_with_legacy_image_props(self):
|
def test_resource_request_from_request_spec_with_legacy_image_props(self):
|
||||||
expected = FakeResourceRequest()
|
expected = FakeResourceRequest()
|
||||||
expected._rg_by_id[None] = objects.RequestGroup(
|
expected._rg_by_id[None] = objects.RequestGroup(
|
||||||
use_same_provider=False,
|
use_same_provider=False,
|
||||||
|
@ -1054,12 +1057,14 @@ class TestUtils(TestUtilsBase):
|
||||||
'HW_CPU_HYPERTHREADING',
|
'HW_CPU_HYPERTHREADING',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
rs = self._test_resource_request_init_with_legacy_image_props()
|
rs = self._test_resource_request_from_rs_with_legacy_image_props()
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
self.assertTrue(rr.cpu_pinning_requested)
|
self.assertTrue(rr.cpu_pinning_requested)
|
||||||
|
|
||||||
def test_resource_request_init_with_legacy_image_props_no_translate(self):
|
def test_resource_request_from_rs_with_legacy_image_props_no_translate(
|
||||||
|
self
|
||||||
|
):
|
||||||
expected = FakeResourceRequest()
|
expected = FakeResourceRequest()
|
||||||
expected._rg_by_id[None] = objects.RequestGroup(
|
expected._rg_by_id[None] = objects.RequestGroup(
|
||||||
use_same_provider=False,
|
use_same_provider=False,
|
||||||
|
@ -1074,12 +1079,15 @@ class TestUtils(TestUtilsBase):
|
||||||
# because enable_pinning_translate=False
|
# because enable_pinning_translate=False
|
||||||
required_traits=set(),
|
required_traits=set(),
|
||||||
)
|
)
|
||||||
rs = self._test_resource_request_init_with_legacy_image_props()
|
rs = self._test_resource_request_from_rs_with_legacy_image_props()
|
||||||
rr = utils.ResourceRequest(rs, enable_pinning_translate=False)
|
rr = utils.ResourceRequest.from_request_spec(
|
||||||
|
rs, enable_pinning_translate=False)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
self.assertFalse(rr.cpu_pinning_requested)
|
self.assertFalse(rr.cpu_pinning_requested)
|
||||||
|
|
||||||
def _test_resource_request_init_with_mixed_cpus(self, extra_specs):
|
def _test_resource_request_from_request_spec_with_mixed_cpus(
|
||||||
|
self, extra_specs
|
||||||
|
):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=4, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
vcpus=4, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||||
extra_specs=extra_specs)
|
extra_specs=extra_specs)
|
||||||
|
@ -1095,10 +1103,12 @@ class TestUtils(TestUtilsBase):
|
||||||
},
|
},
|
||||||
required_traits=set(),
|
required_traits=set(),
|
||||||
)
|
)
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
|
|
||||||
def test_resource_request_init_with_mixed_cpus_dedicated(self):
|
def test_resource_request_from_request_spec_with_mixed_cpus_dedicated(
|
||||||
|
self
|
||||||
|
):
|
||||||
"""Ensure the mixed instance, which is generated through
|
"""Ensure the mixed instance, which is generated through
|
||||||
'hw:cpu_dedicated_mask' extra spec, properly requests the PCPU, VCPU,
|
'hw:cpu_dedicated_mask' extra spec, properly requests the PCPU, VCPU,
|
||||||
MEMORY_MB and DISK_GB resources.
|
MEMORY_MB and DISK_GB resources.
|
||||||
|
@ -1107,9 +1117,10 @@ class TestUtils(TestUtilsBase):
|
||||||
'hw:cpu_policy': 'mixed',
|
'hw:cpu_policy': 'mixed',
|
||||||
'hw:cpu_dedicated_mask': '2,3'
|
'hw:cpu_dedicated_mask': '2,3'
|
||||||
}
|
}
|
||||||
self._test_resource_request_init_with_mixed_cpus(extra_specs)
|
self._test_resource_request_from_request_spec_with_mixed_cpus(
|
||||||
|
extra_specs)
|
||||||
|
|
||||||
def test_resource_request_init_with_mixed_cpus_realtime(self):
|
def test_resource_request_from_request_spec_with_mixed_cpus_realtime(self):
|
||||||
"""Ensure the mixed instance, which is generated through real-time CPU
|
"""Ensure the mixed instance, which is generated through real-time CPU
|
||||||
interface, properly requests the PCPU, VCPU, MEMORY_BM and DISK_GB
|
interface, properly requests the PCPU, VCPU, MEMORY_BM and DISK_GB
|
||||||
resources.
|
resources.
|
||||||
|
@ -1119,9 +1130,12 @@ class TestUtils(TestUtilsBase):
|
||||||
"hw:cpu_realtime": "yes",
|
"hw:cpu_realtime": "yes",
|
||||||
"hw:cpu_realtime_mask": '2,3'
|
"hw:cpu_realtime_mask": '2,3'
|
||||||
}
|
}
|
||||||
self._test_resource_request_init_with_mixed_cpus(extra_specs)
|
self._test_resource_request_from_request_spec_with_mixed_cpus(
|
||||||
|
extra_specs)
|
||||||
|
|
||||||
def _test_resource_request_init_with_mixed_cpus_iso_emu(self, extra_specs):
|
def _test_resource_request_from_request_spec_with_mixed_cpus_iso_emu(
|
||||||
|
self, extra_specs
|
||||||
|
):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=4, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
vcpus=4, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||||
extra_specs=extra_specs)
|
extra_specs=extra_specs)
|
||||||
|
@ -1139,10 +1153,10 @@ class TestUtils(TestUtilsBase):
|
||||||
},
|
},
|
||||||
required_traits=set(),
|
required_traits=set(),
|
||||||
)
|
)
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
|
|
||||||
def test_resource_request_init_with_mixed_cpus_iso_emu_realtime(self):
|
def test_resource_request_from_rswith_mixed_cpus_iso_emu_realtime(self):
|
||||||
"""Ensure the mixed instance, which is generated through the
|
"""Ensure the mixed instance, which is generated through the
|
||||||
'hw:cpu_dedicated_mask' extra spec, specs, properly requests the PCPU,
|
'hw:cpu_dedicated_mask' extra spec, specs, properly requests the PCPU,
|
||||||
VCPU, MEMORY_MB, DISK_GB resources, ensure an extra PCPU resource is
|
VCPU, MEMORY_MB, DISK_GB resources, ensure an extra PCPU resource is
|
||||||
|
@ -1153,9 +1167,10 @@ class TestUtils(TestUtilsBase):
|
||||||
'hw:cpu_dedicated_mask': '2,3',
|
'hw:cpu_dedicated_mask': '2,3',
|
||||||
'hw:emulator_threads_policy': 'isolate',
|
'hw:emulator_threads_policy': 'isolate',
|
||||||
}
|
}
|
||||||
self._test_resource_request_init_with_mixed_cpus_iso_emu(extra_specs)
|
self._test_resource_request_from_request_spec_with_mixed_cpus_iso_emu(
|
||||||
|
extra_specs)
|
||||||
|
|
||||||
def test_resource_request_init_with_mixed_cpus_iso_emu_dedicated(self):
|
def test_resource_request_from_rs_with_mixed_cpus_iso_emu_dedicated(self):
|
||||||
"""Ensure the mixed instance, which is generated through realtime extra
|
"""Ensure the mixed instance, which is generated through realtime extra
|
||||||
specs, properly requests the PCPU, VCPU, MEMORY_MB, DISK_GB resources,
|
specs, properly requests the PCPU, VCPU, MEMORY_MB, DISK_GB resources,
|
||||||
ensure an extra PCPU resource is requested due to a ISOLATE emulator
|
ensure an extra PCPU resource is requested due to a ISOLATE emulator
|
||||||
|
@ -1167,9 +1182,10 @@ class TestUtils(TestUtilsBase):
|
||||||
"hw:cpu_realtime_mask": '2,3',
|
"hw:cpu_realtime_mask": '2,3',
|
||||||
'hw:emulator_threads_policy': 'isolate',
|
'hw:emulator_threads_policy': 'isolate',
|
||||||
}
|
}
|
||||||
self._test_resource_request_init_with_mixed_cpus_iso_emu(extra_specs)
|
self._test_resource_request_from_request_spec_with_mixed_cpus_iso_emu(
|
||||||
|
extra_specs)
|
||||||
|
|
||||||
def test_resource_request_init_is_bfv(self):
|
def test_resource_request_from_request_spec_is_bfv(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=1555)
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=1555)
|
||||||
|
|
||||||
|
@ -1185,10 +1201,10 @@ class TestUtils(TestUtilsBase):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
rs = objects.RequestSpec(flavor=flavor, is_bfv=True)
|
rs = objects.RequestSpec(flavor=flavor, is_bfv=True)
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
|
|
||||||
def test_resource_request_with_vpmems(self):
|
def test_resource_request_from_request_spec_with_vpmems(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||||
extra_specs={'hw:pmem': '4GB, 4GB,SMALL'})
|
extra_specs={'hw:pmem': '4GB, 4GB,SMALL'})
|
||||||
|
@ -1205,10 +1221,10 @@ class TestUtils(TestUtilsBase):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
|
|
||||||
def test_resource_request_with_vtpm_1_2(self):
|
def test_resource_request_from_request_spec_with_vtpm_1_2(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||||
extra_specs={'hw:tpm_version': '1.2', 'hw:tpm_model': 'tpm-tis'},
|
extra_specs={'hw:tpm_version': '1.2', 'hw:tpm_model': 'tpm-tis'},
|
||||||
|
@ -1230,10 +1246,10 @@ class TestUtils(TestUtilsBase):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
rs = objects.RequestSpec(flavor=flavor, image=image, is_bfv=False)
|
rs = objects.RequestSpec(flavor=flavor, image=image, is_bfv=False)
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
|
|
||||||
def test_resource_request_with_vtpm_2_0(self):
|
def test_resource_request_from_request_spec_with_vtpm_2_0(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||||
extra_specs={'hw:tpm_version': '2.0', 'hw:tpm_model': 'tpm-crb'},
|
extra_specs={'hw:tpm_version': '2.0', 'hw:tpm_model': 'tpm-crb'},
|
||||||
|
@ -1255,14 +1271,14 @@ class TestUtils(TestUtilsBase):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
rs = objects.RequestSpec(flavor=flavor, image=image, is_bfv=False)
|
rs = objects.RequestSpec(flavor=flavor, image=image, is_bfv=False)
|
||||||
rr = utils.ResourceRequest(rs)
|
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||||
self.assertResourceRequestsEqual(expected, rr)
|
self.assertResourceRequestsEqual(expected, rr)
|
||||||
|
|
||||||
def test_resource_request_add_group_inserts_the_group(self):
|
def test_resource_request_add_group_inserts_the_group(self):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
||||||
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
req = utils.ResourceRequest(rs)
|
req = utils.ResourceRequest.from_request_spec(rs)
|
||||||
rg1 = objects.RequestGroup(requester_id='foo',
|
rg1 = objects.RequestGroup(requester_id='foo',
|
||||||
required_traits={'CUSTOM_FOO'})
|
required_traits={'CUSTOM_FOO'})
|
||||||
req._add_request_group(rg1)
|
req._add_request_group(rg1)
|
||||||
|
@ -1279,7 +1295,7 @@ class TestUtils(TestUtilsBase):
|
||||||
flavor = objects.Flavor(
|
flavor = objects.Flavor(
|
||||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0)
|
||||||
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
rs = objects.RequestSpec(flavor=flavor, is_bfv=False)
|
||||||
req = utils.ResourceRequest(rs)
|
req = utils.ResourceRequest.from_request_spec(rs)
|
||||||
rg = objects.RequestGroup(requester_id='foo')
|
rg = objects.RequestGroup(requester_id='foo')
|
||||||
self.assertRaises(ValueError, req._add_request_group, rg)
|
self.assertRaises(ValueError, req._add_request_group, rg)
|
||||||
|
|
||||||
|
@ -1620,7 +1636,7 @@ class TestEncryptedMemoryTranslation(TestUtilsBase):
|
||||||
|
|
||||||
def _get_resource_request(self, extra_specs, image):
|
def _get_resource_request(self, extra_specs, image):
|
||||||
reqspec = self._get_request_spec(extra_specs, image)
|
reqspec = self._get_request_spec(extra_specs, image)
|
||||||
return utils.ResourceRequest(reqspec)
|
return utils.ResourceRequest.from_request_spec(reqspec)
|
||||||
|
|
||||||
def _get_expected_resource_request(self, mem_encryption_context):
|
def _get_expected_resource_request(self, mem_encryption_context):
|
||||||
expected_resources = {
|
expected_resources = {
|
||||||
|
@ -1707,7 +1723,7 @@ class TestEncryptedMemoryTranslation(TestUtilsBase):
|
||||||
)
|
)
|
||||||
exc = self.assertRaises(
|
exc = self.assertRaises(
|
||||||
exception.FlavorImageConflict,
|
exception.FlavorImageConflict,
|
||||||
utils.ResourceRequest, reqspec
|
utils.ResourceRequest.from_request_spec, reqspec
|
||||||
)
|
)
|
||||||
error_data = {
|
error_data = {
|
||||||
'flavor_name': self.flavor_name,
|
'flavor_name': self.flavor_name,
|
||||||
|
|
|
@ -655,7 +655,8 @@ def mdev_uuid2name(mdev_uuid: str) -> str:
|
||||||
|
|
||||||
def get_flags_by_flavor_specs(flavor: 'objects.Flavor') -> ty.Set[str]:
|
def get_flags_by_flavor_specs(flavor: 'objects.Flavor') -> ty.Set[str]:
|
||||||
req_spec = objects.RequestSpec(flavor=flavor)
|
req_spec = objects.RequestSpec(flavor=flavor)
|
||||||
resource_request = scheduler_utils.ResourceRequest(req_spec)
|
resource_request = scheduler_utils.ResourceRequest.from_request_spec(
|
||||||
|
req_spec)
|
||||||
required_traits = resource_request.all_required_traits
|
required_traits = resource_request.all_required_traits
|
||||||
|
|
||||||
flags = [TRAITS_CPU_MAPPING[trait] for trait in required_traits
|
flags = [TRAITS_CPU_MAPPING[trait] for trait in required_traits
|
||||||
|
|
Loading…
Reference in New Issue