From: Vipin Balachandran Date: Tue, 4 Aug 2015 06:33:25 +0000 (+0530) Subject: Fix volume limit exceeded exception X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=1d0695bf86c5bdd12db235b8a2634f3404132977;p=openstack-build%2Fcinder-build.git Fix volume limit exceeded exception The VolumeLimitExceeded exception contains the wrong limit when the number of volumes exceeds the quota corresponding to a volume type. It always contains the limit of quota 'volumes'. This patch fixes the limit in both exception and log message. It also adds the quota name to exception and log message for better clarity. Change-Id: I3e2d4fa00fe49f64b2153930e901fccd8015483e Closes-Bug: #1481182 --- diff --git a/cinder/exception.py b/cinder/exception.py index efaf1b3f0..a3f2df680 100644 --- a/cinder/exception.py +++ b/cinder/exception.py @@ -468,7 +468,12 @@ class VolumeBackupSizeExceedsAvailableQuota(QuotaError): class VolumeLimitExceeded(QuotaError): - message = _("Maximum number of volumes allowed (%(allowed)d) exceeded") + message = _("Maximum number of volumes allowed (%(allowed)d) exceeded for " + "quota '%(name)s'.") + + def __init__(self, message=None, **kwargs): + kwargs.setdefault('name', 'volumes') + super(VolumeLimitExceeded, self).__init__(message, **kwargs) class SnapshotLimitExceeded(QuotaError): diff --git a/cinder/tests/unit/api/contrib/test_backups.py b/cinder/tests/unit/api/contrib/test_backups.py index 22978c7f1..fdb4176b8 100644 --- a/cinder/tests/unit/api/contrib/test_backups.py +++ b/cinder/tests/unit/api/contrib/test_backups.py @@ -1213,10 +1213,10 @@ class BackupsAPITestCase(test.TestCase): res = req.get_response(fakes.wsgi_app()) res_dict = json.loads(res.body) - self.assertEqual(res.status_int, 413) - self.assertEqual(res_dict['overLimit']['code'], 413) - self.assertEqual(res_dict['overLimit']['message'], - 'Maximum number of volumes allowed (1) exceeded') + self.assertEqual(413, res.status_int) + self.assertEqual(413, res_dict['overLimit']['code']) + self.assertEqual("Maximum number of volumes allowed (1) exceeded for" + " quota 'volumes'.", res_dict['overLimit']['message']) def test_restore_backup_to_undersized_volume(self): backup_size = 10 diff --git a/cinder/tests/unit/api/contrib/test_volume_transfer.py b/cinder/tests/unit/api/contrib/test_volume_transfer.py index 9d86c0618..a026a7e7a 100644 --- a/cinder/tests/unit/api/contrib/test_volume_transfer.py +++ b/cinder/tests/unit/api/contrib/test_volume_transfer.py @@ -589,6 +589,6 @@ class VolumeTransferAPITestCase(test.TestCase): self.assertEqual(413, res.status_int) self.assertEqual(413, res_dict['overLimit']['code']) - self.assertEqual('VolumeLimitExceeded: Maximum number of volumes ' - 'allowed (1) exceeded', + self.assertEqual("VolumeLimitExceeded: Maximum number of volumes " + "allowed (1) exceeded for quota 'volumes'.", res_dict['overLimit']['message']) diff --git a/cinder/tests/unit/test_quota.py b/cinder/tests/unit/test_quota.py index 983a21c69..e4fd9e931 100644 --- a/cinder/tests/unit/test_quota.py +++ b/cinder/tests/unit/test_quota.py @@ -21,6 +21,7 @@ import datetime import mock from oslo_config import cfg from oslo_utils import timeutils +import six from cinder import backup from cinder import context @@ -114,10 +115,13 @@ class QuotaIntegrationTestCase(test.TestCase): for _i in range(CONF.quota_volumes): vol_ref = self._create_volume() volume_ids.append(vol_ref['id']) - self.assertRaises(exception.VolumeLimitExceeded, - volume.API().create, - self.context, 1, '', '', - volume_type=self.volume_type) + ex = self.assertRaises(exception.VolumeLimitExceeded, + volume.API().create, + self.context, 1, '', '', + volume_type=self.volume_type) + msg = ("Maximum number of volumes allowed (%d) exceeded for" + " quota 'volumes'." % CONF.quota_volumes) + self.assertEqual(msg, six.text_type(ex)) for volume_id in volume_ids: db.volume_destroy(self.context, volume_id) @@ -130,10 +134,13 @@ class QuotaIntegrationTestCase(test.TestCase): } self.flags(**flag_args) vol_ref = self._create_volume() - self.assertRaises(exception.VolumeLimitExceeded, - volume.API().create, - self.context, 1, '', '', - volume_type=self.volume_type) + ex = self.assertRaises(exception.VolumeLimitExceeded, + volume.API().create, + self.context, 1, '', '', + volume_type=self.volume_type) + msg = ("Maximum number of volumes allowed (1) exceeded for" + " quota '%s'." % resource) + self.assertEqual(msg, six.text_type(ex)) db.volume_destroy(self.context, vol_ref['id']) def test_too_many_snapshots_of_type(self): diff --git a/cinder/volume/flows/api/create_volume.py b/cinder/volume/flows/api/create_volume.py index 5f1a4adfc..e10582e9b 100644 --- a/cinder/volume/flows/api/create_volume.py +++ b/cinder/volume/flows/api/create_volume.py @@ -547,6 +547,7 @@ class QuotaReserveTask(flow_utils.CinderTask): return None over_name = _get_over('gigabytes') + exceeded_vol_limit_name = _get_over('volumes') if over_name: msg = _LW("Quota exceeded for %(s_pid)s, tried to create " "%(s_size)sG volume (%(d_consumed)dG " @@ -560,13 +561,18 @@ class QuotaReserveTask(flow_utils.CinderTask): requested=size, consumed=_consumed(over_name), quota=quotas[over_name]) - elif _get_over('volumes'): - msg = _LW("Quota exceeded for %(s_pid)s, tried to create " - "volume (%(d_consumed)d volumes " - "already consumed)") - LOG.warning(msg, {'s_pid': context.project_id, - 'd_consumed': _consumed('volumes')}) - raise exception.VolumeLimitExceeded(allowed=quotas['volumes']) + elif exceeded_vol_limit_name: + msg = _LW("Quota %(s_name)s exceeded for %(s_pid)s, tried " + "to create volume (%(d_consumed)d volume(s) " + "already consumed).") + LOG.warning(msg, + {'s_name': exceeded_vol_limit_name, + 's_pid': context.project_id, + 'd_consumed': + _consumed(exceeded_vol_limit_name)}) + raise exception.VolumeLimitExceeded( + allowed=quotas[exceeded_vol_limit_name], + name=exceeded_vol_limit_name) else: # If nothing was reraised, ensure we reraise the initial error raise