Merge branch 'master' of github.com:NixOS/hydra

This commit is contained in:
Rob Vermaas 2012-04-18 11:24:12 +02:00
commit b0596c214a
43 changed files with 510 additions and 400 deletions

View file

@ -22,9 +22,6 @@ our $VERSION = '0.01';
__PACKAGE__->config(
name => 'Hydra',
default_view => "TT",
session => {
storage => Hydra::Model::DB::getHydraPath . "/session_data"
},
authentication => {
default_realm => "dbic",
realms => {
@ -49,6 +46,7 @@ __PACKAGE__->config(
},
'Plugin::Session' => {
expires => 3600 * 24 * 2,
storage => Hydra::Model::DB::getHydraPath . "/session_data"
},
);

View file

@ -15,6 +15,7 @@ use Email::Sender::Simple qw(sendmail);
use Email::Sender::Transport::SMTP;
use Config::General;
sub nixMachines {
my ($c) = @_;
my $result = "# GENERATED BY HYDRA\n";
@ -32,6 +33,7 @@ sub nixMachines {
return $result;
}
sub saveNixMachines {
my ($c) = @_;
@ -42,12 +44,14 @@ sub saveNixMachines {
close (NIXMACHINES);
}
sub admin : Chained('/') PathPart('admin') CaptureArgs(0) {
my ($self, $c) = @_;
requireAdmin($c);
$c->stash->{admin} = 1;
}
sub index : Chained('admin') PathPart('') Args(0) {
my ($self, $c) = @_;
$c->stash->{machines} = [$c->model('DB::BuildMachines')->search(
@ -62,7 +66,8 @@ sub index : Chained('admin') PathPart('') Args(0) {
, order_by => [ 'machine', 'stepnr' ]
} ) ];
$c->stash->{template} = 'admin.tt';
}
}
sub updateUser {
my ($c, $user) = @_;
@ -88,6 +93,16 @@ sub updateUser {
}
}
sub create_user : Chained('admin') PathPart('create-user') Args(0) {
my ($self, $c) = @_;
requireAdmin($c);
error($c, "Not implemented yet!"); # FIXME
}
sub user : Chained('admin') PathPart('user') CaptureArgs(1) {
my ($self, $c, $username) = @_;
@ -99,6 +114,7 @@ sub user : Chained('admin') PathPart('user') CaptureArgs(1) {
$c->stash->{user} = $user;
}
sub users : Chained('admin') PathPart('users') Args(0) {
my ($self, $c) = @_;
$c->stash->{users} = [$c->model('DB::Users')->search({}, {order_by => "username"})];
@ -106,6 +122,7 @@ sub users : Chained('admin') PathPart('users') Args(0) {
$c->stash->{template} = 'users.tt';
}
sub user_edit : Chained('user') PathPart('edit') Args(0) {
my ($self, $c) = @_;
@ -113,16 +130,23 @@ sub user_edit : Chained('user') PathPart('edit') Args(0) {
$c->stash->{edit} = 1;
}
sub user_edit_submit : Chained('user') PathPart('submit') Args(0) {
my ($self, $c) = @_;
requirePost($c);
txn_do($c->model('DB')->schema, sub {
updateUser($c, $c->stash->{user}) ;
if (($c->request->params->{submit} || "") eq "delete") {
$c->stash->{user}->delete;
} else {
updateUser($c, $c->stash->{user});
}
});
$c->res->redirect("/admin/users");
}
sub sendemail {
my ($to, $subject, $body) = @_;
@ -141,6 +165,7 @@ sub sendemail {
sendmail($email);
}
sub reset_password : Chained('user') PathPart('reset-password') Args(0) {
my ($self, $c) = @_;
@ -168,6 +193,7 @@ sub reset_password : Chained('user') PathPart('reset-password') Args(0) {
$c->res->redirect("/admin/users");
}
sub machines : Chained('admin') PathPart('machines') Args(0) {
my ($self, $c) = @_;
$c->stash->{machines} = [$c->model('DB::BuildMachines')->search({}, {order_by => "hostname"})];
@ -176,7 +202,8 @@ sub machines : Chained('admin') PathPart('machines') Args(0) {
$c->stash->{nixMachinesWritable} = (-e "/etc/nix.machines" && -w "/etc/nix.machines");
$c->stash->{template} = 'machines.tt';
}
}
sub machine : Chained('admin') PathPart('machine') CaptureArgs(1) {
my ($self, $c, $machineName) = @_;
@ -189,6 +216,7 @@ sub machine : Chained('admin') PathPart('machine') CaptureArgs(1) {
$c->stash->{machine} = $machine;
}
sub machine_edit : Chained('machine') PathPart('edit') Args(0) {
my ($self, $c) = @_;
$c->stash->{template} = 'machine.tt';
@ -196,19 +224,27 @@ sub machine_edit : Chained('machine') PathPart('edit') Args(0) {
$c->stash->{edit} = 1;
}
sub machine_edit_submit : Chained('machine') PathPart('submit') Args(0) {
my ($self, $c) = @_;
requirePost($c);
txn_do($c->model('DB')->schema, sub {
updateMachine($c, $c->stash->{machine}) ;
if (($c->request->params->{submit} || "") eq "delete") {
$c->stash->{machine}->delete;
} else {
updateMachine($c, $c->stash->{machine});
}
});
saveNixMachines($c);
$c->res->redirect("/admin/machines");
}
sub updateMachine {
my ($c, $machine) = @_;
my ($c, $machine) = @_;
my $hostname = trim $c->request->params->{"hostname"};
my $username = trim $c->request->params->{"username"};
@ -240,6 +276,7 @@ sub updateMachine {
}
}
sub create_machine : Chained('admin') PathPart('create-machine') Args(0) {
my ($self, $c) = @_;
@ -269,16 +306,6 @@ sub create_machine_submit : Chained('admin') PathPart('create-machine/submit') A
$c->res->redirect("/admin/machines");
}
sub machine_delete : Chained('machine') PathPart('delete') Args(0) {
my ($self, $c) = @_;
requirePost($c);
txn_do($c->model('DB')->schema, sub {
$c->stash->{machine}->delete;
});
saveNixMachines($c);
$c->res->redirect("/admin/machines");
}
sub machine_enable : Chained('machine') PathPart('enable') Args(0) {
my ($self, $c) = @_;
@ -287,6 +314,7 @@ sub machine_enable : Chained('machine') PathPart('enable') Args(0) {
$c->res->redirect("/admin/machines");
}
sub machine_disable : Chained('machine') PathPart('disable') Args(0) {
my ($self, $c) = @_;
$c->stash->{machine}->update({ enabled => 0});
@ -294,6 +322,7 @@ sub machine_disable : Chained('machine') PathPart('disable') Args(0) {
$c->res->redirect("/admin/machines");
}
sub clear_queue_non_current : Chained('admin') Path('clear-queue-non-current') Args(0) {
my ($self, $c) = @_;
# !!! Mark the builds as cancelled instead.
@ -301,6 +330,7 @@ sub clear_queue_non_current : Chained('admin') Path('clear-queue-non-current') A
$c->res->redirect("/admin");
}
sub clear_queue : Chained('admin') Path('clear-queue') Args(0) {
my ($self, $c) = @_;
# !!! Mark the builds as cancelled instead.
@ -308,6 +338,7 @@ sub clear_queue : Chained('admin') Path('clear-queue') Args(0) {
$c->res->redirect("/admin");
}
sub clearfailedcache : Chained('admin') Path('clear-failed-cache') Args(0) {
my ($self, $c) = @_;
@ -316,6 +347,7 @@ sub clearfailedcache : Chained('admin') Path('clear-failed-cache') Args(0) {
$c->res->redirect("/admin");
}
sub clearvcscache : Chained('admin') Path('clear-vcs-cache') Args(0) {
my ($self, $c) = @_;
@ -334,6 +366,7 @@ sub clearvcscache : Chained('admin') Path('clear-vcs-cache') Args(0) {
$c->res->redirect("/admin");
}
sub managenews : Chained('admin') Path('news') Args(0) {
my ($self, $c) = @_;
@ -342,6 +375,7 @@ sub managenews : Chained('admin') Path('news') Args(0) {
$c->stash->{template} = 'news.tt';
}
sub news_submit : Chained('admin') Path('news/submit') Args(0) {
my ($self, $c) = @_;
@ -359,6 +393,7 @@ sub news_submit : Chained('admin') Path('news/submit') Args(0) {
$c->res->redirect("/admin/news");
}
sub news_delete : Chained('admin') Path('news/delete') Args(1) {
my ($self, $c, $id) = @_;
@ -371,6 +406,7 @@ sub news_delete : Chained('admin') Path('news/delete') Args(1) {
$c->res->redirect("/admin/news");
}
sub force_eval : Chained('admin') Path('eval') Args(2) {
my ($self, $c, $projectName, $jobsetName) = @_;
@ -387,4 +423,5 @@ sub force_eval : Chained('admin') Path('eval') Args(2) {
$c->res->redirect("/project/$projectName");
}
1;

View file

@ -351,9 +351,9 @@ sub restart : Chained('build') PathPart Args(0) {
requireProjectOwner($c, $build->project);
my $drvpath = $build->drvpath ;
my $drvpath = $build->drvpath;
error($c, "This build cannot be restarted.")
unless $build->finished && -f $drvpath ;
unless $build->finished && -f $drvpath;
restartBuild($c->model('DB')->schema, $build);

View file

@ -221,7 +221,7 @@ sub updateJobset {
my ($c, $jobset) = @_;
my $jobsetName = trim $c->request->params->{"name"};
error($c, "Invalid jobset name: $jobsetName") unless $jobsetName =~ /^[[:alpha:]][\w\-]*$/;
error($c, "Invalid jobset name: $jobsetName") if $jobsetName !~ /^$jobsetNameRE$/;
my ($nixExprPath, $nixExprInput) = nixExprPathFromParams $c;
@ -298,13 +298,13 @@ sub clone_submit : Chained('jobset') PathPart('clone/submit') Args(0) {
requireProjectOwner($c, $jobset->project);
requirePost($c);
my $newjobsetName = trim $c->request->params->{"newjobset"};
error($c, "Invalid jobset name: $newjobsetName") unless $newjobsetName =~ /^[[:alpha:]][\w\-]*$/;
my $newJobsetName = trim $c->request->params->{"newjobset"};
error($c, "Invalid jobset name: $newJobsetName") unless $newJobsetName =~ /^[[:alpha:]][\w\-]*$/;
my $newjobset;
my $newJobset;
txn_do($c->model('DB')->schema, sub {
$newjobset = $jobset->project->jobsets->create(
{ name => $newjobsetName
$newJobset = $jobset->project->jobsets->create(
{ name => $newJobsetName
, description => $jobset->description
, nixexprpath => $jobset->nixexprpath
, nixexprinput => $jobset->nixexprinput
@ -314,14 +314,14 @@ sub clone_submit : Chained('jobset') PathPart('clone/submit') Args(0) {
});
foreach my $input ($jobset->jobsetinputs) {
my $newinput = $newjobset->jobsetinputs->create({name => $input->name, type => $input->type});
my $newinput = $newJobset->jobsetinputs->create({name => $input->name, type => $input->type});
foreach my $inputalt ($input->jobsetinputalts) {
$newinput->jobsetinputalts->create({altnr => $inputalt->altnr, value => $inputalt->value});
}
}
});
$c->res->redirect($c->uri_for($c->controller('Jobset')->action_for("edit"), [$jobset->project->name, $newjobsetName]));
$c->res->redirect($c->uri_for($c->controller('Jobset')->action_for("edit"), [$jobset->project->name, $newJobsetName]));
}

View file

@ -32,13 +32,17 @@ sub view : Chained('eval') PathPart('') Args(0) {
# Allow comparing this evaluation against the previous evaluation
# (default), an arbitrary evaluation, or the latest completed
# evaluation of another jobset.
if (defined $compare && $compare =~ /^\d+$/) {
$eval2 = $c->model('DB::JobsetEvals')->find($compare)
or notFound($c, "Evaluation $compare doesn't exist.");
} elsif (defined $compare && $compare =~ /^($jobNameRE)$/) {
my $j = $c->stash->{project}->jobsets->find({name => $compare})
or notFound($c, "Jobset $compare doesn't exist.");
$eval2 = getLatestFinishedEval($c, $j);
if (defined $compare) {
if ($compare =~ /^\d+$/) {
$eval2 = $c->model('DB::JobsetEvals')->find($compare)
or notFound($c, "Evaluation $compare doesn't exist.");
} elsif (defined $compare && $compare =~ /^($jobsetNameRE)$/) {
my $j = $c->stash->{project}->jobsets->find({name => $compare})
or notFound($c, "Jobset $compare doesn't exist.");
$eval2 = getLatestFinishedEval($c, $j);
} else {
notFound($c, "Unknown comparison source $compare.");
}
} else {
($eval2) = $eval->jobset->jobsetevals->search(
{ hasnewbuilds => 1, id => { '<', $eval->id } },

View file

@ -45,6 +45,11 @@ sub submit : Chained('project') PathPart Args(0) {
requireProjectOwner($c, $c->stash->{project});
requirePost($c);
if (($c->request->params->{submit} || "") eq "delete") {
$c->stash->{project}->delete;
$c->res->redirect($c->uri_for("/"));
}
txn_do($c->model('DB')->schema, sub {
updateProject($c, $c->stash->{project});
});
@ -65,6 +70,7 @@ sub hide : Chained('project') PathPart Args(0) {
$c->res->redirect($c->uri_for("/"));
}
sub unhide : Chained('project') PathPart Args(0) {
my ($self, $c) = @_;
@ -77,19 +83,6 @@ sub unhide : Chained('project') PathPart Args(0) {
$c->res->redirect($c->uri_for("/"));
}
sub delete : Chained('project') PathPart Args(0) {
my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project});
requirePost($c);
txn_do($c->model('DB')->schema, sub {
$c->stash->{project}->delete;
});
$c->res->redirect($c->uri_for("/"));
}
sub requireMayCreateProjects {
my ($c) = @_;
@ -119,6 +112,8 @@ sub create_submit : Path('/create-project/submit') {
my $projectName = trim $c->request->params->{name};
error($c, "Invalid project name: $projectName") if $projectName !~ /^$projectNameRE$/;
txn_do($c->model('DB')->schema, sub {
# Note: $projectName is validated in updateProject,
# which will abort the transaction if the name isn't
@ -152,6 +147,8 @@ sub create_jobset_submit : Chained('project') PathPart('create-jobset/submit') A
my $jobsetName = trim $c->request->params->{name};
error($c, "Invalid jobset name: $jobsetName") if $jobsetName !~ /^$jobsetNameRE$/;
txn_do($c->model('DB')->schema, sub {
# Note: $jobsetName is validated in updateProject, which will
# abort the transaction if the name isn't valid.
@ -167,12 +164,7 @@ sub create_jobset_submit : Chained('project') PathPart('create-jobset/submit') A
sub updateProject {
my ($c, $project) = @_;
my $projectName = trim $c->request->params->{name};
error($c, "Invalid project name: " . ($projectName || "(empty)")) unless $projectName =~ /^[[:alpha:]][\w\-]*$/;
my $displayName = trim $c->request->params->{displayname};
error($c, "Invalid display name: $displayName") if $displayName eq "";
my $owner = $project->owner;
if ($c->check_user_roles('admin')) {
$owner = trim $c->request->params->{owner};
@ -180,6 +172,12 @@ sub updateProject {
unless defined $c->model('DB::Users')->find({username => $owner});
}
my $projectName = trim $c->request->params->{name};
error($c, "Invalid project name: $projectName") if $projectName !~ /^$projectNameRE$/;
my $displayName = trim $c->request->params->{displayname};
error($c, "Invalid display name: $displayName") if $displayName eq "";
$project->update(
{ name => $projectName
, displayname => $displayName

View file

@ -52,6 +52,8 @@ sub edit : Chained('release') PathPart('edit') Args(0) {
my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project});
$c->stash->{template} = 'edit-release.tt';
$c->stash->{members} = [$c->stash->{release}->releasemembers->search({},
{order_by => ["description"]})];
}

View file

@ -116,6 +116,11 @@ sub edit : Chained('view') PathPart('edit') Args(0) {
sub submit : Chained('view') PathPart('submit') Args(0) {
my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project});
if (($c->request->params->{submit} || "") eq "delete") {
$c->stash->{view}->delete;
$c->res->redirect($c->uri_for($c->controller('Project')->action_for('view'),
[$c->stash->{project}->name]));
}
txn_do($c->model('DB')->schema, sub {
updateView($c, $c->stash->{view});
});
@ -123,17 +128,6 @@ sub submit : Chained('view') PathPart('submit') Args(0) {
}
sub delete : Chained('view') PathPart('delete') Args(0) {
my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project});
txn_do($c->model('DB')->schema, sub {
$c->stash->{view}->delete;
});
$c->res->redirect($c->uri_for($c->controller('Project')->action_for('view'),
[$c->stash->{project}->name]));
}
sub latest : Chained('view') PathPart('latest') {
my ($self, $c, @args) = @_;

View file

@ -968,5 +968,11 @@ sub restartBuild {
, busy => 0
, locker => ""
});
# Reset the stats for the evals to which this build belongs.
# !!! Should do this in a trigger.
foreach my $m ($build->jobsetevalmembers->all) {
$m->eval->update({nrsucceeded => undef});
}
});
}

View file

@ -13,7 +13,7 @@ our @EXPORT = qw(
requireLogin requireProjectOwner requireAdmin requirePost isAdmin isProjectOwner
trim
getLatestFinishedEval
$pathCompRE $relPathRE $relNameRE $jobNameRE $systemRE
$pathCompRE $relPathRE $relNameRE $projectNameRE $jobsetNameRE $jobNameRE $systemRE
@buildListColumns
);
@ -181,12 +181,14 @@ sub getLatestFinishedEval {
# Security checking of filenames.
Readonly our $pathCompRE => "(?:[A-Za-z0-9-\+\._][A-Za-z0-9-\+\._]*)";
Readonly our $relPathRE => "(?:$pathCompRE(?:/$pathCompRE)*)";
Readonly our $relNameRE => "(?:[A-Za-z0-9-][A-Za-z0-9-\.]*)";
Readonly our $attrNameRE => "(?:[A-Za-z_][A-Za-z0-9_]*)";
Readonly our $jobNameRE => "(?:$attrNameRE(?:\\.$attrNameRE)*)";
Readonly our $systemRE => "(?:[a-z0-9_]+-[a-z0-9_]+)";
Readonly our $pathCompRE => "(?:[A-Za-z0-9-\+\._][A-Za-z0-9-\+\._]*)";
Readonly our $relPathRE => "(?:$pathCompRE(?:/$pathCompRE)*)";
Readonly our $relNameRE => "(?:[A-Za-z0-9-][A-Za-z0-9-\.]*)";
Readonly our $attrNameRE => "(?:[A-Za-z_][A-Za-z0-9_]*)";
Readonly our $projectNameRE => "(?:[A-Za-z_][A-Za-z0-9-_]*)";
Readonly our $jobsetNameRE => "(?:[A-Za-z_][A-Za-z0-9-_]*)";
Readonly our $jobNameRE => "(?:$attrNameRE(?:\\.$attrNameRE)*)";
Readonly our $systemRE => "(?:[a-z0-9_]+-[a-z0-9_]+)";
1;

View file

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Admin" %]
[% PROCESS common.tt %]
<h2>Machine status</h2>
<div class="page-header"><h1>Machine status</h1></div>
<table class="table table-condensed table-striped">
[% FOREACH m IN machines %]

View file

@ -1,10 +1,10 @@
[% WRAPPER layout.tt title="All Builds" %]
[% WRAPPER layout.tt title="All builds" %]
[% PROCESS common.tt %]
<h1>All Builds
<div class="page-header"><h1>All builds
[% IF job %]for Job [% project.name %]:[% jobset.name %]:[% job.name %]
[% ELSIF jobset %]for Jobset [% project.name %]:[% jobset.name %]
[% ELSIF project %] for Project <tt>[% project.name %]</tt>[% END %]</h1>
[% ELSIF project %] for Project <tt>[% project.name %]</tt>[% END %]</h1></div>
<p>Showing builds [% (page - 1) * resultsPerPage + 1 %] - [% (page - 1) * resultsPerPage + builds.size %]
out of [% total %] in order of descending timestamp.</p>

View file

@ -9,8 +9,6 @@
[% job = build.job %]
[% BLOCK renderBuildSteps %]
<h2 id="buildsteps">[% type %] build steps</h2>
<table class="tablesorter table table-striped table-condensed">
<thead>
<tr><th>Nr</th><th>What</th><th>Duration</th><th>Machine</th><th>Status</th></tr>
@ -67,7 +65,7 @@
[% IF flashMsg %]
<p class="error">[% flashMsg %]</p>
<p class="btn-info btn-large">[% flashMsg %]</p>
[% END %]
<ul id="tab" class="nav nav-tabs">
@ -142,9 +140,14 @@
</table>
[% IF c.user_exists && available %]
<form action="[% c.uri_for('/build' build.id 'add-to-release') %]" method="post">
<p>Add to release: <input type="text" class="string" name="name" />
<button type="submit"><img src="/static/images/success.gif" />Apply</button></p>
<form class="form-horizontal" action="[% c.uri_for('/build' build.id 'add-to-release') %]" method="post">
<div class="control-group">
<label class="control-label">Add to release</label>
<div class="controls">
<input type="text" class="input" name="name"></input>
<button type="submit" class="btn btn-success">Apply</button>
</div>
</div>
</form>
[% END %]
@ -160,12 +163,14 @@
[% END %]
[% IF !build.finished && build.buildsteps.size > 0 %]
[% IF !build.finished %]
<h3>Running build steps</h3>
[% INCLUDE renderBuildSteps type="Running" %]
[% END %]
[% IF build.finished %]
[% IF build.buildsteps && build.buildstatus != 0 && build.buildstatus != 6 %]
<h3>Failed build steps</h3>
[% INCLUDE renderBuildSteps type="Failed" %]
[% END %]
@ -416,9 +421,10 @@
[% END %]
[% IF build.buildsteps %]
<div id="tabs-buildsteps" class="tab-pane">
[% INCLUDE renderBuildSteps type="All" %]
</div>
<div id="tabs-buildsteps" class="tab-pane">
<h2>All build steps</h2>
[% INCLUDE renderBuildSteps type="All" %]
</div>
[% END %]

View file

@ -2,7 +2,7 @@
[% PROCESS common.tt %]
[% USE HTML %]
<h1>Channel <tt>[% channelName %]</tt></h1>
<div class="page-header"><h1>Channel <tt>[% channelName %]</tt></h1></div>
<p>This page provides a <em>channel</em> for the <a
href="http://nixos.org/">Nix package manager</a>. If you have Nix

View file

@ -3,7 +3,7 @@
[% USE HTML %]
[% edit=1 %]
<h1>Clone Build</h1>
<div class="page-header"><h1>Clone Build</h1></div>
<p>Cloning allows you to perform a build with modified inputs.</p>

View file

@ -189,7 +189,7 @@
[% BLOCK maybeLink -%]
[% IF uri %]<a [% HTML.attributes(href => uri) %][% IF confirmmsg %]onclick="javascript:return confirm('[% confirmmsg %]')"[% END %]>[% content %]</a>[% ELSE; content; END -%]
[% IF uri %]<a [% HTML.attributes(href => uri, class => class) %][% IF confirmmsg %]onclick="javascript:return confirm('[% confirmmsg %]')"[% END %]>[% content %]</a>[% ELSE; content; END -%]
[% END -%]
[% BLOCK maybeButton -%]
@ -198,11 +198,24 @@
[% BLOCK renderSelection %]
[% IF edit %]
<select [% HTML.attributes(id => param, name => param) %]>
[% FOREACH name IN options.keys.sort %]
<option [% HTML.attributes(value => name) %] [% IF name == curValue; "selected='selected'"; END %]>[% options.$name %]</option>
[% END %]
</select>
[% IF radiobuttons %]
<div class="controls">
[% FOREACH name IN options.keys.sort %]
<label class="radio inline">
<input type="radio" [% HTML.attributes(id => param, name => param, value => name) %]
[% IF name == curValue; "checked='1'"; END %]>
[% options.$name %]
</input>
</label>
[% END %]
</div>
[% ELSE %]
<select [% HTML.attributes(id => param, name => param) %]>
[% FOREACH name IN options.keys.sort %]
<option [% HTML.attributes(value => name) %] [% IF name == curValue; "selected='selected'"; END %]>[% options.$name %]</option>
[% END %]
</select>
[% END %]
[% ELSE %]
[% options.$curValue %]
[% END %]
@ -273,11 +286,6 @@
since [% INCLUDE renderDateTime timestamp = build.starttime %]
[% ELSE %]
<strong>Scheduled to be built</strong>
[% IF c.user_exists %]
<form action="[% c.uri_for('/build' build.id 'cancel') %]" method="post" class="inline">
<button id="cancel" type="submit">Cancel</button>
</form>
[% END %]
[% END %]
[% END -%]

View file

@ -1,57 +1,63 @@
[% WRAPPER layout.tt title=(create ? "New Release" : "Edit Release") %]
[% WRAPPER layout.tt title=(create ? "New release" : "Edit release") %]
[% PROCESS common.tt %]
[% USE HTML %]
<h1>[% IF create %]New Release[% ELSE %]Release <tt>[% release.name %]</tt>[% END %]</h1>
<div class="page-header"><h1>[% IF create %]New release[% ELSE %]Release <tt>[% release.name %]</tt>[% END %]</h1></div>
<form action="[% IF create %][% c.uri_for('/project' project.name 'create-release/submit') %][% ELSE %][% c.uri_for('/release' project.name release.name 'submit') %][% END %]" method="post">
<form class="form-horizontal" action="[% IF create %][% c.uri_for('/project' project.name 'create-release/submit') %][% ELSE %][% c.uri_for('/release' project.name release.name 'submit') %][% END %]" method="post">
<table class="layoutTable">
<tr>
<th>Identifier:</th>
<td><input type="text" class="string" name="name" [% HTML.attributes(value => release.name) %] /></td>
</tr>
<tr>
<th>Description:</th>
<td><input type="text" class="string" name="description" [% HTML.attributes(value => release.description) %] /></td>
</tr>
</table>
<h3>Release Members</h3>
<fieldset>
<div class="control-group">
<label class="control-label">Identifier</label>
<div class="controls">
<input type="text" class="span3" name="name" [% HTML.attributes(value => release.name) %]></input>
</div>
</div>
<div class="control-group">
<label class="control-label">Description</label>
<div class="controls">
<input type="text" class="span3" name="description" [% HTML.attributes(value => release.description) %]></input>
</div>
</div>
<h3>Release members</h3>
<p><em>Note:</em> to add a build to this release, go to the builds
information page and click on “Add to release”.</p>
[% FOREACH m IN release.releasemembers %]
<div class="releaseMember">
<h4>Build [% m.build.id %] <button type="button" onclick='$(this).parents(".releaseMember").remove()'><img src="/static/images/failure.gif" alt="Delete input" /></button></h4>
<table class="layoutTable">
<tr>
<th>Label:</th>
<td><input type="text" class="string longString" name="member-[% m.build.id %]-description" [% HTML.attributes(value => m.description) %] /></td>
</tr>
</table>
[% FOREACH m IN members %]
<div class="releaseMember control-group">
<label class="control-label">Build [% m.build.id %] Label</label>
<div class="controls">
<input type="text" class="span3" name="member-[% m.build.id %]-description" [% HTML.attributes(value => m.description) %]></input>
<button class="btn btn-warning" type="button" onclick='$(this).parents(".releaseMember").remove()'><i class="icon-trash icon-white"></i></button>
</div>
</div>
[% END %]
<hr />
<p>
<button type="submit"><img alt="Apply" src="/static/images/success.gif" />[%IF create %]Create[% ELSE %]Apply changes[% END %]</button>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i>
[%IF create %]Create[% ELSE %]Apply changes[% END %]
</button>
[% IF !create %]
<button id="delete-release" type="submit" name="action" value="delete"><img alt="Delete" src="/static/images/failure.gif" />Delete this release</button>
<script type="text/javascript">
$("#delete-release").click(function() {
return confirm("Are you sure you want to delete this release?");
});
</script>
<button id="delete-release" type="submit" class="btn btn-danger" name="action" value="delete">
<i class="icon-trash icon-white"></i>
Delete this release
</button>
<script type="text/javascript">
$("#delete-release").click(function() {
return confirm("Are you sure you want to delete this release?");
});
</script>
[% END %]
</p>
</div>
</fieldset>
</form>

View file

@ -1,15 +1,15 @@
[% WRAPPER layout.tt title=(create ? "New View" : "View $project.name:$view.name") %]
[% WRAPPER layout.tt title=(create ? "New view" : "View $project.name:$view.name") %]
[% PROCESS common.tt %]
[% USE HTML %]
<h1>[% IF create %]New View[% ELSE %]View <tt>[% project.name %]:[% view.name %]</tt>[% END %]</h1>
<div class="page-header"><h1>[% IF create %]New view[% ELSE %]View <tt>[% project.name %]:[% view.name %]</tt>[% END %]</h1></div>
[% BLOCK renderJob %]
<tr id="[% id %]" >
<td>
<button type="button" onclick='$(this).parents("tr").remove()'>
<img src="/static/images/failure.gif" alt="Delete job" />
<button type="button" class="btn btn-warning" onclick='$(this).parents("tr").remove()'>
<i class="icon-trash icon-white"></i>
</button>
</td>
<td><input type="radio" id="[% "$baseName-primary" %]" name="primary" [% IF job.isprimary %]
@ -21,19 +21,24 @@
[% END %]
<form action="[% IF create %][% c.uri_for('/project' project.name 'create-view/submit') %][% ELSE %][% c.uri_for('/view' project.name view.name 'submit') %][% END %]" method="post">
<table class="layoutTable">
<tr>
<th>Identifier:</th>
<td><input type="text" class="string" name="name" [% HTML.attributes(value => view.name) %] /></td>
</tr>
<tr>
<th>Description:</th>
<td><input type="text" class="string" name="description" [% HTML.attributes(value => view.description) %] /></td>
</tr>
</table>
<form class="form-horizontal" action="[% IF create %][% c.uri_for('/project' project.name 'create-view/submit') %][% ELSE %][% c.uri_for('/view' project.name view.name 'submit') %][% END %]" method="post">
<fieldset>
<div class="control-group">
<label class="control-label">Identifier</label>
<div class="controls">
<input type="text" class="span3" name="name" [% HTML.attributes(value => view.name) %]></input>
</div>
</div>
<div class="control-group">
<label class="control-label">Description</label>
<div class="controls">
<input type="text" class="span3" name="description" [% HTML.attributes(value => view.description) %]></input>
</div>
</div>
<table class="tablesorter table table-condensed table-striped">
<thead>
<tr>
@ -51,12 +56,28 @@
[% n = n + 1 %]
[% END %]
<tr>
<td colspan="5"><button type="button" class="add-job">Add a new job</button></td>
<td colspan="5" style="text-align: center;"><button type="button" class="add-job btn btn-success"><i class="icon-plus icon-white"></i> Add a job</button></td>
</tr>
</tbody>
</table>
<p><button type="submit"><img src="/static/images/success.gif" />[%IF create %]Create[% ELSE %]Apply changes[% END %]</button></p>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i>
[%IF create %]Create[% ELSE %]Apply changes[% END %]
</button>
[% IF !create %]
<button id="delete-view" type="submit" class="btn btn-danger" name="submit" value="delete">
<i class="icon-trash icon-white"></i>
Delete this view
</button>
<script type="text/javascript">
$("#delete-view").click(function() {
return confirm("Are you sure you want to delete this view?");
});
</script>
[% END %]
</div>
</form>
@ -83,20 +104,5 @@
});
</script>
[% IF !create %]
<form action="[% c.uri_for('/view' project.name view.name 'delete') %]" method="post">
<p><button id="delete-project" type="submit"><img src="/static/images/failure.gif" />Delete this view</button></p>
</form>
<script type="text/javascript">
$("#delete-project").click(function() {
return confirm("Are you sure you want to delete this view?");
});
</script>
[% END %]
[% END %]

View file

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Error" %]
[% USE HTML %]
<h1>[% IF httpStatus %][% httpStatus %][% ELSE %]Error[% END %]</h1>
<div class="page-header"><h1>[% IF httpStatus %][% httpStatus %][% ELSE %]Error[% END %]</h1></div>
<p>I'm very sorry, but the following error(s) occurred:</p>

View file

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Errors" %]
[% PROCESS common.tt %]
<h1>Errors</h1>
<div class="page-header"><h1>Errors</h1></div>
<p>This page provides a quick way to see how FUBARed your packages
are. It shows job expressions that dont evaluate properly and jobs

View file

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Jobset $project.name:$jobset.name evaluation $eval.id" %]
[% PROCESS common.tt %]
<h2>Jobset <tt>[% project.name %]:[% jobset.name %]</tt> evaluation [% eval.id %]</h2>
<div class="page-header"><h1>Jobset <tt>[% project.name %]:[% jobset.name %]</tt> evaluation [% eval.id %]</h1></div>
[%- IF otherEval -%]
<p>Comparisons are relative to [% INCLUDE renderFullJobsetName

View file

@ -1,9 +1,9 @@
[% WRAPPER layout.tt title="Jobset $project.name:$jobset.name Evaluations" %]
[% PROCESS common.tt %]
<h2>Evaluations of Jobset <tt>[% INCLUDE renderLink
<div class="page-header"><h1>Evaluations of Jobset <tt>[% INCLUDE renderLink
uri = c.uri_for(c.controller('Project').action_for('view'), [project.name])
title = project.name %]:[% jobset.name %]</tt></h2>
title = project.name %]:[% jobset.name %]</tt></h1></div>
<p>Showing evaluations [% (page - 1) * resultsPerPage + 1 %] - [%
(page - 1) * resultsPerPage + evals.size %] out of [% total %].</p>

View file

@ -2,7 +2,7 @@
[% PROCESS common.tt %]
[% IF edit %]
<form action="[% IF create %][% c.uri_for('/project' project.name 'create-jobset/submit') %][% ELSE %][% c.uri_for('/jobset' project.name jobset.name 'submit') %][% END %]" method="post">
<form class="form-horizontal" action="[% IF create %][% c.uri_for('/project' project.name 'create-jobset/submit') %][% ELSE %][% c.uri_for('/jobset' project.name jobset.name 'submit') %][% END %]" method="post">
[% END %]
@ -13,7 +13,7 @@
[% BLOCK renderInputAlt %]
[% IF edit %]
<button type="button" onclick='$(this).parents(".inputalt").remove()'><img src="/static/images/failure.gif" alt="Delete value" /></button>
<button type="button" class="btn btn-warning" onclick='$(this).parents(".inputalt").remove()'><i class="icon-trash icon-white"></i></button>
[% INCLUDE maybeEditString param=param value=alt.value %]
<br />
[% ELSE %]
@ -26,7 +26,7 @@
<tr class="input [% extraClass %]" [% IF id %]id="[% id %]"[% END %]>
<td>
[% IF edit %]<button type="button" onclick='$(this).parents(".input").remove()'><img src="/static/images/failure.gif" alt="Delete input" /></button>[% END -%]
[% IF edit %]<button type="button" class="btn btn-warning" onclick='$(this).parents(".input").remove()'><i class="icon-trash icon-white"></i></button>[% END -%]
<tt>[% INCLUDE maybeEditString param="$baseName-name" value=input.name extraClass="shortString" %]</tt>
</td>
<td>
@ -42,7 +42,7 @@
[% END %]
</tt>
[% END %]
[% IF edit %]<button type="button" onclick='return false' class="add-inputalt">+</button>[% END %]
[% IF edit %]<button type="button" class="add-inputalt btn btn-success" onclick='return false'><i class="icon-plus icon-white"></i></button>[% END %]
</td>
</tr>
@ -62,7 +62,7 @@
[% END %]
[% IF edit %]
<tr>
<td colspan="3"><button type="button" class="add-input">Add a new input</button></td>
<td colspan="3" style="text-align: center;"><button type="button" class="add-input btn btn-success"><i class="icon-plus icon-white"></i> Add a new input</button></td>
</tr>
[% END %]
</tbody>
@ -79,6 +79,7 @@
[% END %]
<li><a href="#tabs-setup" data-toggle="tab">Setup</a></li>
</ul>
<div id="generic-tabs" class="tab-content">
<div id="tabs-information" class="tab-pane active">
[% IF !edit && evals.size() > 0 -%]
@ -151,13 +152,13 @@
<tr>
<th>Enabled:</th>
<td>
[% INCLUDE renderSelection param="enabled" curValue=jobset.enabled options={"1" = "Yes", "0" = "No"} %]
[% INCLUDE renderSelection param="enabled" curValue=jobset.enabled radiobuttons=1 options={"1" = "Yes", "0" = "No"} %]
</td>
</tr>
<tr>
<th>Enable email notification:</th>
<td>
[% INCLUDE renderSelection param="enableemail" curValue=jobset.enableemail options={"1" = "Yes", "0" = "No"} %]
[% INCLUDE renderSelection param="enableemail" curValue=jobset.enableemail radiobuttons=1 options={"1" = "Yes", "0" = "No"} %]
</td>
</tr>
<tr>
@ -254,7 +255,7 @@
});
</script>
<p><button type="submit"><img src="/static/images/success.gif" />[%IF create %]Create[% ELSE %]Apply changes[% END %]</button></p>
<p><button type="submit" class="btn btn-primary"><i class="icon-ok icon-white"></i> [%IF create %]Create[% ELSE %]Apply changes[% END %]</button></p>
</form>

View file

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Job Status" %]
[% WRAPPER layout.tt title="Job status" %]
[% PROCESS common.tt %]
<h1>Job Status[% IF project %] of <tt>[% project.name %][% IF jobset %]:[% jobset.name%][% END %][% IF job %]:[% job.name%][% END %]</tt>[% END %]</h1>
<div class="page-header"><h1>Job status[% IF project %] of <tt>[% project.name %][% IF jobset %]:[% jobset.name%][% END %][% IF job %]:[% job.name%][% END %]</tt>[% END %]</h1></div>
<p>Below are the latest builds for each job. It is ordered by the status
change time (the timestamp of the last build that had a different

View file

@ -108,17 +108,16 @@
[% content %]
</div>
<div class="navbar navbar-fixed-bottom">
<div id="footer" style="text-align: center;">
<div id="last-modified">
<em><a href="http://nixos.org/hydra" target="_new">Hydra</a> [% HTML.escape(version) %] (using [% HTML.escape(nixVersion) %]).</em>
Page generated on [% INCLUDE renderDateTime %].
[% IF c.user_exists %]
You are logged in as <tt>[% c.user.username %]</tt>.
[% END %]
</div>
<footer class="navbar">
<hr />
<small>
<em><a href="http://nixos.org/hydra" target="_new">Hydra</a> [% HTML.escape(version) %] (using [% HTML.escape(nixVersion) %]).</em>
Page generated on [% INCLUDE renderDateTime %].
[% IF c.user_exists %]
You are logged in as <tt>[% c.user.username %]</tt>.
[% END %]
</small>
</footer>
</div>

View file

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Logfile" %]
[% PROCESS common.tt %]
<h1>Build log of [% INCLUDE renderFullJobNameOfBuild %] build <a href="[% c.uri_for('/build' build.id) %]">[% build.id %]</a>[%IF step %] step [% step.stepnr %][% END %]</h1>
<div class="page-header"><h1>Build log of [% INCLUDE renderFullJobNameOfBuild %] build <a href="[% c.uri_for('/build' build.id) %]">[% build.id %]</a>[%IF step %] step [% step.stepnr %][% END %]</h1></div>
<p>
This is the build log of path <tt>[% IF step; step.outpath; ELSE; build.outpath; END %]</tt>.

View file

@ -1,36 +1,39 @@
[% WRAPPER layout.tt title="Login to Hydra" %]
[% PROCESS common.tt %]
<h1>Login</h1>
<div class="page-header"><h1>Login</h1></div>
[% IF errorMsg %]
<p class="btn-warning btn-large">Error: [% errorMsg %]</p>
[% END %]
[% IF c.user_exists %]
<p>
<p class="btn-info btn-large">
You are already logged in as <tt>[% c.user.username %]</tt>.
You can <a href="[% c.uri_for('/logout') %]">logout</a> here.
</p>
[% ELSE %]
[% IF errorMsg %]
<p class="error">Error: [% errorMsg %]</p>
[% END %]
<form class="form-horizontal" method="post" action="[% c.uri_for('/login') %]">
<form method="post" action="[% c.uri_for('/login') %]">
<fieldset>
<div class="control-group">
<label class="control-label">User name</label>
<div class="controls">
<input type="text" class="span3" name="username" value=""></input>
</div>
</div>
<table class="layoutTable">
<tr>
<td>Username:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr colspan="2">
<td>
<input type="submit" name="login" value="Login" />
</td>
</tr>
</table>
<div class="control-group">
<label class="control-label">Password</label>
<div class="controls">
<input type="password" class="span3" name="password" value=""></input>
</div>
</div>
<div class="form-actions">
<input type="submit" name="login" value="Login" class="btn btn-primary" />
</div>
</form>

View file

@ -1,77 +1,90 @@
[% WRAPPER layout.tt title=(create ? "New machine" : "Editing machine '$machine.hostname'") %]
[% PROCESS common.tt %]
<form action="[% IF create %][% c.uri_for('/admin/create-machine/submit') %][% ELSE %][% c.uri_for('/admin/machine' machine.hostname 'submit') %][% END %]" method="post">
<div class="page-header"><h1>[% IF create %]New machine[% ELSE %]Machine <tt>[% machine.hostname %]</tt>[% END %]</h1></div>
<form class="form-horizontal" method="post"
action="[% IF create %][% c.uri_for('/admin/create-machine/submit') %][% ELSE %][% c.uri_for('/admin/machine' machine.hostname 'submit') %][% END %]">
<h2>Machine[% IF ! create %] '[% machine.hostname %]'[% END %]</h2>
<table class="layoutTable">
<fieldset>
[% IF create %]
<tr>
<th>Hostname:</th>
<td>[% INCLUDE maybeEditString param="hostname" value=machine.hostname %]</td>
</tr>
<div class="control-group">
<label class="control-label">Host name</label>
<div class="controls">
<input type="text" class="span3" name="hostname" value="[% machine.hostname %]"></input>
</div>
</div>
[% END %]
<tr>
<th>Username:</th>
<td>[% INCLUDE maybeEditString param="username" value=machine.username %]</td>
</tr>
<tr>
<th>SSH key location:</th>
<td>[% INCLUDE maybeEditString param="ssh_key" value=machine.ssh_key %]</td>
</tr>
<tr>
<th>Options:</th>
<td>
[% INCLUDE maybeEditString param="options" value=machine.options %]
</td>
</tr>
<tr>
<th>Max concurrent builds:</th>
<td><tt>[% INCLUDE maybeEditString param="maxconcurrent" value=machine.maxconcurrent %]</tt></td>
</tr>
<tr>
<th>Speed factor:</th>
<td>
[% INCLUDE maybeEditString param="speedfactor" value=machine.speedfactor %]
</td>
</tr>
<tr>
<th>Systems:</th>
<td>
<select multiple name="systems" style="width: 27em;">
[% FOREACH s IN systemtypes %]
<option value="[% s.system %]"
[% checked = false %]
[% FOREACH ms IN machine.buildmachinesystemtypes %]
[% checked = ms.system == s.system %]
[% BREAK IF checked %]
[% END %]
[% IF checked %]
SELECTED
[% END %]
>[% s.system %]</option>
[% END %]
</select>
</td>
</tr>
</table>
<div class="control-group">
<label class="control-label">User name</label>
<div class="controls">
<input type="text" class="span3" name="username" value="[% machine.username %]"></input>
</div>
</div>
<div class="control-group">
<label class="control-label">SSH key location</label>
<div class="controls">
<input type="text" class="span3" name="ssh_key" value="[% machine.ssh_key %]"></input>
</div>
</div>
<div class="control-group">
<label class="control-label">Options</label>
<div class="controls">
<input type="text" class="span3" name="options" value="[% machine.options %]"></input>
</div>
</div>
<div class="control-group">
<label class="control-label">Max concurrent builds</label>
<div class="controls">
<input type="text" class="span3" name="maxconcurrent" value="[% machine.maxconcurrent %]"></input>
</div>
</div>
<div class="control-group">
<label class="control-label">Speed factor</label>
<div class="controls">
<input type="text" class="span3" name="speedfactor" value="[% machine.speedfactor %]"></input>
</div>
</div>
<div class="control-group">
<label class="control-label">Systems</label>
<div class="controls">
<select class="span3" multiple="1" name="systems">
[% FOREACH s IN systemtypes;
checked = false;
FOREACH ms IN machine.buildmachinesystemtypes;
checked = ms.system == s.system;
BREAK IF checked;
END %]
<option value="[% s.system %]" [% IF checked %]selected="1"[% END %]>[% s.system %]</option>
[% END %]
</select>
</div>
</div>
<p><button type="submit"><img src="/static/images/success.gif" />[%IF create %]Create[% ELSE %]Apply changes[% END %]</button></p>
</form>
[% IF !create %]
<form action="[% c.uri_for('/admin/machine' machine.hostname 'delete') %]" method="post">
<p><button id="delete-machine" type="submit"><img src="/static/images/failure.gif" />Remove this machine</button></p>
</form>
<script type="text/javascript">
$("#delete-machine").click(function() {
return confirm("Are you sure you want to delete this machine?");
});
</script>
[% END %]
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i>
[%IF create %]Create[% ELSE %]Apply changes[% END %]
</button>
[% IF !create %]
<button id="delete-machine" type="submit" class="btn btn-danger" name="submit" value="delete">
<i class="icon-trash icon-white"></i>
Delete this machine
</button>
<script type="text/javascript">
$("#delete-machine").click(function() {
return confirm("Are you sure you want to delete this machine?");
});
</script>
[% END %]
</div>
</fieldset>
[% END %]

View file

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Machines" %]
[% PROCESS common.tt %]
<h1>Build machines</h1>
<div class="page-header"><h1>Build machines</h1></div>
<table class="table table-condensed table-striped">
<thead>
@ -9,7 +9,7 @@
<th>Enabled</th>
<th>Machine</th>
<th>Max concurrent</th>
<th>Speedfactor</th>
<th>Speed factor</th>
[% FOREACH s IN systems %]<th>[% s.system %]</th>[% END %]
</tr>
</thead>
@ -17,7 +17,7 @@
[% FOREACH m IN machines %]
<tr>
<td><input type="checkbox" name="enabled" [% IF m.enabled == 1 %]CHECKED[% END %] onclick="window.location='[% IF m.enabled == 1 %][%c.uri_for('/admin/machine' m.hostname 'disable' )%][% ELSE %][%c.uri_for('/admin/machine' m.hostname 'enable' )%][% END %]'"/></td>
<td>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('machine_edit'), [m.hostname]) content = m.hostname %]</td>
<td><a href="[% c.uri_for(c.controller('Admin').action_for('machine_edit'), [m.hostname]) %]">[% m.hostname %]</a></td>
<td>[% m.maxconcurrent %]</td>
<td>[% m.speedfactor %]</td>
[% FOREACH s IN systems %]
@ -36,8 +36,7 @@
</table>
<p>[ <a href="[% c.uri_for(c.controller('Admin').action_for('create_machine')) %]">Add a new machine</a> ]</p>
<p><a class="btn" href="[% c.uri_for(c.controller('Admin').action_for('create_machine')) %]"><i class="icon-plus"></i> Add a new machine</a></p>
<p>
Resulting <tt>/etc/nix.machines</tt> [% IF nixMachinesWritable == 0 %](note: file is not writable!)[% END%]:

View file

@ -2,7 +2,7 @@
[% PROCESS common.tt %]
[% USE String %]
<h1>News items</h1>
<div class="page-header"><h1>News items</h1></div>
[% IF newsItems.size == 0 %]
<p>No news items</p>
@ -15,25 +15,29 @@
<tr>
<td>[% INCLUDE renderDateTime timestamp=i.createtime %]</td>
<td>[% contents.replace('\n','<br />\n') %]</td>
<td>[ [% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('news_delete') i.id) content = "Delete" confirmmsg = "Are you sure you want to delete this news item?" %] ]</td>
<td>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('news_delete') i.id) content = "Delete" confirmmsg = "Are you sure you want to delete this news item?" class = "btn btn-mini btn-danger" %]</td>
</tr>
[% END %]
</tbody>
</table>
[% END %]
<form action="[% c.uri_for('/admin/news/submit') %]" method="post">
<h2>Add news item</h2>
<p>
<textarea class="longString" name="contents"></textarea>
</p>
<p>
<button type="submit">Post</button>
</p>
<form class="form-horizontal" action="[% c.uri_for('/admin/news/submit') %]" method="post">
<fieldset>
<legend>Add news item</legend>
<div class="control-group">
<label class="control-label">News text (HTML)</label>
<div class="controls">
<textarea class="span9" name="contents"></textarea>
</div>
</div>
</fieldset>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i>
Post
</button>
</div>
</form>
[% END %]

View file

@ -5,7 +5,7 @@
[% jobset = build.jobset %]
[% job = build.job %]
<h1>[% title %]</h1>
<div class="page-header"><h1>[% title %]</h1></div>
<div class="buildlog">
[% contents -%]

View file

@ -133,33 +133,35 @@
<tr>
<th>Enabled:</th>
<td>
[% INCLUDE renderSelection param="enabled" curValue=project.enabled options={"1" = "Yes", "0" = "No"} %]
[% INCLUDE renderSelection param="enabled" curValue=project.enabled radiobuttons=1 options={"1" = "Yes", "0" = "No"} %]
</td>
</tr>
</table>
[% IF edit %]
<p><button type="submit"><img src="/static/images/success.gif" />[%IF create %]Create[% ELSE %]Apply changes[% END %]</button></p>
<p>
<button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i>
[%IF create %]Create[% ELSE %]Apply changes[% END %]
</button>
[% IF !create %]
<button id="delete-project" type="submit" class="btn btn-danger" name="submit" value="delete">
<i class="icon-trash icon-white"></i>
Delete this project
</button>
<script type="text/javascript">
$("#delete-project").click(function() {
return confirm("Are you sure you want to delete this project?");
});
</script>
[% END %]
</p>
</form>
[% IF !create %]
<form action="[% c.uri_for('/project' project.name 'delete') %]" method="post">
<p><button id="delete-project" type="submit"><img src="/static/images/failure.gif" />Delete this project</button></p>
</form>
<script type="text/javascript">
$("#delete-project").click(function() {
return confirm("Are you sure you want to delete this project?");
});
</script>
[% END %]
[% END %]
</form>
</div>
[% IF !edit %]
@ -175,7 +177,7 @@
[% FOREACH view IN views %]
<li>
<a href="[% c.uri_for('/view' project.name view.name) %]"><tt>[% view.name %]</tt></a>
[<a href="[% c.uri_for('/view' project.name view.name "edit") %]">Edit</a>]
<a class="btn btn-mini" href="[% c.uri_for('/view' project.name view.name "edit") %]">Edit</a>
</li>
[% END %]
</ul>
@ -186,7 +188,9 @@
[% END %]
<p><a href="[% c.uri_for('/project' project.name 'create-view') %]">[Create a new view]</a></p>
<p><a class="btn" href="[% c.uri_for('/project' project.name 'create-view') %]">
<i class="icon-plus"></i> Create a new view
</a></p>
</div>
[% END %]

View file

@ -1,12 +1,12 @@
[% WRAPPER layout.tt title="Queue" %]
[% PROCESS common.tt %]
<h1>Hydra Queue</h1>
<div class="page-header"><h1>Hydra queue</h1></div>
<p>[ <a href="[% c.uri_for('/status') %]">Running build steps</a> ]</p>
<p><a class="btn" href="[% c.uri_for('/status') %]">Running build steps</a></p>
[% IF flashMsg %]
<p class="error">[% flashMsg %]</p>
<p class="btn-info btn-large">[% flashMsg %]</p>
[% END %]
[% IF queue.size == 0 %]

View file

@ -3,8 +3,8 @@
[% PROCESS "product-list.tt" %]
[% USE HTML %]
<h1>Release <tt>[% release.name %]</tt> <a
class="smallLink" href="[% c.uri_for('/release' project.name release.name "edit") %]">[Edit]</a></h1>
<div class="page-header"><h1>Release <tt>[% release.name %]</tt>
<a class="btn" href="[% c.uri_for('/release' project.name release.name "edit") %]"><i class="icon-edit"></i></a></h1></div>
<p><em>Released on [% INCLUDE renderDateTime timestamp =
release.timestamp %].</em></p>
@ -17,11 +17,11 @@ release.timestamp %].</em></p>
[% FOREACH m IN members %]
<h2>
<h3>
<a href="[% c.uri_for('/build' m.build.id) %]">
[% HTML.escape(m.description) %]
</a>
</h2>
</h3>
[% INCLUDE renderProductList build=m.build %]

View file

@ -2,7 +2,7 @@
[% PROCESS common.tt %]
[% USE HTML %]
<h1>Releases for Project <tt>[% project.name %]</tt></h1>
<div class="page-header"><h1>Releases for Project <tt>[% project.name %]</tt></h1></div>
[% IF releases.size == 0 %]
@ -33,9 +33,9 @@
[% END %]
[% IF c.user_exists %]
<p>
[<a href="[% c.uri_for('/project' project.name 'create-release') %]">Create a release</a>]
</p>
<p><a class="btn" href="[% c.uri_for('/project' project.name 'create-release') %]">
<i class="icon-plus"></i> Create a release
</a></p>
[% END %]
[% END %]

View file

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Hydra status" %]
[% PROCESS common.tt %]
<h1>Hydra Status</h1>
<div class="page-header"><h1>Hydra status</h1></div>
[% INCLUDE hydraStatus %]

View file

@ -4,7 +4,7 @@
[% PROCESS common.tt %]
<h1>Hydra timeline of last 24 hours</h1>
<div class="page-header"><h1>Hydra timeline of last 24 hours</h1></div>
<script type="text/javascript">
Timeline_urlPrefix="http://simile.mit.edu/timeline/api/";

View file

@ -87,7 +87,7 @@
<li class="divider"></li>
[% INCLUDE menuItem uri = c.uri_for('/jobset' project.name jobset.name 'clone') title="Clone jobset" %]
[% INCLUDE menuItem uri = c.uri_for('/jobset' project.name jobset.name 'edit') title="Edit jobset" %]
[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('force_eval'), project.name, jobset.name) content = "Evaluate" confirmmsg = ("Are you sure you want to force evaluation of jobset " _ project.name _ ":" _ jobset.name _ "?") %]
[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('force_eval'), project.name, jobset.name) content = "Evaluate" confirmmsg = ("Are you sure you want to force evaluation of jobset " _ project.name _ ":" _ jobset.name _ "?") class = "" %]
[% IF jobset.hidden %]
[% INCLUDE menuItem uri = c.uri_for('/jobset' project.name jobset.name 'unhide') title = "Unhide" %]
[% ELSE %]
@ -114,8 +114,8 @@
[% INCLUDE makeLink
uri = c.uri_for(c.controller('Job').action_for('errors'), [project.name, jobset.name, job.name])
title = "Errors" %]
<li>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('users')) content = "Manage users" %]</li>
<li>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('news')) content = "Manage news" %]</li>
<li>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('users')) content = "Manage users" class = "" %]</li>
<li>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('news')) content = "Manage news" class = "" %]</li>
[% END %]
[% END %]
@ -145,6 +145,9 @@
[% INCLUDE makeLink
uri = c.uri_for('/build' build.id 'restart')
title = "Restart build" %]
[% INCLUDE makeLink
uri = c.uri_for('/build' build.id 'cancel')
title = "Cancel build" %]
[% END %]
[% END %]
@ -171,11 +174,13 @@
[% INCLUDE maybeLink
uri = c.uri_for(c.controller('Admin').action_for('clearfailedcache'))
content = "Clear failed builds cache"
confirmmsg = "Are you sure you want to clear the failed builds cache?" %]
confirmmsg = "Are you sure you want to clear the failed builds cache?"
class = "" %]
[% INCLUDE maybeLink
uri = c.uri_for(c.controller('Admin').action_for('clear_queue_non_current'))
content = "Clear all non-running old builds from queue."
confirmmsg = "Are you sure you want to clear the queue?"
confirmmsg = "Are you sure you want to clear the queue?"
class = ""
%]
<li class="divider"></li>
[% IF c.check_user_roles('admin') %]

View file

@ -14,57 +14,64 @@
>[% role %]</option>
[% END %]
<form action="[% IF create %][% c.uri_for('/admin/create-user/submit') %][% ELSE %][% c.uri_for('/admin/user' user.username 'submit') %][% END %]" method="post">
<div class="page-header"><h1>[% IF create %]New user[% ELSE %]User <tt>[% user.username %]</tt>[% END %]</h1></div>
<h2>User[% IF ! create %] '[% user.username %]'[% END %]</h2>
<table class="layoutTable">
<form class="form-horizontal" action="[% IF create %][% c.uri_for('/admin/create-user/submit') %][% ELSE %][% c.uri_for('/admin/user' user.username 'submit') %][% END %]" method="post">
<fieldset>
[% IF create %]
<tr>
<th>Username:</th>
<td>[% INCLUDE maybeEditString param="username" value=user.username %]</td>
</tr>
<div class="control-group">
<label class="control-label">User name</label>
<div class="controls">
<input type="text" class="span3" name="username" value=""></input>
</div>
</div>
[% END %]
<tr>
<th>Full name:</th>
<td>[% INCLUDE maybeEditString param="fullname" value=user.fullname %]</td>
</tr>
<tr>
<th>Email:</th>
<td>[% INCLUDE maybeEditString param="emailaddress" value=user.emailaddress %]</td>
</tr>
<tr>
<th>Evaluation error notifications:</th>
<td>
[% INCLUDE renderSelection param="emailonerror" curValue=user.emailonerror options={"1" = "Yes", "0" = "No"} %]
</td>
</tr>
<tr>
<th>Roles:</th>
<td>
<select multiple name="roles" style="width: 27em;">
[% INCLUDE roleoption role="admin" %]
[% INCLUDE roleoption role="create-project" %]
</select>
</td>
</tr>
</table>
<div class="control-group">
<label class="control-label">Full name</label>
<div class="controls">
<input type="text" class="span3" name="fullname" [% HTML.attributes(value => user.fullname) %]></input>
</div>
</div>
<div class="control-group">
<label class="control-label">Email</label>
<div class="controls">
<input type="text" class="span3" name="emailaddress" [% HTML.attributes(value => user.emailaddress) %]></input>
</div>
</div>
<div class="control-group">
<label class="control-label">Evaluation error notifications</label>
[% INCLUDE renderSelection param="emailonerror" curValue=user.emailonerror radiobuttons=1 options={"1" = "Yes", "0" = "No"} %]
</div>
<div class="control-group">
<label class="control-label">Roles</label>
<div class="controls">
<select multiple name="roles" class="span3">
[% INCLUDE roleoption role="admin" %]
[% INCLUDE roleoption role="create-project" %]
</select>
</div>
</div>
<p><button type="submit"><img src="/static/images/success.gif" />[%IF create %]Create[% ELSE %]Apply changes[% END %]</button></p>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i>
[%IF create %]Create[% ELSE %]Apply changes[% END %]
</button>
[% IF !create %]
<button id="delete-user" type="submit" class="btn btn-danger" name="submit" value="delete">
<i class="icon-trash icon-white"></i>
Delete this user
</button>
<script type="text/javascript">
$("#delete-user").click(function() {
return confirm("Are you sure you want to delete this user?");
});
</script>
[% END %]
</div>
</p>
</form>
[% IF !create %]
<form action="[% c.uri_for('/admin/user' user.hostname 'delete') %]" method="post">
<p><button id="delete-user" type="submit"><img src="/static/images/failure.gif" />Remove this user</button></p>
</form>
<script type="text/javascript">
$("#delete-user").click(function() {
return confirm("Are you sure you want to delete this user?");
});
</script>
[% END %]
[% END %]

View file

@ -1,7 +1,7 @@
[% WRAPPER layout.tt title="Users" %]
[% PROCESS common.tt %]
<h1>Users</h1>
<div class="page-header"><h1>Users</h1></div>
<table class="table table-striped table-condensed">
<thead>
@ -17,18 +17,20 @@
<tbody>
[% FOREACH u IN users %]
<tr>
<td>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('user_edit'), [u.username]) content = u.username %]</td>
<td><a href="[% c.uri_for(c.controller('Admin').action_for('user_edit'), [u.username]) %]">[% u.username %]</a></td>
<td>[% u.fullname %]</td>
<td>[% u.emailaddress %]</td>
<td>[% FOREACH r IN u.userroles %]<i>[% r.role %]</i> [% END %]</td>
<td>[% IF u.emailonerror %]Yes[% ELSE %]No[% END %]</td>
<td>[ [% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('reset_password'), [u.username]) content = "Reset password" confirmmsg = "Are you sure you want to reset the password for this user?" %] ]</td>
<td>[% INCLUDE maybeLink uri = c.uri_for(c.controller('Admin').action_for('reset_password'), [u.username]) content = "Reset password" confirmmsg = "Are you sure you want to reset the password for this user?" class = "btn btn-mini" %]</td>
</tr>
[% END %]
</tbody>
</table>
<p>[ <a href="[% c.uri_for(c.controller('Admin').action_for('create_user')) %]">Add a new user</a> ]</p>
<p><a class="btn" href="[% c.uri_for(c.controller('Admin').action_for('create_user')) %]">
<i class="icon-plus"></i> Add a new user
</a></p>
[% END %]

View file

@ -4,7 +4,7 @@
[% PROCESS "product-list.tt" %]
[% USE HTML %]
<h1>View <tt>[% view.project.name %]:[% view.name %]</tt> result [% result.id %][% IF result.releasename %] (<tt>[% result.releasename %]</tt>)[% END %]</h1>
<div class="page-header"><h1>View <tt>[% view.project.name %]:[% view.name %]</tt> result [% result.id %][% IF result.releasename %] (<tt>[% result.releasename %]</tt>)[% END %]</h1></div>
<p><em>Finished building on [% INCLUDE renderDateTime timestamp = result.timestamp %].</em></p>
@ -46,11 +46,13 @@
[% END %]
<br />
[% END %]
[% IF c.user_exists %]
<p>
[<a href="[% c.uri_for('/view' project.name view.name result.id 'release') %]">Release</a>]
<a class="btn" href="[% c.uri_for('/view' project.name view.name result.id 'release') %]">Release</a>
</p>
[% END %]

View file

@ -2,11 +2,11 @@
[% PROCESS common.tt %]
[% USE HTML %]
<h1>View <tt>[% view.project.name %]:[% view.name %]</tt></h1>
<div class="page-header"><h1>View <tt>[% view.project.name %]:[% view.name %]</tt></h1></div>
<p>
[<a href="[% c.uri_for('/view' project.name view.name "edit") %]">Edit</a>]
[<a href="[% c.uri_for('/view' project.name view.name "latest") %]">Latest</a>]
<a class="btn" href="[% c.uri_for('/view' project.name view.name "edit") %]"><i class="icon-edit"></i> Edit</a>
<a class="btn" href="[% c.uri_for('/view' project.name view.name "latest") %]"><i class="icon-share-alt"></i> Latest</a>
</p>
<p>Showing results [% (page - 1) * resultsPerPage + 1 %] - [% (page - 1) * resultsPerPage + results.size %] out of [% totalResults %].</p>
@ -65,8 +65,12 @@
</table>
<ul class="pager">
[% IF page > 1 %]
<li class="previous"><a href="[% "$baseUri?page="; (page - 1) %]">Prev</a></li>
[% END %]
[% IF page * resultsPerPage < totalResults %]
<li class="next"><a href="[% "$baseUri?page="; (page + 1) %]">Next</a></li>
[% END %]
</ul>
<!--

View file

@ -194,7 +194,7 @@ sub checkJobset {
$ev->builds->update({iscurrent => 1});
} else {
print STDERR " created cached eval ", $ev->id, "\n";
$prevEval->builds->update({iscurrent => 1});
$prevEval->builds->update({iscurrent => 1}) if defined $prevEval;
}
});