Skip to content

Instantly share code, notes, and snippets.

@kennym
Created January 7, 2011 18:49
Show Gist options
  • Save kennym/769910 to your computer and use it in GitHub Desktop.
Save kennym/769910 to your computer and use it in GitHub Desktop.
I cannot see why inner_table is not being rendered...
From 659677d234dced2f0f7f012bfda434a0689cab13 Mon Sep 17 00:00:00 2001
From: Kenny Meyer <knny.myer@gmail.com>
Date: Wed, 5 Jan 2011 17:04:19 -0300
Subject: [PATCH] Implement pagination for cluster detail -> virtual machines
---
ganeti/templates/virtual_machine/inner_table.html | 138 +++++++++++++++++++++
ganeti/templates/virtual_machine/list.html | 4 +-
ganeti/templates/virtual_machine/table.html | 83 +------------
ganeti/urls.py | 3 +
ganeti/views/cluster.py | 16 ++-
ganeti/views/virtual_machine.py | 46 ++++++-
6 files changed, 195 insertions(+), 95 deletions(-)
create mode 100644 ganeti/templates/virtual_machine/inner_table.html
diff --git a/ganeti/templates/virtual_machine/inner_table.html b/ganeti/templates/virtual_machine/inner_table.html
new file mode 100644
index 0000000..c52b9c1
--- /dev/null
+++ b/ganeti/templates/virtual_machine/inner_table.html
@@ -0,0 +1,138 @@
+{% load webmgr_tags %}
+
+{% block head %}
+<style>
+ td.actions div.delete {
+ float:none;
+ }
+ #content td.actions a, #content td.actions {
+ padding:5px 0 0 0;
+ }
+</style>
+
+<script type="text/javascript" src="{{MEDIA_URL}}/js/jquery.ajax.delete.js"></script>
+<script type="text/javascript" src="{{MEDIA_URL}}/js/jquery.tablesorter.min.js"></script>
+<script type="text/javascript">
+$(document).ready(function() {
+ $("#vmlist").tablesorter();
+});
+
+function ajax_get_update() {
+ $.get(url, function(results){
+ var table = $("table", results);
+ var span = $("span.step-links", results);
+
+ // update vmlist with the return value
+ $('#vmlist').html(table);
+ $('.step-links').html(span);
+ }, "html");
+}
+
+$(document).ready( function() {
+ $('.step-links #prev').click(function(e) {
+ e.preventDefault();
+ url = ($('.step-links #prev')[0].href);
+ ajax_get_update();
+ });
+ $('.step-links #next').click(function(e) {
+ e.preventDefault();
+ url = ($('.step-links #next')[0].href);
+ ajax_get_update();
+ });
+});
+
+$(document).ajaxStop( function() {
+ $('.step-links #prev').click( function(e) {
+ e.preventDefault();
+ url = ($('.step-links #prev')[0].href);
+ ajax_get_update();
+ });
+ $('.step-links #next').click( function(e) {
+ e.preventDefault();
+ url = ($('.step-links #next')[0].href);
+ ajax_get_update();
+ });
+});
+</script>
+{% endblock %}
+
+{% if vms.object_list %}
+<table id="vmlist" class="sorted">
+<thead>
+ <tr>
+ <th class="status"></th>
+ <th>Name</th>
+ {% if not cluster %}
+ <th>Cluster</th>
+ {% endif %}
+ <th>Node</th>
+ <th>OS</th>
+ <th>RAM</th>
+ <th>Disk Space</th>
+ <th>vCPUs</th>
+ </tr>
+</thead>
+<tbody id="vms">
+ {% for vm in vms.object_list %}
+ {% with vm.info as info %}
+ <tr>
+
+ <td class="status">
+ {% if vm.error %}
+ <div class="icon_error" title="Ganeti API Error: {{vm.error}}, last status was {{ info.status|render_instance_status }}"></div>
+ {% else %}
+ {% if info.admin_state %}
+ {% if info.oper_state %}
+ <div class="icon_running" title="running"></div>
+ {% else %}
+ <div class="icon_error" title="{{ info.status|render_instance_status }}"></div>
+ {% endif %}
+ {% else %}
+ {% if info.oper_state %}vm
+ <div class="icon_error" title="{{ info.status|render_instance_status }}"></div>
+ {% else %}
+ <div class="icon_stopped" title="stopped"></div>
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ </td>
+
+ <td class="name">
+ <a href="{% url instance-detail vm.cluster.slug vm.hostname %}">
+ {{ vm.hostname }}
+ </a>
+ </td>
+ {% if not cluster %}
+ <td>{{ vm.cluster|abbreviate_fqdn }}</td>
+ {% endif %}
+ <td>{{ info.pnode|abbreviate_fqdn }}</td>
+ <td>{{ vm.operating_system|render_os }}</td>
+ <td>{{ vm.ram|render_storage }}</td>
+ <td>{{ vm.disk_size|render_storage }}</td>
+ <td>{{ vm.virtual_cpus }}</td>
+ {% endwith %}
+ {% empty %}
+ <tr class="none"><td colspan="100%">No Virtual Machines</td></tr>
+ {% endfor %}
+</tbody>
+</table>
+<div class="pagination">
+ <span class="step-links">
+ {% if vms.has_previous %}
+ <a id="prev" href="{% url virtualmachine-table %}?page={{ vms.previous_page_number }}">previous</a>
+ {% else %}
+ <span style="visibility:hidden;">previous</span>
+ {% endif %}
+
+ <span class="current">
+ Page {{ vms.number }} of {{ vms.paginator.num_pages }}.
+ </span>
+
+ {% if vms.has_next %}
+ <a id="next" href="{% url virtualmachine-table %}?page={{ vms.next_page_number }}">next</a>
+ {% else %}
+ <span style="visibility:hidden;">next</span>
+ {% endif %}
+ </span>
+</div>
+{% endif %}
diff --git a/ganeti/templates/virtual_machine/list.html b/ganeti/templates/virtual_machine/list.html
index 23be7ba..ff76b77 100644
--- a/ganeti/templates/virtual_machine/list.html
+++ b/ganeti/templates/virtual_machine/list.html
@@ -3,6 +3,6 @@
{% block title %}Virtual Machines{% endblock %}
{% block content %}
-<h1>Virtual Machines </h1>
+<h1>Virtual Machines</h1>
{% include "virtual_machine/table.html" %}
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/ganeti/templates/virtual_machine/table.html b/ganeti/templates/virtual_machine/table.html
index 9393424..e7cf251 100644
--- a/ganeti/templates/virtual_machine/table.html
+++ b/ganeti/templates/virtual_machine/table.html
@@ -1,25 +1,3 @@
-{% load webmgr_tags %}
-
-{% block head %}
-
-<style>
- td.actions div.delete {
- float:none;
- }
- #content td.actions a, #content td.actions {
- padding:5px 0 0 0;
- }
-</style>
-
-<script type="text/javascript" src="{{MEDIA_URL}}/js/jquery.ajax.delete.js"></script>
-<script type="text/javascript" src="{{MEDIA_URL}}/js/jquery.tablesorter.min.js"></script>
-<script type="text/javascript">
- $(document).ready(function() {
- $("#vmlist").tablesorter();
- });
-</script>
-{% endblock %}
-
{% if cluster %}
<a class="button add" href="{% url instance-create cluster.slug %}">Add Virtual Machine</a>
{% else %}
@@ -27,62 +5,5 @@
<a class="button add" href="{% url instance-create %}">Add Virtual Machine</a>
{% endif %}
{% endif %}
-<table id="vmlist" class="sorted">
-<thead>
- <tr>
- <th class="status"></th>
- <th>Name</th>
- {% if not cluster %}
- <th>Cluster</th>
- {% endif %}
- <th>Node</th>
- <th>OS</th>
- <th>RAM</th>
- <th>Disk Space</th>
- <th>vCPUs</th>
- </tr>
-</thead>
-<tbody id="vms">
- {% for vm in vms %}
- {% with vm.info as info %}
- <tr>
-
- <td class="status">
- {% if vm.error %}
- <div class="icon_error" title="Ganeti API Error: {{vm.error}}, last status was {{ info.status|render_instance_status }}"></div>
- {% else %}
- {% if info.admin_state %}
- {% if info.oper_state %}
- <div class="icon_running" title="running"></div>
- {% else %}
- <div class="icon_error" title="{{ info.status|render_instance_status }}"></div>
- {% endif %}
- {% else %}
- {% if info.oper_state %}
- <div class="icon_error" title="{{ info.status|render_instance_status }}"></div>
- {% else %}
- <div class="icon_stopped" title="stopped"></div>
- {% endif %}
- {% endif %}
- {% endif %}
- </td>
-
- <td class="name">
- <a href="{% url instance-detail vm.cluster.slug vm.hostname %}">
- {{ vm.hostname }}
- </a>
- </td>
- {% if not cluster %}
- <td>{{ vm.cluster|abbreviate_fqdn }}</td>
- {% endif %}
- <td>{{ info.pnode|abbreviate_fqdn }}</td>
- <td>{{ vm.operating_system|render_os }}</td>
- <td>{{ vm.ram|render_storage }}</td>
- <td>{{ vm.disk_size|render_storage }}</td>
- <td>{{ vm.virtual_cpus }}</td>
- {% endwith %}
- {% empty %}
- <tr class="none"><td colspan="100%">No Virtual Machines</td></tr>
- {% endfor %}
-</tbody>
-</table>
+
+{% include "virtual_machine/inner_table.html" %}
diff --git a/ganeti/urls.py b/ganeti/urls.py
index 7f30409..a517762 100644
--- a/ganeti/urls.py
+++ b/ganeti/urls.py
@@ -91,6 +91,9 @@ urlpatterns += patterns('ganeti.views.virtual_machine',
# SSH Keys
url(r'^%s/keys/(?P<api_key>\w+)/?$' % vm_prefix, "ssh_keys", name="instance-keys"),
+
+ # Table
+ url(r'^vms/table/$', 'vm_table', name="virtualmachine-table"),
)
diff --git a/ganeti/views/cluster.py b/ganeti/views/cluster.py
index 5067162..0e670c8 100644
--- a/ganeti/views/cluster.py
+++ b/ganeti/views/cluster.py
@@ -26,6 +26,7 @@ from django import forms
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required, user_passes_test
from django.core.urlresolvers import reverse
+from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
@@ -39,7 +40,7 @@ from logs.models import LogItem
log_action = LogItem.objects.log_action
from ganeti.models import *
-from ganeti.views import render_403, render_404
+from ganeti.views import render_403, render_404, virtual_machine
from util.portforwarder import forward_port
# Regex for a resolvable hostname
@@ -98,10 +99,15 @@ def virtual_machines(request, cluster_slug):
vms = cluster.virtual_machines.all()
else:
vms = user.filter_on_perms(['admin'], VirtualMachine, cluster=cluster)
-
- return render_to_response("virtual_machine/table.html", \
- {'cluster': cluster, 'vms':vms}, \
- context_instance=RequestContext(request))
+
+ vms = virtual_machine.render_vms(request, vms)
+
+ return render_to_response("virtual_machine/table.html", {
+ 'cluster': cluster,
+ 'vms': vms
+ },
+ context_instance=RequestContext(request)
+ )
@login_required
diff --git a/ganeti/views/virtual_machine.py b/ganeti/views/virtual_machine.py
index fe16b74..42f97f6 100644
--- a/ganeti/views/virtual_machine.py
+++ b/ganeti/views/virtual_machine.py
@@ -28,6 +28,7 @@ from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group
from django.core.urlresolvers import reverse
+from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.http import HttpResponse, HttpResponseRedirect, \
HttpResponseNotAllowed, HttpResponseForbidden
from django.shortcuts import get_object_or_404, render_to_response
@@ -206,19 +207,51 @@ def list_(request):
user = request.user
if user.is_superuser:
vms = VirtualMachine.objects.all()
- can_create = True
else:
vms = user.get_objects_any_perms(VirtualMachine, ['admin', 'power','remove'])
- can_create = user.has_any_perms(Cluster, ['create_vm'])
-
+
+ vms = render_vms(request, vms)
+
return render_to_response('virtual_machine/list.html', {
- 'vms':vms,
- 'can_create':can_create,
+ 'vms': vms,
},
- context_instance=RequestContext(request),
+ context_instance=RequestContext(request)
+ )
+
+
+@login_required
+def vm_table(request):
+ user = request.user
+ if user.is_superuser:
+ vms = VirtualMachine.objects.all()
+ else:
+ vms = user.get_objects_any_perms(VirtualMachine, ['admin', 'power','remove'])
+
+ vms = render_vms(request, vms)
+
+ return render_to_response('virtual_machine/inner_table.html', {
+ 'vms': vms
+ },
+ context_instance=RequestContext(request)
)
+def render_vms(request, query):
+ paginator = Paginator(query, 10)
+ page = 1
+ if request.is_ajax:
+ query = request.GET.get('page')
+ if query is not None:
+ page = query
+
+ try:
+ vms = paginator.page(page)
+ except (EmptyPage, InvalidPage):
+ vms = paginator.page(paginator.num_pages)
+
+ return vms
+
+
@login_required
def detail(request, cluster_slug, instance):
cluster = get_object_or_404(Cluster, slug=cluster_slug)
@@ -549,7 +582,6 @@ def cluster_defaults(request):
content = json.dumps(cluster_default_info(cluster))
return HttpResponse(content, mimetype='application/json')
-
def cluster_default_info(cluster):
"""
Returns a dictionary containing the following
--
1.7.3.4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment