This commit is contained in:
Eelco Dolstra 2008-11-09 00:48:36 +00:00
parent 74c952d073
commit f4a44db664
15 changed files with 141 additions and 91 deletions

View file

@ -29,6 +29,7 @@ sub getBuild {
sub index :Path :Args(0) { sub index :Path :Args(0) {
my ( $self, $c ) = @_; my ( $self, $c ) = @_;
$c->stash->{template} = 'index.tt'; $c->stash->{template} = 'index.tt';
$c->stash->{projects} = [$c->model('DB::Projects')->all];
$c->stash->{allBuilds} = [$c->model('DB::Builds')->search(undef, {order_by => "timestamp DESC"})]; $c->stash->{allBuilds} = [$c->model('DB::Builds')->search(undef, {order_by => "timestamp DESC"})];
# Get the latest build for each unique job. # Get the latest build for each unique job.
# select * from builds as x where timestamp == (select max(timestamp) from builds where jobName == x.jobName); # select * from builds as x where timestamp == (select max(timestamp) from builds where jobName == x.jobName);

View file

@ -8,8 +8,8 @@ use base 'DBIx::Class::Schema';
__PACKAGE__->load_classes; __PACKAGE__->load_classes;
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-08 23:34:46 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Gl/KqOOAg3rH0hWZUovhxw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:G17vptu+2rEUXbsqVtoXzQ
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -8,7 +8,7 @@ use base 'DBIx::Class';
__PACKAGE__->load_components("Core"); __PACKAGE__->load_components("Core");
__PACKAGE__->table("buildLogs"); __PACKAGE__->table("buildLogs");
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
"buildid", "build",
{ data_type => "integer", is_nullable => 0, size => undef }, { data_type => "integer", is_nullable => 0, size => undef },
"logphase", "logphase",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
@ -17,16 +17,12 @@ __PACKAGE__->add_columns(
"type", "type",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
); );
__PACKAGE__->set_primary_key("buildid", "logphase"); __PACKAGE__->set_primary_key("build", "logphase");
__PACKAGE__->belongs_to( __PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" });
"buildid",
"HydraFrontend::Schema::Builds",
{ id => "buildid" },
);
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-08 23:34:46 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:tlyJLjDbR0vk3Jt/O3M4nw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:xvWlrugDQD11vH+7f91K0A
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -8,7 +8,7 @@ use base 'DBIx::Class';
__PACKAGE__->load_components("Core"); __PACKAGE__->load_components("Core");
__PACKAGE__->table("buildProducts"); __PACKAGE__->table("buildProducts");
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
"buildid", "build",
{ data_type => "integer", is_nullable => 0, size => undef }, { data_type => "integer", is_nullable => 0, size => undef },
"path", "path",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
@ -17,16 +17,12 @@ __PACKAGE__->add_columns(
"subtype", "subtype",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
); );
__PACKAGE__->set_primary_key("buildid", "path"); __PACKAGE__->set_primary_key("build", "path");
__PACKAGE__->belongs_to( __PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" });
"buildid",
"HydraFrontend::Schema::Builds",
{ id => "buildid" },
);
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-08 23:34:46 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:lCdfeZud7izQv/11dVFFVA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:SMsT6htcybeWNHhv82+ilA
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -39,25 +39,25 @@ __PACKAGE__->add_columns(
); );
__PACKAGE__->set_primary_key("id"); __PACKAGE__->set_primary_key("id");
__PACKAGE__->has_many( __PACKAGE__->has_many(
"buildinputs", "inputs",
"HydraFrontend::Schema::Buildinputs", "HydraFrontend::Schema::Inputs",
{ "foreign.buildid" => "self.id" }, { "foreign.build" => "self.id" },
); );
__PACKAGE__->has_many( __PACKAGE__->has_many(
"buildproducts", "buildproducts",
"HydraFrontend::Schema::Buildproducts", "HydraFrontend::Schema::Buildproducts",
{ "foreign.buildid" => "self.id" }, { "foreign.build" => "self.id" },
); );
__PACKAGE__->has_many( __PACKAGE__->has_many(
"buildlogs", "buildlogs",
"HydraFrontend::Schema::Buildlogs", "HydraFrontend::Schema::Buildlogs",
{ "foreign.buildid" => "self.id" }, { "foreign.build" => "self.id" },
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-08 23:34:46 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:JRXGOLW2h+DOY7LZUdkCWQ # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:nfVureYYGM1V/NHroQA5Tw
__PACKAGE__->has_many(dependentBuildInputs => 'HydraFrontend::Schema::Buildinputs', 'inputid'); __PACKAGE__->has_many(dependents => 'HydraFrontend::Schema::Inputs', 'dependency');
1; 1;

View file

@ -1,4 +1,4 @@
package HydraFrontend::Schema::Buildinputs; package HydraFrontend::Schema::Inputs;
use strict; use strict;
use warnings; use warnings;
@ -6,9 +6,13 @@ use warnings;
use base 'DBIx::Class'; use base 'DBIx::Class';
__PACKAGE__->load_components("Core"); __PACKAGE__->load_components("Core");
__PACKAGE__->table("buildInputs"); __PACKAGE__->table("inputs");
__PACKAGE__->add_columns( __PACKAGE__->add_columns(
"buildid", "id",
{ data_type => "integer", is_nullable => 0, size => undef },
"build",
{ data_type => "integer", is_nullable => 0, size => undef },
"job",
{ data_type => "integer", is_nullable => 0, size => undef }, { data_type => "integer", is_nullable => 0, size => undef },
"name", "name",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
@ -20,28 +24,20 @@ __PACKAGE__->add_columns(
{ data_type => "integer", is_nullable => 0, size => undef }, { data_type => "integer", is_nullable => 0, size => undef },
"tag", "tag",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
"inputid", "value",
{ data_type => "text", is_nullable => 0, size => undef },
"dependency",
{ data_type => "integer", is_nullable => 0, size => undef }, { data_type => "integer", is_nullable => 0, size => undef },
"path", "path",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
"value",
{ data_type => "text", is_nullable => 0, size => undef },
);
__PACKAGE__->set_primary_key("buildid", "name");
__PACKAGE__->belongs_to(
"buildid",
"HydraFrontend::Schema::Builds",
{ id => "buildid" },
); );
__PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" });
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-08 23:34:46 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:2XeATQWeO3i3eSHlquS2QA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:3PAsUD+79bZk4vGeSyyACg
__PACKAGE__->belongs_to( __PACKAGE__->belongs_to("dependency", "HydraFrontend::Schema::Builds", { id => "dependency" });
"build",
"HydraFrontend::Schema::Builds",
{ id => "inputid" },
);
1; 1;

View file

@ -0,0 +1,40 @@
package HydraFrontend::Schema::Jobs;
use strict;
use warnings;
use base 'DBIx::Class';
__PACKAGE__->load_components("Core");
__PACKAGE__->table("jobs");
__PACKAGE__->add_columns(
"id",
{ data_type => "integer", is_nullable => 0, size => undef },
"timestamp",
{ data_type => "integer", is_nullable => 0, size => undef },
"priority",
{ data_type => "integer", is_nullable => 0, size => undef },
"project",
{ data_type => "text", is_nullable => 0, size => undef },
"jobset",
{ data_type => "text", is_nullable => 0, size => undef },
"attrname",
{ data_type => "text", is_nullable => 0, size => undef },
"description",
{ data_type => "text", is_nullable => 0, size => undef },
"drvpath",
{ data_type => "text", is_nullable => 0, size => undef },
"outpath",
{ data_type => "text", is_nullable => 0, size => undef },
"system",
{ data_type => "text", is_nullable => 0, size => undef },
);
__PACKAGE__->set_primary_key("id");
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:T8O0XTTOZXapWpJbzjKLTw
# You can replace this text with custom content, and it will be preserved on regeneration
1;

View file

@ -33,8 +33,8 @@ __PACKAGE__->belongs_to(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-08 23:34:46 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:m24w17dWVxjIqPlea77G3A # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:DzEHCDlnponciGmGASknlg
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -43,8 +43,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-08 23:34:46 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ufIbhVFTzl7awpRrZofvJQ # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Lm2oIWEUSHFICYMX2qmTfw
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -40,8 +40,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-08 23:34:46 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:7hm28Izo7wCZc07fH1EJRg # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:EmATMMeNmMd2AI8lVzcLFA
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -19,8 +19,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-08 23:34:46 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-09 01:36:21
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:WCqXnL5vOhpwjYB9/Aw7tg # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZifQocKoHOPRrJQSPggZ+w
# You can replace this text with custom content, and it will be preserved on regeneration # You can replace this text with custom content, and it will be preserved on regeneration

View file

@ -33,11 +33,11 @@
</tr> </tr>
<tr> <tr>
<th>Build started:</th> <th>Build started:</th>
<td>[% date.format(build.starttime, '%Y-%m-%d %H:%M:%S') %]</td> <td>[% IF build.starttime %][% date.format(build.starttime, '%Y-%m-%d %H:%M:%S') %][% ELSE %]<em>(cached build)</em>[% END %]</td>
</tr> </tr>
<tr> <tr>
<th>Build finished:</th> <th>Build finished:</th>
<td>[% date.format(build.stoptime, '%Y-%m-%d %H:%M:%S') %]</td> <td>[% IF build.stoptime %][% date.format(build.stoptime, '%Y-%m-%d %H:%M:%S') %][% ELSE %]<em>(cached build)</em>[% END %]</td>
</tr> </tr>
<tr> <tr>
<th>Duration (seconds):</th> <th>Duration (seconds):</th>
@ -81,13 +81,13 @@
<tr><th>Name</th><th>Type</th><th>What</th><th>Store path</th></tr> <tr><th>Name</th><th>Type</th><th>What</th><th>Store path</th></tr>
</thead> </thead>
<tbody> <tbody>
[% FOREACH input IN build.buildinputs -%] [% FOREACH input IN build.inputs -%]
<tr> <tr>
<td><tt>[% input.name %]</tt></td> <td><tt>[% input.name %]</tt></td>
<td><tt>[% input.type %]</tt></td> <td><tt>[% input.type %]</tt></td>
<td> <td>
[% IF input.type == "build" %] [% IF input.type == "build" %]
<a href="[% c.uri_for('/build' input.inputid) %]">Job <tt>[% input.build.project %]:[% input.build.attrname %]</tt> build [% input.inputid %]</a> <a href="[% c.uri_for('/build' input.dependency.id) %]">Job <tt>[% input.dependency.project %]:[% input.dependency.attrname %]</tt> build [% input.dependency.id %]</a>
[% ELSIF input.type == "string" %] [% ELSIF input.type == "string" %]
<tt>"[% input.value %]"</tt> <tt>"[% input.value %]"</tt>
[% ELSE %] [% ELSE %]
@ -140,7 +140,7 @@
</table> </table>
[% IF build.dependentBuildInputs %] [% IF build.dependents %]
<h2>Used by</h2> <h2>Used by</h2>
@ -151,12 +151,12 @@
<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.dependentBuildInputs -%] [% FOREACH input IN build.dependents -%]
<tr> <tr>
<td><a href="[% c.uri_for('/build' input.buildid.id) %]">Job <tt>[% input.buildid.project %]:[% input.buildid.attrname %]</tt> build [% input.buildid.id %]</a></td> <td><a href="[% c.uri_for('/build' input.build.id) %]">Job <tt>[% input.build.project %]:[% input.build.attrname %]</tt> build [% input.build.id %]</a></td>
<td><tt>[% input.name %]</tt></td> <td><tt>[% input.name %]</tt></td>
<td><tt>[% input.buildid.system %]</tt></td> <td><tt>[% input.build.system %]</tt></td>
<td>[% date.format(input.buildid.timestamp, '%Y-%m-%d %H:%M:%S') %]</td> <td>[% date.format(input.build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td>
</tr> </tr>
[% END -%] [% END -%]
</tbody> </tbody>

View file

@ -30,4 +30,12 @@
</tbody> </tbody>
</table> </table>
<h1>Projects</h1>
<ul>
[% FOREACH project IN projects -%]
<li><a href="[% c.uri_for('/project' project.name) %]"><tt>[% project.name %]</tt></a></li>
[% END -%]
</ul>
[% END %] [% END %]

View file

@ -20,8 +20,13 @@ create table builds (
); );
create table buildInputs ( -- Inputs of jobs/builds.
buildId integer not null, create table inputs (
id integer primary key autoincrement not null,
-- Which job or build this input belongs to. Exactly one must be non-null.
build integer,
job 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,
@ -30,33 +35,33 @@ create table buildInputs (
revision integer, revision integer,
tag text, tag text,
value text, value text,
inputId integer, -- build ID of the input, for type == 'build' dependency integer, -- build ID of the input, for type == 'build'
path text, path text,
primary key (buildId, name), foreign key (build) references builds(id) -- ignored by sqlite
foreign key (buildId) references builds(id) on delete cascade -- ignored by sqlite foreign key (job) references jobs(id) -- ignored by sqlite
foreign key (inputId) references builds(id) -- ignored by sqlite foreign key (dependency) references builds(id) -- ignored by sqlite
); );
create table buildProducts ( create table buildProducts (
buildId integer not null, build integer not null,
path text not null, path text not null,
type text not null, -- "nix-build", "file", "doc", "report", ... type text not null, -- "nix-build", "file", "doc", "report", ...
subtype text not null, -- "source-dist", "rpm", ... subtype text not null, -- "source-dist", "rpm", ...
primary key (buildId, path), primary key (build, path),
foreign key (buildId) references builds(id) on delete cascade -- ignored by sqlite foreign key (build) references builds(id) on delete cascade -- ignored by sqlite
); );
create table buildLogs ( create table buildLogs (
buildId integer not null, build integer not null,
logPhase text not null, logPhase text not null,
path text not null, path text not null,
type text not null, type text not null,
primary key (buildId, logPhase), primary key (build, logPhase),
foreign key (buildId) references builds(id) on delete cascade -- ignored by sqlite foreign key (build) references builds(id) on delete cascade -- ignored by sqlite
); );
@ -64,9 +69,9 @@ create table buildLogs (
create trigger cascadeBuildDeletion create trigger cascadeBuildDeletion
before delete on builds before delete on builds
for each row begin for each row begin
delete from buildInputs where buildId = old.id; --delete from buildInputs where build = old.id;
delete from buildLogs where buildId = old.id; delete from buildLogs where build = old.id;
delete from buildProducts where buildId = old.id; delete from buildProducts where build = old.id;
end; end;
@ -117,10 +122,12 @@ create table jobSetInputAlts (
); );
create table jobQueue ( create table jobs (
id integer primary key autoincrement not null, id integer primary key autoincrement not null,
timestamp integer not null, -- time this build was added to the db (in Unix time) timestamp integer not null, -- time this build was added to the db (in Unix time)
priority integer not null,
-- Info about the inputs. -- Info about the inputs.
project text not null, -- !!! foreign key project text not null, -- !!! foreign key
jobSet text not null, -- !!! foreign key jobSet text not null, -- !!! foreign key

View file

@ -70,15 +70,15 @@ sub buildJob {
foreach my $inputName (keys %{$usedInputs}) { foreach my $inputName (keys %{$usedInputs}) {
my $input = $usedInputs->{$inputName}; my $input = $usedInputs->{$inputName};
$db->resultset('Buildinputs')->create( $db->resultset('Inputs')->create(
{ buildid => $build->id { build => $build->id
, name => $inputName , name => $inputName
, type => $input->{type} , type => $input->{type}
, uri => $input->{uri} , uri => $input->{uri}
#, revision => $input->{orig}->revision #, revision => $input->{orig}->revision
#, tag => $input->{orig}->tag #, tag => $input->{orig}->tag
, value => $input->{value} , value => $input->{value}
, inputid => $input->{id} , dependency => $input->{id}
, path => ($input->{storePath} or "") # !!! temporary hack , path => ($input->{storePath} or "") # !!! temporary hack
}); });
} }
@ -87,7 +87,7 @@ sub buildJob {
if (-e $logPath) { if (-e $logPath) {
print " LOG $logPath\n"; print " LOG $logPath\n";
$db->resultset('Buildlogs')->create( $db->resultset('Buildlogs')->create(
{ buildid => $build->id { build => $build->id
, logphase => "full" , logphase => "full"
, path => $logPath , path => $logPath
, type => "raw" , type => "raw"
@ -100,7 +100,7 @@ sub buildJob {
foreach my $logPath (glob "$outPath/log/*") { foreach my $logPath (glob "$outPath/log/*") {
print " LOG $logPath\n"; print " LOG $logPath\n";
$db->resultset('Buildlogs')->create( $db->resultset('Buildlogs')->create(
{ buildid => $build->id { build => $build->id
, logphase => basename($logPath) , logphase => basename($logPath)
, path => $logPath , path => $logPath
, type => "raw" , type => "raw"
@ -117,7 +117,7 @@ sub buildJob {
my $path = $3; my $path = $3;
die unless -e $path; die unless -e $path;
$db->resultset('Buildproducts')->create( $db->resultset('Buildproducts')->create(
{ buildid => $build->id { build => $build->id
, type => $type , type => $type
, subtype => $subtype , subtype => $subtype
, path => $path , path => $path
@ -126,7 +126,7 @@ sub buildJob {
close LIST; close LIST;
} else { } else {
$db->resultset('Buildproducts')->create( $db->resultset('Buildproducts')->create(
{ buildid => $build->id { build => $build->id
, type => "nix-build" , type => "nix-build"
, subtype => "" , subtype => ""
, path => $outPath , path => $outPath
@ -193,7 +193,10 @@ sub checkJobAlternatives {
my ($project, $jobset, $inputInfo, $nixExprPath, $jobName, $jobExpr, $extraArgs, $argsNeeded, $n) = @_; my ($project, $jobset, $inputInfo, $nixExprPath, $jobName, $jobExpr, $extraArgs, $argsNeeded, $n) = @_;
if ($n >= scalar @{$argsNeeded}) { if ($n >= scalar @{$argsNeeded}) {
checkJob($project, $jobset, $inputInfo, $nixExprPath, $jobName, $jobExpr, $extraArgs); eval {
checkJob($project, $jobset, $inputInfo, $nixExprPath, $jobName, $jobExpr, $extraArgs);
};
warn $@ if $@;
return; return;
} }
@ -303,9 +306,12 @@ sub checkJobSet {
} }
} }
checkJobAlternatives( eval {
$project, $jobset, {}, $nixExprPath, checkJobAlternatives(
$jobName, $jobExpr, "", \@argsNeeded, 0); $project, $jobset, {}, $nixExprPath,
$jobName, $jobExpr, "", \@argsNeeded, 0);
};
warn $@ if $@;
} }
} }