Quota: Fix until_refresh config changes

until_refresh configuration option changes are only picked up by cinder
if the quota usage rows didn't exist in the DB or if until_refresh was
already set.

This means that if we enable until_refresh on an existing project then
it wouldn't be picked up.

This patch fixes this so configuration changes to until_refresh are
picked up in a timely fashion.

Closes-Bug: #1697906
Change-Id: I035ad9cdf5802b4c03c8e0fd683891f904ed321a
This commit is contained in:
Gorka Eguileor 2021-03-02 16:11:56 +01:00
parent 29edc0fd25
commit 85aee67dc7
3 changed files with 66 additions and 0 deletions

View File

@ -1232,6 +1232,15 @@ def quota_reserve(context, resources, quotas, deltas, expire,
# for. We don't check, because this is
# a best-effort mechanism.
# There are 3 cases where we want to update "until_refresh" in the
# DB: when we enabled it, when we disabled it, and when we changed
# to a value lower than the current remaining value.
else:
res_until = usages[resource].until_refresh
if ((res_until is None and until_refresh) or
((res_until or 0) > (until_refresh or 0))):
usages[resource].until_refresh = until_refresh or None
# Check for deltas that would go negative
if is_allocated_reserve:
unders = [r for r, delta in deltas.items()

View File

@ -1692,6 +1692,57 @@ class QuotaReserveSqlAlchemyTestCase(test.TestCase):
usage_id=self.usages['gigabytes'],
delta=2 * 1024), ])
def test_quota_reserve_until_refresh_enable(self):
"""Test that enabling until_refresh works."""
# Simulate service running with until_refresh disabled
self.init_usage('test_project', 'volumes', 3, 0, until_refresh=None)
self.init_usage('test_project', 'gigabytes', 100, 0,
until_refresh=None)
context = FakeContext('test_project', 'test_class')
quotas = dict(volumes=5, gigabytes=10 * 1024, )
deltas = dict(volumes=2, gigabytes=2 * 1024, )
self._mock_allocated_get_all_by_project()
# Simulate service is now running with until_refresh set to 5
sqa_api.quota_reserve(context, self.resources, quotas, deltas,
self.expire, 5, 0)
self.compare_usage(self.usages, [dict(resource='volumes',
project_id='test_project',
in_use=3,
reserved=2,
until_refresh=5),
dict(resource='gigabytes',
project_id='test_project',
in_use=100,
reserved=2 * 1024,
until_refresh=5), ])
def test_quota_reserve_until_refresh_disable(self):
"""Test that disabling until_refresh works."""
# Simulate service running with until_refresh enabled and set to 5
self.init_usage('test_project', 'volumes', 3, 0, until_refresh=5)
self.init_usage('test_project', 'gigabytes', 100, 0, until_refresh=5)
context = FakeContext('test_project', 'test_class')
quotas = dict(volumes=5, gigabytes=10 * 1024, )
deltas = dict(volumes=2, gigabytes=2 * 1024, )
self._mock_allocated_get_all_by_project()
# Simulate service is now running with until_refresh disabled
sqa_api.quota_reserve(context, self.resources, quotas, deltas,
self.expire, None, 0)
self.compare_usage(self.usages, [dict(resource='volumes',
project_id='test_project',
in_use=3,
reserved=2,
until_refresh=None),
dict(resource='gigabytes',
project_id='test_project',
in_use=100,
reserved=2 * 1024,
until_refresh=None), ])
def test_quota_reserve_max_age(self):
max_age = 3600
record_created = (timeutils.utcnow() -

View File

@ -0,0 +1,6 @@
---
fixes:
- |
`Bug #1697906 <https://bugs.launchpad.net/cinder/+bug/1697906>`_: Fix
``until_refresh`` configuration changes not taking effect in a timely
fashion or at all.