Merge lp://staging/~dooferlad/offspring/ssh_ui_mods into lp://staging/~linaro-automation/offspring/private-builds
- ssh_ui_mods
- Merge into private-builds
Status: | Merged |
---|---|
Merged at revision: | 75 |
Proposed branch: | lp://staging/~dooferlad/offspring/ssh_ui_mods |
Merge into: | lp://staging/~linaro-automation/offspring/private-builds |
Diff against target: |
767 lines (+556/-44) 10 files modified
lib/offspring/web/media/js/jquery.placeholder.js (+106/-0) lib/offspring/web/queuemanager/admin.py (+3/-1) lib/offspring/web/queuemanager/forms.py (+133/-5) lib/offspring/web/queuemanager/models.py (+1/-1) lib/offspring/web/queuemanager/tests/test_views.py (+107/-1) lib/offspring/web/queuemanager/views.py (+47/-0) lib/offspring/web/templates/queuemanager/project_create.html (+59/-18) lib/offspring/web/templates/queuemanager/project_edit.html (+35/-18) lib/offspring/web/templates/queuemanager/project_edit_credentials.html (+64/-0) lib/offspring/web/urls.py (+1/-0) |
To merge this branch: | bzr merge lp://staging/~dooferlad/offspring/ssh_ui_mods |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Guilherme Salgado | Pending | ||
James Tunnicliffe | Pending | ||
Review via email: mp+81217@code.staging.launchpad.net |
This proposal supersedes a proposal from 2011-10-29.
Commit message
Description of the change
Adds to the web UI so Launchpad SSH credentials can be easily added, modified and removed without sharing the value of the SSH private key.
Guilherme Salgado (salgado) wrote : Posted in a previous version of this proposal | # |
James Tunnicliffe (dooferlad) wrote : Posted in a previous version of this proposal | # |
Have rebased. Should be fine now.
Guilherme Salgado (salgado) wrote : Posted in a previous version of this proposal | # |
Hi James,
In my previous review I suggested creating a new page to edit the SSH keys and lp username because it would:
1. be simpler to implement
2. as a consequence, less fragile and easier to test
3. allow us to provide a simple UI: we could use one form button to save an SSHkey/lp_username change and another to remove the SSHkey/username. Remember that these two things need to be removed together as having just one of them will cause the slave to crash
I see you've added a way to remove an ssh key, but using a checkbox for that is poor UI at best, and it doesn't seem to remove the LP user, as we should do, at the same time (if it did, it'd be even more confusing).
I also suggested placing the "An SSH key is stored for this project...." helper text outside of the textarea instead of using JS to place it inside because the latter doesn't add (IMO) much value and can't be unit tested (unless we spend a significant amount of time writing/configuring some way of testing the JS in our views). This also depends on jquery and an extra jquery plugin, which should not be included without some discussion because Offspring already includes a javascript library (http://
I'm not trying to make things perfect here, but I think we should try hard to avoid unnecessary complexity, and I do believe my suggestions would make things just as nice (nicer, in some cases) to the user and much simpler for us.
James Tunnicliffe (dooferlad) wrote : Posted in a previous version of this proposal | # |
Right, have moved the SSH credentials editing to a new page, removed the extra jquery, added some more unit tests and made sure that help text is always complete outside the placeholder text inside the SSH key entry box.
Guilherme Salgado (salgado) wrote : Posted in a previous version of this proposal | # |
Hi James,
This one still has stuff that ought to have been removed, like the two js files and changes to project_
James Tunnicliffe (dooferlad) wrote : Posted in a previous version of this proposal | # |
Sorry, I was under the impression that I was keeping in the updates to
project_
will get the changes reverted and remove the js. If we want something more
fancy in the future I can go back and revisit it.
I am out at dinner now so don't expect any updates tonight.
James
On Oct 28, 2011 8:53 PM, "Guilherme Salgado" <email address hidden>
wrote:
> Review: Resubmit
>
> Hi James,
> This one still has stuff that ought to have been removed, like the two js
> files and changes to project_
> you submit a MP so that the person who's reviewing the code can focus on the
> interesting things rather than trying to guess what's left over from
> previous commits and what's actually used in the current code.
> --
> https:/
> You are the owner of lp:~dooferlad/offspring/ssh_ui_mods.
>
Guilherme Salgado (salgado) wrote : Posted in a previous version of this proposal | # |
Oh, sorry, I mixed up project_create with project_edit. You're right that we want to allow people to enter the ssh key when creating a new project, but I don't see a reason for having the ssh_key/lp_user fields hidden initially, so we could probably get rid of the other js file. There's also the showAddAnotherP
I'm not fond of using javascript (and specially a jquery placeholder plugin, as that's not the js library used in Offspring) to have the help text displayed inside the text area, but if you feel strong about it, that's fine.
James Tunnicliffe (dooferlad) wrote : Posted in a previous version of this proposal | # |
No worries. I have got rid of the show/hide bit on the project add page and showAddAnotherP
Guilherme Salgado (salgado) wrote : Posted in a previous version of this proposal | # |
Here are the things we discussed in person today...
> === modified file 'lib/offspring/
> --- lib/offspring/
> +++ lib/offspring/
> @@ -1,8 +1,11 @@
> # Copyright 2010 Canonical Ltd. This software is licensed under the
> # GNU Affero General Public License version 3 (see the file LICENSE).
>
> +import re
> +
> from django.
> from django.db import models
> +from django import forms
> from django.forms import (
> Form, ModelChoiceField, ModelForm, Textarea, TextInput, ValidationError)
> from django.forms import fields
> @@ -15,9 +18,81 @@
>
> from offspring.
>
> -class ProjectBaseForm
> - status = fields.
> - widget=
> +class SSHPrivateKeyFi
> +
> + def validate(self, value):
> + "Check to see if the value looks like an SSH private key"
> +
> + # Use the parent's handling of required fields, etc.
> + super(SSHPrivat
> +
> + key_search_regexp = (r"-----BEGIN \w+ PRIVATE KEY-----"+
> + r".*"+
> + r"-----END \w+ PRIVATE KEY-----")
> + is_key = re.search(
> +
> + if not is_key and not value == "":
> + msg = ("The key you entered doesn't appear to be valid. I am "+
> + "expecting a key in the form:\n "+
> + "-----BEGIN <type> PRIVATE KEY-----\n"+
> + "<ASCII key>\n"+
> + "-----END <type> PRIVATE KEY-----\n")
> + raise forms.Validatio
> +
> +class ProjectSSHCredF
> + ssh_help = ("Enter a private SSH ASCII key block, complete with begin "+
> + "and end markers.")
> +
> + lp_ssh_key_input = SSHPrivateKeyFi
> + required=False,
> + widget=
> + attrs={'cols': 70, 'rows' : 4}),
> + help_text=ssh_help)
> +
> + lp_fields_set = False
> + lp_ssh_set = False
> + lp_ssh_set_message = ("An SSH key is stored for this project. To replace "+
> + "it, paste a new SSH private key block here.")
> + lp_ssh_
> + "enter an SSH private key here in the form of an "+
> + "ASCII key block.")
> +
> + def __init__(self, *args, **kwargs):
> + super(ProjectSS
> + # Set the form fields based on the model object
> + if kwargs.
> + instance = kwargs['instance']
> + if instance.lp_ssh_key and instance.lp_ssh_key != "":
The second clause is redundant her...
Guilherme Salgado (salgado) wrote : | # |
On Thu, 2011-11-03 at 22:21 +0000, James Tunnicliffe wrote:
> === modified file 'lib/offspring/
> --- lib/offspring/
> +++ lib/offspring/
> @@ -5,7 +5,9 @@
> {% endblock %}
>
> {% block header_js %}
> -<script type="text/
> +<script type="text/
> +<script type="text/
> +<script type="text/
> <script type="text/
> /* Override showAddAnotherPopup to use custom height and width. */
> function showAddAnotherP
> @@ -29,29 +31,68 @@
> {% endblock %}
>
> {% block content %}
> - <form method="POST" action="">{% csrf_token %}
> + <form method="POST" action="" name="projsetti
> <div class="module aligned ">
> {% for field in form %}
> - <div class="form-row {% if line.errors %} errors{% endif %} {{ field.name }}">
> - <div{% if not line.fields|
> - {% if field.is_checkbox %}
> - {{ field }}{{ field.label_tag }}
> - {% else %}
> - {{ field.label_tag }}
> - {% if field.is_readonly %}
> - <p>{{ field.contents }}</p>
> + {% if field.html_name == "lp_user" or field.html_name == "lp_ssh_key_input" %}
> + <!-- This catches lp_user and lp_ssh_key_input so they aren't shown in the top of
> + the page. They are displayed below in their own section after some help text -->
> + {% else %}
> + <div class="form-row {% if line.errors %} errors{% endif %} {{ field.name }}">
> + <div{% if not line.fields|
> + {% if field.is_checkbox %}
> + {{ field }}{{ field.label_tag }}
> {% else %}
> - {{ field }}
> - {% endif %}
> - {% endif %}
> - {% if field.field.
> - <p class="help">{{ field.field.
> - {% endif %}
> + {{ field.label_tag }}
> + {% if field.is_readonly %}
> + <p>{{ field.contents }}</p>
> + {% else %}
> + {{ field }}
> + {% endif %}
> + {% endif %}
> + {% if field.field.
> + <p class...
James Tunnicliffe (dooferlad) wrote : | # |
On 4 November 2011 20:46, Guilherme Salgado
<email address hidden> wrote:
> On Thu, 2011-11-03 at 22:21 +0000, James Tunnicliffe wrote:
>> === modified file 'lib/offspring/
<snip>
>> + If the config URL above points to a Bazaar repository that is only
>> + available to authenticated users, you should add a user and private SSH
>> + key to give the builder access. The SSH key will never be revealed. It
>> + can be changed or deleted later. It should not be passphrase protected.
>> + If you would like to add these details, tick here:
>
> Hmm. There's nothing to tick here anymore, right?
Good catch!
>> === modified file 'lib/offspring/
>> --- lib/offspring/
>> +++ lib/offspring/
>> @@ -5,7 +5,7 @@
>> {% endblock %}
>>
>> {% block header_js %}
>> -<script type="text/
>> +<script type="text/
>> <script type="text/
>> /* Override showAddAnotherPopup to use custom height and width. */
>> function showAddAnotherP
>> @@ -29,29 +29,46 @@
>> {% endblock %}
>>
>> {% block content %}
>> - <form method="POST" action="">{% csrf_token %}
>> + <form method="POST" action="" name="projsetti
>> <div class="module aligned ">
>> {% for field in form %}
>> - <div class="form-row {% if line.errors %} errors{% endif %} {{ field.name }}">
>> - <div{% if not line.fields|
>> - {% if field.is_checkbox %}
>> - {{ field }}{{ field.label_tag }}
>> - {% else %}
>> - {{ field.label_tag }}
>> - {% if field.is_readonly %}
>> - <p>{{ field.contents }}</p>
>> + {% if field.html_name == "lp_user" or field.html_name == "lp_ssh_
>
> This is no longer needed, right? We've agreed on that in the previous
> review already, IIRC.
It is still required because the new fields are part of the project
form, so they need to be filtered out where they aren't needed.
Actually I just noticed that since I have switched lp_user to a
TextField to match the internal representation of Launchpad, it can
now contain newlines and the form doesn't stop this. I see my options
as:
012345678901234
1. Leave it as it is and add a custom validate to exclude newlines
2. Switch it back to a CharField in the DB and set max_length to None, or if
that isn't allowed, something large, like 256.
3. Do something similar to the ssh input field - leave the internal
representation as is, and have a CharField input box with a max_length
set to something massive.
...
Guilherme Salgado (salgado) wrote : | # |
On Mon, 2011-11-07 at 17:10 +0000, James Tunnicliffe wrote:
> >> === modified file 'lib/offspring/
> >> --- lib/offspring/
> >> +++ lib/offspring/
> >> @@ -5,7 +5,7 @@
> >> {% endblock %}
> >>
> >> {% block header_js %}
> >> -<script type="text/
> >> +<script type="text/
> >> <script type="text/
> >> /* Override showAddAnotherPopup to use custom height and width. */
> >> function showAddAnotherP
> >> @@ -29,29 +29,46 @@
> >> {% endblock %}
> >>
> >> {% block content %}
> >> - <form method="POST" action="">{% csrf_token %}
> >> + <form method="POST" action="" name="projsetti
> >> <div class="module aligned ">
> >> {% for field in form %}
> >> - <div class="form-row {% if line.errors %} errors{% endif %} {{ field.name }}">
> >> - <div{% if not line.fields|
> >> - {% if field.is_checkbox %}
> >> - {{ field }}{{ field.label_tag }}
> >> - {% else %}
> >> - {{ field.label_tag }}
> >> - {% if field.is_readonly %}
> >> - <p>{{ field.contents }}</p>
> >> + {% if field.html_name == "lp_user" or field.html_name == "lp_ssh_
> >
> > This is no longer needed, right? We've agreed on that in the previous
> > review already, IIRC.
>
> It is still required because the new fields are part of the project
> form, so they need to be filtered out where they aren't needed.
But the template is the worst place to do that, because the templating
language is not as powerfull as python and testing templates is harder
(and usually slower) than testing forms/views. And the above looks like
an ugly hack to me because of the empty if block, without even a
comment.
Having said that, I've just noticed that you already exclude the
unwanted fields in the form used by this template, so unless I'm missing
something this isn't needed.
class EditProjectForm
class Meta(ProjectBas
I thought the above would be enough to get rid of the lp_* fields on the
edit page, but I've just reverted the template changes locally and the
ssh key text area is still present on the form. That's probably why you
ended up doing the template changes, but instead of doing that we need
to find out why the ssh key field is still shown and fix it so that we
don't need the template hack to omit the field. I'll keep di...
James Tunnicliffe (dooferlad) wrote : | # |
On 8 November 2011 15:46, Guilherme Salgado
<email address hidden> wrote:
> On Mon, 2011-11-07 at 17:10 +0000, James Tunnicliffe wrote:
>> >> === modified file 'lib/offspring/
>> >> --- lib/offspring/
>> >> +++ lib/offspring/
>> >> @@ -5,7 +5,7 @@
>> >> {% endblock %}
>> >>
>> >> {% block header_js %}
>> >> -<script type="text/
>> >> +<script type="text/
>> >> <script type="text/
>> >> /* Override showAddAnotherPopup to use custom height and width. */
>> >> function showAddAnotherP
>> >> @@ -29,29 +29,46 @@
>> >> {% endblock %}
>> >>
>> >> {% block content %}
>> >> - <form method="POST" action="">{% csrf_token %}
>> >> + <form method="POST" action="" name="projsetti
>> >> <div class="module aligned ">
>> >> {% for field in form %}
>> >> - <div class="form-row {% if line.errors %} errors{% endif %} {{ field.name }}">
>> >> - <div{% if not line.fields|
>> >> - {% if field.is_checkbox %}
>> >> - {{ field }}{{ field.label_tag }}
>> >> - {% else %}
>> >> - {{ field.label_tag }}
>> >> - {% if field.is_readonly %}
>> >> - <p>{{ field.contents }}</p>
>> >> + {% if field.html_name == "lp_user" or field.html_name == "lp_ssh_
>> >
>> > This is no longer needed, right? We've agreed on that in the previous
>> > review already, IIRC.
>>
>> It is still required because the new fields are part of the project
>> form, so they need to be filtered out where they aren't needed.
>
> But the template is the worst place to do that, because the templating
> language is not as powerfull as python and testing templates is harder
> (and usually slower) than testing forms/views. And the above looks like
> an ugly hack to me because of the empty if block, without even a
> comment.
>
> Having said that, I've just noticed that you already exclude the
> unwanted fields in the form used by this template, so unless I'm missing
> something this isn't needed.
>
> class EditProjectForm
> launchpad_project = ModelChoiceField(
> LaunchpadProjec
> class Meta(ProjectBas
> exclude = ('name', 'priority', 'is_active', 'access_groups',
> 'lp_user', 'lp_ssh_key_input')
>
> I thought the above would be enough to get rid of the lp_* fields on the
> edit page, but I've just reverted the template changes locally and the
> ssh key text area is still present on the form. That's probably why you
> ended up doing the template changes, but instead o...
James Tunnicliffe (dooferlad) wrote : | # |
On 8 November 2011 16:43, James Tunnicliffe <email address hidden> wrote:
>> Did you change anything to make field.help_text work or is that just an
>> existing shortcut to field.field.
>
> I remember field.field.
> changed it to field.help_text, but I will try reverting it and seeing
> if it is still the case. It could be that I broke something during
> development.
Just confirmed that field.field.
is a bug fix.
--
James Tunnicliffe
James Tunnicliffe (dooferlad) wrote : | # |
Got it (I think). Multiple inheritance saves the day!
class ProjectBaseWith
pass
Using this as the form for ProjectAdmin and the base for
CreateProjectForm, leaving EditProjectForm as is, it creates the
correct combined forms when we need them. Will submit a new patch
after I have cleaned things up and verified the DB changes.
Guilherme Salgado (salgado) wrote : | # |
On Tue, 2011-11-08 at 16:43 +0000, James Tunnicliffe wrote:
> On 8 November 2011 15:46, Guilherme Salgado
> <email address hidden> wrote:
> > On Mon, 2011-11-07 at 17:10 +0000, James Tunnicliffe wrote:
> >> >> === modified file 'lib/offspring/
> >> >> --- lib/offspring/
> >> >> +++ lib/offspring/
> >> >> @@ -5,7 +5,7 @@
> >> >> {% endblock %}
> >> >>
> >> >> {% block header_js %}
> >> >> -<script type="text/
> >> >> +<script type="text/
> >> >> <script type="text/
> >> >> /* Override showAddAnotherPopup to use custom height and width. */
> >> >> function showAddAnotherP
> >> >> @@ -29,29 +29,46 @@
> >> >> {% endblock %}
> >> >>
> >> >> {% block content %}
> >> >> - <form method="POST" action="">{% csrf_token %}
> >> >> + <form method="POST" action="" name="projsetti
> >> >> <div class="module aligned ">
> >> >> {% for field in form %}
> >> >> - <div class="form-row {% if line.errors %} errors{% endif %} {{ field.name }}">
> >> >> - <div{% if not line.fields|
> >> >> - {% if field.is_checkbox %}
> >> >> - {{ field }}{{ field.label_tag }}
> >> >> - {% else %}
> >> >> - {{ field.label_tag }}
> >> >> - {% if field.is_readonly %}
> >> >> - <p>{{ field.contents }}</p>
> >> >> + {% if field.html_name == "lp_user" or field.html_name == "lp_ssh_
> >> >
> >> > This is no longer needed, right? We've agreed on that in the previous
> >> > review already, IIRC.
> >>
> >> It is still required because the new fields are part of the project
> >> form, so they need to be filtered out where they aren't needed.
> >
> > But the template is the worst place to do that, because the templating
> > language is not as powerfull as python and testing templates is harder
> > (and usually slower) than testing forms/views. And the above looks like
> > an ugly hack to me because of the empty if block, without even a
> > comment.
> >
> > Having said that, I've just noticed that you already exclude the
> > unwanted fields in the form used by this template, so unless I'm missing
> > something this isn't needed.
> >
> > class EditProjectForm
> > launchpad_project = ModelChoiceField(
> > LaunchpadProjec
> > class Meta(ProjectBas
> > exclude = ('name', 'priority', 'is_active', 'access_groups',
> > 'lp_user', 'lp_ssh_key_input')
> >
> > I thought the above would be enough to get rid of the lp_* fields on the
> > edit page, but I've j...
Guilherme Salgado (salgado) wrote : | # |
Ok, so after admitting this code was too complicated for my small brain I decided to try and simplify it a bit. lp:~salgado/offspring/ssh_ui_mods has a simpler version of this, with a much simpler form class, no need for the custom field and validation on the lowest possible level. As a bonus I've also fixed a bug in which the +editcredentials page was setting some attributes back to their default values because these fields were not in Meta.exclude, but also weren't rendered in the template (the list of fields rendered there are hard-coded to just lp_user and lp_ssh_key).
The key was using separate form classes depending on whether you're creating or editing a project and moving the validation to the model so that it's used in both forms. Please let me know if it looks good, James, or if you see any issues with it: https:/
Hi James, this branch has a conflict; care to resolve it before I review?