diff --git a/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm b/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm index 9bf9caba..5c9e8f91 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm @@ -29,12 +29,17 @@ sub getBuild { sub index :Path :Args(0) { my ( $self, $c ) = @_; $c->stash->{template} = 'index.tt'; - $c->stash->{jobs} = [$c->model('DB::Jobs')->all]; $c->stash->{projects} = [$c->model('DB::Projects')->all]; - $c->stash->{allBuilds} = [$c->model('DB::Builds')->search(undef, {order_by => "timestamp DESC"})]; - # Get the latest build for each unique job. - # select * from builds as x where timestamp == (select max(timestamp) from builds where jobName == x.jobName); - $c->stash->{latestBuilds} = [$c->model('DB::Builds')->search(undef, {order_by => "project, attrName", where => "timestamp == (select max(timestamp) from builds where project == me.project and attrName == me.attrName)"})]; + $c->stash->{scheduled} = [$c->model('DB::Builds')->search( + {finished => 0}, {join => 'schedulingInfo'})]; # !!! + $c->stash->{allBuilds} = [$c->model('DB::Builds')->search( + {finished => 1}, {order_by => "timestamp DESC"})]; + # Get the latest finished build for each unique job. + $c->stash->{latestBuilds} = [$c->model('DB::Builds')->search(undef, + { join => 'resultInfo' + , where => "finished != 0 and timestamp = (select max(timestamp) from Builds where project == me.project and attrName == me.attrName)" + , order_by => "project, attrname" + })]; } @@ -54,7 +59,9 @@ sub job :Local { $c->stash->{template} = 'job.tt'; $c->stash->{projectName} = $project; $c->stash->{jobName} = $jobName; - $c->stash->{builds} = [$c->model('DB::Builds')->search({project => $project, attrName => $jobName}, {order_by => "timestamp DESC"})]; + $c->stash->{builds} = [$c->model('DB::Builds')->search( + {finished => 1, project => $project, attrName => $jobName}, + {order_by => "timestamp DESC"})]; } diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema.pm b/src/HydraFrontend/lib/HydraFrontend/Schema.pm index e9b028ed..052fc9cf 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Schema.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Schema.pm @@ -8,8 +8,8 @@ use base 'DBIx::Class::Schema'; __PACKAGE__->load_classes; -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dBO/r6lVlITiJ/HlltKcpQ +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:1AgCf4sf5h2RU24Slo0sTA # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Inputs.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildinputs.pm similarity index 69% rename from src/HydraFrontend/lib/HydraFrontend/Schema/Inputs.pm rename to src/HydraFrontend/lib/HydraFrontend/Schema/Buildinputs.pm index 0781f01b..eda11d4d 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Schema/Inputs.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildinputs.pm @@ -1,4 +1,4 @@ -package HydraFrontend::Schema::Inputs; +package HydraFrontend::Schema::Buildinputs; use strict; use warnings; @@ -6,14 +6,12 @@ use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components("Core"); -__PACKAGE__->table("inputs"); +__PACKAGE__->table("BuildInputs"); __PACKAGE__->add_columns( "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 }, "name", { data_type => "text", is_nullable => 0, size => undef }, "type", @@ -33,11 +31,16 @@ __PACKAGE__->add_columns( ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" }); +__PACKAGE__->belongs_to( + "dependency", + "HydraFrontend::Schema::Builds", + { id => "dependency" }, +); -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:A3Is4VTFkTl2DzrYjzdrZA +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dKMSSomUN+gJX57Z5e295w -__PACKAGE__->belongs_to("dependency", "HydraFrontend::Schema::Builds", { id => "dependency" }); +# You can replace this text with custom content, and it will be preserved on regeneration 1; diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Buildlogs.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildlogs.pm index 2b6843fd..2f21bb8f 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Schema/Buildlogs.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildlogs.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components("Core"); -__PACKAGE__->table("buildLogs"); +__PACKAGE__->table("BuildLogs"); __PACKAGE__->add_columns( "build", { data_type => "integer", is_nullable => 0, size => undef }, @@ -21,8 +21,8 @@ __PACKAGE__->set_primary_key("build", "logphase"); __PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" }); -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:eMNna7u2l0ec+OYuvtGRpg +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZOxJeT+ltgyc/zuDl9aEDQ # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Buildproducts.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildproducts.pm index 68797703..22ef546a 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Schema/Buildproducts.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildproducts.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components("Core"); -__PACKAGE__->table("buildProducts"); +__PACKAGE__->table("BuildProducts"); __PACKAGE__->add_columns( "build", { data_type => "integer", is_nullable => 0, size => undef }, @@ -21,8 +21,8 @@ __PACKAGE__->set_primary_key("build", "path"); __PACKAGE__->belongs_to("build", "HydraFrontend::Schema::Builds", { id => "build" }); -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LaXQ4zxxvzdKFBRVcjMdMQ +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:rZPTilX/PAiIoxffxc0nJw # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Buildresultinfo.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildresultinfo.pm new file mode 100644 index 00000000..1125256d --- /dev/null +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildresultinfo.pm @@ -0,0 +1,33 @@ +package HydraFrontend::Schema::Buildresultinfo; + +use strict; +use warnings; + +use base 'DBIx::Class'; + +__PACKAGE__->load_components("Core"); +__PACKAGE__->table("BuildResultInfo"); +__PACKAGE__->add_columns( + "id", + { data_type => "integer", is_nullable => 0, size => undef }, + "iscachedbuild", + { data_type => "integer", is_nullable => 0, size => undef }, + "buildstatus", + { data_type => "integer", is_nullable => 0, size => undef }, + "errormsg", + { data_type => "text", is_nullable => 0, size => undef }, + "starttime", + { data_type => "integer", is_nullable => 0, size => undef }, + "stoptime", + { data_type => "integer", is_nullable => 0, size => undef }, +); +__PACKAGE__->set_primary_key("id"); +__PACKAGE__->belongs_to("id", "HydraFrontend::Schema::Builds", { id => "id" }); + + +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:2Vfqs9RUhbDrje18yZb3AA + + +# You can replace this text with custom content, and it will be preserved on regeneration +1; diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Builds.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Builds.pm index c92253ae..92d358d6 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Schema/Builds.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Builds.pm @@ -6,10 +6,12 @@ use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components("Core"); -__PACKAGE__->table("builds"); +__PACKAGE__->table("Builds"); __PACKAGE__->add_columns( "id", { data_type => "integer", is_nullable => 0, size => undef }, + "finished", + { data_type => "integer", is_nullable => 0, size => undef }, "timestamp", { data_type => "integer", is_nullable => 0, size => undef }, "project", @@ -24,16 +26,6 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 0, size => undef }, "outpath", { data_type => "text", is_nullable => 0, size => undef }, - "iscachedbuild", - { data_type => "integer", is_nullable => 0, size => undef }, - "buildstatus", - { data_type => "integer", is_nullable => 0, size => undef }, - "errormsg", - { data_type => "text", is_nullable => 0, size => undef }, - "starttime", - { data_type => "integer", is_nullable => 0, size => undef }, - "stoptime", - { data_type => "integer", is_nullable => 0, size => undef }, "system", { data_type => "text", is_nullable => 0, size => undef }, ); @@ -49,10 +41,25 @@ __PACKAGE__->belongs_to( { name => "jobset", project => "project" }, ); __PACKAGE__->has_many( - "inputs", - "HydraFrontend::Schema::Inputs", + "buildschedulinginfoes", + "HydraFrontend::Schema::Buildschedulinginfo", + { "foreign.id" => "self.id" }, +); +__PACKAGE__->has_many( + "buildresultinfoes", + "HydraFrontend::Schema::Buildresultinfo", + { "foreign.id" => "self.id" }, +); +__PACKAGE__->has_many( + "buildinputs_builds", + "HydraFrontend::Schema::Buildinputs", { "foreign.build" => "self.id" }, ); +__PACKAGE__->has_many( + "buildinputs_dependencies", + "HydraFrontend::Schema::Buildinputs", + { "foreign.dependency" => "self.id" }, +); __PACKAGE__->has_many( "buildproducts", "HydraFrontend::Schema::Buildproducts", @@ -65,9 +72,23 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:C1XPkCXQImyXduKER0Dllg +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:1GZeB3YVr064AZrGargmFg -__PACKAGE__->has_many(dependents => 'HydraFrontend::Schema::Inputs', 'dependency'); +__PACKAGE__->has_many(dependents => 'HydraFrontend::Schema::Buildinputs', 'dependency'); + +__PACKAGE__->has_many(inputs => 'HydraFrontend::Schema::Buildinputs', 'build'); + +__PACKAGE__->belongs_to( + "schedulingInfo", + "HydraFrontend::Schema::Buildschedulinginfo", + { id => "id" }, +); + +__PACKAGE__->belongs_to( + "resultInfo", + "HydraFrontend::Schema::Buildresultinfo", + { id => "id" }, +); 1; diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Buildschedulinginfo.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildschedulinginfo.pm new file mode 100644 index 00000000..851a75b0 --- /dev/null +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Buildschedulinginfo.pm @@ -0,0 +1,31 @@ +package HydraFrontend::Schema::Buildschedulinginfo; + +use strict; +use warnings; + +use base 'DBIx::Class'; + +__PACKAGE__->load_components("Core"); +__PACKAGE__->table("BuildSchedulingInfo"); +__PACKAGE__->add_columns( + "id", + { data_type => "integer", is_nullable => 0, size => undef }, + "priority", + { data_type => "integer", is_nullable => 0, size => undef }, + "busy", + { data_type => "integer", is_nullable => 0, size => undef }, + "locker", + { data_type => "text", is_nullable => 0, size => undef }, + "logfile", + { data_type => "text", is_nullable => 0, size => undef }, +); +__PACKAGE__->set_primary_key("id"); +__PACKAGE__->belongs_to("id", "HydraFrontend::Schema::Builds", { id => "id" }); + + +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:rN7v2+MnC8TkrEHUzt2Gqg + + +# You can replace this text with custom content, and it will be preserved on regeneration +1; diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Jobs.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Jobs.pm deleted file mode 100644 index 86250094..00000000 --- a/src/HydraFrontend/lib/HydraFrontend/Schema/Jobs.pm +++ /dev/null @@ -1,58 +0,0 @@ -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 }, - "busy", - { data_type => "integer", is_nullable => 0, size => undef }, - "locker", - { data_type => "text", 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"); -__PACKAGE__->belongs_to( - "project", - "HydraFrontend::Schema::Projects", - { name => "project" }, -); -__PACKAGE__->belongs_to( - "jobset", - "HydraFrontend::Schema::Jobsets", - { name => "jobset", project => "project" }, -); - - -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZF8UB1MtbPuOk7wTSFJR5Q - -__PACKAGE__->has_many( - "inputs", - "HydraFrontend::Schema::Inputs", - { "foreign.job" => "self.id" }, -); - -1; diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsetinputalts.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsetinputalts.pm index 033c2c50..f7603979 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsetinputalts.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsetinputalts.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components("Core"); -__PACKAGE__->table("jobsetInputAlts"); +__PACKAGE__->table("JobsetInputAlts"); __PACKAGE__->add_columns( "project", { data_type => "text", is_nullable => 0, size => undef }, @@ -33,8 +33,8 @@ __PACKAGE__->belongs_to( ); -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ibTncC1AslPWt1eiTtwplA +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:bvEulSFMDlAMs39sIyHgZQ # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsetinputs.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsetinputs.pm index f17cf73d..61bfcfd3 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsetinputs.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsetinputs.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components("Core"); -__PACKAGE__->table("jobsetInputs"); +__PACKAGE__->table("JobsetInputs"); __PACKAGE__->add_columns( "project", { data_type => "text", is_nullable => 0, size => undef }, @@ -43,8 +43,8 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:D1UzSZwPtwDmOI7q6g8uKQ +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:54xK3D1D0Jm5oKgRelXN7Q # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsets.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsets.pm index 91af1263..06f0d939 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsets.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Jobsets.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components("Core"); -__PACKAGE__->table("jobsets"); +__PACKAGE__->table("Jobsets"); __PACKAGE__->add_columns( "name", { data_type => "text", is_nullable => 0, size => undef }, @@ -46,18 +46,10 @@ __PACKAGE__->has_many( "foreign.project" => "self.project", }, ); -__PACKAGE__->has_many( - "jobs", - "HydraFrontend::Schema::Jobs", - { - "foreign.jobset" => "self.name", - "foreign.project" => "self.project", - }, -); -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:6Pyrgervmq03S5Nx8QfA1Q +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:JHirlq7Jc8dQOy+Op/VflA # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/src/HydraFrontend/lib/HydraFrontend/Schema/Projects.pm b/src/HydraFrontend/lib/HydraFrontend/Schema/Projects.pm index 1c1104c1..564297e5 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Schema/Projects.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Schema/Projects.pm @@ -6,7 +6,7 @@ use warnings; use base 'DBIx::Class'; __PACKAGE__->load_components("Core"); -__PACKAGE__->table("projects"); +__PACKAGE__->table("Projects"); __PACKAGE__->add_columns( "name", { data_type => "text", is_nullable => 0, size => undef }, @@ -22,15 +22,10 @@ __PACKAGE__->has_many( "HydraFrontend::Schema::Jobsets", { "foreign.project" => "self.name" }, ); -__PACKAGE__->has_many( - "jobs", - "HydraFrontend::Schema::Jobs", - { "foreign.project" => "self.name" }, -); -# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-10 14:25:07 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:p8LbF31qRl/JfMK5wfkeCg +# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-11-11 13:41:38 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:7Ag5ZfYVgfw3MJZkNUmBYw # You can replace this text with custom content, and it will be preserved on regeneration diff --git a/src/HydraFrontend/root/build.tt b/src/HydraFrontend/root/build.tt index 2b7137c3..67f29b2b 100644 --- a/src/HydraFrontend/root/build.tt +++ b/src/HydraFrontend/root/build.tt @@ -1,7 +1,12 @@ [% WRAPPER layout.tt title="Hydra Overview" %] [% USE date %] -
[% ELSE %]
[% END %]
[% ELSE %]
diff --git a/src/build.pl b/src/build.pl
index d449f71a..b35e7aa5 100644
--- a/src/build.pl
+++ b/src/build.pl
@@ -16,11 +16,11 @@ sub isValidPath {
}
-sub buildJob {
- my ($job) = @_;
+sub doBuild {
+ my ($build) = @_;
- my $drvPath = $job->drvpath;
- my $outPath = $job->outpath;
+ my $drvPath = $build->drvpath;
+ my $outPath = $build->outpath;
my $isCachedBuild = 1;
my $outputCreated = 1; # i.e., the Nix build succeeded (but it could be a positive failure)
@@ -52,27 +52,17 @@ sub buildJob {
}
$db->txn_do(sub {
- my $build = $db->resultset('Builds')->create(
- { timestamp => time()
- , project => $job->project->name
- , jobset => $job->jobset->name
- , attrname => $job->attrname
- , description => $job->description
- , drvpath => $drvPath
- , outpath => $outPath
+ $build->finished(1);
+ $build->timestamp(time());
+ $build->update;
+
+ $db->resultset('Buildresultinfo')->create(
+ { id => $build->id
, iscachedbuild => $isCachedBuild
, buildstatus => $buildStatus
, starttime => $startTime
, stoptime => $stopTime
- , system => $job->system
});
- print " build ID = ", $build->id, "\n";
-
- foreach my $input ($job->inputs) {
- $input->job(undef);
- $input->build($build->id);
- $input->update;
- }
my $logPath = "/nix/var/log/nix/drvs/" . basename $drvPath;
if (-e $logPath) {
@@ -125,47 +115,44 @@ sub buildJob {
}
}
- $job->delete;
-
+ $build->schedulingInfo->delete;
});
-
- print "STOP ", time, "\n";
}
-my $jobId = $ARGV[0] or die;
-print "building job $jobId\n";
+my $buildId = $ARGV[0] or die;
+print "performing build $buildId\n";
-# Lock the job. If necessary, steal the lock from the parent process
-# (runner.pl). This is so that if the runner dies, the children
-# (i.e. the job builders) can continue to run and won't have the lock
-# taken away.
-my $job;
+# Lock the build. If necessary, steal the lock from the parent
+# process (runner.pl). This is so that if the runner dies, the
+# children (i.e. the build.pl instances) can continue to run and won't
+# have the lock taken away.
+my $build;
$db->txn_do(sub {
- ($job) = $db->resultset('Jobs')->search({ id => $jobId });
- die "job $jobId doesn't exist" unless defined $job;
- if ($job->busy != 0 && $job->locker != getppid) {
- die "job $jobId is already being built";
+ ($build) = $db->resultset('Builds')->search({id => $buildId});
+ die "build $buildId doesn't exist" unless defined $build;
+ if ($build->schedulingInfo->busy != 0 && $build->schedulingInfo->locker != getppid) {
+ die "build $buildId is already being built";
}
- $job->busy(1);
- $job->locker($$);
- $job->update;
+ $build->schedulingInfo->busy(1);
+ $build->schedulingInfo->locker($$);
+ $build->schedulingInfo->update;
});
-die unless $job;
+die unless $build;
-# Build the job. If it throws an error, unlock the job so that it can
-# be retried.
+# Do the build. If it throws an error, unlock the build so that it
+# can be retried.
eval {
print "BUILD\n";
- buildJob $job;
+ doBuild $build;
print "DONE\n";
};
if ($@) {
warn $@;
$db->txn_do(sub {
- $job->busy(0);
- $job->locker($$);
- $job->update;
+ $build->schedulingInfo->busy(0);
+ $build->schedulingInfo->locker($$);
+ $build->schedulingInfo->update;
});
}
diff --git a/src/hydra.sql b/src/hydra.sql
index ab9e9bb5..bd3b6d7c 100644
--- a/src/hydra.sql
+++ b/src/hydra.sql
@@ -1,6 +1,15 @@
-create table builds (
+-- This table contains all builds, either scheduled or finished. For
+-- scheduled builds, additional info (such as the priority) can be
+-- found in the BuildSchedulingInfo table. For finished builds,
+-- additional info (such as the logs, build products, etc.) can be
+-- found in several tables, such as BuildResultInfo, BuildLogs and
+-- BuildProducts.
+create table Builds (
id integer primary key autoincrement not null,
- timestamp integer not null, -- time this build was added to the db (in Unix time)
+
+ finished integer not null, -- 0 = scheduled, 1 = finished
+
+ timestamp integer not null, -- time this build was scheduled / finished building
-- Info about the inputs.
project text not null, -- !!! foreign key
@@ -11,25 +20,51 @@ create table builds (
description text,
drvPath text not null,
outPath text not null,
- isCachedBuild integer not null, -- boolean
- buildStatus integer, -- 0 = succeeded, 1 = Nix build failure, 2 = positive build failure
- errorMsg text, -- error message in case of a Nix failure
- startTime integer, -- in Unix time, 0 = used cached build result
- stopTime integer,
system text not null,
-
- foreign key (project) references projects(name), -- ignored by sqlite
- foreign key (project, jobset) references jobsets(project, name) -- ignored by sqlite
+
+ foreign key (project) references Projects(name), -- ignored by sqlite
+ foreign key (project, jobset) references Jobsets(project, name) -- ignored by sqlite
);
--- Inputs of jobs/builds.
-create table inputs (
+-- Info for a scheduled build.
+create table BuildSchedulingInfo (
+ id integer primary key not null,
+
+ priority integer not null default 0,
+
+ busy integer not null default 0, -- true means someone is building this job now
+ locker text not null default '', -- !!! hostname/pid of the process building this job?
+
+ logfile text, -- if busy, the path of the logfile
+
+ foreign key (id) references Builds(id) on delete cascade -- ignored by sqlite
+);
+
+
+-- Info for a finished build.
+create table BuildResultInfo (
+ id integer primary key not null,
+
+ isCachedBuild integer not null, -- boolean
+
+ buildStatus integer, -- 0 = succeeded, 1 = Nix build failure, 2 = positive build failure
+
+ errorMsg text, -- error message in case of a Nix failure
+
+ startTime integer, -- in Unix time, 0 = used cached build result
+ stopTime integer,
+
+ foreign key (id) references Builds(id) on delete cascade -- ignored by sqlite
+);
+
+
+-- Inputs of builds.
+create table BuildInputs (
id integer primary key autoincrement not null,
- -- Which job or build this input belongs to. Exactly one must be non-null.
+ -- Which build this input belongs to.
build integer,
- job integer,
-- Copied from the jobsetinputs from which the build was created.
name text not null,
@@ -42,29 +77,28 @@ create table inputs (
path text,
- foreign key (build) references builds(id) -- ignored by sqlite
- foreign key (job) references jobs(id) -- ignored by sqlite
- foreign key (dependency) references builds(id) -- ignored by sqlite
+ foreign key (build) references Builds(id) on delete cascade, -- ignored by sqlite
+ foreign key (dependency) references Builds(id) -- ignored by sqlite
);
-create table buildProducts (
+create table BuildProducts (
build integer not null,
path text not null,
type text not null, -- "nix-build", "file", "doc", "report", ...
subtype text not null, -- "source-dist", "rpm", ...
primary key (build, path),
- foreign key (build) 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 (
build integer not null,
logPhase text not null,
path text not null,
type text not null,
primary key (build, logPhase),
- foreign key (build) references builds(id) on delete cascade -- ignored by sqlite
+ foreign key (build) references Builds(id) on delete cascade -- ignored by sqlite
);
@@ -72,13 +106,15 @@ create table buildLogs (
create trigger cascadeBuildDeletion
before delete on builds
for each row begin
- --delete from buildInputs where build = old.id;
- delete from buildLogs where build = old.id;
- delete from buildProducts where build = old.id;
+ delete from BuildSchedulingInfo where id = old.id;
+ delete from BuildResultInfo where id = old.id;
+ delete from BuildInputs where build = old.id;
+ delete from BuildLogs where build = old.id;
+ delete from BuildProducts where build = old.id;
end;
-create table projects (
+create table Projects (
name text primary key not null
);
@@ -86,29 +122,29 @@ create table projects (
-- A jobset consists of a set of inputs (e.g. SVN repositories), one
-- of which contains a Nix expression containing an attribute set
-- describing build jobs.
-create table jobsets (
+create table Jobsets (
name text not null,
project text not null,
description text,
nixExprInput text not null, -- name of the jobsetInput containing the Nix expression
nixExprPath text not null, -- relative path of the Nix expression
primary key (project, name),
- foreign key (project) references projects(name) on delete cascade, -- ignored by sqlite
- foreign key (project, name, nixExprInput) references jobsetInputs(project, job, name)
+ foreign key (project) references Projects(name) on delete cascade, -- ignored by sqlite
+ foreign key (project, name, nixExprInput) references JobsetInputs(project, job, name)
);
-create table jobsetInputs (
+create table JobsetInputs (
project text not null,
jobset text not null,
name text not null,
type text not null, -- "svn", "cvs", "path", "file", "string"
primary key (project, jobset, name),
- foreign key (project, jobset) references jobsets(project, name) on delete cascade -- ignored by sqlite
+ foreign key (project, jobset) references Jobsets(project, name) on delete cascade -- ignored by sqlite
);
-create table jobsetInputAlts (
+create table JobsetInputAlts (
project text not null,
jobset text not null,
input text not null,
@@ -121,30 +157,5 @@ create table jobsetInputAlts (
value text, -- for type == 'string'
primary key (project, jobset, input, altnr),
- foreign key (project, jobset, input) references jobsetInputs(project, jobset, name) on delete cascade -- ignored by sqlite
-);
-
-
-create table jobs (
- id integer primary key autoincrement not null,
- timestamp integer not null, -- time this build was added to the db (in Unix time)
-
- priority integer not null default 0,
-
- busy integer not null default 0, -- true means someone is building this job now
- locker text not null default '', -- !!! hostname/pid of the process building this job?
-
- -- Info about the inputs.
- project text not null, -- !!! foreign key
- jobset text not null, -- !!! foreign key
- attrName text not null,
-
- -- What this job will build.
- description text,
- drvPath text not null,
- outPath text not null,
- system text not null,
-
- foreign key (project) references projects(name), -- ignored by sqlite
- foreign key (project, jobset) references jobsets(project, name) -- ignored by sqlite
+ foreign key (project, jobset, input) references JobsetInputs(project, jobset, name) on delete cascade -- ignored by sqlite
);
diff --git a/src/runner.pl b/src/runner.pl
index 7889eb74..8d45721a 100644
--- a/src/runner.pl
+++ b/src/runner.pl
@@ -12,14 +12,16 @@ $db->storage->dbh->do("PRAGMA synchronous = OFF;");
# Unlock jobs whose building process has died.
$db->txn_do(sub {
- my @jobs = $db->resultset('Jobs')->search({ busy => 1 });
+ my @jobs = $db->resultset('Builds')->search(
+ {finished => 0, busy => 1}, {join => 'schedulingInfo'});
foreach my $job (@jobs) {
- my $pid = $job->locker;
+ print $job, "\n";
+ my $pid = $job->schedulingInfo->locker;
if (kill(0, $pid) != 1) { # see if we can signal the process
print "job ", $job->id, " pid $pid died, unlocking\n";
- $job->busy(0);
- $job->locker("");
- $job->update;
+ $job->schedulingInfo->busy(0);
+ $job->schedulingInfo->locker("");
+ $job->schedulingInfo->update;
}
}
});
@@ -32,15 +34,17 @@ sub checkJobs {
$db->txn_do(sub {
- my @jobs = $db->resultset('Jobs')->search({ busy => 0 }, {order_by => ["priority", "timestamp"]});
+ my @jobs = $db->resultset('Builds')->search(
+ {finished => 0, busy => 0},
+ {join => 'schedulingInfo', order_by => ["priority", "timestamp"]});
print "# of available jobs: ", scalar(@jobs), "\n";
if (scalar @jobs > 0) {
$job = $jobs[0];
- $job->busy(1);
- $job->locker($$);
- $job->update;
+ $job->schedulingInfo->busy(1);
+ $job->schedulingInfo->locker($$);
+ $job->schedulingInfo->update;
}
});
@@ -66,9 +70,9 @@ sub checkJobs {
if ($@) {
warn $@;
$db->txn_do(sub {
- $job->busy(0);
- $job->locker($$);
- $job->update;
+ $job->schedulingInfo->busy(0);
+ $job->schedulingInfo->locker($$);
+ $job->schedulingInfo->update;
});
}
}
diff --git a/src/scheduler.pl b/src/scheduler.pl
index d1731b9d..c74bdd69 100644
--- a/src/scheduler.pl
+++ b/src/scheduler.pl
@@ -67,24 +67,15 @@ sub checkJob {
{ project => $project->name, jobset => $jobset->name
, attrname => $jobName, outPath => $outPath })) > 0)
{
- print " already done\n";
+ print " already scheduled/done\n";
return;
}
- if (scalar($db->resultset('Jobs')->search(
- { project => $project->name, jobset => $jobset->name
- , attrname => $jobName, outPath => $outPath })) > 0)
- {
- print " already queued\n";
- return;
- }
-
print " adding to queue\n";
- my $job = $db->resultset('Jobs')->create(
- { timestamp => time()
- , priority => 0
- , busy => 0
- , locker => ""
+
+ my $build = $db->resultset('Builds')->create(
+ { finished => 0
+ , timestamp => time()
, project => $project->name
, jobset => $jobset->name
, attrname => $jobName
@@ -94,10 +85,17 @@ sub checkJob {
, system => $job->{system}
});
+ $db->resultset('Buildschedulinginfo')->create(
+ { id => $build->id
+ , priority => 0
+ , busy => 0
+ , locker => ""
+ });
+
foreach my $inputName (keys %{$inputInfo}) {
my $input = $inputInfo->{$inputName};
- $db->resultset('Inputs')->create(
- { job => $job->id
+ $db->resultset('Buildinputs')->create(
+ { build => $build->id
, name => $inputName
, type => $input->{type}
, uri => $input->{uri}
@@ -151,8 +149,8 @@ sub checkJobAlternatives {
else {
(my $prevBuild) = $db->resultset('Builds')->search(
- {project => $project->name, jobset => $jobset->name, attrname => $argName, buildStatus => 0},
- {order_by => "timestamp DESC", rows => 1});
+ {finished => 1, project => $project->name, jobset => $jobset->name, attrname => $argName, buildStatus => 0},
+ {join => 'resultInfo', order_by => "timestamp DESC", rows => 1});
if (!defined $prevBuild) {
# !!! reschedule?