Merge "Refactor aggregate _get_trees_matching_all()"
This commit is contained in:
commit
befebba68d
|
@ -1863,6 +1863,19 @@ def get_trees_matching_all(ctx, resources, required_traits, forbidden_traits,
|
||||||
are limited to the resource providers under the given
|
are limited to the resource providers under the given
|
||||||
root resource provider.
|
root resource provider.
|
||||||
"""
|
"""
|
||||||
|
# If 'member_of' has values, do a separate lookup to identify the
|
||||||
|
# resource providers that meet the member_of constraints.
|
||||||
|
if member_of:
|
||||||
|
rps_in_aggs = provider_ids_matching_aggregates(ctx, member_of)
|
||||||
|
if not rps_in_aggs:
|
||||||
|
# Short-circuit. The user either asked for a non-existing
|
||||||
|
# aggregate or there were no resource providers that matched
|
||||||
|
# the requirements...
|
||||||
|
return rp_candidates.RPCandidateList()
|
||||||
|
|
||||||
|
if forbidden_aggs:
|
||||||
|
rps_bad_aggs = provider_ids_matching_aggregates(ctx, [forbidden_aggs])
|
||||||
|
|
||||||
# To get all trees that collectively have all required resource,
|
# To get all trees that collectively have all required resource,
|
||||||
# aggregates and traits, we use `RPCandidateList` which has a list of
|
# aggregates and traits, we use `RPCandidateList` which has a list of
|
||||||
# three-tuples with the first element being resource provider ID, the
|
# three-tuples with the first element being resource provider ID, the
|
||||||
|
@ -1902,6 +1915,29 @@ def get_trees_matching_all(ctx, resources, required_traits, forbidden_traits,
|
||||||
len(sharing_providers), amount, rc_name,
|
len(sharing_providers), amount, rc_name,
|
||||||
len(provs_with_inv_rc.trees))
|
len(provs_with_inv_rc.trees))
|
||||||
|
|
||||||
|
if member_of:
|
||||||
|
# Aggregate on root spans the whole tree, so the rp itself
|
||||||
|
# *or its root* should be in the aggregate
|
||||||
|
provs_with_inv_rc.filter_by_rp_or_tree(rps_in_aggs)
|
||||||
|
LOG.debug("found %d providers under %d trees after applying "
|
||||||
|
"aggregate filter %s",
|
||||||
|
len(provs_with_inv_rc.rps), len(provs_with_inv_rc.trees),
|
||||||
|
member_of)
|
||||||
|
if not provs_with_inv_rc:
|
||||||
|
# Short-circuit returning an empty RPCandidateList
|
||||||
|
return rp_candidates.RPCandidateList()
|
||||||
|
if forbidden_aggs:
|
||||||
|
# Aggregate on root spans the whole tree, so the rp itself
|
||||||
|
# *and its root* should be outside the aggregate
|
||||||
|
provs_with_inv_rc.filter_by_rp_nor_tree(rps_bad_aggs)
|
||||||
|
LOG.debug("found %d providers under %d trees after applying "
|
||||||
|
"negative aggregate filter %s",
|
||||||
|
len(provs_with_inv_rc.rps), len(provs_with_inv_rc.trees),
|
||||||
|
forbidden_aggs)
|
||||||
|
if not provs_with_inv_rc:
|
||||||
|
# Short-circuit returning an empty RPCandidateList
|
||||||
|
return rp_candidates.RPCandidateList()
|
||||||
|
|
||||||
# Adding the resource providers we've got for this resource class,
|
# Adding the resource providers we've got for this resource class,
|
||||||
# filter provs_with_inv to have only trees with enough inventories
|
# filter provs_with_inv to have only trees with enough inventories
|
||||||
# for this resource class. Here "tree" includes sharing providers
|
# for this resource class. Here "tree" includes sharing providers
|
||||||
|
@ -1914,33 +1950,6 @@ def get_trees_matching_all(ctx, resources, required_traits, forbidden_traits,
|
||||||
if not provs_with_inv:
|
if not provs_with_inv:
|
||||||
return rp_candidates.RPCandidateList()
|
return rp_candidates.RPCandidateList()
|
||||||
|
|
||||||
# If 'member_of' has values, do a separate lookup to identify the
|
|
||||||
# resource providers that meet the member_of constraints.
|
|
||||||
if member_of:
|
|
||||||
rps_in_aggs = provider_ids_matching_aggregates(
|
|
||||||
ctx, member_of, rp_ids=provs_with_inv.all_rps)
|
|
||||||
if not rps_in_aggs:
|
|
||||||
# Short-circuit. The user either asked for a non-existing
|
|
||||||
# aggregate or there were no resource providers that matched
|
|
||||||
# the requirements...
|
|
||||||
return rp_candidates.RPCandidateList()
|
|
||||||
# Aggregate on root spans the whole tree, so the rp itself
|
|
||||||
# *or its root* should be in the aggregate
|
|
||||||
provs_with_inv.filter_by_rp_or_tree(rps_in_aggs)
|
|
||||||
LOG.debug("found %d providers under %d trees after applying "
|
|
||||||
"aggregate filter %s",
|
|
||||||
len(provs_with_inv.rps), len(provs_with_inv.trees),
|
|
||||||
member_of)
|
|
||||||
|
|
||||||
if forbidden_aggs:
|
|
||||||
rps_bad_aggs = provider_ids_matching_aggregates(
|
|
||||||
ctx, [forbidden_aggs], rp_ids=provs_with_inv.all_rps)
|
|
||||||
provs_with_inv.filter_by_rp_nor_tree(rps_bad_aggs)
|
|
||||||
LOG.debug("found %d providers under %d trees after applying "
|
|
||||||
"negative aggregate filter %s",
|
|
||||||
len(provs_with_inv.rps), len(provs_with_inv.trees),
|
|
||||||
forbidden_aggs)
|
|
||||||
|
|
||||||
if (not required_traits and not forbidden_traits) or (
|
if (not required_traits and not forbidden_traits) or (
|
||||||
any(sharing.values())):
|
any(sharing.values())):
|
||||||
# If there were no traits required, there's no difference in how we
|
# If there were no traits required, there's no difference in how we
|
||||||
|
|
|
@ -492,15 +492,8 @@ class ProviderTreeDBHelperTestCase(tb.PlacementDbBaseTestCase):
|
||||||
# non-root does NOT span the whole tree. Thus cn2 can't provide VCPU
|
# non-root does NOT span the whole tree. Thus cn2 can't provide VCPU
|
||||||
# or MEMORY_MB resource
|
# or MEMORY_MB resource
|
||||||
member_of = [[uuids.agg2]]
|
member_of = [[uuids.agg2]]
|
||||||
# TODO(tetsuro): "cn2_numa1_pf1" comes up. This will be filtered out
|
expected_trees = ['cn1', 'cn3']
|
||||||
# later in _alloc_candidates_multiple_providers(), so this is not a
|
|
||||||
# bug that operator faces, but filtering this out here is cleaner.
|
|
||||||
# expected_trees = ['cn1', 'cn3']
|
|
||||||
# expected_rps = ['cn1', 'cn1_numa0_pf0', 'cn1_numa1_pf1',
|
|
||||||
# 'cn3', 'cn3_numa0_pf0', 'cn3_numa1_pf1']
|
|
||||||
expected_trees = ['cn1', 'cn2', 'cn3']
|
|
||||||
expected_rps = ['cn1', 'cn1_numa0_pf0', 'cn1_numa1_pf1',
|
expected_rps = ['cn1', 'cn1_numa0_pf0', 'cn1_numa1_pf1',
|
||||||
'cn2_numa1_pf1',
|
|
||||||
'cn3', 'cn3_numa0_pf0', 'cn3_numa1_pf1']
|
'cn3', 'cn3_numa0_pf0', 'cn3_numa1_pf1']
|
||||||
_run_test(expected_trees, expected_rps, member_of=member_of)
|
_run_test(expected_trees, expected_rps, member_of=member_of)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue