diff options
| author | Eoghan Glynn <eglynn@redhat.com> | 2012-07-04 11:21:19 +0000 |
|---|---|---|
| committer | Eoghan Glynn <eglynn@redhat.com> | 2012-07-04 16:39:04 +0100 |
| commit | dea224ae26c752d328ccbb622048a63e990bee50 (patch) | |
| tree | 0cab8091383831ff520a4bebe121b5044da6a3a0 /nova | |
| parent | 980c76266629ea66bc23fddb02f5be61c51d873c (diff) | |
| download | nova-dea224ae26c752d328ccbb622048a63e990bee50.tar.gz nova-dea224ae26c752d328ccbb622048a63e990bee50.tar.xz nova-dea224ae26c752d328ccbb622048a63e990bee50.zip | |
Distinguish over-quota for volume size and number.
Fixes LP 1020634
Ensure that exceeding the allowed number of volumes is not
mis-represented in log messages and exception handling as
excessive space usage.
Change-Id: I71ec995c77bc447bfc9221084b057bd8d69a4513
Diffstat (limited to 'nova')
| -rw-r--r-- | nova/exception.py | 4 | ||||
| -rw-r--r-- | nova/tests/test_volume.py | 33 | ||||
| -rw-r--r-- | nova/volume/api.py | 25 |
3 files changed, 58 insertions, 4 deletions
diff --git a/nova/exception.py b/nova/exception.py index c1f417afe..ff9a20a41 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -1005,6 +1005,10 @@ class VolumeSizeTooLarge(QuotaError): message = _("Maximum volume size exceeded") +class VolumeLimitExceeded(QuotaError): + message = _("Maximum number of volumes allowed (%(allowed)d) exceeded") + + class FloatingIpLimitExceeded(QuotaError): message = _("Maximum number of floating ips exceeded") diff --git a/nova/tests/test_volume.py b/nova/tests/test_volume.py index 2e149f950..0478eb545 100644 --- a/nova/tests/test_volume.py +++ b/nova/tests/test_volume.py @@ -121,6 +121,39 @@ class VolumeTestCase(test.TestCase): self.context, volume_id) + def _do_test_create_over_quota(self, resource, expected): + """Test volume creation over quota.""" + + def fake_reserve(context, **deltas): + kwargs = dict(overs=[resource], + quotas=dict(gigabytes=1000, volumes=10), + usages=dict(gigabytes=dict(reserved=1, in_use=999), + volumes=dict(reserved=1, in_use=9))) + raise exception.OverQuota(**kwargs) + + def fake_commit(context, reservations): + self.fail('should not commit over quota') + + self.stubs.Set(QUOTAS, 'reserve', fake_reserve) + self.stubs.Set(QUOTAS, 'commit', fake_commit) + + volume_api = nova.volume.api.API() + + self.assertRaises(expected, + volume_api.create, + self.context, + 2, + 'name', + 'description') + + def test_create_volumes_over_quota(self): + self._do_test_create_over_quota('volumes', + exception.VolumeLimitExceeded) + + def test_create_gigabytes_over_quota(self): + self._do_test_create_over_quota('gigabytes', + exception.VolumeSizeTooLarge) + def test_delete_busy_volume(self): """Test volume survives deletion if driver reports it as busy.""" volume = self._create_volume() diff --git a/nova/volume/api.py b/nova/volume/api.py index 28f78a7e1..ee079021a 100644 --- a/nova/volume/api.py +++ b/nova/volume/api.py @@ -82,11 +82,28 @@ class API(base.Base): try: reservations = QUOTAS.reserve(context, volumes=1, gigabytes=size) - except exception.OverQuota: + except exception.OverQuota as e: + overs = e.kwargs['overs'] + usages = e.kwargs['usages'] + quotas = e.kwargs['quotas'] + + def _consumed(name): + return (usages[name]['reserved'] + usages[name]['in_use']) + pid = context.project_id - LOG.warn(_("Quota exceeded for %(pid)s, tried to create" - " %(size)sG volume") % locals()) - raise exception.VolumeSizeTooLarge() + if 'gigabytes' in overs: + consumed = _consumed('gigabytes') + quota = quotas['gigabytes'] + LOG.warn(_("Quota exceeded for %(pid)s, tried to create " + "%(size)sG volume (%(consumed)dG of %(quota)dG " + "already consumed)") % locals()) + raise exception.VolumeSizeTooLarge() + elif 'volumes' in overs: + consumed = _consumed('volumes') + LOG.warn(_("Quota exceeded for %(pid)s, tried to create " + "volume (%(consumed)d volumes already consumed)") + % locals()) + raise exception.VolumeLimitExceeded(allowed=quotas['volumes']) if availability_zone is None: availability_zone = FLAGS.storage_availability_zone |
