Catching OverQuota Exception

When any vm creation fails because of exceeding 'gigabytes',
'volumes', 'per_volume_gigabytes' quotas, the error message
generated is specific to 'volumes' quota which says
"Volume resource quota exceeded". Instead, the error message
should be specific to the quota which failed.

Change-Id: I9c1ac2cd4752d5aac20d06407792647b4549ad3d
Closes-Bug: 1680457
(cherry picked from commit 510371d526)
This commit is contained in:
Abhishek Sharma 2017-04-26 16:38:15 -04:00 committed by Abhishek Sharma M
parent 506465a027
commit f5a17d9ed3
4 changed files with 17 additions and 17 deletions

View File

@ -1586,11 +1586,11 @@ class ComputeManager(manager.Manager):
self._block_device_info_to_legacy(block_device_info) self._block_device_info_to_legacy(block_device_info)
return block_device_info return block_device_info
except exception.OverQuota: except exception.OverQuota as e:
msg = _LW('Failed to create block device for instance due to ' LOG.warning(_LW('Failed to create block device for instance due'
'being over volume resource quota') ' to exceeding volume related resource quota.'
LOG.warning(msg, instance=instance) ' Error: %s'), e.message, instance=instance)
raise exception.VolumeLimitExceeded() raise
except Exception: except Exception:
LOG.exception(_LE('Instance failed block device setup'), LOG.exception(_LE('Instance failed block device setup'),
@ -2104,8 +2104,7 @@ class ComputeManager(manager.Manager):
if network_info is not None: if network_info is not None:
network_info.wait(do_raise=False) network_info.wait(do_raise=False)
except (exception.UnexpectedTaskStateError, except (exception.UnexpectedTaskStateError,
exception.VolumeLimitExceeded, exception.OverQuota, exception.InvalidBDM) as e:
exception.InvalidBDM) as e:
# Make sure the async call finishes # Make sure the async call finishes
if network_info is not None: if network_info is not None:
network_info.wait(do_raise=False) network_info.wait(do_raise=False)

View File

@ -57,16 +57,17 @@ class TestCinderOverLimit(test.TestCase):
self.api = api_fixture.api self.api = api_fixture.api
@mock.patch('nova.volume.cinder.cinderclient') @mock.patch('nova.volume.cinder.cinderclient')
def test_over_limit_volumes(self, mock_cinder): def test_over_limit_volumes_with_message(self, mock_cinder):
"""Regression test for bug #1554631. """Regression test for bug #1680457.
When the Cinder client returns OverLimit when trying to create When the Cinder client returns OverLimit when trying to create
a volume, an OverQuota exception should be raised with the value being a volume, an OverQuota exception should be raised.
volumes.
""" """
cinder_client = mock.Mock() cinder_client = mock.Mock()
mock_cinder.return_value = cinder_client mock_cinder.return_value = cinder_client
exc = cinder_exceptions.OverLimit(413) msg = ("VolumeSizeExceedsLimit: Requested volume size XG is larger"
" than maximum allowed limit YG.")
exc = cinder_exceptions.OverLimit(413, message=msg)
cinder_client.volumes.create.side_effect = exc cinder_client.volumes.create.side_effect = exc
volume = {'display_name': 'vol1', 'size': 3} volume = {'display_name': 'vol1', 'size': 3}
@ -74,7 +75,7 @@ class TestCinderOverLimit(test.TestCase):
self.api.post_volume, {'volume': volume}) self.api.post_volume, {'volume': volume})
self.assertEqual(403, e.response.status_code) self.assertEqual(403, e.response.status_code)
# Make sure we went over on volumes # Make sure we went over on volumes
self.assertIn('volumes', e.response.text) self.assertIn('VolumeSizeExceedsLimit', e.response.text)
@mock.patch('nova.volume.cinder.cinderclient') @mock.patch('nova.volume.cinder.cinderclient')
def test_over_limit_snapshots(self, mock_cinder): def test_over_limit_snapshots(self, mock_cinder):

View File

@ -1214,7 +1214,7 @@ class ComputeVolumeTestCase(BaseTestCase):
self.instance_object, 'fake_id', 'fake_id2', {}) self.instance_object, 'fake_id', 'fake_id2', {})
@mock.patch.object(cinder.API, 'create', @mock.patch.object(cinder.API, 'create',
side_effect=exception.OverQuota(overs='volumes')) side_effect=exception.OverQuota(overs='something'))
def test_prep_block_device_over_quota_failure(self, mock_create): def test_prep_block_device_over_quota_failure(self, mock_create):
instance = self._create_fake_instance_obj() instance = self._create_fake_instance_obj()
bdms = [ bdms = [
@ -1231,7 +1231,7 @@ class ComputeVolumeTestCase(BaseTestCase):
})] })]
bdms = block_device_obj.block_device_make_list_from_dicts( bdms = block_device_obj.block_device_make_list_from_dicts(
self.context, bdms) self.context, bdms)
self.assertRaises(exception.VolumeLimitExceeded, self.assertRaises(exception.OverQuota,
compute_manager.ComputeManager()._prep_block_device, compute_manager.ComputeManager()._prep_block_device,
self.context, instance, bdms) self.context, instance, bdms)
self.assertTrue(mock_create.called) self.assertTrue(mock_create.called)

View File

@ -190,8 +190,8 @@ def translate_volume_exception(method):
res = method(self, ctx, volume_id, *args, **kwargs) res = method(self, ctx, volume_id, *args, **kwargs)
except (keystone_exception.NotFound, cinder_exception.NotFound): except (keystone_exception.NotFound, cinder_exception.NotFound):
_reraise(exception.VolumeNotFound(volume_id=volume_id)) _reraise(exception.VolumeNotFound(volume_id=volume_id))
except cinder_exception.OverLimit: except cinder_exception.OverLimit as e:
_reraise(exception.OverQuota(overs='volumes')) _reraise(exception.OverQuota(message=e.message))
return res return res
return translate_cinder_exception(wrapper) return translate_cinder_exception(wrapper)