From 8ad33cf8553d9bb52d5b2bcab20cb5bef840aee2 Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Tue, 26 Jun 2018 16:26:40 +0100 Subject: [PATCH] [placement] Fix capacity tracking in POST /allocations Add a change to _check_capacity_exceeded to also compare the amount needed by a given allocation to a running total of amounts needed against this class of resource on this resource provider. Change-Id: Id8dde9a1f4b62112925616dfa54e77704109481c Closes-Bug: #1778743 --- .../placement/objects/resource_provider.py | 6 +++++- .../placement/gabbits/allocations-bug-1778743.yaml | 14 ++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/nova/api/openstack/placement/objects/resource_provider.py b/nova/api/openstack/placement/objects/resource_provider.py index ea4f648392e7..e41bc128a296 100644 --- a/nova/api/openstack/placement/objects/resource_provider.py +++ b/nova/api/openstack/placement/objects/resource_provider.py @@ -1665,12 +1665,15 @@ def _check_capacity_exceeded(ctx, allocs): resource_provider=provider_str) res_providers = {} + rp_resource_class_sum = collections.defaultdict( + lambda: collections.defaultdict(int)) for alloc in allocs: rc_id = _RC_CACHE.id_from_string(alloc.resource_class) rp_uuid = alloc.resource_provider.uuid if rp_uuid not in res_providers: res_providers[rp_uuid] = alloc.resource_provider amount_needed = alloc.used + rp_resource_class_sum[rp_uuid][rc_id] += amount_needed # No use checking usage if we're not asking for anything if amount_needed == 0: continue @@ -1708,7 +1711,8 @@ def _check_capacity_exceeded(ctx, allocs): # usage["used"] can be returned as None used = usage['used'] or 0 capacity = (usage['total'] - usage['reserved']) * allocation_ratio - if capacity < (used + amount_needed): + if (capacity < (used + amount_needed) or + capacity < (used + rp_resource_class_sum[rp_uuid][rc_id])): LOG.warning( "Over capacity for %(rc)s on resource provider %(rp)s. " "Needed: %(needed)s, Used: %(used)s, Capacity: %(cap)s", diff --git a/nova/tests/functional/api/openstack/placement/gabbits/allocations-bug-1778743.yaml b/nova/tests/functional/api/openstack/placement/gabbits/allocations-bug-1778743.yaml index a2324d7e89b2..17bb002bf6ec 100644 --- a/nova/tests/functional/api/openstack/placement/gabbits/allocations-bug-1778743.yaml +++ b/nova/tests/functional/api/openstack/placement/gabbits/allocations-bug-1778743.yaml @@ -1,5 +1,5 @@ # Test to see if capacity check in POST allocations works as expected. -# It does not, due to bug 1778743. +# It did not, due to bug 1778743, but it is now fixed. fixtures: @@ -7,7 +7,8 @@ fixtures: defaults: request_headers: - openstack-api-version: placement latest + # 1.28 provides consumer generation in allocations + openstack-api-version: placement 1.28 x-auth-token: admin content-type: application/json accept: application/json @@ -29,7 +30,7 @@ tests: total: 2 - name: post multiple allocations - desc: this should fail because we're allocating 3 VCPU! + desc: this should 409 because we're allocating 3 VCPU! POST: /allocations data: a6ace019-f230-4dcc-8a76-36d27b9c2257: @@ -56,15 +57,12 @@ tests: project_id: a2cec092-0f67-42ed-b870-f3925cc5c6d4 user_id: d28385b2-7860-4055-b32d-4cd1057cd5f2 consumer_generation: null - # we expect 409 but are getting 204 - # status: 409 - status: 204 + status: 409 - name: check usage GET: /resource_providers/4e05a85b-e8a6-4b3a-82c1-5f6ad3f71d55/usages response_json_paths: - # this ought to be impossible - $.usages.VCPU: 3 + $.usages.VCPU: 0 - name: check inventory GET: /resource_providers/4e05a85b-e8a6-4b3a-82c1-5f6ad3f71d55/inventories