Added detail view for images.

* fixes bug 897078

Change-Id: I20d8567ecac232b67f2f90f57edbad8d65eb493c
This commit is contained in:
Emma Steimann 2012-02-04 19:42:58 -06:00 committed by jakedahn
parent 86764391bc
commit eceeadbd1b
6 changed files with 102 additions and 7 deletions

View File

@ -66,7 +66,8 @@ def get_container_format(image):
class ImagesTable(tables.DataTable): class ImagesTable(tables.DataTable):
name = tables.Column("name") name = tables.Column("name", link="horizon:nova:images_and_snapshots:" \
"images:detail")
image_type = tables.Column(get_image_type, image_type = tables.Column(get_image_type,
verbose_name=_("Type"), verbose_name=_("Type"),
filters=(filters.title,)) filters=(filters.title,))

View File

@ -210,3 +210,17 @@ class ImageViewTests(test.TestCase):
args=[image.id]) args=[image.id])
res = self.client.post(url, form_data) res = self.client.post(url, form_data)
self.assertRedirectsNoFollow(res, IMAGES_INDEX_URL) self.assertRedirectsNoFollow(res, IMAGES_INDEX_URL)
def test_image_detail_get(self):
image = self.images.first()
self.mox.StubOutWithMock(api.glance, 'image_get_meta')
api.glance.image_get_meta(IsA(http.HttpRequest), str(image.id)) \
.AndReturn(self.images.first())
self.mox.ReplayAll()
res = self.client.get(
reverse('horizon:nova:images_and_snapshots:images:detail',
args=[image.id]))
self.assertTemplateUsed(res,
'nova/images_and_snapshots/images/detail.html')
self.assertEqual(res.context['image'].name, image.name)

View File

@ -20,12 +20,13 @@
from django.conf.urls.defaults import patterns, url from django.conf.urls.defaults import patterns, url
from .views import UpdateView, LaunchView from .views import UpdateView, LaunchView, DetailView
VIEWS_MOD = 'horizon.dashboards.nova.images_and_snapshots.images.views' VIEWS_MOD = 'horizon.dashboards.nova.images_and_snapshots.images.views'
urlpatterns = patterns(VIEWS_MOD, urlpatterns = patterns(VIEWS_MOD,
url(r'^(?P<image_id>[^/]+)/launch/$', LaunchView.as_view(), name='launch'), url(r'^(?P<image_id>[^/]+)/launch/$', LaunchView.as_view(), name='launch'),
url(r'^(?P<image_id>[^/]+)/update/$', UpdateView.as_view(), name='update') url(r'^(?P<image_id>[^/]+)/update/$', UpdateView.as_view(), name='update'),
url(r'^(?P<image_id>[^/]+)/$', DetailView.as_view(), name='detail'),
) )

View File

@ -24,12 +24,14 @@ Views for managing Nova images.
import logging import logging
from django import shortcuts
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from horizon import api from horizon import api
from horizon import exceptions from horizon import exceptions
from horizon import forms from horizon import forms
from horizon import views
from .forms import UpdateImageForm, LaunchForm from .forms import UpdateImageForm, LaunchForm
@ -168,3 +170,18 @@ class UpdateView(forms.ModalFormView):
'architecture': properties.get('architecture', ''), 'architecture': properties.get('architecture', ''),
'container_format': self.object.get('container_format', ''), 'container_format': self.object.get('container_format', ''),
'disk_format': self.object.get('disk_format', ''), } 'disk_format': self.object.get('disk_format', ''), }
class DetailView(views.APIView):
template_name = 'nova/images_and_snapshots/images/detail.html'
def get_data(self, request, context, *args, **kwargs):
image_id = kwargs['image_id']
try:
image = api.glance.image_get_meta(self.request, kwargs['image_id'])
except:
exceptions.handle(request, _('Unable to retrieve details for '
'instance "%s".') % image_id,
redirect=redirect)
shortcuts.redirect('horizon:nova:images_and_snapshots:index')
return {'image': image}

View File

@ -0,0 +1,55 @@
{% extends 'nova/base.html' %}
{% load i18n sizeformat %}
{% block title %}{% trans "Image Detail "%}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title="Image Detail: "|add:image.name %}
{% endblock page_header %}
{% block dash_main %}
<ul class="item_detail dash_block">
<li class="status detail_section">
<h3>{% trans "Status" %}</h3>
<ul>
<li><label>{% trans "Image ID:" %}</label>{{ image.id|default:"None" }}</li>
<li><label>{% trans "Image Status:" %}</label> {{ image.status|default:"None" }}</li>
<li><label>{% trans "Image Name:" %}</label> {{ image.name|default:"None" }}</li>
<li><label>{% trans "Public:" %}</label> {{ image.is_public }}</li>
<li><label>{% trans "Checksum:" %}</label> {{ image.checksum|default:"None" }}</li>
<li><label>{% trans "Created At:" %}</label> {{ image.created_at|default:"None" }}</li>
<li><label>{% trans "Last Updated At:" %}</label> {{ image.updated_app|default:"None" }}</li>
</ul>
</li>
<li class="specs detail_section">
<h3>{% trans "Specs" %}</h3>
<ul>
<li><label>{% trans "Size:" %}</label> {{ image.size|filesizeformat }}</li>
<li><label>{% trans "Container Format:" %}</label> {{ image.container_format|default:"None" }}</li>
<li><label>{% trans "Disk Format:" %}</label> {{ image.disk_format|default:"None" }}</li>
</ul>
</li>
<li class="custom_properties detail_section">
<h3>{% trans "Custom Properties" %}</h3>
<ul>
{% if image.properties.architecture %}
<li><label>{% trans "Architecture:" %}</label> {{ image.properties.architecture }}</li>
{% endif %}
{% if image.properties.kernel_id %}
<li><label>{% trans "Kernel ID:" %}</label> {{ image.properties.kernel_id }}</li>
{% endif %}
{% if image.properties.ramdisk_id %}
<li><label>{% trans "Ramdisk ID:" %}</label> {{ image.properties.ramdisk_id }}</li>
{% endif %}
{% if image.properties.image_state %}
<li><label>{% trans "Euca2ools state:" %}</label> {{ image.properties.image_state }}</li>
{% endif %}
{% if image.properties.project_id %}
<li><label>{% trans "Project ID:" %}</label> {{ image.properties.project_id }}</li>
{% endif %}
{% if image.properties.image_type %}
<li><label>{% trans "Image Type:" %}</label> {{ image.properties.image_type }}</li>
{% endif %}
</ul>
</li>
</ul>
{% endblock %}

View File

@ -852,10 +852,11 @@ iframe {
border: none; border: none;
} }
form .error { .item_detail ul li label {
background: #fce6e6; color: #000;
color: #b94a48; font-weight: bold;
border: 1px solid #E9B1B0; display: block;
margin-top: 5px;
} }
.progress_bar { .progress_bar {
@ -902,3 +903,9 @@ form .error {
.header_rule { .header_rule {
margin: 0 0 10px; margin: 0 0 10px;
} }
.item_detail .detail_section {
margin-bottom: 25px;
float: left;
margin-right: 50px;
}