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:
|
if image_id is not None:
|
||||||
query = query.filter(models.Image.id != image_id)
|
query = query.filter(models.Image.id != image_id)
|
||||||
query = query.filter(models.Image.size > 0)
|
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()
|
images = query.all()
|
||||||
|
|
||||||
total = 0
|
total = 0
|
||||||
@@ -815,7 +816,8 @@ def _image_get_staging_usage_by_owner(context, session, owner):
|
|||||||
query = query.filter(~models.Image.status.in_(('uploading',
|
query = query.filter(~models.Image.status.in_(('uploading',
|
||||||
'importing',
|
'importing',
|
||||||
'killed',
|
'killed',
|
||||||
'deleted')))
|
'deleted',
|
||||||
|
'pending_delete')))
|
||||||
copying_images = query.all()
|
copying_images = query.all()
|
||||||
|
|
||||||
return sum(i.size for i in itertools.chain(importing_images,
|
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):
|
def _image_get_count_by_owner(context, session, owner):
|
||||||
query = session.query(models.Image)
|
query = session.query(models.Image)
|
||||||
query = query.filter(models.Image.owner == owner)
|
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()
|
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.join(props, props.c.image_id == models.Image.id)
|
||||||
query = query.filter(models.Image.owner == owner)
|
query = query.filter(models.Image.owner == owner)
|
||||||
query = query.filter(~models.Image.status.in_(importing_statuses +
|
query = query.filter(~models.Image.status.in_(importing_statuses +
|
||||||
('killed', 'deleted')))
|
('killed', 'deleted',
|
||||||
|
'pending_delete')))
|
||||||
copying = query.count()
|
copying = query.count()
|
||||||
|
|
||||||
return uploading + copying
|
return uploading + copying
|
||||||
|
@@ -35,6 +35,8 @@ import requests
|
|||||||
|
|
||||||
from glance.api import policy
|
from glance.api import policy
|
||||||
from glance.common import wsgi
|
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.quota import keystone as ks_quota
|
||||||
from glance.tests import functional
|
from glance.tests import functional
|
||||||
from glance.tests.functional import ft_utils as func_utils
|
from glance.tests.functional import ft_utils as func_utils
|
||||||
@@ -4549,6 +4551,61 @@ class TestKeystoneQuotas(functional.SynchronousAPIBase):
|
|||||||
# Make sure we can still import.
|
# Make sure we can still import.
|
||||||
self._create_and_import(stores=['store1'])
|
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):
|
class TestStoreWeight(functional.SynchronousAPIBase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
Reference in New Issue
Block a user