Merge "Fix member_of with sharing providers"
This commit is contained in:
commit
d487ce5526
|
@ -1075,7 +1075,7 @@ class ResourceProvider(base.VersionedObject, base.TimestampedObject):
|
|||
|
||||
|
||||
@db_api.api_context_manager.reader
|
||||
def _get_providers_with_shared_capacity(ctx, rc_id, amount):
|
||||
def _get_providers_with_shared_capacity(ctx, rc_id, amount, member_of=None):
|
||||
"""Returns a list of resource provider IDs (internal IDs, not UUIDs)
|
||||
that have capacity for a requested amount of a resource and indicate that
|
||||
they share resource via an aggregate association.
|
||||
|
@ -1111,6 +1111,13 @@ def _get_providers_with_shared_capacity(ctx, rc_id, amount):
|
|||
To follow the example above, if we were to call
|
||||
_get_providers_with_shared_capacity(ctx, "DISK_GB", 100), we would want to
|
||||
get back the ID for the NFS_SHARE resource provider.
|
||||
|
||||
:param rc_id: Internal ID of the requested resource class.
|
||||
:param amount: Amount of the requested resource.
|
||||
:param member_of: When present, contains a list of lists of aggregate
|
||||
uuids that are used to filter the returned list of
|
||||
resource providers that *directly* belong to the
|
||||
aggregates referenced.
|
||||
"""
|
||||
# The SQL we need to generate here looks like this:
|
||||
#
|
||||
|
@ -1178,18 +1185,28 @@ def _get_providers_with_shared_capacity(ctx, rc_id, amount):
|
|||
inv_tbl.c.resource_provider_id == usage.c.resource_provider_id,
|
||||
)
|
||||
|
||||
where_conds = sa.and_(
|
||||
func.coalesce(usage.c.used, 0) + amount <= (
|
||||
inv_tbl.c.total - inv_tbl.c.reserved) * inv_tbl.c.allocation_ratio,
|
||||
inv_tbl.c.min_unit <= amount,
|
||||
inv_tbl.c.max_unit >= amount,
|
||||
amount % inv_tbl.c.step_size == 0)
|
||||
|
||||
# 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 []
|
||||
where_conds.append(rp_tbl.c.id.in_(rps_in_aggs))
|
||||
|
||||
sel = sa.select([rp_tbl.c.id]).select_from(inv_to_usage_join)
|
||||
sel = sel.where(
|
||||
sa.and_(
|
||||
func.coalesce(usage.c.used, 0) + amount <= (
|
||||
inv_tbl.c.total - inv_tbl.c.reserved
|
||||
) * inv_tbl.c.allocation_ratio,
|
||||
inv_tbl.c.min_unit <= amount,
|
||||
inv_tbl.c.max_unit >= amount,
|
||||
amount % inv_tbl.c.step_size == 0,
|
||||
),
|
||||
)
|
||||
sel = sel.where(where_conds)
|
||||
sel = sel.group_by(rp_tbl.c.id)
|
||||
|
||||
return [r[0] for r in ctx.session.execute(sel)]
|
||||
|
||||
|
||||
|
@ -4176,7 +4193,7 @@ class AllocationCandidates(base.VersionedObject):
|
|||
# particular resource class.
|
||||
sharing_providers = {
|
||||
rc_id: _get_providers_with_shared_capacity(context, rc_id,
|
||||
amount)
|
||||
amount, member_of)
|
||||
for rc_id, amount in resources.items()
|
||||
}
|
||||
# We check this here as an optimization: if we have no sharing
|
||||
|
|
|
@ -1600,28 +1600,12 @@ class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
|||
)}
|
||||
)
|
||||
|
||||
# Bug#1763907: We should get providers only in agg1, but the actual
|
||||
# is that we get all the resource providers shared by rps in agg1.
|
||||
# expected = [
|
||||
# [('cn1', fields.ResourceClass.VCPU, 2),
|
||||
# ('ss1', fields.ResourceClass.DISK_GB, 1500)],
|
||||
# ]
|
||||
expected = [
|
||||
[('cn1', fields.ResourceClass.VCPU, 2),
|
||||
('ss1', fields.ResourceClass.DISK_GB, 1500)],
|
||||
[('cn1', fields.ResourceClass.VCPU, 2),
|
||||
('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
]
|
||||
self._validate_allocation_requests(expected, alloc_cands)
|
||||
|
||||
# expected = {
|
||||
# 'cn1': set([
|
||||
# (fields.ResourceClass.VCPU, 24, 0),
|
||||
# ]),
|
||||
# 'ss1': set([
|
||||
# (fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
# ]),
|
||||
# }
|
||||
expected = {
|
||||
'cn1': set([
|
||||
(fields.ResourceClass.VCPU, 24, 0),
|
||||
|
@ -1629,9 +1613,6 @@ class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
|||
'ss1': set([
|
||||
(fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
]),
|
||||
'ss2': set([
|
||||
(fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
]),
|
||||
}
|
||||
self._validate_provider_summary_resources(expected, alloc_cands)
|
||||
|
||||
|
@ -1647,35 +1628,14 @@ class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
|||
)}
|
||||
)
|
||||
|
||||
# expected = [
|
||||
# [('cn1', fields.ResourceClass.VCPU, 2),
|
||||
# ('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
# [('cn2', fields.ResourceClass.VCPU, 2),
|
||||
# ('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
# ]
|
||||
expected = [
|
||||
[('cn1', fields.ResourceClass.VCPU, 2),
|
||||
('ss1', fields.ResourceClass.DISK_GB, 1500)],
|
||||
[('cn1', fields.ResourceClass.VCPU, 2),
|
||||
('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
[('cn2', fields.ResourceClass.VCPU, 2),
|
||||
('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
[('cn2', fields.ResourceClass.VCPU, 2),
|
||||
('ss3', fields.ResourceClass.DISK_GB, 1500)],
|
||||
]
|
||||
self._validate_allocation_requests(expected, alloc_cands)
|
||||
|
||||
# expected = {
|
||||
# 'cn1': set([
|
||||
# (fields.ResourceClass.VCPU, 24, 0),
|
||||
# ]),
|
||||
# 'cn2': set([
|
||||
# (fields.ResourceClass.VCPU, 24, 0),
|
||||
# ]),
|
||||
# 'ss2': set([
|
||||
# (fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
# ]),
|
||||
# }
|
||||
expected = {
|
||||
'cn1': set([
|
||||
(fields.ResourceClass.VCPU, 24, 0),
|
||||
|
@ -1683,15 +1643,9 @@ class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
|||
'cn2': set([
|
||||
(fields.ResourceClass.VCPU, 24, 0),
|
||||
]),
|
||||
'ss1': set([
|
||||
(fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
]),
|
||||
'ss2': set([
|
||||
(fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
]),
|
||||
'ss3': set([
|
||||
(fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
]),
|
||||
}
|
||||
self._validate_provider_summary_resources(expected, alloc_cands)
|
||||
|
||||
|
@ -1708,27 +1662,10 @@ class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
|||
)}
|
||||
)
|
||||
|
||||
# expected = []
|
||||
expected = [
|
||||
[('cn1', fields.ResourceClass.VCPU, 2),
|
||||
('ss1', fields.ResourceClass.DISK_GB, 1500)],
|
||||
[('cn1', fields.ResourceClass.VCPU, 2),
|
||||
('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
]
|
||||
expected = []
|
||||
self._validate_allocation_requests(expected, alloc_cands)
|
||||
|
||||
# expected = {}
|
||||
expected = {
|
||||
'cn1': set([
|
||||
(fields.ResourceClass.VCPU, 24, 0),
|
||||
]),
|
||||
'ss1': set([
|
||||
(fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
]),
|
||||
'ss2': set([
|
||||
(fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
]),
|
||||
}
|
||||
expected = {}
|
||||
self._validate_provider_summary_resources(expected, alloc_cands)
|
||||
|
||||
# The request from agg1 *OR* agg2 would provide three candidates
|
||||
|
@ -1743,14 +1680,6 @@ class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
|||
)}
|
||||
)
|
||||
|
||||
# expected = [
|
||||
# [('cn1', fields.ResourceClass.VCPU, 2),
|
||||
# ('ss1', fields.ResourceClass.DISK_GB, 1500)],
|
||||
# [('cn1', fields.ResourceClass.VCPU, 2),
|
||||
# ('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
# [('cn2', fields.ResourceClass.VCPU, 2),
|
||||
# ('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
# ]
|
||||
expected = [
|
||||
[('cn1', fields.ResourceClass.VCPU, 2),
|
||||
('ss1', fields.ResourceClass.DISK_GB, 1500)],
|
||||
|
@ -1758,25 +1687,9 @@ class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
|||
('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
[('cn2', fields.ResourceClass.VCPU, 2),
|
||||
('ss2', fields.ResourceClass.DISK_GB, 1500)],
|
||||
[('cn2', fields.ResourceClass.VCPU, 2),
|
||||
('ss3', fields.ResourceClass.DISK_GB, 1500)],
|
||||
]
|
||||
self._validate_allocation_requests(expected, alloc_cands)
|
||||
|
||||
# expected = {
|
||||
# 'cn1': set([
|
||||
# (fields.ResourceClass.VCPU, 24, 0),
|
||||
# ]),
|
||||
# 'cn2': set([
|
||||
# (fields.ResourceClass.VCPU, 24, 0),
|
||||
# ]),
|
||||
# 'ss1': set([
|
||||
# (fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
# ]),
|
||||
# 'ss2': set([
|
||||
# (fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
# ]),
|
||||
# }
|
||||
expected = {
|
||||
'cn1': set([
|
||||
(fields.ResourceClass.VCPU, 24, 0),
|
||||
|
@ -1790,9 +1703,6 @@ class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
|||
'ss2': set([
|
||||
(fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
]),
|
||||
'ss3': set([
|
||||
(fields.ResourceClass.DISK_GB, 1600, 0),
|
||||
]),
|
||||
}
|
||||
self._validate_provider_summary_resources(expected, alloc_cands)
|
||||
|
||||
|
|
Loading…
Reference in New Issue