Remove trailing whitespace

This commit is contained in:
Eelco Dolstra 2013-01-22 14:41:02 +01:00
parent aa28ffe3a8
commit 67aefde62c
65 changed files with 1034 additions and 1034 deletions

View file

@ -54,7 +54,7 @@
regular package management system. Thus, you can use Hydra on a regular package management system. Thus, you can use Hydra on a
Debian, Fedora, SuSE, or Ubuntu system. Debian, Fedora, SuSE, or Ubuntu system.
</para> </para>
</section> </section>
<section> <section>
@ -104,7 +104,7 @@ nix-env -i hydra</screen>
<screen> <screen>
hydra-build hydra-init hydra-update-gc-roots hydra-build hydra-init hydra-update-gc-roots
hydra-eval-jobs hydra-queue-runner hydra-eval-jobs hydra-queue-runner
hydra-evaluator hydra-server hydra-evaluator hydra-server
</screen> </screen>
</para> </para>
@ -191,7 +191,7 @@ hydra-init</screen>
<title>Getting Started</title> <title>Getting Started</title>
<para> <para>
To start the Hydra web server, execute: To start the Hydra web server, execute:
<screen> <screen>
hydra-server</screen> hydra-server</screen>
@ -225,7 +225,7 @@ hydra-server</screen>
functional, though it's possible to temporarily stop any one of functional, though it's possible to temporarily stop any one of
them for maintenance purposes, for instance. them for maintenance purposes, for instance.
</para> </para>
</section> </section>
</chapter> </chapter>

View file

@ -219,8 +219,8 @@
<link <link
xlink:href="http://hydra.nixos.org/"><literal>http://hydra.nixos.org/</literal></link>. xlink:href="http://hydra.nixos.org/"><literal>http://hydra.nixos.org/</literal></link>.
That installation is used to build software components from the That installation is used to build software components from the
<link xlink:href="http://nixos.org">Nix</link>, <link xlink:href="http://nixos.org">Nix</link>,
<link xlink:href="http://nixos.org/nixos">NixOS</link>, <link xlink:href="http://nixos.org/nixos">NixOS</link>,
<link xlink:href="http://www.gnu.org/">GNU</link>, <link xlink:href="http://www.gnu.org/">GNU</link>,
<link xlink:href="http://strategoxt.org">Stratego/XT</link>, <link xlink:href="http://strategoxt.org">Stratego/XT</link>,

View file

@ -58,12 +58,12 @@
</copyright> </copyright>
<date>March 2010</date> <date>March 2010</date>
</info> </info>
<xi:include href="introduction.xml" /> <xi:include href="introduction.xml" />
<xi:include href="installation.xml" /> <xi:include href="installation.xml" />
<xi:include href="projects.xml" /> <xi:include href="projects.xml" />
</book> </book>

View file

@ -45,7 +45,7 @@ Identifier: patchelf
get an error message such as: get an error message such as:
<screen> <screen>
I'm very sorry, but an error occurred: I'm very sorry, but an error occurred:
DBIx::Class::ResultSet::create(): DBI Exception: DBD::SQLite::st execute failed: column name is not unique(19) at dbdimp.c line 402 DBIx::Class::ResultSet::create(): DBI Exception: DBD::SQLite::st execute failed: column name is not unique(19) at dbdimp.c line 402
</screen> </screen>
@ -122,14 +122,14 @@ Nix expression: release.nix in input patchelfSrc
be added. For patchelf we declare the following inputs. be added. For patchelf we declare the following inputs.
<screen> <screen>
patchelfSrc patchelfSrc
'Subversion checkout' https://svn.nixos.org/repos/nix/patchelf/trunk 'Subversion checkout' https://svn.nixos.org/repos/nix/patchelf/trunk
nixpkgs 'Subversion checkout' https://svn.nixos.org/repos/nix/nixpkgs/trunk nixpkgs 'Subversion checkout' https://svn.nixos.org/repos/nix/nixpkgs/trunk
officialRelease Boolean false officialRelease Boolean false
system String value "i686-linux" system String value "i686-linux"
</screen> </screen>
</para> </para>
</section> </section>
@ -389,7 +389,7 @@ $ nix-build -I ~/src release.nix -A build
The <varname>build</varname> job reuses the result of the The <varname>build</varname> job reuses the result of the
<varname>tarball</varname> job, rebuilding it only if it needs to. <varname>tarball</varname> job, rebuilding it only if it needs to.
</para> </para>
</section> </section>
<section> <section>

View file

@ -5,14 +5,14 @@ with pkgs.lib;
let let
cfg = config.services.hydra; cfg = config.services.hydra;
hydraConf = pkgs.writeScript "hydra.conf" hydraConf = pkgs.writeScript "hydra.conf"
'' ''
using_frontend_proxy 1 using_frontend_proxy 1
base_uri ${cfg.hydraURL} base_uri ${cfg.hydraURL}
notification_sender ${cfg.notificationSender} notification_sender ${cfg.notificationSender}
max_servers 25 max_servers 25
''; '';
env = ''export NIX_REMOTE=daemon '' env = ''export NIX_REMOTE=daemon ''
+ ''HYDRA_DBI="${cfg.dbi}" '' + ''HYDRA_DBI="${cfg.dbi}" ''
+ ''HYDRA_CONFIG=${cfg.baseDir}/data/hydra.conf '' + ''HYDRA_CONFIG=${cfg.baseDir}/data/hydra.conf ''
@ -29,7 +29,7 @@ in
###### interface ###### interface
options = { options = {
services.hydra = rec { services.hydra = rec {
enable = mkOption { enable = mkOption {
default = false; default = false;
description = '' description = ''
@ -50,7 +50,7 @@ in
The user the Hydra services should run as. The user the Hydra services should run as.
''; '';
}; };
dbi = mkOption { dbi = mkOption {
default = "dbi:Pg:dbname=hydra;host=localhost;user=root;"; default = "dbi:Pg:dbname=hydra;host=localhost;user=root;";
example = "dbi:SQLite:/home/hydra/db/hydra.sqlite"; example = "dbi:SQLite:/home/hydra/db/hydra.sqlite";
@ -58,18 +58,18 @@ in
The DBI string for Hydra database connection. The DBI string for Hydra database connection.
''; '';
}; };
hydra = mkOption { hydra = mkOption {
default = pkgs.hydra; default = pkgs.hydra;
description = '' description = ''
Location of hydra Location of hydra
''; '';
}; };
hydraURL = mkOption { hydraURL = mkOption {
default = "http://hydra.nixos.org"; default = "http://hydra.nixos.org";
description = '' description = ''
The base URL for the Hydra webserver instance. Used for links in emails. The base URL for the Hydra webserver instance. Used for links in emails.
''; '';
}; };
@ -83,23 +83,23 @@ in
minimumDiskFree = mkOption { minimumDiskFree = mkOption {
default = 5; default = 5;
description = '' description = ''
Threshold of minimum disk space (G) to determine if queue runner should run or not. Threshold of minimum disk space (G) to determine if queue runner should run or not.
''; '';
}; };
minimumDiskFreeEvaluator = mkOption { minimumDiskFreeEvaluator = mkOption {
default = 2; default = 2;
description = '' description = ''
Threshold of minimum disk space (G) to determine if evaluator should run or not. Threshold of minimum disk space (G) to determine if evaluator should run or not.
''; '';
}; };
notificationSender = mkOption { notificationSender = mkOption {
default = "e.dolstra@tudelft.nl"; default = "e.dolstra@tudelft.nl";
description = '' description = ''
Sender email address used for email notifications. Sender email address used for email notifications.
''; '';
}; };
tracker = mkOption { tracker = mkOption {
default = ""; default = "";
@ -120,12 +120,12 @@ in
description = '' description = ''
If hydra upstart jobs should start automatically. If hydra upstart jobs should start automatically.
''; '';
}; };
}; };
}; };
###### implementation ###### implementation
@ -138,7 +138,7 @@ in
home = cfg.baseDir; home = cfg.baseDir;
createHome = true; createHome = true;
useDefaultShell = true; useDefaultShell = true;
} }
]; ];
# We have our own crontab entries for GC, see below. # We have our own crontab entries for GC, see below.

View file

@ -4,7 +4,7 @@
rec { rec {
tarball = tarball =
with import <nixpkgs> { }; with import <nixpkgs> { };
let nix = nixUnstable; in let nix = nixUnstable; in
@ -41,7 +41,7 @@ rec {
''; '';
}; };
build = build =
{ system ? "x86_64-linux" }: { system ? "x86_64-linux" }:
let pkgs = import <nixpkgs> {inherit system;}; in let pkgs = import <nixpkgs> {inherit system;}; in
@ -52,7 +52,7 @@ rec {
releaseTools.nixBuild { releaseTools.nixBuild {
name = "hydra"; name = "hydra";
src = tarball; src = tarball;
configureFlags = "--with-nix=${nix}"; configureFlags = "--with-nix=${nix}";
buildInputs = buildInputs =
@ -99,10 +99,10 @@ rec {
with import <nixos/lib/testing.nix> { inherit system; }; with import <nixos/lib/testing.nix> { inherit system; };
{ {
install = simpleTest { install = simpleTest {
machine = machine =
{ config, pkgs, ... }: { config, pkgs, ... }:
{ services.postgresql.enable = true; { services.postgresql.enable = true;
environment.systemPackages = [ hydra ]; environment.systemPackages = [ hydra ];
@ -123,9 +123,9 @@ rec {
#$machine->mustSucceed("HYDRA_DATA=/var/lib/hydra HYDRA_DBI='dbi:Pg:dbname=hydra;user=hydra;' hydra-server >&2 &"); #$machine->mustSucceed("HYDRA_DATA=/var/lib/hydra HYDRA_DBI='dbi:Pg:dbname=hydra;user=hydra;' hydra-server >&2 &");
#$machine->waitForOpenPort("3000"); #$machine->waitForOpenPort("3000");
''; '';
}; };
}; };

View file

@ -92,7 +92,7 @@ static string queryMetaFieldString(MetaInfo & meta, const string & name)
return value.stringValue; return value.stringValue;
} }
static int queryMetaFieldInt(MetaInfo & meta, const string & name, int def) static int queryMetaFieldInt(MetaInfo & meta, const string & name, int def)
{ {
MetaValue value = meta[name]; MetaValue value = meta[name];
@ -118,7 +118,7 @@ static void findJobsWrapped(EvalState & state, XMLWriter & doc,
if (v.type == tAttrs) { if (v.type == tAttrs) {
DrvInfo drv; DrvInfo drv;
if (getDerivation(state, v, drv, false)) { if (getDerivation(state, v, drv, false)) {
XMLAttrs xmlAttrs; XMLAttrs xmlAttrs;
Path drvPath; Path drvPath;
@ -162,7 +162,7 @@ static void findJobsWrapped(EvalState & state, XMLWriter & doc,
Path root = gcRootsDir + "/" + baseNameOf(drvPath); Path root = gcRootsDir + "/" + baseNameOf(drvPath);
if (!pathExists(root)) addPermRoot(*store, drvPath, root, false); if (!pathExists(root)) addPermRoot(*store, drvPath, root, false);
} }
XMLOpenElement _(doc, "job", xmlAttrs); XMLOpenElement _(doc, "job", xmlAttrs);
showArgsUsed(doc, argsUsed); showArgsUsed(doc, argsUsed);
} }
@ -213,7 +213,7 @@ void run(Strings args)
/* Prevent undeclared dependencies in the evaluation via /* Prevent undeclared dependencies in the evaluation via
$NIX_PATH. */ $NIX_PATH. */
unsetenv("NIX_PATH"); unsetenv("NIX_PATH");
EvalState state; EvalState state;
Path releaseExpr; Path releaseExpr;
AutoArgs autoArgs; AutoArgs autoArgs;
@ -249,9 +249,9 @@ void run(Strings args)
} }
if (releaseExpr == "") throw UsageError("no expression specified"); if (releaseExpr == "") throw UsageError("no expression specified");
if (gcRootsDir == "") printMsg(lvlError, "warning: `--gc-roots-dir' not specified"); if (gcRootsDir == "") printMsg(lvlError, "warning: `--gc-roots-dir' not specified");
store = openStore(); store = openStore();
Expr * e = state.parseExprFromFile(releaseExpr); Expr * e = state.parseExprFromFile(releaseExpr);

View file

@ -9,7 +9,7 @@ use Hydra::Helper::CatalystUtils;
sub getJobStatus { sub getJobStatus {
my ($self, $c) = @_; my ($self, $c) = @_;
my $maintainer = $c->request->params->{"maintainer"}; my $maintainer = $c->request->params->{"maintainer"};
my $latest = $c->stash->{jobStatus}->search( my $latest = $c->stash->{jobStatus}->search(
@ -30,7 +30,7 @@ sub jobstatus : Chained('get_builds') PathPart Args(0) {
# A convenient way to see all the errors - i.e. things demanding # A convenient way to see all the errors - i.e. things demanding
# attention - at a glance. # attention - at a glance.
sub errors : Chained('get_builds') PathPart Args(0) { sub errors : Chained('get_builds') PathPart Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
$c->stash->{template} = 'errors.tt'; $c->stash->{template} = 'errors.tt';
@ -44,7 +44,7 @@ sub errors : Chained('get_builds') PathPart Args(0) {
[getJobStatus($self, $c)->search({buildStatus => {'!=' => 0}})]; [getJobStatus($self, $c)->search({buildStatus => {'!=' => 0}})];
} }
sub all : Chained('get_builds') PathPart { sub all : Chained('get_builds') PathPart {
my ($self, $c) = @_; my ($self, $c) = @_;
@ -96,7 +96,7 @@ sub latest : Chained('get_builds') PathPart('latest') {
{finished => 1, buildstatus => 0}, {order_by => ["isCurrent DESC", "timestamp DESC"]}); {finished => 1, buildstatus => 0}, {order_by => ["isCurrent DESC", "timestamp DESC"]});
notFound($c, "There is no successful build to redirect to.") unless defined $latest; notFound($c, "There is no successful build to redirect to.") unless defined $latest;
$c->res->redirect($c->uri_for($c->controller('Build')->action_for("view_build"), [$latest->id], @rest)); $c->res->redirect($c->uri_for($c->controller('Build')->action_for("view_build"), [$latest->id], @rest));
} }
@ -106,12 +106,12 @@ sub latest_for : Chained('get_builds') PathPart('latest-for') {
my ($self, $c, $system, @rest) = @_; my ($self, $c, $system, @rest) = @_;
notFound($c, "You need to specify a platform type in the URL.") unless defined $system; notFound($c, "You need to specify a platform type in the URL.") unless defined $system;
my ($latest) = $c->stash->{allBuilds}->search( my ($latest) = $c->stash->{allBuilds}->search(
{finished => 1, buildstatus => 0, system => $system}, {order_by => ["isCurrent DESC", "timestamp DESC"]}); {finished => 1, buildstatus => 0, system => $system}, {order_by => ["isCurrent DESC", "timestamp DESC"]});
notFound($c, "There is no successful build for platform `$system' to redirect to.") unless defined $latest; notFound($c, "There is no successful build for platform `$system' to redirect to.") unless defined $latest;
$c->res->redirect($c->uri_for($c->controller('Build')->action_for("view_build"), [$latest->id], @rest)); $c->res->redirect($c->uri_for($c->controller('Build')->action_for("view_build"), [$latest->id], @rest));
} }

View file

@ -27,22 +27,22 @@ sub projectToHash {
return { return {
name => $project->name, name => $project->name,
description => $project->description description => $project->description
}; };
} }
sub projects : Chained('api') PathPart('projects') Args(0) { sub projects : Chained('api') PathPart('projects') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
my @projects = $c->model('DB::Projects')->search({hidden => 0}, {order_by => 'name'}); my @projects = $c->model('DB::Projects')->search({hidden => 0}, {order_by => 'name'});
my @list; my @list;
foreach my $p (@projects) { foreach my $p (@projects) {
push @list, projectToHash($p); push @list, projectToHash($p);
} }
$c->stash->{'plain'} = { $c->stash->{'plain'} = {
data => scalar (JSON::Any->objToJson(\@list)) data => scalar (JSON::Any->objToJson(\@list))
}; };
$c->forward('Hydra::View::Plain'); $c->forward('Hydra::View::Plain');
} }
@ -61,13 +61,13 @@ sub buildToHash {
timestamp => $build->timestamp timestamp => $build->timestamp
}; };
if($build->finished) { if($build->finished) {
$result->{'buildstatus'} = $build->get_column("buildstatus"); $result->{'buildstatus'} = $build->get_column("buildstatus");
} else { } else {
$result->{'busy'} = $build->get_column("busy"); $result->{'busy'} = $build->get_column("busy");
$result->{'priority'} = $build->get_column("priority"); $result->{'priority'} = $build->get_column("priority");
} }
return $result; return $result;
}; };
@ -81,20 +81,20 @@ sub latestbuilds : Chained('api') PathPart('latestbuilds') Args(0) {
my $jobset = $c->request->params->{jobset}; my $jobset = $c->request->params->{jobset};
my $job = $c->request->params->{job}; my $job = $c->request->params->{job};
my $system = $c->request->params->{system}; my $system = $c->request->params->{system};
my $filter = {finished => 1}; my $filter = {finished => 1};
$filter->{project} = $project if ! $project eq ""; $filter->{project} = $project if ! $project eq "";
$filter->{jobset} = $jobset if ! $jobset eq ""; $filter->{jobset} = $jobset if ! $jobset eq "";
$filter->{job} = $job if !$job eq ""; $filter->{job} = $job if !$job eq "";
$filter->{system} = $system if !$system eq ""; $filter->{system} = $system if !$system eq "";
my @latest = $c->model('DB::Builds')->search($filter, {rows => $nr, order_by => ["timestamp DESC"] }); my @latest = $c->model('DB::Builds')->search($filter, {rows => $nr, order_by => ["timestamp DESC"] });
my @list; my @list;
push @list, buildToHash($_) foreach @latest; push @list, buildToHash($_) foreach @latest;
$c->stash->{'plain'} = { $c->stash->{'plain'} = {
data => scalar (JSON::Any->objToJson(\@list)) data => scalar (JSON::Any->objToJson(\@list))
}; };
$c->forward('Hydra::View::Plain'); $c->forward('Hydra::View::Plain');
} }
@ -110,7 +110,7 @@ sub jobsetToHash {
nrfailed => $jobset->get_column("nrfailed"), nrfailed => $jobset->get_column("nrfailed"),
nrtotal => $jobset->get_column("nrtotal") nrtotal => $jobset->get_column("nrtotal")
}; };
} }
sub jobsets : Chained('api') PathPart('jobsets') Args(0) { sub jobsets : Chained('api') PathPart('jobsets') Args(0) {
@ -123,12 +123,12 @@ sub jobsets : Chained('api') PathPart('jobsets') Args(0) {
or notFound($c, "Project $projectName doesn't exist."); or notFound($c, "Project $projectName doesn't exist.");
my @jobsets = jobsetOverview($c, $project); my @jobsets = jobsetOverview($c, $project);
my @list; my @list;
push @list, jobsetToHash($_) foreach @jobsets; push @list, jobsetToHash($_) foreach @jobsets;
$c->stash->{'plain'} = { $c->stash->{'plain'} = {
data => scalar (JSON::Any->objToJson(\@list)) data => scalar (JSON::Any->objToJson(\@list))
}; };
$c->forward('Hydra::View::Plain'); $c->forward('Hydra::View::Plain');
} }
@ -141,12 +141,12 @@ sub queue : Chained('api') PathPart('queue') Args(0) {
error($c, "Parameter not defined!") if !defined $nr; error($c, "Parameter not defined!") if !defined $nr;
my @builds = $c->model('DB::Builds')->search({finished => 0}, {rows => $nr, order_by => ["busy DESC", "priority DESC", "timestamp"]}); my @builds = $c->model('DB::Builds')->search({finished => 0}, {rows => $nr, order_by => ["busy DESC", "priority DESC", "timestamp"]});
my @list; my @list;
push @list, buildToHash($_) foreach @builds; push @list, buildToHash($_) foreach @builds;
$c->stash->{'plain'} = { $c->stash->{'plain'} = {
data => scalar (JSON::Any->objToJson(\@list)) data => scalar (JSON::Any->objToJson(\@list))
}; };
$c->forward('Hydra::View::Plain'); $c->forward('Hydra::View::Plain');
} }
@ -155,7 +155,7 @@ sub queue : Chained('api') PathPart('queue') Args(0) {
sub nrqueue : Chained('api') PathPart('nrqueue') Args(0) { sub nrqueue : Chained('api') PathPart('nrqueue') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
my $nrQueuedBuilds = $c->model('DB::Builds')->search({finished => 0})->count(); my $nrQueuedBuilds = $c->model('DB::Builds')->search({finished => 0})->count();
$c->stash->{'plain'} = { $c->stash->{'plain'} = {
data => "$nrQueuedBuilds" data => "$nrQueuedBuilds"
}; };
$c->forward('Hydra::View::Plain'); $c->forward('Hydra::View::Plain');
@ -176,7 +176,7 @@ sub nrbuilds : Chained('api') PathPart('nrbuilds') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
my $nr = $c->request->params->{nr}; my $nr = $c->request->params->{nr};
my $period = $c->request->params->{period}; my $period = $c->request->params->{period};
error($c, "Parameter not defined!") if !defined $nr || !defined $period; error($c, "Parameter not defined!") if !defined $nr || !defined $period;
my $base; my $base;
@ -186,21 +186,21 @@ sub nrbuilds : Chained('api') PathPart('nrbuilds') Args(0) {
my $system = $c->request->params->{system}; my $system = $c->request->params->{system};
my $filter = {finished => 1}; my $filter = {finished => 1};
$filter->{project} = $project if ! $project eq ""; $filter->{project} = $project if ! $project eq "";
$filter->{jobset} = $jobset if ! $jobset eq ""; $filter->{jobset} = $jobset if ! $jobset eq "";
$filter->{job} = $job if !$job eq ""; $filter->{job} = $job if !$job eq "";
$filter->{system} = $system if !$system eq ""; $filter->{system} = $system if !$system eq "";
$base = 60*60 if($period eq "hour"); $base = 60*60 if($period eq "hour");
$base = 24*60*60 if($period eq "day"); $base = 24*60*60 if($period eq "day");
my @stats = $c->model('DB::Builds')->search($filter, {select => [{ count => "*" }], as => ["nr"], group_by => ["timestamp - timestamp % $base"], order_by => "timestamp - timestamp % $base DESC", rows => $nr}); my @stats = $c->model('DB::Builds')->search($filter, {select => [{ count => "*" }], as => ["nr"], group_by => ["timestamp - timestamp % $base"], order_by => "timestamp - timestamp % $base DESC", rows => $nr});
my @arr; my @arr;
push @arr, int($_->get_column("nr")) foreach @stats; push @arr, int($_->get_column("nr")) foreach @stats;
@arr = reverse(@arr); @arr = reverse(@arr);
$c->stash->{'plain'} = { $c->stash->{'plain'} = {
data => scalar (JSON::Any->objToJson(\@arr)) data => scalar (JSON::Any->objToJson(\@arr))
}; };
$c->forward('Hydra::View::Plain'); $c->forward('Hydra::View::Plain');
} }

View file

@ -101,7 +101,7 @@ sub create_user : Chained('admin') PathPart('create-user') Args(0) {
$c->stash->{template} = 'user.tt'; $c->stash->{template} = 'user.tt';
$c->stash->{edit} = 1; $c->stash->{edit} = 1;
$c->stash->{create} = 1; $c->stash->{create} = 1;
} }
sub create_user_submit : Chained('admin') PathPart('create-user/submit') Args(0) { sub create_user_submit : Chained('admin') PathPart('create-user/submit') Args(0) {
@ -160,7 +160,7 @@ sub user_edit_submit : Chained('user') PathPart('submit') Args(0) {
updateUser($c, $c->stash->{user}); updateUser($c, $c->stash->{user});
} }
}); });
$c->res->redirect("/admin/users"); $c->res->redirect("/admin/users");
} }
@ -252,9 +252,9 @@ sub machine_edit_submit : Chained('machine') PathPart('submit') Args(0) {
updateMachine($c, $c->stash->{machine}); updateMachine($c, $c->stash->{machine});
} }
}); });
saveNixMachines($c); saveNixMachines($c);
$c->res->redirect("/admin/machines"); $c->res->redirect("/admin/machines");
} }

View file

@ -27,18 +27,18 @@ sub overview : Chained('job') PathPart('') Args(0) {
$c->stash->{currentBuilds} = [$c->stash->{job}->builds->search({finished => 1, iscurrent => 1}, { order_by => 'system' })]; $c->stash->{currentBuilds} = [$c->stash->{job}->builds->search({finished => 1, iscurrent => 1}, { order_by => 'system' })];
$c->stash->{lastBuilds} = $c->stash->{lastBuilds} =
[ $c->stash->{job}->builds->search({ finished => 1 }, [ $c->stash->{job}->builds->search({ finished => 1 },
{ order_by => 'timestamp DESC', rows => 10, columns => [@buildListColumns] }) ]; { order_by => 'timestamp DESC', rows => 10, columns => [@buildListColumns] }) ];
$c->stash->{runningBuilds} = [ $c->stash->{runningBuilds} = [
$c->stash->{job}->builds->search( $c->stash->{job}->builds->search(
{ busy => 1 }, { busy => 1 },
{ join => ['project'] { join => ['project']
, order_by => ["priority DESC", "timestamp"] , order_by => ["priority DESC", "timestamp"]
, '+select' => ['project.enabled'] , '+select' => ['project.enabled']
, '+as' => ['enabled'] , '+as' => ['enabled']
} }
) ]; ) ];
$c->stash->{systems} = [$c->stash->{job}->builds->search({iscurrent => 1}, {select => ["system"], distinct => 1})]; $c->stash->{systems} = [$c->stash->{job}->builds->search({iscurrent => 1}, {select => ["system"], distinct => 1})];

View file

@ -51,7 +51,7 @@ sub jobsetIndex {
$c->stash->{evals} = getEvals($self, $c, 0, 5); $c->stash->{evals} = getEvals($self, $c, 0, 5);
$c->stash->{systems} = $c->stash->{systems} =
[ $c->stash->{jobset}->builds->search({ iscurrent => 1 }, { select => ["system"], distinct => 1, order_by => "system" }) ]; [ $c->stash->{jobset}->builds->search({ iscurrent => 1 }, { select => ["system"], distinct => 1, order_by => "system" }) ];
# status per system # status per system
@ -332,9 +332,9 @@ sub clone_submit : Chained('jobset') PathPart('clone/submit') Args(0) {
sub getEvals { sub getEvals {
my ($self, $c, $offset, $rows) = @_; my ($self, $c, $offset, $rows) = @_;
my @evals = $c->stash->{jobset}->jobsetevals->search( my @evals = $c->stash->{jobset}->jobsetevals->search(
{ hasnewbuilds => 1 }, { hasnewbuilds => 1 },
{ order_by => "id DESC", rows => $rows + 1, offset => $offset }); { order_by => "id DESC", rows => $rows + 1, offset => $offset });
my @res = (); my @res = ();
@ -366,12 +366,12 @@ sub getEvals {
foreach my $input (@{$curInputs}) { foreach my $input (@{$curInputs}) {
my $p = $prevInputsHash{$input->name}; my $p = $prevInputsHash{$input->name};
push @changedInputs, $input push @changedInputs, $input
if !defined $p || ($input->revision || "") ne ($p->revision || "") || $input->type ne $p->type || ($input->uri || "") ne ($p->uri || "") || if !defined $p || ($input->revision || "") ne ($p->revision || "") || $input->type ne $p->type || ($input->uri || "") ne ($p->uri || "") ||
( defined $input->dependency && defined $p->dependency && $input->dependency->id ne $p->dependency->id); ( defined $input->dependency && defined $p->dependency && $input->dependency->id ne $p->dependency->id);
} }
$prevInputs = $curInputs; $prevInputs = $curInputs;
my $e = my $e =
{ eval => $cur { eval => $cur
, nrScheduled => $nrScheduled , nrScheduled => $nrScheduled
, nrSucceeded => $nrSucceeded , nrSucceeded => $nrSucceeded
@ -382,7 +382,7 @@ sub getEvals {
push @res, $e if $n < $rows; push @res, $e if $n < $rows;
$prev = $e; $prev = $e;
} }
return [reverse @res]; return [reverse @res];
} }

View file

@ -9,7 +9,7 @@ use Hydra::Helper::CatalystUtils;
sub eval : Chained('/') PathPart('eval') CaptureArgs(1) { sub eval : Chained('/') PathPart('eval') CaptureArgs(1) {
my ($self, $c, $evalId) = @_; my ($self, $c, $evalId) = @_;
my $eval = $c->model('DB::JobsetEvals')->find($evalId) my $eval = $c->model('DB::JobsetEvals')->find($evalId)
or notFound($c, "Evaluation $evalId doesn't exist."); or notFound($c, "Evaluation $evalId doesn't exist.");
@ -50,7 +50,7 @@ sub view : Chained('eval') PathPart('') Args(0) {
} }
$c->stash->{otherEval} = $eval2 if defined $eval2; $c->stash->{otherEval} = $eval2 if defined $eval2;
my @builds = $eval->builds->search({}, { order_by => ["job", "system", "id"], columns => [@buildListColumns] }); my @builds = $eval->builds->search({}, { order_by => ["job", "system", "id"], columns => [@buildListColumns] });
my @builds2 = defined $eval2 my @builds2 = defined $eval2
? $eval2->builds->search({}, { order_by => ["job", "system", "id"], columns => [@buildListColumns] }) ? $eval2->builds->search({}, { order_by => ["job", "system", "id"], columns => [@buildListColumns] })
@ -94,7 +94,7 @@ sub view : Chained('eval') PathPart('') Args(0) {
} }
push @{$c->stash->{new}}, $build if !$found; push @{$c->stash->{new}}, $build if !$found;
} }
$c->stash->{full} = ($c->req->params->{full} || "0") eq "1"; $c->stash->{full} = ($c->req->params->{full} || "0") eq "1";
} }
@ -104,7 +104,7 @@ sub release : Chained('eval') PathPart('release') Args(0) {
my $eval = $c->stash->{eval}; my $eval = $c->stash->{eval};
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
my @builds = $eval->builds; my @builds = $eval->builds;
my $releaseName; my $releaseName;

View file

@ -9,7 +9,7 @@ use Hydra::Helper::CatalystUtils;
sub project : Chained('/') PathPart('project') CaptureArgs(1) { sub project : Chained('/') PathPart('project') CaptureArgs(1) {
my ($self, $c, $projectName) = @_; my ($self, $c, $projectName) = @_;
my $project = $c->model('DB::Projects')->find($projectName) my $project = $c->model('DB::Projects')->find($projectName)
or notFound($c, "Project $projectName doesn't exist."); or notFound($c, "Project $projectName doesn't exist.");
@ -44,7 +44,7 @@ sub submit : Chained('project') PathPart Args(0) {
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
requirePost($c); requirePost($c);
if (($c->request->params->{submit} || "") eq "delete") { if (($c->request->params->{submit} || "") eq "delete") {
$c->stash->{project}->delete; $c->stash->{project}->delete;
$c->res->redirect($c->uri_for("/")); $c->res->redirect($c->uri_for("/"));
@ -53,7 +53,7 @@ sub submit : Chained('project') PathPart Args(0) {
txn_do($c->model('DB')->schema, sub { txn_do($c->model('DB')->schema, sub {
updateProject($c, $c->stash->{project}); updateProject($c, $c->stash->{project});
}); });
$c->res->redirect($c->uri_for($self->action_for("view"), [$c->stash->{project}->name])); $c->res->redirect($c->uri_for($self->action_for("view"), [$c->stash->{project}->name]));
} }
@ -62,11 +62,11 @@ sub hide : Chained('project') PathPart Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
txn_do($c->model('DB')->schema, sub { txn_do($c->model('DB')->schema, sub {
$c->stash->{project}->update({ hidden => 1, enabled => 0 }); $c->stash->{project}->update({ hidden => 1, enabled => 0 });
}); });
$c->res->redirect($c->uri_for("/")); $c->res->redirect($c->uri_for("/"));
} }
@ -75,18 +75,18 @@ sub unhide : Chained('project') PathPart Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
txn_do($c->model('DB')->schema, sub { txn_do($c->model('DB')->schema, sub {
$c->stash->{project}->update({ hidden => 0 }); $c->stash->{project}->update({ hidden => 0 });
}); });
$c->res->redirect($c->uri_for("/")); $c->res->redirect($c->uri_for("/"));
} }
sub requireMayCreateProjects { sub requireMayCreateProjects {
my ($c) = @_; my ($c) = @_;
requireLogin($c) if !$c->user_exists; requireLogin($c) if !$c->user_exists;
error($c, "Only administrators or authorised users can perform this operation.") error($c, "Only administrators or authorised users can perform this operation.")
@ -111,7 +111,7 @@ sub create_submit : Path('/create-project/submit') {
requireMayCreateProjects($c); requireMayCreateProjects($c);
my $projectName = trim $c->request->params->{name}; my $projectName = trim $c->request->params->{name};
error($c, "Invalid project name: $projectName") if $projectName !~ /^$projectNameRE$/; error($c, "Invalid project name: $projectName") if $projectName !~ /^$projectNameRE$/;
txn_do($c->model('DB')->schema, sub { txn_do($c->model('DB')->schema, sub {
@ -124,7 +124,7 @@ sub create_submit : Path('/create-project/submit') {
{name => $projectName, displayname => "", owner => $owner}); {name => $projectName, displayname => "", owner => $owner});
updateProject($c, $project); updateProject($c, $project);
}); });
$c->res->redirect($c->uri_for($self->action_for("view"), [$projectName])); $c->res->redirect($c->uri_for($self->action_for("view"), [$projectName]));
} }
@ -133,7 +133,7 @@ sub create_jobset : Chained('project') PathPart('create-jobset') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
$c->stash->{template} = 'jobset.tt'; $c->stash->{template} = 'jobset.tt';
$c->stash->{create} = 1; $c->stash->{create} = 1;
$c->stash->{edit} = 1; $c->stash->{edit} = 1;
@ -144,7 +144,7 @@ sub create_jobset_submit : Chained('project') PathPart('create-jobset/submit') A
my ($self, $c) = @_; my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
my $jobsetName = trim $c->request->params->{name}; my $jobsetName = trim $c->request->params->{name};
my $exprType = my $exprType =
$c->request->params->{"nixexprpath"} =~ /.scm$/ ? "guile" : "nix"; $c->request->params->{"nixexprpath"} =~ /.scm$/ ? "guile" : "nix";
@ -158,7 +158,7 @@ sub create_jobset_submit : Chained('project') PathPart('create-jobset/submit') A
{name => $jobsetName, nixexprinput => "", nixexprpath => "", emailoverride => ""}); {name => $jobsetName, nixexprinput => "", nixexprpath => "", emailoverride => ""});
Hydra::Controller::Jobset::updateJobset($c, $jobset); Hydra::Controller::Jobset::updateJobset($c, $jobset);
}); });
$c->res->redirect($c->uri_for($c->controller('Jobset')->action_for("index"), $c->res->redirect($c->uri_for($c->controller('Jobset')->action_for("index"),
[$c->stash->{project}->name, $jobsetName])); [$c->stash->{project}->name, $jobsetName]));
} }
@ -166,7 +166,7 @@ sub create_jobset_submit : Chained('project') PathPart('create-jobset/submit') A
sub updateProject { sub updateProject {
my ($c, $project) = @_; my ($c, $project) = @_;
my $owner = $project->owner; my $owner = $project->owner;
if ($c->check_user_roles('admin')) { if ($c->check_user_roles('admin')) {
$owner = trim $c->request->params->{owner}; $owner = trim $c->request->params->{owner};
@ -176,7 +176,7 @@ sub updateProject {
my $projectName = trim $c->request->params->{name}; my $projectName = trim $c->request->params->{name};
error($c, "Invalid project name: $projectName") if $projectName !~ /^$projectNameRE$/; error($c, "Invalid project name: $projectName") if $projectName !~ /^$projectNameRE$/;
my $displayName = trim $c->request->params->{displayname}; my $displayName = trim $c->request->params->{displayname};
error($c, "Invalid display name: $displayName") if $displayName eq ""; error($c, "Invalid display name: $displayName") if $displayName eq "";
@ -209,7 +209,7 @@ sub create_view_submit : Chained('project') PathPart('create-view/submit') Args(
my ($self, $c) = @_; my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
my $viewName = $c->request->params->{name}; my $viewName = $c->request->params->{name};
my $view; my $view;
@ -253,7 +253,7 @@ sub create_release : Chained('project') PathPart('create-release') Args(0) {
sub create_release_submit : Chained('project') PathPart('create-release/submit') Args(0) { sub create_release_submit : Chained('project') PathPart('create-release/submit') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
my $releaseName = $c->request->params->{name}; my $releaseName = $c->request->params->{name};

View file

@ -28,11 +28,11 @@ sub view : Chained('release') PathPart('') Args(0) {
sub updateRelease { sub updateRelease {
my ($c, $release) = @_; my ($c, $release) = @_;
my $releaseName = trim $c->request->params->{name}; my $releaseName = trim $c->request->params->{name};
error($c, "Invalid release name: $releaseName") error($c, "Invalid release name: $releaseName")
unless $releaseName =~ /^$relNameRE$/; unless $releaseName =~ /^$relNameRE$/;
$release->update( $release->update(
{ name => $releaseName { name => $releaseName
, description => trim $c->request->params->{description} , description => trim $c->request->params->{description}
@ -59,7 +59,7 @@ sub edit : Chained('release') PathPart('edit') Args(0) {
sub submit : Chained('release') PathPart('submit') Args(0) { sub submit : Chained('release') PathPart('submit') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
if (($c->request->params->{action} || "") eq "delete") { if (($c->request->params->{action} || "") eq "delete") {

View file

@ -87,7 +87,7 @@ sub timeline :Local {
$c->stash->{template} = 'timeline.tt'; $c->stash->{template} = 'timeline.tt';
$c->stash->{builds} = [ $c->model('DB::Builds')->search $c->stash->{builds} = [ $c->model('DB::Builds')->search
( { finished => 1, stoptime => { '>' => $pit } } ( { finished => 1, stoptime => { '>' => $pit } }
, { order_by => ["starttime"] } , { order_by => ["starttime"] }
) ]; ) ];
} }
@ -199,7 +199,7 @@ sub nar :Local :Args(1) {
sub nix_cache_info :Path('nix-cache-info') :Args(0) { sub nix_cache_info :Path('nix-cache-info') :Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
$c->response->content_type('text/plain'); $c->response->content_type('text/plain');
$c->stash->{'plain'} = { data => $c->stash->{'plain'} = { data =>
#"StoreDir: $Nix::Config::storeDir\n" . # FIXME #"StoreDir: $Nix::Config::storeDir\n" . # FIXME
"StoreDir: /nix/store\n" . "StoreDir: /nix/store\n" .
"WantMassQuery: 0\n" . "WantMassQuery: 0\n" .

View file

@ -9,7 +9,7 @@ use Hydra::Helper::CatalystUtils;
sub getView { sub getView {
my ($c, $projectName, $viewName) = @_; my ($c, $projectName, $viewName) = @_;
my $project = $c->model('DB::Projects')->find($projectName); my $project = $c->model('DB::Projects')->find($projectName);
notFound($c, "Project $projectName doesn't exist.") if !defined $project; notFound($c, "Project $projectName doesn't exist.") if !defined $project;
$c->stash->{project} = $project; $c->stash->{project} = $project;
@ -32,11 +32,11 @@ sub getView {
sub updateView { sub updateView {
my ($c, $view) = @_; my ($c, $view) = @_;
my $viewName = trim $c->request->params->{name}; my $viewName = trim $c->request->params->{name};
error($c, "Invalid view name: $viewName") error($c, "Invalid view name: $viewName")
unless $viewName =~ /^[[:alpha:]][\w\-]*$/; unless $viewName =~ /^[[:alpha:]][\w\-]*$/;
$view->update( $view->update(
{ name => $viewName { name => $viewName
, description => trim $c->request->params->{description} }); , description => trim $c->request->params->{description} });
@ -61,7 +61,7 @@ sub updateView {
# !!! We could check whether the job exists, but that would # !!! We could check whether the job exists, but that would
# require the evaluator to have seen the job, which may not be # require the evaluator to have seen the job, which may not be
# the case. # the case.
$view->viewjobs->create( $view->viewjobs->create(
{ jobset => $jobsetName { jobset => $jobsetName
, job => $jobName , job => $jobName
@ -112,7 +112,7 @@ sub edit : Chained('view') PathPart('edit') Args(0) {
$c->stash->{template} = 'edit-view.tt'; $c->stash->{template} = 'edit-view.tt';
} }
sub submit : Chained('view') PathPart('submit') Args(0) { sub submit : Chained('view') PathPart('submit') Args(0) {
my ($self, $c) = @_; my ($self, $c) = @_;
requireProjectOwner($c, $c->stash->{project}); requireProjectOwner($c, $c->stash->{project});
@ -127,10 +127,10 @@ sub submit : Chained('view') PathPart('submit') Args(0) {
$c->res->redirect($c->uri_for($self->action_for("view_view"), $c->req->captures)); $c->res->redirect($c->uri_for($self->action_for("view_view"), $c->req->captures));
} }
sub latest : Chained('view') PathPart('latest') { sub latest : Chained('view') PathPart('latest') {
my ($self, $c, @args) = @_; my ($self, $c, @args) = @_;
# Redirect to the latest result in the view in which every build # Redirect to the latest result in the view in which every build
# is successful. # is successful.
my $latest = getLatestSuccessfulViewResult( my $latest = getLatestSuccessfulViewResult(
@ -142,7 +142,7 @@ sub latest : Chained('view') PathPart('latest') {
sub latest_finished : Chained('view') PathPart('latest-finished') { sub latest_finished : Chained('view') PathPart('latest-finished') {
my ($self, $c, @args) = @_; my ($self, $c, @args) = @_;
# Redirect to the latest result in the view in which every build # Redirect to the latest result in the view in which every build
# is successful *and* where the jobset evaluation has finished # is successful *and* where the jobset evaluation has finished
# completely. # completely.
@ -155,7 +155,7 @@ sub latest_finished : Chained('view') PathPart('latest-finished') {
sub result : Chained('view') PathPart('') { sub result : Chained('view') PathPart('') {
my ($self, $c, $id, @args) = @_; my ($self, $c, $id, @args) = @_;
$c->stash->{template} = 'view-result.tt'; $c->stash->{template} = 'view-result.tt';
# Note: we don't actually check whether $id is a primary build, # Note: we don't actually check whether $id is a primary build,
@ -206,9 +206,9 @@ sub result : Chained('view') PathPart('') {
$c->res->redirect($c->uri_for($c->controller('JobsetEval')->action_for("view"), $c->res->redirect($c->uri_for($c->controller('JobsetEval')->action_for("view"),
[$eval->id], @args[1..$#args], $c->req->params)); [$eval->id], @args[1..$#args], $c->req->params));
} }
# Provide a redirect to the specified job of this view result # Provide a redirect to the specified job of this view result
# through `http://.../view/$project/$viewName/$viewResult/$jobName'. # through `http://.../view/$project/$viewName/$viewResult/$jobName'.
# Optionally, you can append `-$system' to the $jobName to get a # Optionally, you can append `-$system' to the $jobName to get a
# build for a specific platform. # build for a specific platform.
elsif (scalar @args != 0) { elsif (scalar @args != 0) {

View file

@ -39,9 +39,9 @@ sub getPreviousBuild {
, project => $build->project->name , project => $build->project->name
, jobset => $build->jobset->name , jobset => $build->jobset->name
, job => $build->job->name , job => $build->job->name
, 'me.id' => { '<' => $build->id } , 'me.id' => { '<' => $build->id }
}, {rows => 1, order_by => "me.id DESC"}); }, {rows => 1, order_by => "me.id DESC"});
return $prevBuild; return $prevBuild;
} }
@ -56,9 +56,9 @@ sub getNextBuild {
, project => $build->project->name , project => $build->project->name
, jobset => $build->jobset->name , jobset => $build->jobset->name
, job => $build->job->name , job => $build->job->name
, 'me.id' => { '>' => $build->id } , 'me.id' => { '>' => $build->id }
}, {rows => 1, order_by => "me.id ASC"}); }, {rows => 1, order_by => "me.id ASC"});
return $nextBuild; return $nextBuild;
} }
@ -74,27 +74,27 @@ sub getPreviousSuccessfulBuild {
, jobset => $build->jobset->name , jobset => $build->jobset->name
, job => $build->job->name , job => $build->job->name
, buildstatus => 0 , buildstatus => 0
, 'me.id' => { '<' => $build->id } , 'me.id' => { '<' => $build->id }
}, {rows => 1, order_by => "me.id DESC"}); }, {rows => 1, order_by => "me.id DESC"});
return $prevBuild; return $prevBuild;
} }
sub getBuildStats { sub getBuildStats {
my ($c, $builds) = @_; my ($c, $builds) = @_;
$c->stash->{finishedBuilds} = $builds->search({finished => 1}) || 0; $c->stash->{finishedBuilds} = $builds->search({finished => 1}) || 0;
$c->stash->{succeededBuilds} = $builds->search({finished => 1, buildStatus => 0}) || 0; $c->stash->{succeededBuilds} = $builds->search({finished => 1, buildStatus => 0}) || 0;
$c->stash->{scheduledBuilds} = $builds->search({finished => 0}) || 0; $c->stash->{scheduledBuilds} = $builds->search({finished => 0}) || 0;
$c->stash->{busyBuilds} = $builds->search({finished => 0, busy => 1}) || 0; $c->stash->{busyBuilds} = $builds->search({finished => 0, busy => 1}) || 0;
my $res; my $res;
$res = $builds->search({}, {select => {sum => 'stoptime - starttime'}, as => ['sum']})->first; $res = $builds->search({}, {select => {sum => 'stoptime - starttime'}, as => ['sum']})->first;
$c->stash->{totalBuildTime} = defined ($res) ? $res->get_column('sum') : 0 ; $c->stash->{totalBuildTime} = defined ($res) ? $res->get_column('sum') : 0 ;
} }
@ -131,7 +131,7 @@ sub isProjectOwner {
sub requireProjectOwner { sub requireProjectOwner {
my ($c, $project) = @_; my ($c, $project) = @_;
requireLogin($c) if !$c->user_exists; requireLogin($c) if !$c->user_exists;
error($c, "Only the project members or administrators can perform this operation.") error($c, "Only the project members or administrators can perform this operation.")
@ -150,7 +150,7 @@ sub requireAdmin {
my ($c) = @_; my ($c) = @_;
requireLogin($c) if !$c->user_exists; requireLogin($c) if !$c->user_exists;
error($c, "Only administrators can perform this operation.") error($c, "Only administrators can perform this operation.")
unless isAdmin($c); unless isAdmin($c);
} }

View file

@ -464,7 +464,7 @@ __PACKAGE__->has_many(
__PACKAGE__->has_one( __PACKAGE__->has_one(
"actualBuildStep", "actualBuildStep",
"Hydra::Schema::BuildSteps", "Hydra::Schema::BuildSteps",
{ 'foreign.outpath' => 'self.outpath' { 'foreign.outpath' => 'self.outpath'
, 'foreign.build' => 'self.id' , 'foreign.build' => 'self.id'
}, },
); );
@ -480,7 +480,7 @@ sub makeSource {
sub makeQueries { sub makeQueries {
my ($name, $constraint) = @_; my ($name, $constraint) = @_;
my $activeJobs = "(select distinct project, jobset, job, system from Builds where isCurrent = 1 $constraint)"; my $activeJobs = "(select distinct project, jobset, job, system from Builds where isCurrent = 1 $constraint)";
makeSource( makeSource(
@ -489,11 +489,11 @@ sub makeQueries {
<<QUERY <<QUERY
select x.*, b.id as statusChangeId, b.timestamp as statusChangeTime select x.*, b.id as statusChangeId, b.timestamp as statusChangeTime
from from
(select (select
(select max(b.id) from Builds b (select max(b.id) from Builds b
where where
project = activeJobs.project and jobset = activeJobs.jobset project = activeJobs.project and jobset = activeJobs.jobset
and job = activeJobs.job and system = activeJobs.system and job = activeJobs.job and system = activeJobs.system
and finished = 1 and finished = 1
) as id ) as id
from $activeJobs as activeJobs from $activeJobs as activeJobs
@ -512,17 +512,17 @@ QUERY
); );
makeSource("ActiveJobs$name", "(select distinct project, jobset, job from Builds where isCurrent = 1 $constraint)"); makeSource("ActiveJobs$name", "(select distinct project, jobset, job from Builds where isCurrent = 1 $constraint)");
makeSource( makeSource(
"LatestSucceeded$name", "LatestSucceeded$name",
<<QUERY <<QUERY
select * select *
from from
(select (select
(select max(b.id) from builds b (select max(b.id) from builds b
where where
project = activeJobs.project and jobset = activeJobs.jobset project = activeJobs.project and jobset = activeJobs.jobset
and job = activeJobs.job and system = activeJobs.system and job = activeJobs.job and system = activeJobs.system
and finished = 1 and buildstatus = 0 and finished = 1 and buildstatus = 0
) as id ) as id
from $activeJobs as activeJobs from $activeJobs as activeJobs

View file

@ -276,7 +276,7 @@ __PACKAGE__->has_many(
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:vHluB+s1FkpJBPWmpv+wUQ # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:vHluB+s1FkpJBPWmpv+wUQ
1; 1;
# End of lines loaded from '/home/rbvermaa/src/hydra/src/lib/Hydra/Schema/Users.pm' # End of lines loaded from '/home/rbvermaa/src/hydra/src/lib/Hydra/Schema/Users.pm'
# These lines were loaded from '/home/rbvermaa/src/hydra/src/lib/Hydra/Schema/Users.pm' found in @INC. # These lines were loaded from '/home/rbvermaa/src/hydra/src/lib/Hydra/Schema/Users.pm' found in @INC.
# They are now part of the custom portion of this file # They are now part of the custom portion of this file
# for you to hand-edit. If you do not either delete # for you to hand-edit. If you do not either delete

View file

@ -9,7 +9,7 @@ sub process {
my ($self, $c) = @_; my ($self, $c) = @_;
my $storePath = $c->stash->{storePath}; my $storePath = $c->stash->{storePath};
$c->response->content_type('text/x-nix-narinfo'); # !!! check MIME type $c->response->content_type('text/x-nix-narinfo'); # !!! check MIME type
my ($deriver, $narHash, $time, $narSize, $refs) = queryPathInfo($storePath, 1); my ($deriver, $narHash, $time, $narSize, $refs) = queryPathInfo($storePath, 1);

View file

@ -6,17 +6,17 @@ use IO::Pipe;
sub process { sub process {
my ($self, $c) = @_; my ($self, $c) = @_;
$c->response->content_type('application/x-nix-export'); $c->response->content_type('application/x-nix-export');
my @storePaths = @{$c->stash->{storePaths}}; my @storePaths = @{$c->stash->{storePaths}};
my $fh = new IO::Handle; my $fh = new IO::Handle;
open $fh, "nix-store --export `nix-store -qR @storePaths` | gzip |"; open $fh, "nix-store --export `nix-store -qR @storePaths` | gzip |";
$c->response->body($fh); $c->response->body($fh);
return 1; return 1;
} }

View file

@ -10,7 +10,7 @@ sub process {
my ($self, $c) = @_; my ($self, $c) = @_;
my @storePaths = @{$c->stash->{storePaths}}; my @storePaths = @{$c->stash->{storePaths}};
$c->response->content_type('text/x-nix-manifest'); $c->response->content_type('text/x-nix-manifest');
my @paths = computeFSClosure(0, 1, @storePaths); my @paths = computeFSClosure(0, 1, @storePaths);
@ -19,7 +19,7 @@ sub process {
"version {\n" . "version {\n" .
" ManifestVersion: 4\n" . " ManifestVersion: 4\n" .
"}\n"; "}\n";
foreach my $path (@paths) { foreach my $path (@paths) {
my ($deriver, $hash, $time, $narSize, $refs) = queryPathInfo($path, 0); my ($deriver, $hash, $time, $narSize, $refs) = queryPathInfo($path, 0);
@ -30,7 +30,7 @@ sub process {
$escaped =~ s/\+/%2b/g; $escaped =~ s/\+/%2b/g;
$escaped =~ s/\=/%3d/g; $escaped =~ s/\=/%3d/g;
$escaped =~ s/\?/%3f/g; $escaped =~ s/\?/%3f/g;
my $url = $c->stash->{narBase} . "/" . $escaped; my $url = $c->stash->{narBase} . "/" . $escaped;
my $system = $c->stash->{systemForPath}->{$path}; my $system = $c->stash->{systemForPath}->{$path};

View file

@ -7,11 +7,11 @@ sub process {
my ($self, $c) = @_; my ($self, $c) = @_;
my $storePath = $c->stash->{storePath}; my $storePath = $c->stash->{storePath};
$c->response->content_type('application/x-nix-archive'); # !!! check MIME type $c->response->content_type('application/x-nix-archive'); # !!! check MIME type
my $fh = new IO::Handle; my $fh = new IO::Handle;
open $fh, "nix-store --dump '$storePath' | bzip2 |"; open $fh, "nix-store --dump '$storePath' | bzip2 |";
$c->response->body($fh); $c->response->body($fh);

View file

@ -14,7 +14,7 @@ sub process {
. " " . $build->nixname . " " . $build->system . " " . $build->nixname . " " . $build->system
. " " . $build->drvpath . " " . $build->outpath . " " . $build->drvpath . " " . $build->outpath
. " " . $c->uri_for('/'); . " " . $c->uri_for('/');
$c->response->body($s); $c->response->body($s);
return 1; return 1;

View file

@ -9,57 +9,57 @@
[% job = build.job %] [% job = build.job %]
[% BLOCK renderBuildSteps %] [% BLOCK renderBuildSteps %]
<table class="tablesorter table table-striped table-condensed"> <table class="tablesorter table table-striped table-condensed">
<thead> <thead>
<tr><th>Nr</th><th>What</th><th>Duration</th><th>Machine</th><th>Status</th></tr> <tr><th>Nr</th><th>What</th><th>Duration</th><th>Machine</th><th>Status</th></tr>
</thead> </thead>
<tbody> <tbody>
[% FOREACH step IN build.buildsteps -%] [% FOREACH step IN build.buildsteps -%]
[% IF ( type == "All" ) || ( type == "Failed" && step.status != 0 ) || ( type == "Running" && step.busy == 1 ) -%] [% IF ( type == "All" ) || ( type == "Failed" && step.status != 0 ) || ( type == "Running" && step.busy == 1 ) -%]
[% log = c.uri_for('/build' build.id 'nixlog' step.stepnr) %] [% log = c.uri_for('/build' build.id 'nixlog' step.stepnr) %]
<tr class="[% IF step.logfile %]clickable[% END %]" <tr class="[% IF step.logfile %]clickable[% END %]"
[% IF step.logfile %] onclick="window.location = '[% log %]'" [% END %]> [% IF step.logfile %] onclick="window.location = '[% log %]'" [% END %]>
<td>[% step.stepnr %]</td> <td>[% step.stepnr %]</td>
<td> <td>
[% IF step.type == 0 %] [% IF step.type == 0 %]
Build of <tt>[% step.outpath %]</tt> Build of <tt>[% step.outpath %]</tt>
[% ELSE %] [% ELSE %]
Substitution of <tt>[% step.outpath %]</tt> Substitution of <tt>[% step.outpath %]</tt>
[% END %] [% END %]
</td> </td>
<td> <td>
[% IF step.busy == 0 %] [% IF step.busy == 0 %]
[% INCLUDE renderDuration duration = step.stoptime - step.starttime %] [% INCLUDE renderDuration duration = step.stoptime - step.starttime %]
[% ELSE %] [% ELSE %]
[% IF build.finished %] [% IF build.finished %]
[% INCLUDE renderDuration duration = build.stoptime - step.starttime %] [% INCLUDE renderDuration duration = build.stoptime - step.starttime %]
[% ELSE %] [% ELSE %]
[% INCLUDE renderDuration duration = curTime - step.starttime %] [% INCLUDE renderDuration duration = curTime - step.starttime %]
[% END %] [% END %]
[% END %] [% END %]
</td> </td>
<td>[% step.machine.split('@').1 %]</td> <td>[% step.machine.split('@').1 %]</td>
<td> <td>
[% IF step.busy == 1 %] [% IF step.busy == 1 %]
[% IF build.finished %] [% IF build.finished %]
<span class="error">Aborted</span> <span class="error">Aborted</span>
[% ELSE %] [% ELSE %]
<strong>Building</strong> <strong>Building</strong>
[% END %] [% END %]
[% ELSIF step.status == 0 %] [% ELSIF step.status == 0 %]
Succeeded Succeeded
[% ELSE %] [% ELSE %]
<span class="error">Failed: [% HTML.escape(step.errormsg) %]</span> <span class="error">Failed: [% HTML.escape(step.errormsg) %]</span>
[% END %] [% END %]
[% IF step.logfile %] [% IF step.logfile %]
(<a href="[% log %]">log</a>, <a href="[% "$log/raw" %]">raw</a>, <a href="[% "$log/tail-reload" %]">tail</a>) (<a href="[% log %]">log</a>, <a href="[% "$log/raw" %]">raw</a>, <a href="[% "$log/tail-reload" %]">tail</a>)
[% END %] [% END %]
</td> </td>
</tr> </tr>
[% END %] [% END %]
[% END %] [% END %]
</tbody> </tbody>
</table> </table>
[% END %] [% END %]
@ -68,79 +68,79 @@
<p class="btn-info btn-large">[% flashMsg %]</p> <p class="btn-info btn-large">[% flashMsg %]</p>
[% END %] [% END %]
<ul id="tab" class="nav nav-tabs"> <ul id="tab" class="nav nav-tabs">
<li><a href="#tabs-summary" data-toggle="tab">Summary</a></li> <li><a href="#tabs-summary" data-toggle="tab">Summary</a></li>
<li><a href="#tabs-information" data-toggle="tab">Information</a></li> <li><a href="#tabs-information" data-toggle="tab">Information</a></li>
<li><a href="#tabs-buildinputs" data-toggle="tab">Build inputs</a></li> <li><a href="#tabs-buildinputs" data-toggle="tab">Build inputs</a></li>
[% IF relatedbuilds %]<li><a href="#tabs-relatedbuilds" data-toggle="tab">Related builds</a></li>[% END %] [% IF relatedbuilds %]<li><a href="#tabs-relatedbuilds" data-toggle="tab">Related builds</a></li>[% END %]
[% IF build.buildsteps %]<li><a href="#tabs-buildsteps" data-toggle="tab">Build steps</a></li>[% END %] [% IF build.buildsteps %]<li><a href="#tabs-buildsteps" data-toggle="tab">Build steps</a></li>[% END %]
[% IF build.dependents %]<li><a href="#tabs-usedby" data-toggle="tab">Used by</a></li>[% END%] [% IF build.dependents %]<li><a href="#tabs-usedby" data-toggle="tab">Used by</a></li>[% END%]
[% IF prevBuilds %]<li><a href="#tabs-history" data-toggle="tab">History chart</a></li>[% END %] [% IF prevBuilds %]<li><a href="#tabs-history" data-toggle="tab">History chart</a></li>[% END %]
</ul> </ul>
<div id="generic-tabs" class="tab-content"> <div id="generic-tabs" class="tab-content">
<div id="tabs-summary" class="tab-pane active"> <div id="tabs-summary" class="tab-pane active">
<table class="layoutTable"> <table class="layoutTable">
<tr> <tr>
<td> <td>
[% INCLUDE renderBuildStatusIcon size=128, build=build %] [% INCLUDE renderBuildStatusIcon size=128, build=build %]
</td> </td>
<td> <td>
<table class="layoutTable"> <table class="layoutTable">
<tr> <tr>
<th>Build ID:</th> <th>Build ID:</th>
<td>[% build.id %]</td> <td>[% build.id %]</td>
</tr> </tr>
[% IF build.releasename %] [% IF build.releasename %]
<tr> <tr>
<th>Release name:</th> <th>Release name:</th>
<td><tt>[% HTML.escape(build.releasename) %]</tt></td> <td><tt>[% HTML.escape(build.releasename) %]</tt></td>
</tr> </tr>
[% ELSE %] [% ELSE %]
<tr> <tr>
<th>Nix name:</th> <th>Nix name:</th>
<td><tt>[% build.nixname %]</tt></td> <td><tt>[% build.nixname %]</tt></td>
</tr> </tr>
[% END %] [% END %]
<tr> <tr>
<th>Status:</th> <th>Status:</th>
<td> <td>
[% INCLUDE renderStatus build=build %] [% INCLUDE renderStatus build=build %]
</td> </td>
</tr> </tr>
<tr> <tr>
<th>System:</th> <th>System:</th>
<td><tt>[% build.system %]</tt></td> <td><tt>[% build.system %]</tt></td>
</tr> </tr>
[% IF build.finished %] [% IF build.finished %]
<tr> <tr>
<th>Duration:</th> <th>Duration:</th>
<td> <td>
[% IF build.iscachedbuild %] [% IF build.iscachedbuild %]
(cached[% IF cachedBuild %] from [% INCLUDE renderFullBuildLink build=cachedBuild %][% END %]) (cached[% IF cachedBuild %] from [% INCLUDE renderFullBuildLink build=cachedBuild %][% END %])
[% ELSE %] [% ELSE %]
[% INCLUDE renderDuration duration = build.stoptime - build.starttime %] finished at [% INCLUDE renderDateTime timestamp = build.stoptime %] [% INCLUDE renderDuration duration = build.stoptime - build.starttime %] finished at [% INCLUDE renderDateTime timestamp = build.stoptime %]
[% END %] [% END %]
</td> </td>
</tr> </tr>
[% END %] [% END %]
[% IF build.logfile %] [% IF build.logfile %]
<tr> <tr>
<th>Logfile:</th> <th>Logfile:</th>
<td> <td>
<a class="btn btn-mini btn-primary" href="[% c.uri_for('/build' build.id 'log') %]">pretty</a> <a class="btn btn-mini btn-primary" href="[% c.uri_for('/build' build.id 'log') %]">pretty</a>
<a class="btn btn-mini" href="[% c.uri_for('/build' build.id 'log' 'raw') %]">raw</a> <a class="btn btn-mini" href="[% c.uri_for('/build' build.id 'log' 'raw') %]">raw</a>
<a class="btn btn-mini" href="[% c.uri_for('/build' build.id 'log' 'tail-reload') %]">tail</a> <a class="btn btn-mini" href="[% c.uri_for('/build' build.id 'log' 'tail-reload') %]">tail</a>
</td> </td>
</tr> </tr>
[% END %] [% END %]
</table> </table>
</td> </td>
</tr> </tr>
</table> </table>
[% IF c.user_exists && available %] [% IF c.user_exists && available %]
<form class="form-horizontal" action="[% c.uri_for('/build' build.id 'add-to-release') %]" method="post"> <form class="form-horizontal" action="[% c.uri_for('/build' build.id 'add-to-release') %]" method="post">
<div class="control-group"> <div class="control-group">
<label class="control-label">Add to release</label> <label class="control-label">Add to release</label>
<div class="controls"> <div class="controls">
@ -148,31 +148,31 @@
<button type="submit" class="btn btn-success">Apply</button> <button type="submit" class="btn btn-success">Apply</button>
</div> </div>
</div> </div>
</form> </form>
[% END %] [% END %]
[% IF build.buildproducts %]
<h3>Build products</h3> [% IF build.buildproducts %]
[% IF !available %] <h3>Build products</h3>
<p class="error">Note: this build is no longer available.</p>
[% END %] [% IF !available %]
<p class="error">Note: this build is no longer available.</p>
[% INCLUDE renderProductList latestRoot=['/job' build.project.name build.jobset.name build.job.name 'latest'] %] [% END %]
[% END %] [% INCLUDE renderProductList latestRoot=['/job' build.project.name build.jobset.name build.job.name 'latest'] %]
[% END %]
[% IF !build.finished %] [% IF !build.finished %]
<h3>Running build steps</h3> <h3>Running build steps</h3>
[% INCLUDE renderBuildSteps type="Running" %] [% INCLUDE renderBuildSteps type="Running" %]
[% END %] [% END %]
[% IF build.finished %] [% IF build.finished %]
[% IF build.buildsteps && build.buildstatus != 0 && build.buildstatus != 6 %] [% IF build.buildsteps && build.buildstatus != 0 && build.buildstatus != 6 %]
<h3>Failed build steps</h3> <h3>Failed build steps</h3>
[% INCLUDE renderBuildSteps type="Failed" %] [% INCLUDE renderBuildSteps type="Failed" %]
[% END %] [% END %]
[% IF prevSuccessfulBuild %] [% IF prevSuccessfulBuild %]
<h3>Changes</h3> <h3>Changes</h3>
@ -192,7 +192,7 @@
<td valign="center">[% INCLUDE renderBuildStatusIcon build=prevSuccessfulBuild size=32 %] [% INCLUDE renderFullBuildLink build=prevSuccessfulBuild, hideProjectName=1, hideJobsetName=1 %]</td> <td valign="center">[% INCLUDE renderBuildStatusIcon build=prevSuccessfulBuild size=32 %] [% INCLUDE renderFullBuildLink build=prevSuccessfulBuild, hideProjectName=1, hideJobsetName=1 %]</td>
[% IF prevSuccessfulBuild && firstBrokenBuild && firstBrokenBuild.id != build.id %]<td valign="center">[% INCLUDE renderBuildStatusIcon build=firstBrokenBuild size=32 %] [% INCLUDE renderFullBuildLink build=firstBrokenBuild, hideProjectName=1, hideJobsetName=1 %]</td>[% END %] [% IF prevSuccessfulBuild && firstBrokenBuild && firstBrokenBuild.id != build.id %]<td valign="center">[% INCLUDE renderBuildStatusIcon build=firstBrokenBuild size=32 %] [% INCLUDE renderFullBuildLink build=firstBrokenBuild, hideProjectName=1, hideJobsetName=1 %]</td>[% END %]
<td>[% INCLUDE renderBuildStatusIcon build=build size=32 %] [% INCLUDE renderFullBuildLink build=build, hideProjectName=1, hideJobsetName=1 %]</td> <td>[% INCLUDE renderBuildStatusIcon build=build size=32 %] [% INCLUDE renderFullBuildLink build=build, hideProjectName=1, hideJobsetName=1 %]</td>
</tr> </tr>
<tr> <tr>
<td></td> <td></td>
[% IF prevSuccessfulBuild && firstBrokenBuild && firstBrokenBuild.id != build.id %]<td>[% INCLUDE renderInputDiff build1=prevSuccessfulBuild , build2=firstBrokenBuild %]</td>[% END %] [% IF prevSuccessfulBuild && firstBrokenBuild && firstBrokenBuild.id != build.id %]<td>[% INCLUDE renderInputDiff build1=prevSuccessfulBuild , build2=firstBrokenBuild %]</td>[% END %]
@ -201,207 +201,207 @@
</table> </table>
[% END %] [% END %]
[% IF build.errormsg && build.buildstatus != 5 %] [% IF build.errormsg && build.buildstatus != 5 %]
<h2 id="nix-error">Nix error output</h2>
<pre class="buildlog">[% HTML.escape(build.errormsg) -%]</pre>
[% END %]
[% END %]
[% IF logtext %]
<h2>Log</h2>
<pre class="buildlog">[% HTML.escape(logtext) -%]</pre>
[% END %]
</div>
<div id="tabs-information" class="tab-pane">
<h2>Information</h2> <h2 id="nix-error">Nix error output</h2>
<table class="layoutTable"> <pre class="buildlog">[% HTML.escape(build.errormsg) -%]</pre>
<tr> [% END %]
<th>Build ID:</th> [% END %]
<td>[% build.id %]</td> [% IF logtext %]
</tr> <h2>Log</h2>
<tr>
<th>Status:</th> <pre class="buildlog">[% HTML.escape(logtext) -%]</pre>
<td> [% END %]
[% INCLUDE renderStatus build=build %] </div>
</td> <div id="tabs-information" class="tab-pane">
</tr>
<tr> <h2>Information</h2>
<th>Project:</th>
<td>[% INCLUDE renderProjectName project=project.name %]</td> <table class="layoutTable">
</tr> <tr>
<tr> <th>Build ID:</th>
<th>Jobset:</th> <td>[% build.id %]</td>
<td>[% INCLUDE renderJobsetName project=project.name jobset=jobset.name %]</td> </tr>
</tr> <tr>
<tr> <th>Status:</th>
<th>Job name:</th> <td>
<td>[% INCLUDE renderJobName project=project.name jobset=jobset.name job=job.name %]</td> [% INCLUDE renderStatus build=build %]
</tr> </td>
[% IF build.nixexprinput %] </tr>
<tr> <tr>
<th>Nix expression:</th> <th>Project:</th>
<td>file <tt>[% HTML.escape(build.nixexprpath) %]</tt> in input <tt>[% HTML.escape(build.nixexprinput) %]</tt></td> <td>[% INCLUDE renderProjectName project=project.name %]</td>
</tr> </tr>
[% END %] <tr>
<tr> <th>Jobset:</th>
<th>Nix name:</th> <td>[% INCLUDE renderJobsetName project=project.name jobset=jobset.name %]</td>
<td><tt>[% build.nixname %]</tt></td> </tr>
</tr> <tr>
[% IF build.releasename %] <th>Job name:</th>
<tr> <td>[% INCLUDE renderJobName project=project.name jobset=jobset.name job=job.name %]</td>
<th>Release name:</th> </tr>
<td><tt>[% HTML.escape(build.releasename) %]</tt></td> [% IF build.nixexprinput %]
</tr> <tr>
[% END %] <th>Nix expression:</th>
<tr> <td>file <tt>[% HTML.escape(build.nixexprpath) %]</tt> in input <tt>[% HTML.escape(build.nixexprinput) %]</tt></td>
<th>Short description:</th> </tr>
<td>[% IF build.description %][% HTML.escape(build.description) %][% ELSE %]<em>(not given)</em>[% END %]</td>
</tr>
<tr>
<th>Long description:</th>
<td>[% IF build.longdescription %][% HTML.escape(build.longdescription) %][% ELSE %]<em>(not given)</em>[% END %]</td>
</tr>
<tr>
<th>License:</th>
<td>[% IF build.license %][% HTML.escape(build.license) %][% ELSE %]<em>(not given)</em>[% END %]</td>
</tr>
<tr>
<th>Homepage:</th>
<td>[% IF build.homepage %]<a [% HTML.attributes(href => build.homepage) %]>[% HTML.escape(build.homepage) %]</a>[% ELSE %]<em>(not given)</em>[% END %]</td>
</tr>
<tr>
<th>Maintainer(s):</th>
<td>[% IF build.maintainers %]<tt>[% HTML.escape(build.maintainers) %]</tt>[% ELSE %]<em>(not given)</em>[% END %]</td>
</tr>
<tr>
<th>System:</th>
<td><tt>[% build.system %]</tt></td>
</tr>
<tr>
<th>Max silent / timeout:</th>
<td>[% build.maxsilent %]s / [% build.timeout %]s</td>
</tr>
<tr>
<th>Derivation store path:</th>
<td>
<tt>[% build.drvpath %]</tt>
[% IF drvAvailable %]
(<a href="[% c.uri_for('/build' build.id 'deps') %]#buildtime">build-time dependencies</a>)
[% END %]
</td>
</tr>
<tr>
<th>Output store path:</th>
<td>
<tt>[% build.outpath %]</tt>
[% IF available %]
(<a href="[% c.uri_for('/build' build.id 'deps') %]#runtime">runtime dependencies</a>)
[% END %]
</td>
</tr>
[% IF pathHash %]
<tr>
<th>Output store path hash:</th>
<td>
<tt>[% pathHash %]</tt>
</td>
</tr>
[% END %] [% END %]
<tr> <tr>
<th>Time added:</th> <th>Nix name:</th>
<td>[% INCLUDE renderDateTime timestamp = build.timestamp %]</td> <td><tt>[% build.nixname %]</tt></td>
</tr> </tr>
[% IF build.finished && build.buildstatus != 4 %] [% IF build.releasename %]
[% IF build.iscachedbuild && cachedBuild %] <tr>
<tr> <th>Release name:</th>
<th>Cached build:</th> <td><tt>[% HTML.escape(build.releasename) %]</tt></td>
<td>[% INCLUDE renderFullBuildLink build=cachedBuild %]</td> </tr>
</tr> [% END %]
[% END %] <tr>
<th>Short description:</th>
<tr> <td>[% IF build.description %][% HTML.escape(build.description) %][% ELSE %]<em>(not given)</em>[% END %]</td>
<th>Build started:</th> </tr>
<td>[% IF build.starttime %][% INCLUDE renderDateTime timestamp = build.starttime %][% ELSE %]<em>(cached build)</em>[% END %]</td> <tr>
</tr> <th>Long description:</th>
<tr> <td>[% IF build.longdescription %][% HTML.escape(build.longdescription) %][% ELSE %]<em>(not given)</em>[% END %]</td>
<th>Build finished:</th> </tr>
<td>[% IF build.stoptime %][% INCLUDE renderDateTime timestamp = build.stoptime %][% ELSE %]<em>(cached build)</em>[% END %]</td> <tr>
</tr> <th>License:</th>
<tr> <td>[% IF build.license %][% HTML.escape(build.license) %][% ELSE %]<em>(not given)</em>[% END %]</td>
<th>Duration:</th> </tr>
<td> <tr>
[% IF build.iscachedbuild %] <th>Homepage:</th>
<em>(cached build)</em> <td>[% IF build.homepage %]<a [% HTML.attributes(href => build.homepage) %]>[% HTML.escape(build.homepage) %]</a>[% ELSE %]<em>(not given)</em>[% END %]</td>
[% ELSE %] </tr>
[% INCLUDE renderDuration duration = build.stoptime - build.starttime %] <tr>
[% END %] <th>Maintainer(s):</th>
</td> <td>[% IF build.maintainers %]<tt>[% HTML.escape(build.maintainers) %]</tt>[% ELSE %]<em>(not given)</em>[% END %]</td>
</tr> </tr>
[% IF build.logfile %] <tr>
<tr> <th>System:</th>
<th>Logfile:</th> <td><tt>[% build.system %]</tt></td>
<td> </tr>
<a href="[% c.uri_for('/build' build.id 'log') %]"><strong>Available</strong></a> <tr>
(<a href="[% c.uri_for('/build' build.id 'log' 'raw') %]">raw</a>, <th>Max silent / timeout:</th>
<a href="[% c.uri_for('/build' build.id 'log' 'tail-reload') %]">tail</a>) <td>[% build.maxsilent %]s / [% build.timeout %]s</td>
</td> </tr>
</tr> <tr>
[% END %] <th>Derivation store path:</th>
[% END %] <td>
[% IF !build.finished %] <tt>[% build.drvpath %]</tt>
<tr> [% IF drvAvailable %]
<th>Priority:</th> (<a href="[% c.uri_for('/build' build.id 'deps') %]#buildtime">build-time dependencies</a>)
<td>[% build.priority %]</td> [% END %]
</tr> </td>
[% END %] </tr>
[% IF build.finished && build.buildproducts %] <tr>
<tr> <th>Output store path:</th>
<th>Availability:</th> <td>
<td> <tt>[% build.outpath %]</tt>
[% IF !available %] [% IF available %]
<em>Build output is no longer available</em> (<a href="[% c.uri_for('/build' build.id 'deps') %]#runtime">runtime dependencies</a>)
[% ELSIF build.keep %] [% END %]
<em>Build output will be kept permanently</em> </td>
[% ELSE %] </tr>
<em>Build output is available, but may be garbage-collected</em> [% IF pathHash %]
[% END %] <tr>
</td> <th>Output store path hash:</th>
</tr> <td>
[% END %] <tt>[% pathHash %]</tt>
</table> </td>
</div> </tr>
<div id="tabs-buildinputs" class="tab-pane"> [% END %]
<tr>
<h2>Build inputs</h2> <th>Time added:</th>
<td>[% INCLUDE renderDateTime timestamp = build.timestamp %]</td>
<table class="tablesorter table table-striped table-condensed"> </tr>
<thead> [% IF build.finished && build.buildstatus != 4 %]
<tr><th>Name</th><th>Type</th><th>Value</th><th>Revision</th><th>Store path</th></tr> [% IF build.iscachedbuild && cachedBuild %]
</thead> <tr>
<tbody> <th>Cached build:</th>
[% FOREACH input IN build.inputs -%] <td>[% INCLUDE renderFullBuildLink build=cachedBuild %]</td>
<tr> </tr>
<td><tt>[% input.name %]</tt></td> [% END %]
<td><tt>[% type = input.type; inputTypes.$type %]</tt></td>
<td> <tr>
[% IF input.type == "build" || input.type == "sysbuild" %] <th>Build started:</th>
[% INCLUDE renderFullBuildLink build=input.dependency %]</a> <td>[% IF build.starttime %][% INCLUDE renderDateTime timestamp = build.starttime %][% ELSE %]<em>(cached build)</em>[% END %]</td>
[% ELSIF input.type == "string" || input.type == "boolean" %] </tr>
<tt>"[% input.value %]"</tt> <tr>
[% ELSE %] <th>Build finished:</th>
<tt>[% input.uri %]</tt> <td>[% IF build.stoptime %][% INCLUDE renderDateTime timestamp = build.stoptime %][% ELSE %]<em>(cached build)</em>[% END %]</td>
[% END %] </tr>
</td> <tr>
<td>[% IF input.revision %][% input.revision %][% END %]</td> <th>Duration:</th>
<td><tt>[% input.path %]</tt></td> <td>
</tr> [% IF build.iscachedbuild %]
[% END -%] <em>(cached build)</em>
</tbody> [% ELSE %]
</table> [% INCLUDE renderDuration duration = build.stoptime - build.starttime %]
[% END %]
</td>
</tr>
[% IF build.logfile %]
<tr>
<th>Logfile:</th>
<td>
<a href="[% c.uri_for('/build' build.id 'log') %]"><strong>Available</strong></a>
(<a href="[% c.uri_for('/build' build.id 'log' 'raw') %]">raw</a>,
<a href="[% c.uri_for('/build' build.id 'log' 'tail-reload') %]">tail</a>)
</td>
</tr>
[% END %]
[% END %]
[% IF !build.finished %]
<tr>
<th>Priority:</th>
<td>[% build.priority %]</td>
</tr>
[% END %]
[% IF build.finished && build.buildproducts %]
<tr>
<th>Availability:</th>
<td>
[% IF !available %]
<em>Build output is no longer available</em>
[% ELSIF build.keep %]
<em>Build output will be kept permanently</em>
[% ELSE %]
<em>Build output is available, but may be garbage-collected</em>
[% END %]
</td>
</tr>
[% END %]
</table>
</div>
<div id="tabs-buildinputs" class="tab-pane">
<h2>Build inputs</h2>
<table class="tablesorter table table-striped table-condensed">
<thead>
<tr><th>Name</th><th>Type</th><th>Value</th><th>Revision</th><th>Store path</th></tr>
</thead>
<tbody>
[% FOREACH input IN build.inputs -%]
<tr>
<td><tt>[% input.name %]</tt></td>
<td><tt>[% type = input.type; inputTypes.$type %]</tt></td>
<td>
[% IF input.type == "build" || input.type == "sysbuild" %]
[% INCLUDE renderFullBuildLink build=input.dependency %]</a>
[% ELSIF input.type == "string" || input.type == "boolean" %]
<tt>"[% input.value %]"</tt>
[% ELSE %]
<tt>[% input.uri %]</tt>
[% END %]
</td>
<td>[% IF input.revision %][% input.revision %][% END %]</td>
<td><tt>[% input.path %]</tt></td>
</tr>
[% END -%]
</tbody>
</table>
<p/> <p/>
@ -409,15 +409,15 @@
<h3>Changes since previous build : [% INCLUDE renderFullBuildLink build=prevBuild, hideProjectName=1, hideJobsetName=1 %]</h3> <h3>Changes since previous build : [% INCLUDE renderFullBuildLink build=prevBuild, hideProjectName=1, hideJobsetName=1 %]</h3>
[% INCLUDE renderInputDiff build2=build , build1=prevBuild %] [% INCLUDE renderInputDiff build2=build , build1=prevBuild %]
[% END %] [% END %]
</div> </div>
[% IF relatedbuilds %] [% IF relatedbuilds %]
<div id="tabs-relatedbuilds" class="tab-pane"> <div id="tabs-relatedbuilds" class="tab-pane">
<h2>Related builds</h2> <h2>Related builds</h2>
<p>The following builds are part of the same jobset evaluation that produced this build.</p> <p>The following builds are part of the same jobset evaluation that produced this build.</p>
[% INCLUDE renderBuildList builds=relatedbuilds hideProjectName=1 hideJobsetName=1 %] [% INCLUDE renderBuildList builds=relatedbuilds hideProjectName=1 hideJobsetName=1 %]
</div> </div>
[% END %] [% END %]
[% IF build.buildsteps %] [% IF build.buildsteps %]
@ -426,37 +426,37 @@
[% INCLUDE renderBuildSteps type="All" %] [% INCLUDE renderBuildSteps type="All" %]
</div> </div>
[% END %] [% END %]
[% IF build.dependents %] [% IF build.dependents %]
<div id="tabs-usedby" class="tab-pane"> <div id="tabs-usedby" class="tab-pane">
<h2>Used by</h2> <h2>Used by</h2>
<p>The following builds have used this build as an input:</p> <p>The following builds have used this build as an input:</p>
<table class="tablesorter table table-condensed table-striped"> <table class="tablesorter table table-condensed table-striped">
<thead> <thead>
<tr><th>Build</th><th>Input name</th><th>System</th><th>Timestamp</th></tr> <tr><th>Build</th><th>Input name</th><th>System</th><th>Timestamp</th></tr>
</thead> </thead>
<tbody> <tbody>
[% FOREACH input IN build.dependents -%] [% FOREACH input IN build.dependents -%]
<tr> <tr>
<td>[% INCLUDE renderFullBuildLink build=input.build %]</td> <td>[% INCLUDE renderFullBuildLink build=input.build %]</td>
<td><tt>[% input.name %]</tt></td> <td><tt>[% input.name %]</tt></td>
<td><tt>[% input.build.system %]</tt></td> <td><tt>[% input.build.system %]</tt></td>
<td>[% INCLUDE renderDateTime timestamp = input.build.timestamp %]</td> <td>[% INCLUDE renderDateTime timestamp = input.build.timestamp %]</td>
</tr> </tr>
[% END -%] [% END -%]
</tbody> </tbody>
</table> </table>
</div> </div>
[% END %] [% END %]
[% IF prevBuilds %] [% IF prevBuilds %]
<div id="tabs-history" class="tab-pane"> <div id="tabs-history" class="tab-pane">
<h2>Build time history (in seconds)</h2> <h2>Build time history (in seconds)</h2>
<div id="placeholder" style="width:800px;height:400px;"></div> <div id="placeholder" style="width:800px;height:400px;"></div>
<div id="overview" style="margin-left:50px;margin-top:20px;width:600px;height:50px"></div> <div id="overview" style="margin-left:50px;margin-top:20px;width:600px;height:50px"></div>
<script src="/static/js/flot/jquery.flot.js" type="text/javascript"></script> <script src="/static/js/flot/jquery.flot.js" type="text/javascript"></script>
<script src="/static/js/flot/jquery.flot.selection.js" type="text/javascript"></script> <script src="/static/js/flot/jquery.flot.selection.js" type="text/javascript"></script>
@ -467,7 +467,7 @@
[% FOREACH prevbuild IN prevBuilds %][% IF prevbuild.build.starttime != 0 %] [% FOREACH prevbuild IN prevBuilds %][% IF prevbuild.build.starttime != 0 %]
d.push([[% prevbuild.starttime * 1000 %],[% prevbuild.get_column('actualBuildTime') %]]); d.push([[% prevbuild.starttime * 1000 %],[% prevbuild.get_column('actualBuildTime') %]]);
ids[[% prevbuild.starttime * 1000 %]] = [% prevbuild.id %] ; ids[[% prevbuild.starttime * 1000 %]] = [% prevbuild.id %] ;
[% END %][% END %] [% END %][% END %]
var options = { var options = {
xaxis: { mode: "time" }, xaxis: { mode: "time" },
@ -481,10 +481,10 @@
hoverRadius: 4, hoverRadius: 4,
}, },
}; };
var plot = $.plot($("#placeholder"), [d], options); var plot = $.plot($("#placeholder"), [d], options);
var overview = $.plot($("#overview"), [d], { var overview = $.plot($("#overview"), [d], {
series: { series: {
lines: { show: true, lineWidth: 1 }, lines: { show: true, lineWidth: 1 },
@ -494,20 +494,20 @@
yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1 }, yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1 },
selection: { mode: "x" } selection: { mode: "x" }
}); });
// now connect the two // now connect the two
$("#placeholder").bind("plotselected", function (event, ranges) { $("#placeholder").bind("plotselected", function (event, ranges) {
// do the zooming // do the zooming
plot = $.plot($("#placeholder"), [d], plot = $.plot($("#placeholder"), [d],
$.extend(true, {}, options, { $.extend(true, {}, options, {
xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to } xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to }
})); }));
// don't fire event on the overview to prevent eternal loop // don't fire event on the overview to prevent eternal loop
overview.setSelection(ranges, true); overview.setSelection(ranges, true);
}); });
$("#overview").bind("plotselected", function (event, ranges) { $("#overview").bind("plotselected", function (event, ranges) {
plot.setSelection(ranges); plot.setSelection(ranges);
}); });
@ -517,15 +517,15 @@
plot.highlight(item.series, item.datapoint); plot.highlight(item.series, item.datapoint);
buildid = ids[item.datapoint[0]]; buildid = ids[item.datapoint[0]];
window.location = "/build/"+buildid; window.location = "/build/"+buildid;
} }
}); });
}); });
</script> </script>
<h2>Store path size history (in MB)</h2> <h2>Store path size history (in MB)</h2>
<div id="placeholder-size" style="width:800px;height:400px;"></div> <div id="placeholder-size" style="width:800px;height:400px;"></div>
<div id="overview-size" style="margin-left:50px;margin-top:20px;width:600px;height:50px"></div> <div id="overview-size" style="margin-left:50px;margin-top:20px;width:600px;height:50px"></div>
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {
var d = []; var d = [];
@ -533,7 +533,7 @@
[% FOREACH prevbuild IN prevBuilds %][% IF prevbuild.size != 0 %] [% FOREACH prevbuild IN prevBuilds %][% IF prevbuild.size != 0 %]
d.push([[% prevbuild.starttime * 1000 %],[% prevbuild.size / (1024*1024.0) %]]); d.push([[% prevbuild.starttime * 1000 %],[% prevbuild.size / (1024*1024.0) %]]);
ids[[% prevbuild.starttime * 1000 %]] = [% prevbuild.id %] ; ids[[% prevbuild.starttime * 1000 %]] = [% prevbuild.id %] ;
[% END %][% END %] [% END %][% END %]
var options = { var options = {
xaxis: { mode: "time" }, xaxis: { mode: "time" },
@ -547,10 +547,10 @@
hoverRadius: 4, hoverRadius: 4,
}, },
}; };
var plot = $.plot($("#placeholder-size"), [d], options); var plot = $.plot($("#placeholder-size"), [d], options);
var overview = $.plot($("#overview-size"), [d], { var overview = $.plot($("#overview-size"), [d], {
series: { series: {
lines: { show: true, lineWidth: 1 }, lines: { show: true, lineWidth: 1 },
@ -560,20 +560,20 @@
yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1 }, yaxis: { ticks: [], min: 0, autoscaleMargin: 0.1 },
selection: { mode: "x" } selection: { mode: "x" }
}); });
// now connect the two // now connect the two
$("#placeholder-size").bind("plotselected", function (event, ranges) { $("#placeholder-size").bind("plotselected", function (event, ranges) {
// do the zooming // do the zooming
plot = $.plot($("#placeholder-size"), [d], plot = $.plot($("#placeholder-size"), [d],
$.extend(true, {}, options, { $.extend(true, {}, options, {
xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to } xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to }
})); }));
// don't fire event on the overview to prevent eternal loop // don't fire event on the overview to prevent eternal loop
overview.setSelection(ranges, true); overview.setSelection(ranges, true);
}); });
$("#overview-size").bind("plotselected", function (event, ranges) { $("#overview-size").bind("plotselected", function (event, ranges) {
plot.setSelection(ranges); plot.setSelection(ranges);
}); });
@ -583,13 +583,13 @@
plot.highlight(item.series, item.datapoint); plot.highlight(item.series, item.datapoint);
buildid = ids[item.datapoint[0]]; buildid = ids[item.datapoint[0]];
window.location = "/build/"+buildid; window.location = "/build/"+buildid;
} }
}); });
}); });
</script> </script>
</div> </div>
[% END %] [% END %]

View file

@ -21,7 +21,7 @@ $ nix-env -i foo</pre>
<p>You can update to the latest versions of the packages in this channel by executing</p> <p>You can update to the latest versions of the packages in this channel by executing</p>
<pre> <pre>
$ nix-channel --update $ nix-channel --update
$ nix-env -u '*'</pre> $ nix-env -u '*'</pre>
<p>Alternatively, if you have associated the <p>Alternatively, if you have associated the
@ -35,7 +35,7 @@ install the package simply by clicking on the packages below.</p>
<p>This channel contains the following packages.</p> <p>This channel contains the following packages.</p>
<table class="tablesorter table table-condensed table-striped"> <table class="tablesorter table table-condensed table-striped">
<thead> <thead>
<tr> <tr>
<th>#</th> <th>#</th>
@ -44,7 +44,7 @@ install the package simply by clicking on the packages below.</p>
<th>Description</th> <th>Description</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
[% odd = 0 %] [% odd = 0 %]
@ -69,9 +69,9 @@ install the package simply by clicking on the packages below.</p>
[% END %] [% END %]
</tbody> </tbody>
</table> </table>

View file

@ -45,7 +45,7 @@
[% END -%] [% END -%]
</tbody> </tbody>
</table> </table>
<p><button type="submit"><img alt="Add" src="/static/images/success.gif" />Add to queue</button></p> <p><button type="submit"><img alt="Add" src="/static/images/success.gif" />Add to queue</button></p>
</form> </form>

View file

@ -8,7 +8,7 @@
<h2>Cloning jobset [% jobset.project.name %]:[% jobset.name %]</h2> <h2>Cloning jobset [% jobset.project.name %]:[% jobset.name %]</h2>
<p> <p>
Name <tt><input type="text" class="string" name="newjobset" [% HTML.attributes(value => "") %] /></tt> Name <tt><input type="text" class="string" name="newjobset" [% HTML.attributes(value => "") %] /></tt>
</p> </p>
<p> <p>
<button type="submit">Next</button> <button type="submit">Next</button>
</p> </p>

View file

@ -93,7 +93,7 @@
[%- BLOCK renderBuildListBody -%] [%- BLOCK renderBuildListBody -%]
[%- odd = 0 -%] [%- odd = 0 -%]
[%- FOREACH build IN builds -%] [%- FOREACH build IN builds -%]
<tr class="clickable <tr class="clickable
[%- IF showSchedulingInfo -%] [%- IF showSchedulingInfo -%]
[%- IF build.busy %]runningBuild[% ELSIF build.disabled == 1 || build.get_column('enabled') == 0 %]disabledBuild[% END -%] [%- IF build.busy %]runningBuild[% ELSIF build.disabled == 1 || build.get_column('enabled') == 0 %]disabledBuild[% END -%]
[%- ELSE -%] [%- ELSE -%]
@ -229,7 +229,7 @@
END -%] END -%]
[% END -%] [% END -%]
[% BLOCK renderFullBuildLink %] [% BLOCK renderFullBuildLink %]
[% INCLUDE renderFullJobNameOfBuild build=build %] <a href="[% c.uri_for('/build' build.id) %]">build [% build.id %]</a>[% -%] [% INCLUDE renderFullJobNameOfBuild build=build %] <a href="[% c.uri_for('/build' build.id) %]">build [% build.id %]</a>[% -%]
[% END %] [% END %]
@ -252,7 +252,7 @@
<img src="/static/images/error_[% size %].png" alt="Failed (with result)" /> <img src="/static/images/error_[% size %].png" alt="Failed (with result)" />
[%- ELSE -%] [%- ELSE -%]
<img src="/static/images/error_[% size %].png" alt="Failed" /> <img src="/static/images/error_[% size %].png" alt="Failed" />
[%- END -%] [%- END -%]
[%- ELSIF busy -%] [%- ELSIF busy -%]
<img src="/static/images/help_[% size %].png" alt="Busy" /> <img src="/static/images/help_[% size %].png" alt="Busy" />
[%- ELSE -%] [%- ELSE -%]
@ -260,7 +260,7 @@
[%- END -%] [%- END -%]
[%- END -%] [%- END -%]
[% BLOCK renderStatus %] [% BLOCK renderStatus %]
[% IF build.finished %] [% IF build.finished %]
[% buildstatus = build.buildstatus %] [% buildstatus = build.buildstatus %]
[% INCLUDE renderBuildStatusIcon size=16 %] [% INCLUDE renderBuildStatusIcon size=16 %]
@ -279,13 +279,13 @@
[% ELSE %] [% ELSE %]
<span class="error">Build failed</span> <span class="error">Build failed</span>
(see <a href="#nix-error">below</a>) (see <a href="#nix-error">below</a>)
[% END %] [% END %]
[% ELSIF build.busy %] [% ELSIF build.busy %]
<strong>Build in progress</strong> <strong>Build in progress</strong>
since [% INCLUDE renderDateTime timestamp = build.starttime %] since [% INCLUDE renderDateTime timestamp = build.starttime %]
[% ELSE %] [% ELSE %]
<strong>Scheduled to be built</strong> <strong>Scheduled to be built</strong>
[% END %] [% END %]
[% END -%] [% END -%]
[% BLOCK renderInputValue %] [% BLOCK renderInputValue %]
@ -366,10 +366,10 @@
[% INCLUDE renderInputDiff build1=bi1.dependency, build2=bi2.dependency, nestedDiff=1, nestLevel=nestLevel+1 %] [% INCLUDE renderInputDiff build1=bi1.dependency, build2=bi2.dependency, nestedDiff=1, nestLevel=nestLevel+1 %]
</td></tr> </td></tr>
[% END %] [% END %]
[% ELSE %] [% ELSE %]
<tr><td><b>[% bi1.name %]</b></td><td>Changed input type from '[% type = bi1.type; inputTypes.$type %]' to '[% type = bi2.type; inputTypes.$type %]'</td></tr> <tr><td><b>[% bi1.name %]</b></td><td>Changed input type from '[% type = bi1.type; inputTypes.$type %]' to '[% type = bi2.type; inputTypes.$type %]'</td></tr>
[% END %] [% END %]
[% deletedInput = 0 %] [% deletedInput = 0 %]
[% END %] [% END %]
[% END %] [% END %]
@ -439,7 +439,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
[%- FOREACH e IN evals; eval = e.eval; [%- FOREACH e IN evals; eval = e.eval;
link = c.uri_for(c.controller('JobsetEval').action_for('view'), [eval.id]) -%] link = c.uri_for(c.controller('JobsetEval').action_for('view'), [eval.id]) -%]
<tr class="clickable" onclick="window.location = '[% link %]'"> <tr class="clickable" onclick="window.location = '[% link %]'">
<td><a href="[% link %]">[% eval.id %]</a>&nbsp;</td> <td><a href="[% link %]">[% eval.id %]</a>&nbsp;</td>
@ -456,16 +456,16 @@
<td align='right'> <td align='right'>
<span class="label label-success">[% e.nrSucceeded %]</span> <span class="label label-success">[% e.nrSucceeded %]</span>
<span class="label label-important">[% e.nrFailed %]</span> <span class="label label-important">[% e.nrFailed %]</span>
[% IF e.nrScheduled > 0 %] [% IF e.nrScheduled > 0 %]
<span class="label">[% e.nrScheduled %]</span> <span class="label">[% e.nrScheduled %]</span>
[% END %] [% END %]
</td> </td>
<td align='right'> <td align='right'>
[%- IF e.diff > 0 -%] [%- IF e.diff > 0 -%]
<span class='label label-success'><strong>+[% e.diff %]</strong></span> <span class='label label-success'><strong>+[% e.diff %]</strong></span>
[%- ELSIF e.diff < 0 && e.nrScheduled == 0 -%] [%- ELSIF e.diff < 0 && e.nrScheduled == 0 -%]
<span class='label label-important'><strong>[% e.diff %]</strong></span> <span class='label label-important'><strong>[% e.diff %]</strong></span>
[%- END -%] [%- END -%]
</td> </td>
</tr> </tr>
[%- END -%] [%- END -%]

View file

@ -12,7 +12,7 @@
<ul> <ul>
[% FOREACH dep IN runtimedeps -%] [% FOREACH dep IN runtimedeps -%]
<li> <li>
[% IF dep.buildstep %] [% IF dep.buildstep %]
<a href="[% c.uri_for('/build' dep.buildstep.get_column('build') 'nixlog' dep.buildstep.stepnr) %]">[% dep.path %]</a> <a href="[% c.uri_for('/build' dep.buildstep.get_column('build') 'nixlog' dep.buildstep.stepnr) %]">[% dep.path %]</a>
[% ELSE %] [% ELSE %]
[% dep.path %] [% dep.path %]
@ -30,7 +30,7 @@ Path not available anymore!<br />
<ul> <ul>
[% FOREACH dep IN buildtimedeps -%] [% FOREACH dep IN buildtimedeps -%]
<li> <li>
[% IF dep.buildstep %] [% IF dep.buildstep %]
<a href="[% c.uri_for('/build' dep.buildstep.get_column('build') 'nixlog' dep.buildstep.stepnr) %]">[% dep.path %]</a> <a href="[% c.uri_for('/build' dep.buildstep.get_column('build') 'nixlog' dep.buildstep.stepnr) %]">[% dep.path %]</a>
[% ELSE %] [% ELSE %]
[% dep.path %] [% dep.path %]

View file

@ -7,21 +7,21 @@
<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"> <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">
<fieldset> <fieldset>
<div class="control-group"> <div class="control-group">
<label class="control-label">Identifier</label> <label class="control-label">Identifier</label>
<div class="controls"> <div class="controls">
<input type="text" class="span3" name="name" [% HTML.attributes(value => release.name) %]></input> <input type="text" class="span3" name="name" [% HTML.attributes(value => release.name) %]></input>
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Description</label> <label class="control-label">Description</label>
<div class="controls"> <div class="controls">
<input type="text" class="span3" name="description" [% HTML.attributes(value => release.description) %]></input> <input type="text" class="span3" name="description" [% HTML.attributes(value => release.description) %]></input>
</div> </div>
</div> </div>
<h3>Release members</h3> <h3>Release members</h3>
<p><em>Note:</em> to add a build to this release, go to the builds <p><em>Note:</em> to add a build to this release, go to the builds
@ -36,7 +36,7 @@
<button class="btn btn-warning" type="button" onclick='$(this).parents(".releaseMember").remove()'><i class="icon-trash icon-white"></i></button> <button class="btn btn-warning" type="button" onclick='$(this).parents(".releaseMember").remove()'><i class="icon-trash icon-white"></i></button>
</div> </div>
</div> </div>
[% END %] [% END %]
<div class="form-actions"> <div class="form-actions">
@ -55,10 +55,10 @@
}); });
</script> </script>
[% END %] [% END %]
</div> </div>
</fieldset> </fieldset>
</form> </form>
[% END %] [% END %]

View file

@ -24,21 +24,21 @@
<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"> <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> <fieldset>
<div class="control-group"> <div class="control-group">
<label class="control-label">Identifier</label> <label class="control-label">Identifier</label>
<div class="controls"> <div class="controls">
<input type="text" class="span3" name="name" [% HTML.attributes(value => view.name) %]></input> <input type="text" class="span3" name="name" [% HTML.attributes(value => view.name) %]></input>
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Description</label> <label class="control-label">Description</label>
<div class="controls"> <div class="controls">
<input type="text" class="span3" name="description" [% HTML.attributes(value => view.description) %]></input> <input type="text" class="span3" name="description" [% HTML.attributes(value => view.description) %]></input>
</div> </div>
</div> </div>
<table class="tablesorter table table-condensed table-striped"> <table class="tablesorter table table-condensed table-striped">
<thead> <thead>
<tr> <tr>
@ -77,8 +77,8 @@
}); });
</script> </script>
[% END %] [% END %]
</div> </div>
</form> </form>
@ -90,7 +90,7 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var id = [% n %]; var id = [% n %];
$(".add-job").click(function() { $(".add-job").click(function() {
var newnr = id++; var newnr = id++;
var newid = "job-" + newnr; var newid = "job-" + newnr;
@ -104,5 +104,5 @@
}); });
</script> </script>
[% END %] [% END %]

View file

@ -2,51 +2,51 @@
[% PROCESS common.tt %] [% PROCESS common.tt %]
[% hideProjectName=1 hideJobsetName=1 hideJobName=1 %] [% hideProjectName=1 hideJobsetName=1 hideJobName=1 %]
<ul id="tab" class="nav nav-tabs"> <ul id="tab" class="nav nav-tabs">
<li><a href="#tabs-status" data-toggle="tab">Status</a></li> <li><a href="#tabs-status" data-toggle="tab">Status</a></li>
<li><a href="#tabs-channels" data-toggle="tab">Channels</a></li> <li><a href="#tabs-channels" data-toggle="tab">Channels</a></li>
<li><a href="#tabs-latestbuilds" data-toggle="tab">Latest builds</a></li> <li><a href="#tabs-latestbuilds" data-toggle="tab">Latest builds</a></li>
</ul> </ul>
<div id="generic-tabs" class="tab-content"> <div id="generic-tabs" class="tab-content">
<div id="tabs-status" class="tab-pane active"> <div id="tabs-status" class="tab-pane active">
[% IF currentBuilds.size != 0 %] [% IF currentBuilds.size != 0 %]
<h2>Latest builds (latest evaluation)</h2> <h2>Latest builds (latest evaluation)</h2>
[% INCLUDE renderBuildList builds=currentBuilds showStatusChange=0 %] [% INCLUDE renderBuildList builds=currentBuilds showStatusChange=0 %]
[% END %] [% END %]
[% IF runningBuilds.size != 0 %] [% IF runningBuilds.size != 0 %]
<h2>Running builds</h2> <h2>Running builds</h2>
[% INCLUDE renderBuildList builds=runningBuilds showSchedulingInfo=1 hideResultInfo=1 %] [% INCLUDE renderBuildList builds=runningBuilds showSchedulingInfo=1 hideResultInfo=1 %]
[% END %] [% END %]
[% IF lastBuilds.size != 0 %] [% IF lastBuilds.size != 0 %]
<h2>Last 10 builds</h2> <h2>Last 10 builds</h2>
[% INCLUDE renderBuildList builds=lastBuilds showStatusChange=0 %] [% INCLUDE renderBuildList builds=lastBuilds showStatusChange=0 %]
[% END %] [% END %]
</div> </div>
<div id="tabs-channels" class="tab-pane"> <div id="tabs-channels" class="tab-pane">
<p>This job provides the following Nix channel:</p> <p>This job provides the following Nix channel:</p>
<ul> <ul>
<li> <li>
<a href="[% c.uri_for('/job' project.name jobset.name job.name <a href="[% c.uri_for('/job' project.name jobset.name job.name
'channel' 'latest') %]"><tt>latest</tt></a> — contains the latest 'channel' 'latest') %]"><tt>latest</tt></a> — contains the latest
successful build for each platform. successful build for each platform.
</li> </li>
</ul> </ul>
</div> </div>
<div id="tabs-latestbuilds" class="tab-pane"> <div id="tabs-latestbuilds" class="tab-pane">
<ul> <ul>
<li><a href="[% c.uri_for('/job' project.name jobset.name job.name <li><a href="[% c.uri_for('/job' project.name jobset.name job.name
'latest') %]">Latest successful build.</a></li> 'latest') %]">Latest successful build.</a></li>
[% FOREACH system IN systems %] [% FOREACH system IN systems %]
<li><a href="[% c.uri_for('/job' project.name jobset.name job.name <li><a href="[% c.uri_for('/job' project.name jobset.name job.name
'latest-for' system.system) %]">Latest successful build for <tt>[% 'latest-for' system.system) %]">Latest successful build for <tt>[%
system.system %]</tt>.</a></li> system.system %]</tt>.</a></li>
[% END %] [% END %]
</ul> </ul>
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
jQuery(document).ready(function ($) { jQuery(document).ready(function ($) {
$('#tab').tab('show'); $('#tab').tab('show');
}); });
</script> </script>

View file

@ -56,7 +56,7 @@ c.uri_for(c.controller('JobsetEval').action_for('view'),
<tr><th class="subheader" colspan="6">Jobs that now <strong>succeed</strong></th></tr> <tr><th class="subheader" colspan="6">Jobs that now <strong>succeed</strong></th></tr>
[% INCLUDE renderSome builds=nowSucceed %] [% INCLUDE renderSome builds=nowSucceed %]
[% END %] [% END %]
[% IF stillFail.size > 0 %] [% IF stillFail.size > 0 %]
<tr><th class="subheader" colspan="6">Jobs that still <strong>fail</strong></th></tr> <tr><th class="subheader" colspan="6">Jobs that still <strong>fail</strong></th></tr>
[% INCLUDE renderSome builds=stillFail %] [% INCLUDE renderSome builds=stillFail %]

View file

@ -15,7 +15,7 @@
[% IF edit %] [% IF edit %]
<button type="button" class="btn btn-warning" onclick='$(this).parents(".inputalt").remove()'><i class="icon-trash icon-white"></i></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 %] [% INCLUDE maybeEditString param=param value=alt.value %]
<br /> <br />
[% ELSE %] [% ELSE %]
[% INCLUDE maybeEditString param=param value=alt.value %] [% INCLUDE maybeEditString param=param value=alt.value %]
[% END %] [% END %]
@ -50,120 +50,120 @@
[% BLOCK renderInputs %] [% BLOCK renderInputs %]
<h3>Inputs</h3> <h3>Inputs</h3>
<table class="tablesorter table table-striped table-condensed"> <table class="tablesorter table table-striped table-condensed">
<thead> <thead>
<tr><th>Input name</th><th>Type</th><th>Values</th></tr> <tr><th>Input name</th><th>Type</th><th>Values</th></tr>
</thead> </thead>
<tbody class="inputs"> <tbody class="inputs">
[% FOREACH input IN jobset.jobsetinputs -%] [% FOREACH input IN jobset.jobsetinputs -%]
[% INCLUDE renderInput input=input baseName="input-$input.name" %] [% INCLUDE renderInput input=input baseName="input-$input.name" %]
[% END %] [% END %]
[% IF edit %] [% IF edit %]
<tr> <tr>
<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> <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> </tr>
[% END %] [% END %]
</tbody> </tbody>
</table> </table>
[% END %] [% END %]
<ul id="tab" class="nav nav-tabs"> <ul id="tab" class="nav nav-tabs">
[% IF !edit -%] [% IF !edit -%]
<li><a href="#tabs-information" data-toggle="tab">Jobset</a></li> <li><a href="#tabs-information" data-toggle="tab">Jobset</a></li>
[% IF jobset.errormsg -%]<li><a href="#tabs-errors" data-toggle="tab"><img src="/static/images/error_16.png" /> Evaluation errors</a></li>[% END %] [% IF jobset.errormsg -%]<li><a href="#tabs-errors" data-toggle="tab"><img src="/static/images/error_16.png" /> Evaluation errors</a></li>[% END %]
<li><a href="#tabs-jobs" data-toggle="tab">Jobs ([% activeJobs.size %])</a></li> <li><a href="#tabs-jobs" data-toggle="tab">Jobs ([% activeJobs.size %])</a></li>
[% 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 -%]
<h2>Most recent evaluations</h2>
[% INCLUDE renderEvals linkToAll=c.uri_for(c.controller('Jobset').action_for('evals'), [project.name, jobset.name]) %]
[% END %] [% END %]
[% IF !edit && activeJobsStatus -%] <li><a href="#tabs-setup" data-toggle="tab">Setup</a></li>
<h2>Status</h2> </ul>
<table class="table table-striped table-condensed">
<thead><tr><th>Job</th>[% FOREACH s IN systems %]<th>[% s.system %]</th>[% END %]</tr></thead> <div id="generic-tabs" class="tab-content">
<tbody> <div id="tabs-information" class="tab-pane active">
[% IF !edit && evals.size() > 0 -%]
<h2>Most recent evaluations</h2>
[% INCLUDE renderEvals linkToAll=c.uri_for(c.controller('Jobset').action_for('evals'), [project.name, jobset.name]) %]
[% END %]
[% IF !edit && activeJobsStatus -%]
<h2>Status</h2>
<table class="table table-striped table-condensed">
<thead><tr><th>Job</th>[% FOREACH s IN systems %]<th>[% s.system %]</th>[% END %]</tr></thead>
<tbody>
[% odd = 0 %] [% odd = 0 %]
[% FOREACH j IN activeJobsStatus %] [% FOREACH j IN activeJobsStatus %]
<tr class="[% IF odd %] odd [% END; odd = !odd -%]"> <tr class="[% IF odd %] odd [% END; odd = !odd -%]">
<td>[% INCLUDE renderJobName project=project.name jobset = jobset.name job = j.get_column('job') %]</td> <td>[% INCLUDE renderJobName project=project.name jobset = jobset.name job = j.get_column('job') %]</td>
[% FOREACH s IN systems %] [% FOREACH s IN systems %]
[% system = s.system %] [% system = s.system %]
[% systemStatus = j.get_column(system) %] [% systemStatus = j.get_column(system) %]
<td class="centered"> <td class="centered">
[% IF systemStatus != undef %] [% IF systemStatus != undef %]
<a href="[% c.uri_for('/build' j.get_column(system _ '-build') ) %]"> <a href="[% c.uri_for('/build' j.get_column(system _ '-build') ) %]">
[% INCLUDE renderBuildStatusIcon buildstatus=systemStatus size=16 %] [% INCLUDE renderBuildStatusIcon buildstatus=systemStatus size=16 %]
</a> </a>
[% END %] [% END %]
</td> </td>
[% END %] [% END %]
</tr> </tr>
[% END %] [% END %]
</tbody> </tbody>
</table> </table>
[% END %] [% END %]
[% IF !edit && !activeJobsStatus -%] [% IF !edit && !activeJobsStatus -%]
<h2>Status</h2> <h2>Status</h2>
<p> <p>
[ <a href="[% c.uri_for('/jobset' project.name jobset.name 'with-status' ) %]">Show status overview</a> ] [ <a href="[% c.uri_for('/jobset' project.name jobset.name 'with-status' ) %]">Show status overview</a> ]
</p> </p>
[% END %] [% END %]
</div> </div>
[% IF !edit -%] [% IF !edit -%]
[% IF jobset.errormsg -%] [% IF jobset.errormsg -%]
<div id="tabs-errors" class="tab-pane"> <div id="tabs-errors" class="tab-pane">
<h2>Evaluation errors</h2> <h2>Evaluation errors</h2>
<p> <p>
Errors occurred at <tt>[% INCLUDE renderDateTime timestamp=jobset.errortime %]</tt>. Errors occurred at <tt>[% INCLUDE renderDateTime timestamp=jobset.errortime %]</tt>.
</p> </p>
<pre class="multiLineMsg error">[% HTML.escape(jobset.errormsg) %]</pre> <pre class="multiLineMsg error">[% HTML.escape(jobset.errormsg) %]</pre>
</div> </div>
[% END %] [% END %]
[% END %] [% END %]
<div id="tabs-setup" class="tab-pane [% IF edit %]active[% END %]"> <div id="tabs-setup" class="tab-pane [% IF edit %]active[% END %]">
<h2>Information</h2> <h2>Information</h2>
<table class="layoutTable"> <table class="layoutTable">
[% IF edit %] [% IF edit %]
<tr> <tr>
<th>Identifier:</th> <th>Identifier:</th>
<td>[% INCLUDE maybeEditString param="name" value=jobset.name %]</td> <td>[% INCLUDE maybeEditString param="name" value=jobset.name %]</td>
</tr> </tr>
[% END %] [% END %]
<tr> <tr>
<th>Description:</th> <th>Description:</th>
<td>[% INCLUDE maybeEditString param="description" value=jobset.description %]</td> <td>[% INCLUDE maybeEditString param="description" value=jobset.description %]</td>
</tr> </tr>
<tr> <tr>
<th>Nix expression:</th> <th>Nix expression:</th>
<td> <td>
<tt>[% INCLUDE maybeEditString param="nixexprpath" value=jobset.nixexprpath extraClass="shortString" %]</tt> in input <tt>[% INCLUDE maybeEditString param="nixexprpath" value=jobset.nixexprpath extraClass="shortString" %]</tt> in input
<tt>[% INCLUDE maybeEditString param="nixexprinput" value=jobset.nixexprinput extraClass="shortString" %]</tt> <tt>[% INCLUDE maybeEditString param="nixexprinput" value=jobset.nixexprinput extraClass="shortString" %]</tt>
</td> </td>
</tr> </tr>
<tr> <tr>
<th>Enabled:</th> <th>Enabled:</th>
<td> <td>
[% INCLUDE renderSelection param="enabled" curValue=jobset.enabled radiobuttons=1 options={"1" = "Yes", "0" = "No"} %] [% INCLUDE renderSelection param="enabled" curValue=jobset.enabled radiobuttons=1 options={"1" = "Yes", "0" = "No"} %]
</td> </td>
</tr> </tr>
<tr> <tr>
<th>Enable email notification:</th> <th>Enable email notification:</th>
<td> <td>
[% INCLUDE renderSelection param="enableemail" curValue=jobset.enableemail radiobuttons=1 options={"1" = "Yes", "0" = "No"} %] [% INCLUDE renderSelection param="enableemail" curValue=jobset.enableemail radiobuttons=1 options={"1" = "Yes", "0" = "No"} %]
</td> </td>
</tr> </tr>
<tr> <tr>
<th>Email override:</th> <th>Email override:</th>
<td> <td>
@ -176,54 +176,54 @@
[% INCLUDE maybeEditString param="keepnr" value=jobset.keepnr %] [% INCLUDE maybeEditString param="keepnr" value=jobset.keepnr %]
</td> </td>
</tr> </tr>
[% IF !edit %] [% IF !edit %]
<tr> <tr>
<th>Last checked:</th> <th>Last checked:</th>
<td> <td>
[% IF jobset.lastcheckedtime %] [% IF jobset.lastcheckedtime %]
[% INCLUDE renderDateTime timestamp = jobset.lastcheckedtime -%][% IF jobset.errormsg -%]<em>, with errors!</em> [% INCLUDE renderDateTime timestamp = jobset.lastcheckedtime -%][% IF jobset.errormsg -%]<em>, with errors!</em>
[% ELSE %], <em>no errors</em> [% ELSE %], <em>no errors</em>
[% END %] [% END %]
[% ELSE %] [% ELSE %]
<em>never</em> <em>never</em>
[% END %] [% END %]
</td> </td>
</tr> </tr>
[% END %] [% END %]
</table> </table>
[% INCLUDE renderInputs %]
</div>
[% IF !edit -%]
<div id="tabs-jobs" class="tab-pane">
<h2>Jobs</h2>
<p>This jobset currently contains the following [% activeJobs.size %] jobs:
<blockquote>
[% IF activeJobs.size == 0 %]<em>(none)</em>[% END %]
[% FOREACH j IN activeJobs %] [% INCLUDE renderJobName project=project.name jobset=jobset.name job=j %] [% END %]
</blockquote>
</p>
<p>This jobset used to contain the following [% inactiveJobs.size %] jobs: [% INCLUDE renderInputs %]
</div>
<blockquote> [% IF !edit -%]
[% IF inactiveJobs.size == 0 %]<em>(none)</em>[% END %] <div id="tabs-jobs" class="tab-pane">
[% FOREACH j IN inactiveJobs %] [% INCLUDE renderJobName project=project.name jobset=jobset.name job=j %] [% END %]
</blockquote> <h2>Jobs</h2>
</p> <p>This jobset currently contains the following [% activeJobs.size %] jobs:
</div> <blockquote>
[% END %] [% IF activeJobs.size == 0 %]<em>(none)</em>[% END %]
[% FOREACH j IN activeJobs %] [% INCLUDE renderJobName project=project.name jobset=jobset.name job=j %] [% END %]
</blockquote>
</p>
<p>This jobset used to contain the following [% inactiveJobs.size %] jobs:
<blockquote>
[% IF inactiveJobs.size == 0 %]<em>(none)</em>[% END %]
[% FOREACH j IN inactiveJobs %] [% INCLUDE renderJobName project=project.name jobset=jobset.name job=j %] [% END %]
</blockquote>
</p>
</div>
[% END %]
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
jQuery(document).ready(function ($) { jQuery(document).ready(function ($) {
$('#tab').tab('show'); $('#tab').tab('show');
}); });
</script> </script>
@ -233,7 +233,7 @@
<table class="template"> <!-- dummy wrapper needed because “hidden” trs are visible anyway --> <table class="template"> <!-- dummy wrapper needed because “hidden” trs are visible anyway -->
[% INCLUDE renderInput input="" extraClass="template" id="input-template" baseName="input-template" %] [% INCLUDE renderInput input="" extraClass="template" id="input-template" baseName="input-template" %]
</table> </table>
<tt class="inputalt template" id="inputalt-template"> <tt class="inputalt template" id="inputalt-template">
[% INCLUDE renderInputAlt alt=alt %] [% INCLUDE renderInputAlt alt=alt %]
</tt> </tt>
@ -257,7 +257,7 @@
}); });
}); });
</script> </script>
<p><button type="submit" class="btn btn-primary"><i class="icon-ok icon-white"></i> [%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> </form>

View file

@ -2,7 +2,7 @@
[% PROCESS common.tt %] [% PROCESS common.tt %]
<div class="page-header"><h1>[% IF create %]New machine[% ELSE %]Machine <tt>[% machine.hostname %]</tt>[% END %]</h1></div> <div class="page-header"><h1>[% IF create %]New machine[% ELSE %]Machine <tt>[% machine.hostname %]</tt>[% END %]</h1></div>
<form class="form-horizontal" method="post" <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 %]"> action="[% IF create %][% c.uri_for('/admin/create-machine/submit') %][% ELSE %][% c.uri_for('/admin/machine' machine.hostname 'submit') %][% END %]">
@ -15,42 +15,42 @@
</div> </div>
</div> </div>
[% END %] [% END %]
<div class="control-group"> <div class="control-group">
<label class="control-label">User name</label> <label class="control-label">User name</label>
<div class="controls"> <div class="controls">
<input type="text" class="span3" name="username" value="[% machine.username %]"></input> <input type="text" class="span3" name="username" value="[% machine.username %]"></input>
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">SSH key location</label> <label class="control-label">SSH key location</label>
<div class="controls"> <div class="controls">
<input type="text" class="span3" name="ssh_key" value="[% machine.ssh_key %]"></input> <input type="text" class="span3" name="ssh_key" value="[% machine.ssh_key %]"></input>
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Options</label> <label class="control-label">Options</label>
<div class="controls"> <div class="controls">
<input type="text" class="span3" name="options" value="[% machine.options %]"></input> <input type="text" class="span3" name="options" value="[% machine.options %]"></input>
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Max concurrent builds</label> <label class="control-label">Max concurrent builds</label>
<div class="controls"> <div class="controls">
<input type="text" class="span3" name="maxconcurrent" value="[% machine.maxconcurrent %]"></input> <input type="text" class="span3" name="maxconcurrent" value="[% machine.maxconcurrent %]"></input>
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Speed factor</label> <label class="control-label">Speed factor</label>
<div class="controls"> <div class="controls">
<input type="text" class="span3" name="speedfactor" value="[% machine.speedfactor %]"></input> <input type="text" class="span3" name="speedfactor" value="[% machine.speedfactor %]"></input>
</div> </div>
</div> </div>
<div class="control-group"> <div class="control-group">
<label class="control-label">Systems</label> <label class="control-label">Systems</label>
<div class="controls"> <div class="controls">
@ -84,7 +84,7 @@
</script> </script>
[% END %] [% END %]
</div> </div>
</fieldset> </fieldset>
[% END %] [% END %]

View file

@ -33,7 +33,7 @@
</tr> </tr>
[% END %] [% END %]
</tbody> </tbody>
</table> </table>
<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><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>

View file

@ -5,7 +5,7 @@
<div class="alert alert-info"> <div class="alert alert-info">
[% FOREACH i IN newsItems %] [% FOREACH i IN newsItems %]
[% contents = String.new(i.contents) %] [% contents = String.new(i.contents) %]
<h4 class="alert-heading">[% INCLUDE renderDateTime timestamp=i.createtime %] by [% i.author.fullname %]</h4> <h4 class="alert-heading">[% INCLUDE renderDateTime timestamp=i.createtime %] by [% i.author.fullname %]</h4>
[% contents.replace('\n','<br />\n') %] [% contents.replace('\n','<br />\n') %]
[% END %] [% END %]
</div> </div>

View file

@ -9,9 +9,9 @@
[% uri = "${c.uri_for('/build' build.id 'download' product.productnr)}" [% uri = "${c.uri_for('/build' build.id 'download' product.productnr)}"
_ (product.name ? "/" _ product.name : "") _ (product.name ? "/" _ product.name : "")
_ (product.defaultpath ? "/" _ product.defaultpath : "") %] _ (product.defaultpath ? "/" _ product.defaultpath : "") %]
[% contents = c.uri_for('/build' build.id 'contents' product.productnr) %] [% contents = c.uri_for('/build' build.id 'contents' product.productnr) %]
[% SWITCH product.type %] [% SWITCH product.type %]
[% CASE "nix-build" %] [% CASE "nix-build" %]
@ -28,16 +28,16 @@
<div class="well hide productDetails"> <div class="well hide productDetails">
<p>If you have Nix installed on your machine, this failed build output and <p>If you have Nix installed on your machine, this failed build output and
all its dependencies can be unpacked into your local Nix store by doing:</p> all its dependencies can be unpacked into your local Nix store by doing:</p>
<pre>$ curl [% uri %] | gunzip | nix-store --import</pre> <pre>$ curl [% uri %] | gunzip | nix-store --import</pre>
<p>The build output can then be found in the path <tt>[% product.path %]</tt>.</p> <p>The build output can then be found in the path <tt>[% product.path %]</tt>.</p>
</p> </p>
</div> </div>
</td> </td>
</tr> </tr>
[% ELSE %] [% ELSE %]
<tr class="product"> <tr class="product">
<td> <td>
@ -55,61 +55,61 @@
with the <tt>nix-install-package</tt> program in your web with the <tt>nix-install-package</tt> program in your web
browser. Alternatively, you can install it from the browser. Alternatively, you can install it from the
command-line:</p> command-line:</p>
<pre>$ nix-install-package --non-interactive --url [% uri %]</pre> <pre>$ nix-install-package --non-interactive --url [% uri %]</pre>
<p>If you get an error message “Permission denied”, you <p>If you get an error message “Permission denied”, you
should make sure that you have sufficient access rights to should make sure that you have sufficient access rights to
the Nix store, e.g., run the command as <tt>root</tt>. the Nix store, e.g., run the command as <tt>root</tt>.
</p> </p>
</div> </div>
</td> </td>
</tr> </tr>
<tr class="product"> <tr class="product">
<td> <td>
[% filename = "${build.nixname}.closure.gz" %] [% filename = "${build.nixname}.closure.gz" %]
[% uri = c.uri_for('/build' build.id 'nix' 'closure' filename ) %] [% uri = c.uri_for('/build' build.id 'nix' 'closure' filename ) %]
<a href="[% uri %]"> <a href="[% uri %]">
<img src="/static/images/nix-build.png" alt="Source" /> <img src="/static/images/nix-build.png" alt="Source" />
Nix closure of path <tt>[% product.path %]</tt> Nix closure of path <tt>[% product.path %]</tt>
</a> </a>
<a class="productDetailsToggle btn btn-mini" href="javascript:">help</a> <a class="productDetailsToggle btn btn-mini" href="javascript:">help</a>
<div class="well hide productDetails"> <div class="well hide productDetails">
<p>If you have Nix installed on your machine, this build and <p>If you have Nix installed on your machine, this build and
all its dependencies can be unpacked into your local Nix all its dependencies can be unpacked into your local Nix
store by doing:</p> store by doing:</p>
<pre>$ gunzip &lt; [% filename %] | nix-store --import</pre> <pre>$ gunzip &lt; [% filename %] | nix-store --import</pre>
<p>or to download and unpack in one command:</p> <p>or to download and unpack in one command:</p>
<pre>$ curl [% uri %] | gunzip | nix-store --import</pre> <pre>$ curl [% uri %] | gunzip | nix-store --import</pre>
<p>The package can then be found in the path <tt>[% <p>The package can then be found in the path <tt>[%
product.path %]</tt>. Youll probably also want to do</p> product.path %]</tt>. Youll probably also want to do</p>
<pre>$ nix-env -i [% product.path %]</pre> <pre>$ nix-env -i [% product.path %]</pre>
<p>to actually install the package in your Nix user environment.</p> <p>to actually install the package in your Nix user environment.</p>
<p>If you get the error message “imported <p>If you get the error message “imported
archive lacks a signature”, you should make sure that you have archive lacks a signature”, you should make sure that you have
sufficient access rights to the Nix store, e.g., run the sufficient access rights to the Nix store, e.g., run the
command as <tt>root</tt>.</p> command as <tt>root</tt>.</p>
</div> </div>
</td> </td>
</tr> </tr>
[% END %] [% END %]
[% CASE "file" %] [% CASE "file" %]
<tr class="product"> <tr class="product">
<td> <td>
<a href="[% uri %]"> <a href="[% uri %]">
@ -138,7 +138,7 @@
<td><a href="[% uri %]"><tt>[% uri %]</tt></a></td> <td><a href="[% uri %]"><tt>[% uri %]</tt></a></td>
</tr> </tr>
[% IF latestRoot %] [% IF latestRoot %]
<tr> <tr>
<th>Links to latest:</th> <th>Links to latest:</th>
<td> <td>
[% IF build.buildproducts.count > 1 %] [% IF build.buildproducts.count > 1 %]
@ -160,12 +160,12 @@
<tr><th>Full path:</th><td><tt>[% product.path %]</tt></td></tr> <tr><th>Full path:</th><td><tt>[% product.path %]</tt></td></tr>
</table> </table>
</div> </div>
</td> </td>
</tr> </tr>
[% CASE "report" %] [% CASE "report" %]
<tr class="product"> <tr class="product">
<td> <td>
<a href="[% uri %]"> <a href="[% uri %]">
@ -205,7 +205,7 @@
</tr> </tr>
[% CASE DEFAULT %] [% CASE DEFAULT %]
<tr class="product"> <tr class="product">
<td> <td>
Something of type <tt>[% product.type %]</tt> [% product %] Something of type <tt>[% product.type %]</tt> [% product %]

View file

@ -1,40 +1,40 @@
[% WRAPPER layout.tt title=(edit ? (create ? "New Project" : "Editing Project $project.name") : "Project $project.name") %] [% WRAPPER layout.tt title=(edit ? (create ? "New Project" : "Editing Project $project.name") : "Project $project.name") %]
[% PROCESS common.tt %] [% PROCESS common.tt %]
<ul id="tab" class="nav nav-tabs"> <ul id="tab" class="nav nav-tabs">
[% IF !edit %] [% IF !edit %]
<li><a href="#tabs-project" data-toggle="tab">Project</a></li> <li><a href="#tabs-project" data-toggle="tab">Project</a></li>
[% END %] [% END %]
<li><a href="#tabs-settings" data-toggle="tab">Settings</a></li> <li><a href="#tabs-settings" data-toggle="tab">Settings</a></li>
[% IF !edit %] [% IF !edit %]
<li><a href="#tabs-views" data-toggle="tab">Views</a></li> <li><a href="#tabs-views" data-toggle="tab">Views</a></li>
[% END %] [% END %]
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
[% IF !edit %] [% IF !edit %]
<div id="tabs-project" class="tab-pane active"> <div id="tabs-project" class="tab-pane active">
<h2>Jobsets</h2> <h2>Jobsets</h2>
[% IF project.jobsets.size > 0 %] [% IF project.jobsets.size > 0 %]
<p>This project has the following jobsets:</p> <p>This project has the following jobsets:</p>
<table class="tablesorter table table-striped table-condensed"> <table class="tablesorter table table-striped table-condensed">
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th>Id</th> <th>Id</th>
<th>Description</th> <th>Description</th>
<th>Last evaluated</th> <th>Last evaluated</th>
<th colspan="2">Success</th> <th colspan="2">Success</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
[% FOREACH j IN jobsets %] [% FOREACH j IN jobsets %]
[% successrate = 0 %] [% successrate = 0 %]
<tr class="clickable [% IF odd %] odd [% END; odd = !odd %]" <tr class="clickable [% IF odd %] odd [% END; odd = !odd %]"
onclick="window.location = '[% c.uri_for('/jobset' project.name j.name) %]'"> onclick="window.location = '[% c.uri_for('/jobset' project.name j.name) %]'">
<td> <td>
[% IF j.get_column('nrscheduled') > 0 %] [% IF j.get_column('nrscheduled') > 0 %]
<img src="/static/images/help_16.png" alt="Scheduled" /> <img src="/static/images/help_16.png" alt="Scheduled" />
@ -46,8 +46,8 @@
<img src="/static/images/error_16.png" alt="All Failed" /> <img src="/static/images/error_16.png" alt="All Failed" />
[% END %] [% END %]
</td> </td>
<td>[% INCLUDE renderJobsetName project = project.name jobset = j.name %]</td> <td>[% INCLUDE renderJobsetName project = project.name jobset = j.name %]</td>
<td>[% HTML.escape(j.description) %]</td> <td>[% HTML.escape(j.description) %]</td>
<td>[% INCLUDE renderDateTime timestamp = j.lastcheckedtime %]</td> <td>[% INCLUDE renderDateTime timestamp = j.lastcheckedtime %]</td>
[% IF j.get_column('nrtotal') > 0 %] [% IF j.get_column('nrtotal') > 0 %]
[% successrate = ( j.get_column('nrsucceeded') / j.get_column('nrtotal') )*100 %] [% successrate = ( j.get_column('nrsucceeded') / j.get_column('nrtotal') )*100 %]
@ -75,129 +75,129 @@
<span class="label label">[% j.get_column('nrscheduled') %]</span> <span class="label label">[% j.get_column('nrscheduled') %]</span>
[% END %] [% END %]
</td> </td>
</tr> </tr>
[% END %] [% END %]
</tbody> </tbody>
</table> </table>
[% ELSE %] [% ELSE %]
<p>No jobsets have been defined yet.</p> <p>No jobsets have been defined yet.</p>
[% END %] [% END %]
</div> </div>
[% END %] [% END %]
<div id="tabs-settings" class="tab-pane [% IF edit %]active[% END %]"> <div id="tabs-settings" class="tab-pane [% IF edit %]active[% END %]">
[% IF edit %] [% IF edit %]
<form action="[% IF create %][% c.uri_for('/create-project/submit') %][% ELSE %][% c.uri_for('/project' project.name 'submit') %][% END %]" method="post"> <form action="[% IF create %][% c.uri_for('/create-project/submit') %][% ELSE %][% c.uri_for('/project' project.name 'submit') %][% END %]" method="post">
[% END %] [% END %]
<h2>Information</h2> <h2>Information</h2>
<table class="layoutTable"> <table class="layoutTable">
[% IF edit %] [% IF edit %]
<tr> <tr>
<th>Identifier:</th> <th>Identifier:</th>
<td><tt>[% INCLUDE maybeEditString param="name" value=project.name %]</tt></td> <td><tt>[% INCLUDE maybeEditString param="name" value=project.name %]</tt></td>
</tr> </tr>
[% END %] [% END %]
<tr> <tr>
<th>Display name:</th> <th>Display name:</th>
<td>[% INCLUDE maybeEditString param="displayname" value=project.displayname %]</td> <td>[% INCLUDE maybeEditString param="displayname" value=project.displayname %]</td>
</tr> </tr>
<tr> <tr>
<th>Description:</th> <th>Description:</th>
<td>[% INCLUDE maybeEditString param="description" value=project.description %]</td> <td>[% INCLUDE maybeEditString param="description" value=project.description %]</td>
</tr> </tr>
<tr> <tr>
<th>Homepage:</th> <th>Homepage:</th>
<td> <td>
[% IF edit %] [% IF edit %]
[% INCLUDE maybeEditString param="homepage" value=project.homepage %] [% INCLUDE maybeEditString param="homepage" value=project.homepage %]
[% ELSE %] [% ELSE %]
[% IF project.homepage %] [% IF project.homepage %]
<a [% HTML.attributes(href => project.homepage) %]>[% HTML.escape(project.homepage) %]</a> <a [% HTML.attributes(href => project.homepage) %]>[% HTML.escape(project.homepage) %]</a>
[% ELSE %] [% ELSE %]
<em>(not specified)</em> <em>(not specified)</em>
[% END %] [% END %]
[% END %] [% END %]
</td> </td>
</tr> </tr>
<tr> <tr>
<th>Owner:</th> <th>Owner:</th>
<td><tt>[% INCLUDE maybeEditString param="owner" value=(project.owner.username || c.user.username) edit=(edit && c.check_user_roles('admin')) %]</tt></td> <td><tt>[% INCLUDE maybeEditString param="owner" value=(project.owner.username || c.user.username) edit=(edit && c.check_user_roles('admin')) %]</tt></td>
</tr> </tr>
<tr> <tr>
<th>Enabled:</th> <th>Enabled:</th>
<td> <td>
[% INCLUDE renderSelection param="enabled" curValue=project.enabled radiobuttons=1 options={"1" = "Yes", "0" = "No"} %] [% INCLUDE renderSelection param="enabled" curValue=project.enabled radiobuttons=1 options={"1" = "Yes", "0" = "No"} %]
</td> </td>
</tr> </tr>
</table> </table>
[% IF edit %] [% IF edit %]
<p> <p>
<button type="submit" class="btn btn-primary"> <button type="submit" class="btn btn-primary">
<i class="icon-ok icon-white"></i> <i class="icon-ok icon-white"></i>
[%IF create %]Create[% ELSE %]Apply changes[% END %] [%IF create %]Create[% ELSE %]Apply changes[% END %]
</button> </button>
[% IF !create %] [% IF !create %]
<button id="delete-project" type="submit" class="btn btn-danger" name="submit" value="delete"> <button id="delete-project" type="submit" class="btn btn-danger" name="submit" value="delete">
<i class="icon-trash icon-white"></i> <i class="icon-trash icon-white"></i>
Delete this project Delete this project
</button> </button>
<script type="text/javascript"> <script type="text/javascript">
$("#delete-project").click(function() { $("#delete-project").click(function() {
return confirm("Are you sure you want to delete this project?"); return confirm("Are you sure you want to delete this project?");
}); });
</script> </script>
[% END %] [% END %]
</p> </p>
[% END %]
</form>
</div>
[% IF !edit %] [% END %]
<div id="tabs-views" class="tab-pane">
</form>
<h2>Views</h2>
</div>
[% IF views.size > 0 %]
[% IF !edit %]
<p>Project <tt>[% project.name %]</tt> has the following views:</p> <div id="tabs-views" class="tab-pane">
<ul> <h2>Views</h2>
[% FOREACH view IN views %]
<li> [% IF views.size > 0 %]
<a href="[% c.uri_for('/view' project.name view.name) %]"><tt>[% view.name %]</tt></a>
<p>Project <tt>[% project.name %]</tt> has the following views:</p>
<ul>
[% FOREACH view IN views %]
<li>
<a href="[% c.uri_for('/view' project.name view.name) %]"><tt>[% view.name %]</tt></a>
<a class="btn btn-mini" 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> </li>
[% END %] [% END %]
</ul> </ul>
[% ELSE %] [% ELSE %]
<p>Project <tt>[% project.name %]</tt> has no views.</p> <p>Project <tt>[% project.name %]</tt> has no views.</p>
[% END %] [% END %]
<p><a class="btn" href="[% c.uri_for('/project' project.name 'create-view') %]"> <p><a class="btn" href="[% c.uri_for('/project' project.name 'create-view') %]">
<i class="icon-plus"></i> Create a new view <i class="icon-plus"></i> Create a new view
</a></p> </a></p>
</div> </div>
[% END %] [% END %]
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
jQuery(document).ready(function ($) { jQuery(document).ready(function ($) {
$('#tab').tab('show'); $('#tab').tab('show');
}); });
</script> </script>

View file

@ -9,22 +9,22 @@
<script type="text/javascript"> <script type="text/javascript">
Timeline_urlPrefix="http://simile.mit.edu/timeline/api/"; Timeline_urlPrefix="http://simile.mit.edu/timeline/api/";
</script> </script>
<script src="http://simile.mit.edu/timeline/api/timeline-api.js" type="text/javascript"></script> <script src="http://simile.mit.edu/timeline/api/timeline-api.js" type="text/javascript"></script>
<script type="text/javascript"> <script type="text/javascript">
$(function() { $(function() {
doItNow() doItNow()
}); });
var tl; var tl;
function doItNow() { function doItNow() {
var eventSource = new Timeline.DefaultEventSource(); var eventSource = new Timeline.DefaultEventSource();
var bandInfos = [ var bandInfos = [
Timeline.createBandInfo({ Timeline.createBandInfo({
eventSource: eventSource, eventSource: eventSource,
width: "100%", width: "100%",
intervalUnit: Timeline.DateTime.HOUR, intervalUnit: Timeline.DateTime.HOUR,
intervalPixels: 200 intervalPixels: 200
}) })
]; ];
@ -37,22 +37,22 @@ Timeline_urlPrefix="http://simile.mit.edu/timeline/api/";
var event_data = var event_data =
{ "dateTimeFormat": "iso8601", "events":[ { "dateTimeFormat": "iso8601", "events":[
{ "start": "[% date.format(pit, '%Y-%m-%dT%H:%M:%S') %]", { "start": "[% date.format(pit, '%Y-%m-%dT%H:%M:%S') %]",
"end": "[% date.format(pit, '%Y-%m-%dT%H:%M:%S') %]", "end": "[% date.format(pit, '%Y-%m-%dT%H:%M:%S') %]",
"title": "Now" "title": "Now"
} }
[% FOREACH build IN builds -%] [% FOREACH build IN builds -%]
, { "start": "[% date.format(build.get_column("starttime"), '%Y-%m-%dT%H:%M:%S') %]", , { "start": "[% date.format(build.get_column("starttime"), '%Y-%m-%dT%H:%M:%S') %]",
"end": "[% date.format(build.get_column("stoptime"), '%Y-%m-%dT%H:%M:%S') %]", "end": "[% date.format(build.get_column("stoptime"), '%Y-%m-%dT%H:%M:%S') %]",
"isDuration": "true", "isDuration": "true",
"title": "[% build.id %]", "title": "[% build.id %]",
"link": "[% c.uri_for('/build' build.id) %]", "link": "[% c.uri_for('/build' build.id) %]",
"color": "[% IF build.get_column("buildstatus") == 0 %]green[%ELSE%]red[% END%]" "color": "[% IF build.get_column("buildstatus") == 0 %]green[%ELSE%]red[% END%]"
} }
[% END %] [% END %]
]}; ]};
eventSource.loadJSON(event_data, document.location.href); eventSource.loadJSON(event_data, document.location.href);
} }

View file

@ -56,13 +56,13 @@
[% INCLUDE menuItem uri = c.uri_for('/project' project.name 'edit') title="Edit project" %] [% INCLUDE menuItem uri = c.uri_for('/project' project.name 'edit') title="Edit project" %]
[% IF project.hidden %] [% IF project.hidden %]
[% INCLUDE menuItem uri = c.uri_for('/project' project.name 'unhide') title = "Unhide" %] [% INCLUDE menuItem uri = c.uri_for('/project' project.name 'unhide') title = "Unhide" %]
[% ELSE %] [% ELSE %]
[% INCLUDE menuItem uri = c.uri_for('/project' project.name 'hide') title = "Hide" %] [% INCLUDE menuItem uri = c.uri_for('/project' project.name 'hide') title = "Hide" %]
[% END %] [% END %]
[% END %] [% END %]
[% END %] [% END %]
[% END %] [% END %]
[% IF jobset %] [% IF jobset %]
[% WRAPPER makeSubMenu title=("Jobset: " _ jobset.name) collapsed=job %] [% WRAPPER makeSubMenu title=("Jobset: " _ jobset.name) collapsed=job %]
@ -90,7 +90,7 @@
[% 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 = "" %] [% 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 %] [% IF jobset.hidden %]
[% INCLUDE menuItem uri = c.uri_for('/jobset' project.name jobset.name 'unhide') title = "Unhide" %] [% INCLUDE menuItem uri = c.uri_for('/jobset' project.name jobset.name 'unhide') title = "Unhide" %]
[% ELSE %] [% ELSE %]
[% INCLUDE menuItem uri = c.uri_for('/jobset' project.name jobset.name 'hide') title = "Hide" %] [% INCLUDE menuItem uri = c.uri_for('/jobset' project.name jobset.name 'hide') title = "Hide" %]
[% END %] [% END %]
[% END %] [% END %]
@ -98,7 +98,7 @@
[% END %] [% END %]
[% END %] [% END %]
[% IF job %] [% IF job %]
[% WRAPPER makeSubMenu title=("Job: " _ job.name) %] [% WRAPPER makeSubMenu title=("Job: " _ job.name) %]
@ -151,7 +151,7 @@
[% END %] [% END %]
[% END %] [% END %]
[% END %] [% END %]
[% IF c.user_exists %] [% IF c.user_exists %]
@ -171,12 +171,12 @@
uri = c.uri_for(c.controller('Admin').action_for('users')) uri = c.uri_for(c.controller('Admin').action_for('users'))
title = "Manage users" %] title = "Manage users" %]
<li class="divider"></li> <li class="divider"></li>
[% INCLUDE maybeLink [% INCLUDE maybeLink
uri = c.uri_for(c.controller('Admin').action_for('clearfailedcache')) uri = c.uri_for(c.controller('Admin').action_for('clearfailedcache'))
content = "Clear failed builds cache" 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 = "" %] class = "" %]
[% INCLUDE maybeLink [% INCLUDE maybeLink
uri = c.uri_for(c.controller('Admin').action_for('clear_queue_non_current')) uri = c.uri_for(c.controller('Admin').action_for('clear_queue_non_current'))
content = "Clear all non-running old builds from queue." 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?"

View file

@ -7,7 +7,7 @@
[% FOREACH r IN user.userroles %] [% FOREACH r IN user.userroles %]
[% checked = r.role == role %] [% checked = r.role == role %]
[% BREAK IF checked %] [% BREAK IF checked %]
[% END %] [% END %]
[% IF checked %] [% IF checked %]
SELECTED SELECTED
[% END %] [% END %]
@ -17,7 +17,7 @@
<div class="page-header"><h1>[% IF create %]New user[% ELSE %]User <tt>[% user.username %]</tt>[% END %]</h1></div> <div class="page-header"><h1>[% IF create %]New user[% ELSE %]User <tt>[% user.username %]</tt>[% END %]</h1></div>
<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"> <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> <fieldset>
[% IF create %] [% IF create %]
<div class="control-group"> <div class="control-group">
@ -70,7 +70,7 @@
</script> </script>
[% END %] [% END %]
</div> </div>
</p> </p>
</form> </form>

View file

@ -26,7 +26,7 @@
</tr> </tr>
[% END %] [% END %]
</tbody> </tbody>
</table> </table>
<p><a class="btn" href="[% c.uri_for(c.controller('Admin').action_for('create_user')) %]"> <p><a class="btn" href="[% c.uri_for(c.controller('Admin').action_for('create_user')) %]">

View file

@ -37,7 +37,7 @@
[% ELSE %] [% ELSE %]
<p class="error">Build failed</p> <p class="error">Build failed</p>
[% END %] [% END %]
[% ELSE %] [% ELSE %]

View file

@ -23,7 +23,7 @@
[% END %] [% END %]
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
[% FOREACH result IN results %] [% FOREACH result IN results %]
[% link = c.uri_for('/view' project.name view.name result.id) %] [% link = c.uri_for('/view' project.name view.name result.id) %]

View file

@ -28,13 +28,13 @@ elif test "$action" = "status"; then
echo -n "Hydra web server... " echo -n "Hydra web server... "
(kill -0 $(cat $HYDRA_DATA/server.pid) 2> /dev/null && echo "ok") || echo "not running" (kill -0 $(cat $HYDRA_DATA/server.pid) 2> /dev/null && echo "ok") || echo "not running"
echo -n "Hydra evaluator... " echo -n "Hydra evaluator... "
(kill -0 $(cat $HYDRA_DATA/evaluator.pid) 2> /dev/null && echo "ok") || echo "not running" (kill -0 $(cat $HYDRA_DATA/evaluator.pid) 2> /dev/null && echo "ok") || echo "not running"
echo -n "Hydra queue runner... " echo -n "Hydra queue runner... "
(kill -0 $(cat $HYDRA_DATA/queue_runner.pid) 2> /dev/null && echo "ok") || echo "not running" (kill -0 $(cat $HYDRA_DATA/queue_runner.pid) 2> /dev/null && echo "ok") || echo "not running"
else else
echo "Syntax: $0 [start|stop|status]" echo "Syntax: $0 [start|stop|status]"

View file

@ -80,7 +80,7 @@ sub checkBuilds {
my @systemTypes = $db->resultset('Builds')->search( my @systemTypes = $db->resultset('Builds')->search(
{ finished => 0, busy => 0, enabled => 1, disabled => 0 }, { finished => 0, busy => 0, enabled => 1, disabled => 0 },
{ join => ['project'], select => ['system'], as => ['system'], distinct => 1 }); { join => ['project'], select => ['system'], as => ['system'], distinct => 1 });
# For each system type, select up to the maximum number of # For each system type, select up to the maximum number of
# concurrent build for that system type. Choose the highest # concurrent build for that system type. Choose the highest
# priority builds first, then the oldest builds. # priority builds first, then the oldest builds.
@ -165,9 +165,9 @@ while (1) {
eval { eval {
# Clean up zombies. # Clean up zombies.
while ((waitpid(-1, &WNOHANG)) > 0) { }; while ((waitpid(-1, &WNOHANG)) > 0) { };
unlockDeadBuilds; unlockDeadBuilds;
checkBuilds; checkBuilds;
}; };
warn $@ if $@; warn $@ if $@;

View file

@ -90,7 +90,7 @@ foreach my $project ($db->resultset('Projects')->search({}, { order_by => ["name
$project->name, ":", $jobset->name, "\n"; $project->name, ":", $jobset->name, "\n";
keepBuild $_ foreach $jobset->builds->search( keepBuild $_ foreach $jobset->builds->search(
{ 'me.id' => { 'in' => \ { 'me.id' => { 'in' => \
[ "select b2.id from Builds b2 join " . [ "select b2.id from Builds b2 join " .
" (select distinct job, system, coalesce( " . " (select distinct job, system, coalesce( " .
" (select id from builds where project = b.project and jobset = b.jobset and job = b.job and system = b.system and finished = 1 and buildStatus = 0 order by id desc offset ? limit 1)" . " (select id from builds where project = b.project and jobset = b.jobset and job = b.job and system = b.system and finished = 1 and buildStatus = 0 order by id desc offset ? limit 1)" .

View file

@ -87,7 +87,7 @@ create table JobsetInputAlts (
-- urgh -- urgh
value text, -- for most types, a URI; for 'path', an absolute path; for 'string', an arbitrary value value text, -- for most types, a URI; for 'path', an absolute path; for 'string', an arbitrary value
revision text, -- for repositories revision text, -- for repositories
primary key (project, jobset, input, altnr), primary key (project, jobset, input, altnr),
foreign key (project, jobset, input) references JobsetInputs(project, jobset, name) on delete cascade on update cascade foreign key (project, jobset, input) references JobsetInputs(project, jobset, name) on delete cascade on update cascade
); );
@ -121,7 +121,7 @@ create table Builds (
#endif #endif
finished integer not null, -- 0 = scheduled, 1 = finished finished integer not null, -- 0 = scheduled, 1 = finished
timestamp integer not null, -- time this build was scheduled / finished building timestamp integer not null, -- time this build was scheduled / finished building
-- Info about the inputs. -- Info about the inputs.
@ -160,7 +160,7 @@ create table Builds (
logfile text, -- if busy, the path of the logfile logfile text, -- if busy, the path of the logfile
disabled integer not null default 0, -- !!! boolean disabled integer not null default 0, -- !!! boolean
startTime integer, -- if busy, time we started startTime integer, -- if busy, time we started
stopTime integer, stopTime integer,
@ -177,7 +177,7 @@ create table Builds (
buildStatus integer, buildStatus integer,
errorMsg text, -- error message in case of a Nix failure errorMsg text, -- error message in case of a Nix failure
logSize bigint, logSize bigint,
size bigint, size bigint,
closureSize bigint, closureSize bigint,
@ -230,7 +230,7 @@ create table BuildInputs (
-- Which build this input belongs to. -- Which build this input belongs to.
build integer, build integer,
-- Copied from the jobsetinputs from which the build was created. -- Copied from the jobsetinputs from which the build was created.
name text not null, name text not null,
type text not null, type text not null,
@ -240,9 +240,9 @@ create table BuildInputs (
dependency integer, -- build ID of the input, for type == 'build' dependency integer, -- build ID of the input, for type == 'build'
path text, path text,
sha256hash text, sha256hash text,
foreign key (build) references Builds(id) on delete cascade, foreign key (build) references Builds(id) on delete cascade,
foreign key (dependency) references Builds(id) foreign key (dependency) references Builds(id)
); );
@ -339,11 +339,11 @@ create table SystemTypes (
create table Views ( create table Views (
project text not null, project text not null,
name text not null, name text not null,
description text, description text,
-- If true, don't garbage-collect builds included in this view. -- If true, don't garbage-collect builds included in this view.
keep integer not null default 0, keep integer not null default 0,
primary key (project, name), primary key (project, name),
foreign key (project) references Projects(name) on delete cascade on update cascade foreign key (project) references Projects(name) on delete cascade on update cascade
@ -364,9 +364,9 @@ create table ViewJobs (
-- If set, this is the primary job for the view. There can be -- If set, this is the primary job for the view. There can be
-- only one such job per view. -- only one such job per view.
isPrimary integer not null default 0, isPrimary integer not null default 0,
description text, description text,
jobset text not null, jobset text not null,
-- If set, once there is a successful build for every job -- If set, once there is a successful build for every job
@ -374,7 +374,7 @@ create table ViewJobs (
-- builds is automatically added as a release to the Releases -- builds is automatically added as a release to the Releases
-- table. -- table.
autoRelease integer not null default 0, autoRelease integer not null default 0,
primary key (project, view_, job, attrs), primary key (project, view_, job, attrs),
foreign key (project) references Projects(name) on delete cascade on update cascade, foreign key (project) references Projects(name) on delete cascade on update cascade,
foreign key (project, view_) references Views(project, name) on delete cascade on update cascade foreign key (project, view_) references Views(project, name) on delete cascade on update cascade
@ -419,7 +419,7 @@ create table JobsetEvals (
project text not null, project text not null,
jobset text not null, jobset text not null,
timestamp integer not null, -- when this entry was added timestamp integer not null, -- when this entry was added
checkoutTime integer not null, -- how long obtaining the inputs took (in seconds) checkoutTime integer not null, -- how long obtaining the inputs took (in seconds)
evalTime integer not null, -- how long evaluation took (in seconds) evalTime integer not null, -- how long evaluation took (in seconds)
@ -451,7 +451,7 @@ create table JobsetEvalInputs (
eval integer not null references JobsetEvals(id) on delete cascade, eval integer not null references JobsetEvals(id) on delete cascade,
name text not null, name text not null,
altNr integer not null, altNr integer not null,
-- Copied from the jobsetinputs from which the build was created. -- Copied from the jobsetinputs from which the build was created.
type text not null, type text not null,
uri text, uri text,
@ -460,7 +460,7 @@ create table JobsetEvalInputs (
dependency integer, -- build ID of the input, for type == 'build' dependency integer, -- build ID of the input, for type == 'build'
path text, path text,
sha256hash text, sha256hash text,
primary key (eval, name, altNr), primary key (eval, name, altNr),

View file

@ -15,7 +15,7 @@ alter table Builds
add column releaseName text, add column releaseName text,
add column keep integer not null default 0; add column keep integer not null default 0;
update Builds b set update Builds b set
priority = (select priority from BuildSchedulingInfo s where s.id = b.id), priority = (select priority from BuildSchedulingInfo s where s.id = b.id),
busy = (select busy from BuildSchedulingInfo s where s.id = b.id), busy = (select busy from BuildSchedulingInfo s where s.id = b.id),
disabled = (select disabled from BuildSchedulingInfo s where s.id = b.id), disabled = (select disabled from BuildSchedulingInfo s where s.id = b.id),
@ -23,10 +23,10 @@ update Builds b set
logfile = (select logfile from BuildSchedulingInfo s where s.id = b.id) logfile = (select logfile from BuildSchedulingInfo s where s.id = b.id)
where exists (select 1 from BuildSchedulingInfo s where s.id = b.id); where exists (select 1 from BuildSchedulingInfo s where s.id = b.id);
update Builds b set update Builds b set
startTime = ((select startTime from BuildSchedulingInfo s where s.id = b.id) union (select startTime from BuildResultInfo r where r.id = b.id)); startTime = ((select startTime from BuildSchedulingInfo s where s.id = b.id) union (select startTime from BuildResultInfo r where r.id = b.id));
update Builds b set update Builds b set
isCachedBuild = (select isCachedBuild from BuildResultInfo r where r.id = b.id), isCachedBuild = (select isCachedBuild from BuildResultInfo r where r.id = b.id),
buildStatus = (select buildStatus from BuildResultInfo r where r.id = b.id), buildStatus = (select buildStatus from BuildResultInfo r where r.id = b.id),
errorMsg = (select errorMsg from BuildResultInfo r where r.id = b.id), errorMsg = (select errorMsg from BuildResultInfo r where r.id = b.id),

View file

@ -5,7 +5,7 @@ create table JobsetEvalInputs (
eval integer not null references JobsetEvals(id) on delete cascade, eval integer not null references JobsetEvals(id) on delete cascade,
name text not null, name text not null,
altNr integer not null, altNr integer not null,
-- Copied from the jobsetinputs from which the build was created. -- Copied from the jobsetinputs from which the build was created.
type text not null, type text not null,
uri text, uri text,
@ -14,7 +14,7 @@ create table JobsetEvalInputs (
dependency integer, -- build ID of the input, for type == 'build' dependency integer, -- build ID of the input, for type == 'build'
path text, path text,
sha256hash text, sha256hash text,
primary key (eval, name, altNr), primary key (eval, name, altNr),

View file

@ -12,7 +12,7 @@ TESTS_ENVIRONMENT = \
NIX_BUILD_HOOK= \ NIX_BUILD_HOOK= \
PERL5LIB="$(srcdir):$(top_srcdir)/src/lib:$$PERL5LIB" \ PERL5LIB="$(srcdir):$(top_srcdir)/src/lib:$$PERL5LIB" \
PATH=$(abs_top_srcdir)/src/script:$(abs_top_srcdir)/src/c:$$PATH \ PATH=$(abs_top_srcdir)/src/script:$(abs_top_srcdir)/src/c:$$PATH \
perl -w perl -w
EXTRA_DIST = \ EXTRA_DIST = \
$(wildcard *.pm) \ $(wildcard *.pm) \
@ -35,7 +35,7 @@ db.sqlite : $(top_srcdir)/src/sql/hydra-sqlite.sql
repos : dirs repos : dirs
dirs : dirs :
mkdir -p data mkdir -p data
touch data/hydra.conf touch data/hydra.conf
mkdir -p nix mkdir -p nix

View file

@ -32,7 +32,7 @@ sub nrQueuedBuildsForJobset {
sub createBaseJobset { sub createBaseJobset {
my ($jobsetName, $nixexprpath) = @_; my ($jobsetName, $nixexprpath) = @_;
my $db = Hydra::Model::DB->new; my $db = Hydra::Model::DB->new;
my $project = $db->resultset('Projects')->update_or_create({name => "tests", displayname => "", owner => "root"}); my $project = $db->resultset('Projects')->update_or_create({name => "tests", displayname => "", owner => "root"});
my $jobset = $project->jobsets->create({name => $jobsetName, nixexprinput => "jobs", nixexprpath => $nixexprpath, emailoverride => ""}); my $jobset = $project->jobsets->create({name => $jobsetName, nixexprinput => "jobs", nixexprpath => $nixexprpath, emailoverride => ""});

View file

@ -1,18 +1,18 @@
with import ./config.nix; with import ./config.nix;
{ {
empty_dir = empty_dir =
mkDerivation { mkDerivation {
name = "empty-dir"; name = "empty-dir";
builder = ./empty-dir-builder.sh; builder = ./empty-dir-builder.sh;
}; };
fails = fails =
mkDerivation { mkDerivation {
name = "fails"; name = "fails";
builder = ./fail.sh; builder = ./fail.sh;
}; };
succeed_with_failed = succeed_with_failed =
mkDerivation { mkDerivation {
name = "succeed-with-failed"; name = "succeed-with-failed";
builder = ./succeed-with-failed.sh; builder = ./succeed-with-failed.sh;

View file

@ -7,7 +7,7 @@ let
builder = ./empty-dir-builder.sh; builder = ./empty-dir-builder.sh;
}; };
build2 = build2 =
{build1 ? jobs.build1 }: {build1 ? jobs.build1 }:
mkDerivation { mkDerivation {
name = "build2"; name = "build2";

View file

@ -1,7 +1,7 @@
with import ./config.nix; with import ./config.nix;
{ src }: { src }:
{ {
copy = copy =
mkDerivation { mkDerivation {
name = "bzr-checkout-input"; name = "bzr-checkout-input";
builder = ./scm-builder.sh; builder = ./scm-builder.sh;

View file

@ -1,7 +1,7 @@
with import ./config.nix; with import ./config.nix;
{ src }: { src }:
{ {
copy = copy =
mkDerivation { mkDerivation {
name = "bzr-input"; name = "bzr-input";
builder = ./scm-builder.sh; builder = ./scm-builder.sh;

View file

@ -1,7 +1,7 @@
with import ./config.nix; with import ./config.nix;
{ src }: { src }:
{ {
copy = copy =
mkDerivation { mkDerivation {
name = "git-input"; name = "git-input";
builder = ./scm-builder.sh; builder = ./scm-builder.sh;

View file

@ -1,7 +1,7 @@
with import ./config.nix; with import ./config.nix;
{ src }: { src }:
{ {
copy = copy =
mkDerivation { mkDerivation {
name = "git-input"; name = "git-input";
builder = ./scm-builder.sh; builder = ./scm-builder.sh;

View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# This script is used both by git & deepgit checks. # This script is used both by git & deepgit checks.
set -e set -e
repo=git-repo repo=git-repo
export HOME=$(pwd) export HOME=$(pwd)
@ -12,9 +12,9 @@ else
state=0; state=0;
fi fi
echo "STATE: $state" echo "STATE: $state"
case $state in case $state in
(0) echo "::Create repo. -- continue -- updated::" (0) echo "::Create repo. -- continue -- updated::"
git init $repo git init $repo
cd $repo cd $repo
git config --global user.email "you@example.com" git config --global user.email "you@example.com"

View file

@ -1,7 +1,7 @@
with import ./config.nix; with import ./config.nix;
{ src }: { src }:
{ {
copy = copy =
mkDerivation { mkDerivation {
name = "hg-input"; name = "hg-input";
builder = ./scm-builder.sh; builder = ./scm-builder.sh;

View file

@ -1,7 +1,7 @@
with import ./config.nix; with import ./config.nix;
{ src }: { src }:
{ {
copy = copy =
mkDerivation { mkDerivation {
name = "bzr-checkout-input"; name = "bzr-checkout-input";
builder = ./scm-builder.sh; builder = ./scm-builder.sh;

View file

@ -1,7 +1,7 @@
with import ./config.nix; with import ./config.nix;
{ src }: { src }:
{ {
copy = copy =
mkDerivation { mkDerivation {
name = "svn-input"; name = "svn-input";
builder = ./scm-builder.sh; builder = ./scm-builder.sh;