Merged trunk

This commit is contained in:
Devin Carlen 2011-03-30 22:05:11 -07:00
commit 724381a0b7
13 changed files with 41 additions and 257 deletions

View File

@ -196,7 +196,7 @@ class CreateVolumeForm(forms.Form):
class AttachVolumeForm(ProjectFormBase):
volume = forms.ChoiceField()
instance = forms.ChoiceField()
device = forms.CharField(initial='/dev/vdb')
device = forms.CharField(initial='/dev/vdc')
def __init__(self, project, *args, **kwargs):
super(AttachVolumeForm, self).__init__(project, *args, **kwargs)

View File

@ -91,9 +91,9 @@ class ProjectManager(object):
groups='all'):
conn = self.get_nova_connection()
return conn.modify_image_attribute(image_id,
attribute='launchPermission',
operation='remove',
groups='all',)
attribute=attribute,
operation=operation,
groups=groups,)
@wrap_nova_error

View File

@ -1,4 +1,4 @@
<h3 class="image_list_heading"> {{ heading }} </h3>
<h3 class="image_list_heading"> {{ heading }} </h3>
{% if images %}
<table id="image_launch">
<tr>
@ -54,13 +54,13 @@
{% endif %}
<a id="launch_{{ image.id }}" class="launch" href="{% url nova_images_launch project.projectname image.id %}" title="Click to launch image">Launch</a>
{% if can_modify or user.username == ami.ownerId %}
{% if user.username == ami.ownerId %}
<a id="edit_image_link" href="{% url nova_images_update project.projectname ami.id %}">Edit Image</a>
{% endif %}
</div>
{% if can_modify or user.username == ami.ownerId %}
{% if user.username == ami.ownerId %}
<span class="image_privacy">
<form id="privacy_{{ ami.id }}" action="{% url nova_images_privacy project.projectname ami.id %}" method="post" accept-charset="utf-8">
{% csrf_token %}

View File

@ -1,207 +0,0 @@
{% extends "django_nova/images/base.html" %}
{% block title %} - Launch an Image{% endblock %}
{% block headerjs %}
<script type="text/javascript" src="/media/django_nova/js/jquery.form.js"></script>
{% endblock %}
{% block content %}
<div id="right_content">
<div id="page_head">
<h2 id="page_heading">Images</h2>
<p id="page_description">Images are snapshots of running systems which can easily be deployed to run one or more instances.</p>
</div>
{% include "django_nova/_messages.html" %}
{% if images %}
<table id="image_launch">
<tr>
<th>ID</th>
<th>Description</th>
<th colspan="2">Owner</th>
</tr>
{% for image in images %}
<tr class="{% cycle 'odd' 'even' %}">
{% if image.id == ami.id %}
<td class="detail_wrapper" colspan="4">
<div id="{{ ami.id }}" class="image_detail">
<div class="column">
<div class="image_detail_item">
<span class="label">Owner: </span>
<span class="data">{{ ami.ownerId }}</span>
</div>
<div class="image_detail_item">
<span class="label">Description: </span>
<span class="data">{{ ami.description }}</span>
</div>
<div class="image_detail_item">
<span class="label">Location: </span>
<span class="data">{{ ami.location }}</span>
</div>
</div>
<div class="column">
<div class="image_detail_item">
<span class="label">ID: </span>
<span class="data">{{ ami.id }}</span>
</div>
<div class="image_detail_item">
<span class="label">Name: </span>
<span class="data">{% if ami.displayName %}{{ ami.displayName }}{%else%}{{ ami.id }}{% endif %}</span>
</div>
<div class="image_detail_item">
<span class="label">Type: </span>
<span class="data">{{ ami.type }}</span>
</div>
<div class="image_detail_item">
<span class="label">Architecture: </span>
<span class="data">{{ ami.architecture }}</span>
</div>
</div>
<div id="last" class="column">
{% if ami.is_public %}
<div id="public" class="privacy">Public Image</div>
{% else %}
<div id="private" class="privacy">Private Image</div>
{% endif %}
<a id="launch_{{ image.id }}" class="launch" href="{% url nova_images_launch project.projectname image.id %}" title="Click to launch image">Launch</a>
{% if can_modify or user.username == ami.ownerId %}
<a id="edit_image_link" href="{% url nova_images_update project.projectname ami.id %}">Edit Image</a>
{% endif %}
</div>
{% if can_modify or user.username == ami.ownerId %}
<span class="image_privacy">
<form id="privacy_{{ ami.id }}" action="{% url nova_images_privacy project.projectname ami.id %}" method="post" accept-charset="utf-8">
{% csrf_token %}
{% if ami.is_public %}
<input class="private" type="submit" value="Make Private" />
{% else %}
<input class="public" type="submit" value="Make Public" />
{% endif %}
</form>
</span>
<span class="delete">
<form id="delete_{{ ami.id }}" action="{% url nova_images_remove project.projectname ami.id %}" method="post" accept-charset="utf-8">
{% csrf_token %}
<input type="submit" value="Remove Image" />
</form>
</span>
{% endif %}
</div>
</td>
{% else %}
<td class="image_id"><a href="{% url nova_images_detail project.projectname image.id %}">{{ image.id }}</a></td>
<td class="image_location odd">
{% if image.description %}
{{ image.description }}
{% else %}
{{ image.location }}
{% endif %}
</td>
<td class="image_owner_id">{{ image.ownerId }}</td>
<td class="image_launch_btn odd"><a id="launch_{{ image.id }}" class="launch" href="{% url nova_images_launch project.projectname image.id %}">Launch</a></td>
{#<td class="odd"><a class="ui-state-default ui-corner-all" onclick="$('#dlg_launch').dialog('open');">Launch</a></td>#}
{% endif %}
</tr>
{% endfor %}
</table>
{% else %}
<div class="ui-widget">
<div class="ui-state-highlight ui-corner-all">
<p>
<span class="ui-icon ui-icon-info"></span>
No images currently available.
</p>
</div>
</div>
{% endif %}
</div>
<div id="dlg_launch" title="Launch Instance" style="display:none;">
<form id="frm_launch" action="url nova_images_launch project.projectname" method="post">
{% csrf_token %}
{% include "django_nova/images/_launch_form.html" %}
</form>
</div>
<div id="dlg_confirm" title="Confirm Termination">
<p>Are you sure you wish to unregister the <span id="ami_name"></span> image?</p>
</div>
{% endblock %}
{% block footerjs %}
{{ block.super }}
<script type="text/javascript">
var options = {
success: handleResponse,
beforeSubmit: showRequest,
dataType: 'json'
}
// TODO: On dialog open, reset form and validation.
$(function() {
$('#dlg_launch').dialog({
buttons: {
'Ok': function() {
$('#frm_launch').ajaxSubmit(options);
},
'Cancel': function() {
$(this).dialog('close');
}
},
autoOpen: false,
resizable: false,
width: 400,
height: 400
});
});
function showRequest(formData, jqForm, options) {
var queryString = $.param(formData);
alert('About to submit: \n\n' + queryString);
return true;
}
function handleResponse(data, statusText, xhr, $form) {
alert('status: ' + statusText + '\nsuccess:\n\n' + data.success);
}
$(function(){
$('.delete form').submit(function() {
ami_name = $(this).parent().parent().attr("id");
$('#ami_name').text(ami_name);
$('#dlg_confirm').dialog('open');
return false;
});
$('#dlg_confirm').dialog({
buttons: {
'Ok': onConfirmOK,
'Cancel': function() { $(this).dialog('close'); }
},
autoOpen: false,
resizable: false,
width: 500,
height: 200
});
})
function onConfirmOK() {
$(this).dialog('close');
form = document.getElementById('delete_' + ami_name);
if(form) form.submit();
}
</script>
{% endblock %}

View File

@ -19,7 +19,7 @@
<fieldset>
<h3 class="image_id">Launch Image {{ ami.id }}</h3>
<div class="even">
<label>Location</label>
<h4 class="label">Location</h4>
<span class="image_location">{{ ami.location }}</span>
</div>
{% include "django_nova/images/_launch_form.html" %}

View File

@ -33,15 +33,16 @@
<fieldset class="module aligned {{ fieldset.classes }}">
<h3 id="edit_{{ user.username }}">Edit Roles for User: {{ user.username }}</h3>
<div class="form-row">
<label>User</label>
<h4 class="label">User</h4>
<span id="user_name">{{ user.username }}</span>
</div>
<input type="hidden" name="username" value="{{ user.id }}" id="username" />
<label for="id_role_from">Roles</label>
{% for field in form.visible_fields %}
<div class="form-row">
{{ field.errors }}
{{ field.label_tag }}{{ field }}
{{ field }}
{% if field.field.help_text %}<p class="help">{{ field.field.help_text|safe }}</p>{% endif %}
</div>
{% endfor %}

View File

@ -123,8 +123,6 @@ class ImageViewTests(BaseProjectViewTests):
self.project.get_images().AndReturn([self.ami])
self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami)
shortcuts.get_user_image_permissions(mox.IgnoreArg(),
TEST_PROJECT).AndReturn(True)
forms.get_key_pair_choices(self.project).AndReturn(
self.create_key_pair_choices([TEST_KEY]))
forms.get_instance_type_choices().AndReturn(
@ -142,15 +140,12 @@ class ImageViewTests(BaseProjectViewTests):
def test_remove_form(self):
self.mox.StubOutWithMock(self.project, 'get_image')
self.project.get_image(TEST_IMAGE_ID).AndReturn(self.ami)
self.mox.ReplayAll()
res = self.client.get(reverse('nova_images_remove',
args=[TEST_PROJECT, TEST_IMAGE_ID]))
self.assertEqual(res.status_code, 200)
self.assertTemplateUsed(res, 'django_nova/images/detail_list.html')
self.assertEqual(res.context['ami'].id, TEST_IMAGE_ID)
self.assertRedirectsNoFollow(res, reverse('nova_images',
args=[TEST_PROJECT]))
self.mox.VerifyAll()
def test_remove(self):
@ -161,7 +156,7 @@ class ImageViewTests(BaseProjectViewTests):
res = self.client.post(reverse('nova_images_remove',
args=[TEST_PROJECT, TEST_IMAGE_ID]))
self.assertRedirectsNoFollow(res, reverse('nova_images',
args=[TEST_PROJECT]))
args=[TEST_PROJECT]))
self.mox.VerifyAll()

View File

@ -107,12 +107,12 @@ def project_view(request, project_name):
nova = get_nova_admin_connection()
project = nova.get_project(project_name)
users = nova.get_project_members(project_name)
try:
manager = auth_models.User.objects.get(username=project.projectManagerId)
except auth_models.User.DoesNotExist:
manager = None
if request.method == 'POST':
form = forms.ProjectForm(request.POST)
if form.is_valid():
@ -127,8 +127,8 @@ def project_view(request, project_name):
messages.error(request,
'Unable modify the project %s: %s - %s' %
(project_name, e.code, e.error_message))
return redirect('admin_project', request.POST["projectname"])
else:
form = forms.ProjectForm(initial={'projectname': project.projectname,
@ -219,14 +219,16 @@ def remove_global_roles(username):
@staff_member_required
def project_user(request, project_name, project_user):
nova = get_nova_admin_connection()
project = nova.get_project(project_name)
userroles = nova.get_user_roles(project_user, project_name)
try:
modeluser = auth_models.User.objects.get(username = project_user)
except auth_models.User.DoesNotExist:
modeluser = None
if request.method == 'POST':
form = forms.ProjectUserForm(request.POST)
form = forms.ProjectUserForm(project, request.user, request.POST)
if form.is_valid():
username = project_user
@ -240,12 +242,11 @@ def project_user(request, project_name, project_user):
return redirect('admin_project', project_name)
else:
roles = [str(role.role) for role in userroles]
form = forms.ProjectUserForm({
'role': roles,
'user': modeluser,
})
form = forms.ProjectUserForm(project,
request.user,
{'role': roles,
'user': modeluser})
project = nova.get_project(project_name)
return render_to_response('admin/django_nova/project/project_user.html', {
'form' : form,

View File

@ -113,8 +113,6 @@ def detail(request, project_id, image_id):
images = project.get_images()
ami = project.get_image(image_id)
can_modify = shortcuts.get_user_image_permissions(request.user.username,
project_id)
if not ami:
raise http.Http404()
@ -122,10 +120,8 @@ def detail(request, project_id, image_id):
'form': forms.LaunchInstanceForm(project),
'region': project.region,
'project': project,
'images': images,
'image_lists': _image_lists(images, project_id),
'ami': ami,
'can_modify': can_modify,
}, context_instance = template.RequestContext(request))
@ -145,17 +141,7 @@ def remove(request, project_id, image_id):
'Image %s has been successfully deregistered.' %
image_id)
return redirect('nova_images', project_id)
else:
ami = project.get_image(image_id)
#FIXME - is the code below used? if we reach here should we
#just redirect? (anthony)
return render_to_response('django_nova/images/detail_list.html', {
'region': project.region,
'project': project,
'ami': ami,
}, context_instance = template.RequestContext(request))
return redirect('nova_images', project_id)
@login_required

View File

@ -73,6 +73,7 @@ def edit_user(request, project_id, username):
nova = get_nova_admin_connection()
project = get_project_or_404(request, project_id)
user = nova.get_user(username)
userroles = nova.get_user_roles(username, project_id)
if project.projectManagerId != request.user.username:
return redirect('login')
@ -84,7 +85,11 @@ def edit_user(request, project_id, username):
return redirect('nova_project_manage', project_id)
else:
form = nova_forms.ProjectUserForm(project, user)
roles = [str(role.role) for role in userroles]
form = nova_forms.ProjectUserForm(project,
user,
{'role': roles,
'user': user})
return render_to_response('django_nova/projects/edit_user.html', {
'form' : form,

View File

@ -116,7 +116,10 @@ def attach(request, project_id):
'Unable to attach volume: %s' % e.message)
else:
messages.success(request,
'Volume %s has been successfully attached.' %
'Volume %s is scheduled to be attached. If '
'it doesn\'t become attached in two '
'minutes, please try again (you may need to '
'specify a different device).' %
form.cleaned_data['volume'])
else:
volumes = project.get_volumes()

View File

@ -62,7 +62,8 @@
</div>
{% if not request.user.is_authenticated %}
<div class="home_block">
<h3>Don't have an account? <a id="lnk_register" href="{% url registration_register %}">Register</a></h3>
<h3>Don't have an account?</h3><br/>
<a id="lnk_register" href="{% url registration_register %}">Register</a>
</div>
{% endif %}
<div class="home_block">
@ -75,4 +76,3 @@
</div>
{% endif %}
{% endblock %}

View File

@ -195,7 +195,7 @@ span.data {
#home_login fieldset {
width: 400px;
padding: 20px;
padding: 20px 20px 46px 20px;
}
#home_login label {
@ -780,4 +780,4 @@ div.image_detail, div.instance_detail {
form.edit_instance input[type="submit"], form.edit_image input[type="submit"] {
margin-right: 4px;
}
}