Adding pagination to the instance views

Modifying the api.nova.server_list() method to optionally handle
pagination.  The method will also work without pagination to
support the many other place than the instance views that continue
to call the method.

Fixes: bug #1046915

Change-Id: I8195f1f2d8922e1722743d7a2d627a8645e8b3bd
This commit is contained in:
David Lyle
2013-03-14 08:43:33 -06:00
parent de1940c922
commit 81247fda00
17 changed files with 194 additions and 78 deletions

View File

@@ -132,7 +132,8 @@ class FloatingIpViewTests(test.TestCase):
self.mox.StubOutWithMock(api.nova, 'server_list')
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(self.servers.list())
all_tenants=True).AndReturn([self.servers.list(),
False])
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())
api.network.floating_ip_disassociate(IsA(http.HttpRequest),
@@ -154,7 +155,8 @@ class FloatingIpViewTests(test.TestCase):
self.mox.StubOutWithMock(api.nova, 'server_list')
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(self.servers.list())
all_tenants=True).AndReturn([self.servers.list(),
False])
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(self.floating_ips.list())

View File

@@ -91,7 +91,8 @@ class FloatingIPsTab(tabs.TableTab):
instances = []
try:
instances = nova.server_list(self.request, all_tenants=True)
instances, has_more = nova.server_list(self.request,
all_tenants=True)
except:
exceptions.handle(self.request,
_('Unable to retrieve instance list.'))

View File

@@ -43,7 +43,8 @@ class AccessAndSecurityTests(test.TestCase):
self.mox.StubOutWithMock(api.nova, 'server_list')
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True).AndReturn(self.servers.list())
all_tenants=True).AndReturn([self.servers.list(),
False])
api.nova.keypair_list(IsA(http.HttpRequest)).AndReturn(keypairs)
api.network.tenant_floating_ip_list(IsA(http.HttpRequest)) \
.AndReturn(floating_ips)

View File

@@ -46,8 +46,9 @@ class InstanceTests(test.TestCase):
def test_index(self):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(self.limits['absolute'])
@@ -65,7 +66,8 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_list',
'tenant_absolute_limits')})
def test_index_server_list_exception(self):
api.nova.server_list(IsA(http.HttpRequest)) \
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndRaise(self.exceptions.nova)
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(self.limits['absolute'])
@@ -86,8 +88,9 @@ class InstanceTests(test.TestCase):
servers = self.servers.list()
flavors = self.flavors.list()
full_flavors = SortedDict([(f.id, f) for f in flavors])
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(servers)
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndRaise(self.exceptions.nova)
for server in servers:
@@ -117,7 +120,9 @@ class InstanceTests(test.TestCase):
for i, server in enumerate(servers):
server.flavor['id'] = str(uuid.UUID(int=i))
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(servers)
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.flavor_list(IsA(http.HttpRequest)).AndReturn(flavors)
for server in servers:
api.nova.flavor_get(IsA(http.HttpRequest), server.flavor["id"]). \
@@ -141,8 +146,9 @@ class InstanceTests(test.TestCase):
def test_terminate_instance(self):
server = self.servers.first()
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.nova.server_delete(IsA(http.HttpRequest), server.id)
@@ -159,8 +165,9 @@ class InstanceTests(test.TestCase):
def test_terminate_instance_exception(self):
server = self.servers.first()
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.nova.server_delete(IsA(http.HttpRequest), server.id) \
.AndRaise(self.exceptions.nova)
@@ -180,8 +187,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_pause(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
@@ -199,8 +207,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_pause(IsA(http.HttpRequest), server.id) \
.AndRaise(self.exceptions.nova)
@@ -220,8 +229,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_unpause(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
@@ -240,8 +250,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_unpause(IsA(http.HttpRequest), server.id) \
.AndRaise(self.exceptions.nova)
@@ -260,8 +271,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_reboot(IsA(http.HttpRequest), server.id,
api.nova.REBOOT_HARD)
@@ -280,8 +292,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_reboot(IsA(http.HttpRequest), server.id,
api.nova.REBOOT_HARD) \
.AndRaise(self.exceptions.nova)
@@ -301,8 +314,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_reboot(IsA(http.HttpRequest), server.id,
api.nova.REBOOT_SOFT)
@@ -321,8 +335,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_suspend(IsA(http.HttpRequest), unicode(server.id))
self.mox.ReplayAll()
@@ -340,8 +355,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_suspend(IsA(http.HttpRequest), unicode(server.id)) \
.AndRaise(self.exceptions.nova)
@@ -361,8 +377,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_resume(IsA(http.HttpRequest), unicode(server.id))
self.mox.ReplayAll()
@@ -381,8 +398,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.server_resume(IsA(http.HttpRequest),
unicode(server.id)) \
.AndRaise(self.exceptions.nova)
@@ -1181,8 +1199,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(limits)
@@ -1209,8 +1228,9 @@ class InstanceTests(test.TestCase):
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
.MultipleTimes().AndReturn(self.limits['absolute'])
@@ -1281,8 +1301,9 @@ class InstanceTests(test.TestCase):
server = self.servers.first()
fip = self.q_floating_ips.first()
api.nova.server_list(
IsA(http.HttpRequest)).AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.network.floating_ip_target_get_by_instance(
IsA(http.HttpRequest),
@@ -1310,8 +1331,9 @@ class InstanceTests(test.TestCase):
fip = self.q_floating_ips.first()
fip.port_id = server.id
api.nova.server_list(
IsA(http.HttpRequest)).AndReturn(self.servers.list())
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.network.floating_ip_target_get_by_instance(
IsA(http.HttpRequest),

View File

@@ -48,11 +48,20 @@ class IndexView(tables.DataTableView):
table_class = InstancesTable
template_name = 'project/instances/index.html'
def has_more_data(self, table):
return self._more
def get_data(self):
marker = self.request.GET.get(
InstancesTable._meta.pagination_param, None)
# Gather our instances
try:
instances = api.nova.server_list(self.request)
instances, self._more = api.nova.server_list(
self.request,
search_opts={'marker': marker,
'paginate': True})
except:
self._more = False
instances = []
exceptions.handle(self.request,
_('Unable to retrieve instances.'))

View File

@@ -244,8 +244,8 @@ class LoadBalancerTests(test.TestCase):
api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([server1,
server2])
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(
[[server1, server2], False])
api.quantum.port_list(IsA(http.HttpRequest),
device_id=server1.id).AndReturn([port1, ])
@@ -288,8 +288,9 @@ class LoadBalancerTests(test.TestCase):
api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([server1,
server2])
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([[server1,
server2],
False])
self.mox.ReplayAll()
@@ -317,7 +318,7 @@ class LoadBalancerTests(test.TestCase):
api.lbaas.pools_get(IsA(http.HttpRequest)).AndReturn(self.pools.list())
api.nova.server_list(
IsA(http.HttpRequest)).AndReturn([server1, server2])
IsA(http.HttpRequest)).AndReturn([[server1, server2], False])
self.mox.ReplayAll()

View File

@@ -285,7 +285,7 @@ class AddMemberAction(workflows.Action):
members_choices = []
try:
servers = api.nova.server_list(request)
servers, has_more = api.nova.server_list(request)
except:
servers = []
exceptions.handle(request,

View File

@@ -314,11 +314,11 @@ class VolumeViewTests(test.TestCase):
AndReturn(self.volumes.list())
cinder.volume_delete(IsA(http.HttpRequest), volume.id)
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
AndReturn(self.volumes.list())
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
self.mox.ReplayAll()
@@ -342,11 +342,11 @@ class VolumeViewTests(test.TestCase):
cinder.volume_delete(IsA(http.HttpRequest), volume.id).\
AndRaise(exc)
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
cinder.volume_list(IsA(http.HttpRequest), search_opts=None).\
AndReturn(self.volumes.list())
api.nova.server_list(IsA(http.HttpRequest)).\
AndReturn(self.servers.list())
AndReturn([self.servers.list(), False])
self.mox.ReplayAll()
@@ -364,7 +364,7 @@ class VolumeViewTests(test.TestCase):
servers = self.servers.list()
cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(servers)
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([servers, False])
self.mox.ReplayAll()
url = reverse('horizon:project:volumes:attach', args=[volume.id])
@@ -387,7 +387,7 @@ class VolumeViewTests(test.TestCase):
servers = self.servers.list()
cinder.volume_get(IsA(http.HttpRequest), volume.id).AndReturn(volume)
api.nova.server_list(IsA(http.HttpRequest)).AndReturn(servers)
api.nova.server_list(IsA(http.HttpRequest)).AndReturn([servers, False])
self.mox.ReplayAll()
url = reverse('horizon:project:volumes:attach', args=[volume.id])
@@ -407,7 +407,7 @@ class VolumeViewTests(test.TestCase):
cinder.volume_get(IsA(http.HttpRequest), volume.id) \
.AndReturn(volume)
api.nova.server_list(IsA(http.HttpRequest)) \
.AndReturn(self.servers.list())
.AndReturn([self.servers.list(), False])
self.mox.ReplayAll()

View File

@@ -50,7 +50,8 @@ class VolumeTableMixIn(object):
def _get_instances(self):
try:
return api.nova.server_list(self.request)
instances, has_more = api.nova.server_list(self.request)
return instances
except:
exceptions.handle(self.request,
_("Unable to retrieve volume/instance "
@@ -145,7 +146,7 @@ class EditAttachmentsView(tables.DataTableView, forms.ModalFormView):
def get_initial(self):
try:
instances = api.nova.server_list(self.request)
instances, has_more = api.nova.server_list(self.request)
except:
instances = []
exceptions.handle(self.request,