Catch rbd NoSpace exception

Unhelpful error (HTTP 500, Internal Server Error) received if image
creation failed due to insufficient free space. This patch catches rbd
NoSpace exception and re-raise the exact exception
glance_store.StorageFull, and the http client will receive "HTTP 413
Request Entity Too Large".

Closes-Bug: #1808456
Change-Id: Id787d3ae6f761aaa31d2fc7dd26d2f7d327367d4
Co-authored-by: Stefan Dinescu <stefan.dinescu@windriver.com>
Signed-off-by: Liang Fang <liang.a.fang@intel.com>
This commit is contained in:
Liang Fang 2018-12-11 17:11:44 +08:00
parent b8b873433e
commit 7377cf2638
3 changed files with 48 additions and 1 deletions

View File

@ -514,6 +514,21 @@ class Store(driver.Store):
if loc.snapshot:
image.create_snap(loc.snapshot)
image.protect_snap(loc.snapshot)
except rbd.NoSpace:
log_msg = (_LE("Failed to store image %(img_name)s "
"insufficient space available") %
{'img_name': image_name})
LOG.error(log_msg)
# Delete image if one was created
try:
target_pool = loc.pool or self.pool
self._delete_image(target_pool, loc.image,
loc.snapshot)
except exceptions.NotFound:
pass
raise exceptions.StorageFull(message=log_msg)
except Exception as exc:
log_msg = (_LE("Failed to store image %(img_name)s "
"Store Exception %(store_exc)s") %

View File

@ -89,6 +89,9 @@ class MockRBD(object):
class InvalidArgument(Exception):
pass
class NoSpace(Exception):
pass
class Image(object):
def __init__(self, *args, **kwargs):

View File

@ -88,6 +88,9 @@ class MockRBD(object):
class InvalidArgument(Exception):
pass
class NoSpace(Exception):
pass
class Image(object):
def __init__(self, *args, **kwargs):
@ -214,7 +217,6 @@ class TestStore(base.StoreBaseTest,
def _fake_enter(*args, **kwargs):
raise exceptions.NotFound(image="fake_image_id")
create.side_effect = _fake_create_image
delete.side_effect = _fake_delete_image
enter.side_effect = _fake_enter
@ -226,6 +228,33 @@ class TestStore(base.StoreBaseTest,
self.called_commands_expected = ['create', 'delete']
@mock.patch.object(MockRBD.Image, 'resize')
@mock.patch.object(rbd_store.Store, '_create_image')
@mock.patch.object(rbd_store.Store, '_delete_image')
def test_add_w_rbd_no_space_exception(self, delete, create, resize):
def _fake_create_image(*args, **kwargs):
self.called_commands_actual.append('create')
return self.location
def _fake_delete_image(target_pool, image_name, snapshot_name=None):
self.assertEqual(self.location.pool, target_pool)
self.assertEqual(self.location.image, image_name)
self.assertEqual(self.location.snapshot, snapshot_name)
self.called_commands_actual.append('delete')
def _fake_resize(*args, **kwargs):
raise MockRBD.NoSpace()
create.side_effect = _fake_create_image
delete.side_effect = _fake_delete_image
resize.side_effect = _fake_resize
self.assertRaises(exceptions.StorageFull,
self.store.add,
'fake_image_id', self.data_iter, 0,
self.hash_algo)
self.called_commands_expected = ['create', 'delete']
def test_add_duplicate_image(self):
def _fake_create_image(*args, **kwargs):