Merge "Fix inaccurate usage reporting when delayed_delete is enabled"
This commit is contained in:
@@ -777,7 +777,8 @@ def _image_get_disk_usage_by_owner(context, session, owner, image_id=None):
|
||||
if image_id is not None:
|
||||
query = query.filter(models.Image.id != image_id)
|
||||
query = query.filter(models.Image.size > 0)
|
||||
query = query.filter(~models.Image.status.in_(['killed', 'deleted']))
|
||||
query = query.filter(~models.Image.status.in_([
|
||||
'killed', 'deleted', 'pending_delete']))
|
||||
images = query.all()
|
||||
|
||||
total = 0
|
||||
@@ -815,7 +816,8 @@ def _image_get_staging_usage_by_owner(context, session, owner):
|
||||
query = query.filter(~models.Image.status.in_(('uploading',
|
||||
'importing',
|
||||
'killed',
|
||||
'deleted')))
|
||||
'deleted',
|
||||
'pending_delete')))
|
||||
copying_images = query.all()
|
||||
|
||||
return sum(i.size for i in itertools.chain(importing_images,
|
||||
@@ -825,7 +827,8 @@ def _image_get_staging_usage_by_owner(context, session, owner):
|
||||
def _image_get_count_by_owner(context, session, owner):
|
||||
query = session.query(models.Image)
|
||||
query = query.filter(models.Image.owner == owner)
|
||||
query = query.filter(~models.Image.status.in_(['killed', 'deleted']))
|
||||
query = query.filter(~models.Image.status.in_([
|
||||
'killed', 'pending_delete', 'deleted']))
|
||||
return query.count()
|
||||
|
||||
|
||||
@@ -850,7 +853,8 @@ def _image_get_uploading_count_by_owner(context, session, owner):
|
||||
query = query.join(props, props.c.image_id == models.Image.id)
|
||||
query = query.filter(models.Image.owner == owner)
|
||||
query = query.filter(~models.Image.status.in_(importing_statuses +
|
||||
('killed', 'deleted')))
|
||||
('killed', 'deleted',
|
||||
'pending_delete')))
|
||||
copying = query.count()
|
||||
|
||||
return uploading + copying
|
||||
|
@@ -35,6 +35,8 @@ import requests
|
||||
|
||||
from glance.api import policy
|
||||
from glance.common import wsgi
|
||||
from glance import context
|
||||
import glance.db as db_api
|
||||
from glance.quota import keystone as ks_quota
|
||||
from glance.tests import functional
|
||||
from glance.tests.functional import ft_utils as func_utils
|
||||
@@ -4549,6 +4551,61 @@ class TestKeystoneQuotas(functional.SynchronousAPIBase):
|
||||
# Make sure we can still import.
|
||||
self._create_and_import(stores=['store1'])
|
||||
|
||||
def test_image_count_total_with_delayed_delete(self):
|
||||
self.config(delayed_delete=True)
|
||||
self.set_limit({'image_size_total': 100,
|
||||
'image_stage_total': 10,
|
||||
'image_count_total': 1,
|
||||
'image_count_uploading': 10})
|
||||
self.start_server()
|
||||
# Create an image
|
||||
image_id = self._create_and_upload()
|
||||
# Make sure we can not create any more images.
|
||||
resp = self._create()
|
||||
self.assertEqual(413, resp.status_code)
|
||||
|
||||
# Delete one image, which should put us under quota
|
||||
self.api_delete('/v2/images/%s' % image_id)
|
||||
|
||||
# Verify image is in pending_delete state
|
||||
image = self._get_pending_delete_image(image_id)
|
||||
self.assertEqual('pending_delete', image['status'])
|
||||
|
||||
# Now we can create that image
|
||||
self._create()
|
||||
|
||||
def test_image_size_total_with_delayed_delete(self):
|
||||
self.config(delayed_delete=True)
|
||||
self.set_limit({'image_size_total': 6,
|
||||
'image_stage_total': 10,
|
||||
'image_count_total': 10,
|
||||
'image_count_uploading': 1})
|
||||
self.start_server()
|
||||
# Create an image
|
||||
image_id = self._create_and_upload(
|
||||
data_iter=test_utils.FakeData(8 * units.Mi))
|
||||
# Make sure we can not upload any more images.
|
||||
self._create_and_upload(expected_code=413)
|
||||
|
||||
# Delete one image, which should put us under quota
|
||||
self.api_delete('/v2/images/%s' % image_id)
|
||||
|
||||
# Verify image is in pending_delete state
|
||||
image = self._get_pending_delete_image(image_id)
|
||||
self.assertEqual('pending_delete', image['status'])
|
||||
|
||||
# Now we can create that image
|
||||
self._create_and_upload()
|
||||
|
||||
def _get_pending_delete_image(self, image_id):
|
||||
# In Glance V2, there is no way to get the 'pending_delete' image from
|
||||
# API. So we get the image from db here for testing.
|
||||
# Clean the session cache first to avoid connecting to the old db data.
|
||||
admin_context = context.get_admin_context(show_deleted=True)
|
||||
db_api.get_api()._FACADE = None
|
||||
image = db_api.get_api().image_get(admin_context, image_id)
|
||||
return image
|
||||
|
||||
|
||||
class TestStoreWeight(functional.SynchronousAPIBase):
|
||||
def setUp(self):
|
||||
|
Reference in New Issue
Block a user