Get rid of redundant cinder api calls

During executing tenant_limit_usages quotas function we get
information about cinder volumes/snapshots/gigabites usage
that we've already had after tenant_absolute_limits call.
Getting this information we make more api calls that slow down
our application.

This patch fixes this issue.

Closes-Bug: #1703584
Change-Id: Ia6d2dbb8f18ce93f71668d6ebd2689b851586ca9
This commit is contained in:
Mykhailo Dovgal 2017-07-10 19:16:06 +03:00 committed by Michael Dovgal
parent bfd4de0631
commit d132c2eb11
13 changed files with 66 additions and 75 deletions

View File

@ -132,7 +132,7 @@ class CreateCGroupView(forms.ModalFormView):
num_volumes = len(volumes)
usages = quotas.tenant_limit_usages(self.request)
if usages['volumesUsed'] + num_volumes > \
if usages['totalVolumesUsed'] + num_volumes > \
usages['maxTotalVolumes']:
raise ValueError(_('Unable to create consistency group due to '
'exceeding volume quota limit.'))

View File

@ -22,7 +22,7 @@
{% endblock %}
{% block used %}
{{ usages.snapshotsUsed|intcomma }}
{{ usages.totalSnapshotsUsed|intcomma }}
{% endblock %}
{% block total %}
@ -38,5 +38,5 @@
{% endblock %}
{% block used_progress %}
"{{ usages.snapshotsUsed }}"
"{{ usages.totalSnapshotsUsed }}"
{% endblock %}

View File

@ -205,7 +205,7 @@ class CreateSnapshotView(forms.ModalFormView):
num_volumes = len(volumes)
usages = quotas.tenant_limit_usages(self.request)
if usages['snapshotsUsed'] + num_volumes > \
if usages['totalSnapshotsUsed'] + num_volumes > \
usages['maxTotalSnapshots']:
raise ValueError(_('Unable to create snapshots due to '
'exceeding snapshot quota limit.'))
@ -249,7 +249,7 @@ class CloneCGroupView(forms.ModalFormView):
num_volumes = len(volumes)
usages = quotas.tenant_limit_usages(self.request)
if usages['volumesUsed'] + num_volumes > \
if usages['totalVolumesUsed'] + num_volumes > \
usages['maxTotalVolumes']:
raise ValueError(_('Unable to create consistency group due to '
'exceeding volume quota limit.'))

View File

@ -98,7 +98,7 @@
<div class="quota_title">
<strong class="pull-left">{% trans "Total Volume Storage" %}</strong>
<span class="pull-right">
{% blocktrans with used=usages.gigabytesUsed|intcomma quota=usages.maxTotalVolumeGigabytes|intcomma|quotainf %}
{% blocktrans with used=usages.totalGigabytesUsed|intcomma quota=usages.maxTotalVolumeGigabytes|intcomma|quotainf %}
{{ used }} of {{ quota }} GiB Used
{% endblocktrans %}
</span>
@ -107,8 +107,8 @@
class="quota_bar"
data-progress-indicator-flavor
data-quota-limit="{{ usages.maxTotalVolumeGigabytes }}"
data-quota-used="{{ usages.gigabytesUsed }}">
{% widthratio usages.gigabytesUsed usages.maxTotalVolumeGigabytes 100 as volume_storage_percent %}
data-quota-used="{{ usages.totalGigabytesUsed }}">
{% widthratio usages.totalGigabytesUsed usages.maxTotalVolumeGigabytes 100 as volume_storage_percent %}
{% bs_progress_bar volume_storage_percent 0 %}
</div>
{% endif %}

View File

@ -130,8 +130,8 @@ class VolumeSnapshotsViewTests(test.TestCase):
.AndReturn(volume)
snapshot_used = len(self.cinder_volume_snapshots.list())
usage_limit = {'maxTotalVolumeGigabytes': 250,
'gigabytesUsed': 20,
'snapshotsUsed': snapshot_used,
'totalGigabytesUsed': 20,
'totalSnapshotsUsed': snapshot_used,
'maxTotalSnapshots': 6}
quotas.tenant_limit_usages(IsA(http.HttpRequest)).\
AndReturn(usage_limit)

View File

@ -320,8 +320,9 @@ class CreateForm(forms.SelfHandlingForm):
try:
usages = quotas.tenant_limit_usages(self.request)
availableGB = usages['maxTotalVolumeGigabytes'] - \
usages['gigabytesUsed']
availableVol = usages['maxTotalVolumes'] - usages['volumesUsed']
usages['totalGigabytesUsed']
availableVol = usages['maxTotalVolumes'] - \
usages['totalVolumesUsed']
snapshot_id = None
image_id = None
@ -734,7 +735,7 @@ class ExtendForm(forms.SelfHandlingForm):
usages = quotas.tenant_limit_usages(self.request)
availableGB = usages['maxTotalVolumeGigabytes'] - \
usages['gigabytesUsed']
usages['totalGigabytesUsed']
if availableGB < (new_size - orig_size):
message = _('Volume cannot be extended to %(req)iGiB as '
'you only have %(avail)iGiB of your quota '

View File

@ -11,16 +11,16 @@
<strong>{% trans "Total Gibibytes" %}</strong>
</div>
<span class="pull-right">
{% blocktrans with used=usages.gigabytesUsed|intcomma quota=usages.maxTotalVolumeGigabytes|intcomma|quotainf %}{{ used }} of {{ quota }} GiB Used{% endblocktrans %}
{% blocktrans with used=usages.totalGigabytesUsed|intcomma quota=usages.maxTotalVolumeGigabytes|intcomma|quotainf %}{{ used }} of {{ quota }} GiB Used{% endblocktrans %}
</span>
</div>
<div id="quota_size"
data-progress-indicator-for="id_new_size"
data-quota-limit="{{ usages.maxTotalVolumeGigabytes }}"
data-quota-used="{{ usages.gigabytesUsed }}"
data-quota-used="{{ usages.totalGigabytesUsed }}"
class="quota_bar">
{% widthratio usages.gigabytesUsed usages.maxTotalVolumeGigabytes 100 as gigabytes_percent %}
{% widthratio usages.totalGigabytesUsed usages.maxTotalVolumeGigabytes 100 as gigabytes_percent %}
{% bs_progress_bar gigabytes_percent 0 %}
</div>

View File

@ -19,7 +19,7 @@
<strong>{% trans "Total Gibibytes" %}</strong>
</div>
<span class="pull-right">
{% blocktrans with used=usages.gigabytesUsed|intcomma quota=usages.maxTotalVolumeGigabytes|intcomma|quotainf %}{{ used }} of {{ quota }} GiB Used{% endblocktrans %}
{% blocktrans with used=usages.totalGigabytesUsed|intcomma quota=usages.maxTotalVolumeGigabytes|intcomma|quotainf %}{{ used }} of {{ quota }} GiB Used{% endblocktrans %}
</span>
</div>
@ -27,9 +27,9 @@
<div id="quota_size"
data-progress-indicator-for="id_size"
data-quota-limit="{{ usages.maxTotalVolumeGigabytes }}"
data-quota-used={% block gigabytes_used_progress %}"{{ usages.gigabytesUsed }}"{% endblock %}
data-quota-used={% block gigabytes_used_progress %}"{{ usages.totalGigabytesUsed }}"{% endblock %}
class="quota_bar">
{% widthratio usages.gigabytesUsed usages.maxTotalVolumeGigabytes 100 as gigabytes_percent %}
{% widthratio usages.totalGigabytesUsed usages.maxTotalVolumeGigabytes 100 as gigabytes_percent %}
{% bs_progress_bar gigabytes_percent 0 %}
</div>
{{ endminifyspace }}
@ -40,7 +40,7 @@
</div>
<span class="pull-right">
{% block used_of_quota %}
{% blocktrans with used=usages.volumesUsed|intcomma quota=usages.maxTotalVolumes|intcomma|quotainf %}{{ used }} of {{ quota }} Used{% endblocktrans %}
{% blocktrans with used=usages.totalVolumesUsed|intcomma quota=usages.maxTotalVolumes|intcomma|quotainf %}{{ used }} of {{ quota }} Used{% endblocktrans %}
{% endblock %}
</span>
</div>
@ -48,10 +48,10 @@
{{ minifyspace }}
<div id={% block type_id %}"quota_volumes"{% endblock %}
data-quota-limit={% block total_progress %}"{{ usages.maxTotalVolumes }}"{% endblock %}
data-quota-used={% block used_progress %}"{{ usages.volumesUsed }}"{% endblock %}
data-quota-used={% block used_progress %}"{{ usages.totalVolumesUsed }}"{% endblock %}
class="quota_bar">
{% block show_progress_bar %}
{% widthratio usages.volumesUsed usages.maxTotalVolumes 100 as volumes_percent %}
{% widthratio usages.totalVolumesUsed usages.maxTotalVolumes 100 as volumes_percent %}
{% if usages.numRequestedItems %}
{% widthratio 100 usages.maxTotalVolumes usages.numRequestedItems as single_step %}
{% else %}

View File

@ -22,7 +22,7 @@
{% endblock %}
{% block used_of_quota %}
{% blocktrans with used=usages.snapshotsUsed|intcomma quota=usages.maxTotalSnapshots|intcomma|quotainf %}{{ used }} of {{ quota }} Used{% endblocktrans %}
{% blocktrans with used=usages.totalSnapshotsUsed|intcomma quota=usages.maxTotalSnapshots|intcomma|quotainf %}{{ used }} of {{ quota }} Used{% endblocktrans %}
{% endblock %}
{% block type_id %}
@ -34,11 +34,11 @@
{% endblock %}
{% block used_progress %}
"{{ usages.snapshotsUsed }}"
"{{ usages.totalSnapshotsUsed }}"
{% endblock %}
{% block show_progress_bar %}
{% widthratio usages.snapshotsUsed usages.maxTotalSnapshots 100 as volumes_percent %}
{% widthratio usages.totalSnapshotsUsed usages.maxTotalSnapshots 100 as volumes_percent %}
{% if usages.numRequestedItems %}
{% widthratio usages.numRequestedItems usages.maxTotalSnapshots 100 as single_step %}
{% else %}

View File

@ -5,7 +5,7 @@
<div class="quota_title">
<div class="pull-left">
<strong>{% trans "Total Gibibytes" %}</strong>
<span>({% block gigabytes_used %}{{ usages.gigabytesUsed|intcomma }}{% endblock %} {% trans "GiB" %})</span>
<span>({% block gigabytes_used %}{{ usages.totalGigabytesUsed|intcomma }}{% endblock %} {% trans "GiB" %})</span>
</div>
<span class="pull-right">{{ usages.maxTotalVolumeGigabytes|intcomma|quota:_("GiB") }}</span>
</div>
@ -14,9 +14,9 @@
<div id="quota_size"
data-progress-indicator-for="id_size"
data-quota-limit="{{ usages.maxTotalVolumeGigabytes }}"
data-quota-used={% block gigabytes_used_progress %}"{{ usages.gigabytesUsed }}"{% endblock %}
data-quota-used={% block gigabytes_used_progress %}"{{ usages.totalGigabytesUsed }}"{% endblock %}
class="quota_bar">
{% widthratio usages.gigabytesUsed usages.maxTotalVolumeGigabytes 100 as gigabytes_percent %}
{% widthratio usages.totalGigabytesUsed usages.maxTotalVolumeGigabytes 100 as gigabytes_percent %}
{% bs_progress_bar gigabytes_percent 0 %}
</div>
{{ endminifyspace }}
@ -24,7 +24,7 @@
<div class="quota_title">
<div class="pull-left">
<strong>{% block type_title %}{% trans "Number of Volumes" %}{% endblock %}</strong>
<span>({% block used %}{{ usages.volumesUsed|intcomma }}{% endblock %})</span>
<span>({% block used %}{{ usages.totalVolumesUsed|intcomma }}{% endblock %})</span>
</div>
<span class="pull-right">{% block total %}{{ usages.maxTotalVolumes|intcomma|quota }}{% endblock %}</span>
</div>
@ -32,9 +32,9 @@
{{ minifyspace }}
<div id={% block type_id %}"quota_volumes"{% endblock %}
data-quota-limit={% block total_progress %}"{{ usages.maxTotalVolumes }}"{% endblock %}
data-quota-used={% block used_progress %}"{{ usages.volumesUsed }}"{% endblock %}
data-quota-used={% block used_progress %}"{{ usages.totalVolumesUsed }}"{% endblock %}
class="quota_bar">
{% widthratio usages.volumesUsed usages.maxTotalVolumes 100 as volumes_percent %}
{% widthratio usages.totalVolumesUsed usages.maxTotalVolumes 100 as volumes_percent %}
{% if usages.numRequestedItems %}
{% widthratio 100 usages.maxTotalVolumes usages.numRequestedItems as single_step %}
{% else %}

View File

@ -213,8 +213,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
volume_type = self.cinder_volume_types.first()
az = self.cinder_availability_zones.first().zoneName
usage_limit = {'maxTotalVolumeGigabytes': 250,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
formData = {'name': u'A Volume I Am Making',
'description': u'This is a volume I am making for a test.',
@ -286,8 +286,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
volume_type = self.cinder_volume_types.first()
az = self.cinder_availability_zones.first().zoneName
usage_limit = {'maxTotalVolumeGigabytes': 250,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
formData = {'name': '',
'description': u'This is a volume I am making for a test.',
@ -356,8 +356,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
def test_create_volume_dropdown(self):
volume = self.cinder_volumes.first()
usage_limit = {'maxTotalVolumeGigabytes': 250,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
formData = {'name': u'A Volume I Am Making',
'description': u'This is a volume I am making for a test.',
@ -423,8 +423,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
def test_create_volume_from_snapshot(self):
volume = self.cinder_volumes.first()
usage_limit = {'maxTotalVolumeGigabytes': 250,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
snapshot = self.cinder_volume_snapshots.first()
formData = {'name': u'A Volume I Am Making',
@ -480,8 +480,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
def test_create_volume_from_volume(self):
volume = self.cinder_volumes.first()
usage_limit = {'maxTotalVolumeGigabytes': 250,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
formData = {'name': u'A copy of a volume',
@ -553,8 +553,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
def test_create_volume_from_snapshot_dropdown(self):
volume = self.cinder_volumes.first()
usage_limit = {'maxTotalVolumeGigabytes': 250,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
snapshot = self.cinder_volume_snapshots.first()
formData = {'name': u'A Volume I Am Making',
@ -622,8 +622,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
quotas: ('tenant_limit_usages',)})
def test_create_volume_from_snapshot_invalid_size(self):
usage_limit = {'maxTotalVolumeGigabytes': 100,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
snapshot = self.cinder_volume_snapshots.first()
formData = {'name': u'A Volume I Am Making',
@ -673,8 +673,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
def test_create_volume_from_image(self):
volume = self.cinder_volumes.first()
usage_limit = {'maxTotalVolumeGigabytes': 200,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
image = self.images.first()
formData = {'name': u'A Volume I Am Making',
@ -733,8 +733,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
def test_create_volume_from_image_dropdown(self):
volume = self.cinder_volumes.first()
usage_limit = {'maxTotalVolumeGigabytes': 200,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
image = self.images.first()
formData = {'name': u'A Volume I Am Making',
@ -804,8 +804,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
quotas: ('tenant_limit_usages',)})
def test_create_volume_from_image_under_image_size(self):
usage_limit = {'maxTotalVolumeGigabytes': 100,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
image = self.images.first()
formData = {'name': u'A Volume I Am Making',
@ -860,8 +860,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
quotas: ('tenant_limit_usages',)})
def _test_create_volume_from_image_under_image_min_disk_size(self, image):
usage_limit = {'maxTotalVolumeGigabytes': 100,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
formData = {'name': u'A Volume I Am Making',
'description': u'This is a volume I am making for a test.',
@ -930,8 +930,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
quotas: ('tenant_limit_usages',)})
def test_create_volume_gb_used_over_alloted_quota(self):
usage_limit = {'maxTotalVolumeGigabytes': 100,
'gigabytesUsed': 80,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 80,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': 6}
formData = {'name': u'This Volume Is Huge!',
'description': u'This is a volume that is just too big!',
@ -1009,8 +1009,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
quotas: ('tenant_limit_usages',)})
def test_create_volume_number_over_alloted_quota(self):
usage_limit = {'maxTotalVolumeGigabytes': 100,
'gigabytesUsed': 20,
'volumesUsed': len(self.cinder_volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.cinder_volumes.list()),
'maxTotalVolumes': len(self.cinder_volumes.list())}
formData = {'name': u'Too Many...',
'description': u'We have no volumes left!',
@ -1636,8 +1636,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
def test_extend_volume(self):
volume = self.cinder_volumes.first()
usage_limit = {'maxTotalVolumeGigabytes': 100,
'gigabytesUsed': 20,
'volumesUsed': len(self.volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.volumes.list()),
'maxTotalVolumes': 6}
formData = {'name': u'A Volume I Am Making',
'orig_size': volume.size,
@ -1665,8 +1665,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
def test_extend_volume_with_wrong_size(self):
volume = self.cinder_volumes.first()
usage_limit = {'maxTotalVolumeGigabytes': 100,
'gigabytesUsed': 20,
'volumesUsed': len(self.volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.volumes.list()),
'maxTotalVolumes': 6}
formData = {'name': u'A Volume I Am Making',
'orig_size': volume.size,
@ -1793,8 +1793,8 @@ class VolumeViewTests(test.ResetImageAPIVersionMixin, test.TestCase):
def test_extend_volume_with_size_out_of_quota(self):
volume = self.volumes.first()
usage_limit = {'maxTotalVolumeGigabytes': 100,
'gigabytesUsed': 20,
'volumesUsed': len(self.volumes.list()),
'totalGigabytesUsed': 20,
'totalVolumesUsed': len(self.volumes.list()),
'maxTotalVolumes': 6}
formData = {'name': u'A Volume I Am Making',
'orig_size': volume.size,

View File

@ -275,8 +275,8 @@ class ExtendView(forms.ModalFormView):
context['submit_url'] = reverse(self.submit_url, args=args)
try:
usages = quotas.tenant_limit_usages(self.request)
usages['gigabytesUsed'] = (usages['gigabytesUsed']
- context['volume'].size)
usages['totalGigabytesUsed'] = (usages['totalGigabytesUsed']
- context['volume'].size)
context['usages'] = usages
except Exception:
exceptions.handle(self.request)

View File

@ -487,16 +487,6 @@ def tenant_limit_usages(request):
if cinder.is_volume_service_enabled(request):
try:
limits.update(cinder.tenant_absolute_limits(request))
volumes = cinder.volume_list(request)
snapshots = cinder.volume_snapshot_list(request)
# gigabytesUsed should be a total of volumes and snapshots
vol_size = sum([getattr(volume, 'size', 0) for volume
in volumes])
snap_size = sum([getattr(snap, 'size', 0) for snap
in snapshots])
limits['gigabytesUsed'] = vol_size + snap_size
limits['volumesUsed'] = len(volumes)
limits['snapshotsUsed'] = len(snapshots)
except cinder.cinder_exception.ClientException:
msg = _("Unable to retrieve volume limit information.")
exceptions.handle(request, msg)