Fix excessive volume_get requests in snaps table
The volume snapshots table has a column that shows the associated volume name and links to its volume detail page. This calls volume_get twice for each snapshot, so loading the Images & Snapshots page takes forever if you have a decent number of snapshots. This commit instead gets the volume list at the same time as the volume snapshot list, and stores the volume as an attribute on the snapshot so it can be easily retrieved later. Closes-bug: 1218259 Change-Id: I004e50aae51a6ed7549da41967bc42babfa6cb45
This commit is contained in:
parent
e063659d66
commit
f4d56fb134
@ -36,22 +36,16 @@ INDEX_URL = reverse('horizon:project:images_and_snapshots:index')
|
||||
|
||||
class ImagesAndSnapshotsTests(test.TestCase):
|
||||
@test.create_stubs({api.glance: ('image_list_detailed',),
|
||||
api.cinder: ('volume_snapshot_list', 'volume_get')})
|
||||
api.cinder: ('volume_snapshot_list',
|
||||
'volume_list',)})
|
||||
def test_index(self):
|
||||
images = self.images.list()
|
||||
vol_snaps = self.volume_snapshots.list()
|
||||
volumes = self.volumes.list()
|
||||
|
||||
for volume in volumes:
|
||||
volume.volume_id = volume.id
|
||||
for volume in volumes:
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
|
||||
.AndReturn(volume)
|
||||
for volume in volumes:
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
|
||||
.AndReturn(volume)
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id)
|
||||
|
||||
api.cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(vol_snaps)
|
||||
api.cinder.volume_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(volumes)
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
marker=None).AndReturn([images, False])
|
||||
@ -77,21 +71,15 @@ class ImagesAndSnapshotsTests(test.TestCase):
|
||||
self.assertTrue(len(row_actions), 3)
|
||||
|
||||
@test.create_stubs({api.glance: ('image_list_detailed',),
|
||||
api.cinder: ('volume_snapshot_list', 'volume_get')})
|
||||
api.cinder: ('volume_snapshot_list',
|
||||
'volume_list',)})
|
||||
def test_index_no_images(self):
|
||||
vol_snaps = self.volume_snapshots.list()
|
||||
volumes = self.volumes.list()
|
||||
|
||||
for volume in volumes:
|
||||
volume.volume_id = volume.id
|
||||
for volume in volumes:
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
|
||||
.AndReturn(volume)
|
||||
for volume in volumes:
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
|
||||
.AndReturn(volume)
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id)
|
||||
|
||||
api.cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(vol_snaps)
|
||||
api.cinder.volume_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(volumes)
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
marker=None).AndReturn([(), False])
|
||||
@ -101,21 +89,15 @@ class ImagesAndSnapshotsTests(test.TestCase):
|
||||
self.assertTemplateUsed(res, 'project/images_and_snapshots/index.html')
|
||||
|
||||
@test.create_stubs({api.glance: ('image_list_detailed',),
|
||||
api.cinder: ('volume_snapshot_list', 'volume_get')})
|
||||
api.cinder: ('volume_snapshot_list',
|
||||
'volume_list',)})
|
||||
def test_index_error(self):
|
||||
vol_snaps = self.volume_snapshots.list()
|
||||
volumes = self.volumes.list()
|
||||
|
||||
for volume in volumes:
|
||||
volume.volume_id = volume.id
|
||||
for volume in volumes:
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
|
||||
.AndReturn(volume)
|
||||
for volume in volumes:
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
|
||||
.AndReturn(volume)
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id)
|
||||
|
||||
api.cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(vol_snaps)
|
||||
api.cinder.volume_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(volumes)
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
marker=None) \
|
||||
@ -126,22 +108,16 @@ class ImagesAndSnapshotsTests(test.TestCase):
|
||||
self.assertTemplateUsed(res, 'project/images_and_snapshots/index.html')
|
||||
|
||||
@test.create_stubs({api.glance: ('image_list_detailed',),
|
||||
api.cinder: ('volume_snapshot_list', 'volume_get')})
|
||||
api.cinder: ('volume_snapshot_list',
|
||||
'volume_list',)})
|
||||
def test_snapshot_actions(self):
|
||||
snapshots = self.snapshots.list()
|
||||
vol_snaps = self.volume_snapshots.list()
|
||||
volumes = self.volumes.list()
|
||||
|
||||
for volume in volumes:
|
||||
volume.volume_id = volume.id
|
||||
for volume in volumes:
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
|
||||
.AndReturn(volume)
|
||||
for volume in volumes:
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id) \
|
||||
.AndReturn(volume)
|
||||
api.cinder.volume_get(IsA(http.HttpRequest), volume.volume_id)
|
||||
|
||||
api.cinder.volume_snapshot_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(vol_snaps)
|
||||
api.cinder.volume_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(volumes)
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest), marker=None) \
|
||||
.AndReturn([snapshots, False])
|
||||
|
@ -72,10 +72,18 @@ class IndexView(tables.MultiTableView):
|
||||
if base.is_service_enabled(self.request, 'volume'):
|
||||
try:
|
||||
snapshots = api.cinder.volume_snapshot_list(self.request)
|
||||
volumes = api.cinder.volume_list(self.request)
|
||||
volumes = dict((v.id, v) for v in volumes)
|
||||
except Exception:
|
||||
snapshots = []
|
||||
volumes = {}
|
||||
exceptions.handle(self.request, _("Unable to retrieve "
|
||||
"volume snapshots."))
|
||||
|
||||
for snapshot in snapshots:
|
||||
volume = volumes.get(snapshot.volume_id)
|
||||
setattr(snapshot, '_volume', volume)
|
||||
|
||||
else:
|
||||
snapshots = []
|
||||
return snapshots
|
||||
|
@ -62,20 +62,24 @@ class UpdateRow(tables.Row):
|
||||
|
||||
def get_data(self, request, snapshot_id):
|
||||
snapshot = cinder.volume_snapshot_get(request, snapshot_id)
|
||||
snapshot._volume = cinder.volume_get(request, snapshot.volume_id)
|
||||
return snapshot
|
||||
|
||||
|
||||
class SnapshotVolumeNameColumn(tables.Column):
|
||||
def get_raw_data(self, snapshot):
|
||||
request = self.table.request
|
||||
volume_name = api.cinder.volume_get(request,
|
||||
snapshot.volume_id).display_name
|
||||
volume = snapshot._volume
|
||||
if volume:
|
||||
volume_name = volume.display_name or volume.id
|
||||
else:
|
||||
volume_name = _("Unknown")
|
||||
return safestring.mark_safe(volume_name)
|
||||
|
||||
def get_link_url(self, snapshot):
|
||||
volume_id = api.cinder.volume_get(self.table.request,
|
||||
snapshot.volume_id).id
|
||||
return reverse(self.link, args=(volume_id,))
|
||||
volume = snapshot._volume
|
||||
if volume:
|
||||
volume_id = volume.id
|
||||
return reverse(self.link, args=(volume_id,))
|
||||
|
||||
|
||||
class VolumeSnapshotsTable(volume_tables.VolumesTableBase):
|
||||
|
@ -73,20 +73,27 @@ class VolumeSnapshotsViewTests(test.TestCase):
|
||||
|
||||
@test.create_stubs({api.glance: ('image_list_detailed',),
|
||||
api.cinder: ('volume_snapshot_list',
|
||||
'volume_list',
|
||||
'volume_snapshot_delete')})
|
||||
def test_delete_volume_snapshot(self):
|
||||
vol_snapshots = self.volume_snapshots.list()
|
||||
volumes = self.volumes.list()
|
||||
snapshot = self.volume_snapshots.first()
|
||||
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
marker=None).AndReturn(([], False))
|
||||
api.cinder.volume_snapshot_list(IsA(http.HttpRequest)). \
|
||||
AndReturn(vol_snapshots)
|
||||
api.cinder.volume_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(volumes)
|
||||
|
||||
api.cinder.volume_snapshot_delete(IsA(http.HttpRequest), snapshot.id)
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
marker=None).AndReturn(([], False))
|
||||
api.cinder.volume_snapshot_list(IsA(http.HttpRequest)). \
|
||||
AndReturn([])
|
||||
api.cinder.volume_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(volumes)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'action':
|
||||
|
@ -659,7 +659,8 @@ class InstanceTests(test.TestCase):
|
||||
'server_list',
|
||||
'flavor_list',
|
||||
'server_delete'),
|
||||
cinder: ('volume_snapshot_list',),
|
||||
cinder: ('volume_snapshot_list',
|
||||
'volume_list',),
|
||||
api.glance: ('image_list_detailed',)})
|
||||
def test_create_instance_snapshot(self):
|
||||
server = self.servers.first()
|
||||
@ -672,6 +673,7 @@ class InstanceTests(test.TestCase):
|
||||
api.glance.image_list_detailed(IsA(http.HttpRequest),
|
||||
marker=None).AndReturn([[], False])
|
||||
cinder.volume_snapshot_list(IsA(http.HttpRequest)).AndReturn([])
|
||||
cinder.volume_list(IsA(http.HttpRequest)).AndReturn([])
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
|
@ -501,7 +501,15 @@ def data(TEST):
|
||||
'size': 40,
|
||||
'status': 'available',
|
||||
'volume_id': '41023e92-8008-4c8b-8059-7f2293ff3775'})
|
||||
volume_snapshot2 = vol_snaps.Snapshot(vol_snaps.SnapshotManager(None),
|
||||
{'id': 'a374cbb8-3f99-4c3f-a2ef-3edbec842e31',
|
||||
'display_name': '',
|
||||
'display_description': 'vol snap 2!',
|
||||
'size': 80,
|
||||
'status': 'available',
|
||||
'volume_id': '3b189ac8-9166-ac7f-90c9-16c8bf9e01ac'})
|
||||
TEST.volume_snapshots.add(volume_snapshot)
|
||||
TEST.volume_snapshots.add(volume_snapshot2)
|
||||
|
||||
cert_data = {'private_key': 'private',
|
||||
'data': 'certificate_data'}
|
||||
|
Loading…
x
Reference in New Issue
Block a user