Merge "placement: AllocCands.get_by_{filters => requests}"
This commit is contained in:
commit
ffeb538eb2
@ -163,13 +163,10 @@ def list_allocation_candidates(req):
|
||||
schema = _GET_SCHEMA_1_10
|
||||
util.validate_query_params(req, schema)
|
||||
|
||||
resources = util.normalize_resources_qs_param(req.GET['resources'])
|
||||
filters = {
|
||||
'resources': resources,
|
||||
}
|
||||
requests = util.parse_qs_request_groups(req.GET)
|
||||
|
||||
try:
|
||||
cands = rp_obj.AllocationCandidates.get_by_filters(context, filters)
|
||||
cands = rp_obj.AllocationCandidates.get_by_requests(context, requests)
|
||||
except exception.ResourceClassNotFound as exc:
|
||||
raise webob.exc.HTTPBadRequest(
|
||||
_('Invalid resource class in resources parameter: %(error)s') %
|
||||
|
@ -2443,24 +2443,17 @@ class AllocationCandidates(base.NovaObject):
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_by_filters(cls, context, filters):
|
||||
def get_by_requests(cls, context, requests):
|
||||
"""Returns an AllocationCandidates object containing all resource
|
||||
providers matching a set of supplied resource constraints, with a set
|
||||
of allocation requests constructed from that list of resource
|
||||
providers.
|
||||
|
||||
:param filters: A dict of filters containing one or more of the
|
||||
following keys:
|
||||
|
||||
'resources': A dict, keyed by resource class name, of amounts of
|
||||
that resource being requested. The resource provider
|
||||
must either have capacity for the amount being
|
||||
requested or be associated via aggregate to a provider
|
||||
that shares this resource and has capacity for the
|
||||
requested amount.
|
||||
:param requests: List of nova.api.openstack.placement.util.RequestGroup
|
||||
"""
|
||||
_ensure_rc_cache(context)
|
||||
alloc_reqs, provider_summaries = cls._get_by_filters(context, filters)
|
||||
alloc_reqs, provider_summaries = cls._get_by_requests(context,
|
||||
requests)
|
||||
return cls(
|
||||
context,
|
||||
allocation_requests=alloc_reqs,
|
||||
@ -2471,13 +2464,19 @@ class AllocationCandidates(base.NovaObject):
|
||||
# minimize the complexity of this method.
|
||||
@staticmethod
|
||||
@db_api.api_context_manager.reader
|
||||
def _get_by_filters(context, filters):
|
||||
def _get_by_requests(context, requests):
|
||||
# We first get the list of "root providers" that either have the
|
||||
# requested resources or are associated with the providers that
|
||||
# share one or more of the requested resource(s)
|
||||
resources = filters.get('resources')
|
||||
if not resources:
|
||||
raise ValueError(_("Supply a resources collection in filters."))
|
||||
# TODO(efried): Handle traits; handle non-sharing groups.
|
||||
# For now, this extracts just the data expected by 1.10 - no API change
|
||||
resources = [request_group.resources for request_group in requests
|
||||
if not request_group.use_same_provider]
|
||||
if len(resources) != 1:
|
||||
raise ValueError(_("The requests parameter must contain one "
|
||||
"RequestGroup with use_same_provider=False and "
|
||||
"nonempty resources."))
|
||||
resources = resources[0]
|
||||
|
||||
# Transform resource string names to internal integer IDs
|
||||
resources = {
|
||||
|
@ -9,6 +9,7 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from nova.api.openstack.placement import lib as placement_lib
|
||||
from nova import context
|
||||
from nova import exception
|
||||
from nova.objects import fields
|
||||
@ -62,7 +63,7 @@ def _find_summary_for_resource(p_sum, rc_name):
|
||||
|
||||
class AllocationCandidatesTestCase(test.NoDBTestCase):
|
||||
"""Tests a variety of scenarios with both shared and non-shared resource
|
||||
providers that the AllocationCandidates.get_by_filters() method returns a
|
||||
providers that the AllocationCandidates.get_by_requests() method returns a
|
||||
set of alternative allocation requests and provider summaries that may be
|
||||
used by the scheduler to sort/weigh the options it has for claiming
|
||||
resources against providers.
|
||||
@ -84,16 +85,12 @@ class AllocationCandidatesTestCase(test.NoDBTestCase):
|
||||
# _validate_allocation_requests to make failure results more readable.
|
||||
self.rp_uuid_to_name = {}
|
||||
|
||||
def _get_allocation_candidates(self, resources=None):
|
||||
# The resources we will request
|
||||
if resources is None:
|
||||
resources = self.requested_resources
|
||||
return rp_obj.AllocationCandidates.get_by_filters(
|
||||
self.ctx,
|
||||
filters={
|
||||
'resources': resources,
|
||||
},
|
||||
)
|
||||
def _get_allocation_candidates(self, requests=None):
|
||||
if requests is None:
|
||||
requests = [placement_lib.RequestGroup(
|
||||
use_same_provider=False,
|
||||
resources=self.requested_resources)]
|
||||
return rp_obj.AllocationCandidates.get_by_requests(self.ctx, requests)
|
||||
|
||||
def _create_provider(self, name, *aggs):
|
||||
rp = rp_obj.ResourceProvider(self.ctx, name=name,
|
||||
@ -119,7 +116,7 @@ class AllocationCandidatesTestCase(test.NoDBTestCase):
|
||||
],
|
||||
...
|
||||
]
|
||||
:param candidates: The result from AllocationCandidates.get_by_filters.
|
||||
:param candidates: The result from AllocationCandidates.get_by_requests
|
||||
"""
|
||||
# Extract/convert allocation requests from candidates
|
||||
observed = []
|
||||
@ -200,7 +197,7 @@ class AllocationCandidatesTestCase(test.NoDBTestCase):
|
||||
# resources in each allocation request, one each for VCPU, RAM, and
|
||||
# disk. The amounts of the requests should correspond to the requested
|
||||
# resource amounts in the filter:resources dict passed to
|
||||
# AllocationCandidates.get_by_filters().
|
||||
# AllocationCandidates.get_by_requests().
|
||||
expected = [
|
||||
[('cn1', fields.ResourceClass.VCPU, 1),
|
||||
('cn1', fields.ResourceClass.MEMORY_MB, 64),
|
||||
@ -297,7 +294,7 @@ class AllocationCandidatesTestCase(test.NoDBTestCase):
|
||||
# resources in each allocation request, one each for VCPU, RAM, and
|
||||
# disk. The amounts of the requests should correspond to the requested
|
||||
# resource amounts in the filter:resources dict passed to
|
||||
# AllocationCandidates.get_by_filters(). The providers for VCPU and
|
||||
# AllocationCandidates.get_by_requests(). The providers for VCPU and
|
||||
# MEMORY_MB should be the compute nodes while the provider for the
|
||||
# DISK_GB should be the shared storage pool
|
||||
expected = [
|
||||
@ -316,9 +313,12 @@ class AllocationCandidatesTestCase(test.NoDBTestCase):
|
||||
# #1705071, this resulted in a KeyError
|
||||
|
||||
alloc_cands = self._get_allocation_candidates(
|
||||
resources={
|
||||
'DISK_GB': 10,
|
||||
}
|
||||
requests=[placement_lib.RequestGroup(
|
||||
use_same_provider=False,
|
||||
resources={
|
||||
'DISK_GB': 10,
|
||||
}
|
||||
)]
|
||||
)
|
||||
|
||||
# We should only have provider summary information for the sharing
|
||||
@ -383,14 +383,15 @@ class AllocationCandidatesTestCase(test.NoDBTestCase):
|
||||
}
|
||||
|
||||
alloc_cands = self._get_allocation_candidates(
|
||||
resources=requested_resources)
|
||||
requests=[placement_lib.RequestGroup(
|
||||
use_same_provider=False, resources=requested_resources)])
|
||||
|
||||
# Verify the allocation requests that are returned. There should be 2
|
||||
# allocation requests, one for each compute node, containing 3
|
||||
# resources in each allocation request, one each for VCPU, RAM, and
|
||||
# MAGIC. The amounts of the requests should correspond to the requested
|
||||
# resource amounts in the filter:resources dict passed to
|
||||
# AllocationCandidates.get_by_filters(). The providers for VCPU and
|
||||
# AllocationCandidates.get_by_requests(). The providers for VCPU and
|
||||
# MEMORY_MB should be the compute nodes while the provider for the
|
||||
# MAGIC should be the shared custom resource provider.
|
||||
expected = [
|
||||
@ -501,11 +502,15 @@ class AllocationCandidatesTestCase(test.NoDBTestCase):
|
||||
# The shared storage's disk is RAID
|
||||
_set_traits(ss, 'MISC_SHARES_VIA_AGGREGATE', 'CUSTOM_RAID')
|
||||
|
||||
alloc_cands = rp_obj.AllocationCandidates.get_by_filters(
|
||||
self.ctx, filters={
|
||||
'resources': self.requested_resources,
|
||||
'traits': ['HW_CPU_X86_SSE', 'STORAGE_DISK_SSD', 'CUSTOM_RAID']
|
||||
}
|
||||
alloc_cands = rp_obj.AllocationCandidates.get_by_requests(
|
||||
self.ctx, [
|
||||
placement_lib.RequestGroup(
|
||||
use_same_provider=False,
|
||||
resources=self.requested_resources,
|
||||
required_traits=set(['HW_CPU_X86_SSE', 'STORAGE_DISK_SSD',
|
||||
'CUSTOM_RAID'])
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
# TODO(efried): Okay, bear with me here:
|
||||
@ -543,12 +548,15 @@ class AllocationCandidatesTestCase(test.NoDBTestCase):
|
||||
_set_traits(ss2, "MISC_SHARES_VIA_AGGREGATE")
|
||||
_add_inventory(ss2, fields.ResourceClass.DISK_GB, 1600)
|
||||
|
||||
alloc_cands = self._get_allocation_candidates(
|
||||
resources={
|
||||
'IPV4_ADDRESS': 2,
|
||||
'SRIOV_NET_VF': 1,
|
||||
'DISK_GB': 1500,
|
||||
}
|
||||
alloc_cands = self._get_allocation_candidates(requests=[
|
||||
placement_lib.RequestGroup(
|
||||
use_same_provider=False,
|
||||
resources={
|
||||
'IPV4_ADDRESS': 2,
|
||||
'SRIOV_NET_VF': 1,
|
||||
'DISK_GB': 1500,
|
||||
}
|
||||
)]
|
||||
)
|
||||
|
||||
# TODO(efried): Bug https://bugs.launchpad.net/nova/+bug/1730730
|
||||
|
Loading…
x
Reference in New Issue
Block a user