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