* Store build duration, handle cached builds.

This commit is contained in:
Eelco Dolstra 2008-10-28 17:08:29 +00:00
parent 08798f3c07
commit 5915bcaba3
10 changed files with 70 additions and 33 deletions

View file

@ -31,8 +31,8 @@ sub index :Path :Args(0) {
$c->stash->{template} = 'index.tt'; $c->stash->{template} = 'index.tt';
$c->stash->{allBuilds} = [$c->model('DB::Builds')->all]; $c->stash->{allBuilds} = [$c->model('DB::Builds')->all];
# 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 name == x.name); # 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 => "name", where => "timestamp == (select max(timestamp) from builds where name == me.name)"})]; $c->stash->{latestBuilds} = [$c->model('DB::Builds')->search(undef, {order_by => "jobName", where => "timestamp == (select max(timestamp) from builds where jobName == me.jobName)"})];
} }
@ -40,7 +40,7 @@ sub job :Local {
my ( $self, $c, $jobName ) = @_; my ( $self, $c, $jobName ) = @_;
$c->stash->{template} = 'job.tt'; $c->stash->{template} = 'job.tt';
$c->stash->{jobName} = $jobName; $c->stash->{jobName} = $jobName;
$c->stash->{builds} = [$c->model('DB::Builds')->search({name => $jobName}, {order_by => "timestamp DESC"})]; $c->stash->{builds} = [$c->model('DB::Builds')->search({jobName => $jobName}, {order_by => "timestamp DESC"})];
} }

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-10-25 22:23:27 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-10-28 17:59:29
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:iW1lrJQVyiDiAYhJBy9/iQ # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Fayli8dtSdcAYhfKSZnJwg
# 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

@ -25,8 +25,8 @@ __PACKAGE__->belongs_to(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-10-25 22:23:27 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-10-28 17:59:29
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:01Br5qFsV84USpzqnjk7cw # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:xXiHLBKW5fHl7ukdYeIsTw
# 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

@ -25,8 +25,8 @@ __PACKAGE__->belongs_to(
); );
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-10-25 22:23:27 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-10-28 17:59:29
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:jYe9p4xG2Ujnf6TsfeE7tA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:5SPq4at2/NRvbax49TwfDw
# 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

@ -12,7 +12,7 @@ __PACKAGE__->add_columns(
{ data_type => "integer", is_nullable => 0, size => undef }, { data_type => "integer", is_nullable => 0, size => undef },
"timestamp", "timestamp",
{ data_type => "integer", is_nullable => 0, size => undef }, { data_type => "integer", is_nullable => 0, size => undef },
"name", "jobname",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
"description", "description",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
@ -20,23 +20,31 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
"outpath", "outpath",
{ data_type => "text", is_nullable => 0, size => undef }, { data_type => "text", is_nullable => 0, size => undef },
"iscachedbuild",
{ data_type => "integer", is_nullable => 0, size => undef },
"buildstatus", "buildstatus",
{ data_type => "integer", is_nullable => 0, size => undef }, { 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__->set_primary_key("id");
__PACKAGE__->has_many(
"buildlogs",
"HydraFrontend::Schema::Buildlogs",
{ "foreign.buildid" => "self.id" },
);
__PACKAGE__->has_many( __PACKAGE__->has_many(
"buildproducts", "buildproducts",
"HydraFrontend::Schema::Buildproducts", "HydraFrontend::Schema::Buildproducts",
{ "foreign.buildid" => "self.id" }, { "foreign.buildid" => "self.id" },
); );
__PACKAGE__->has_many(
"buildlogs",
"HydraFrontend::Schema::Buildlogs",
{ "foreign.buildid" => "self.id" },
);
# Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-10-25 22:23:27 # Created by DBIx::Class::Schema::Loader v0.04005 @ 2008-10-28 17:59:29
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:gxVH+2KWcgU41JOl9BbHFA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:gp6ZZpDA2VzgnNE9NX99dA
1; 1;

View file

@ -12,7 +12,7 @@
</tr> </tr>
<tr> <tr>
<th>Job name:</th> <th>Job name:</th>
<td>[% build.name %]</td> <td>[% build.jobname %]</td>
</tr> </tr>
<tr> <tr>
<th>Description:</th> <th>Description:</th>
@ -22,6 +22,16 @@
<th>Time added:</th> <th>Time added:</th>
<td>[% date.format(build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td> <td>[% date.format(build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td>
</tr> </tr>
<tr>
<th>Duration (seconds):</th>
<td>
[% IF build.iscachedbuild %]
<em>(cached build)</em>
[% ELSE %]
[% build.stoptime - build.starttime %]
[% END %]
</td>
</tr>
<tr> <tr>
<th>Derivation store path:</th> <th>Derivation store path:</th>
<td><tt>[% build.drvpath %]</tt></td> <td><tt>[% build.drvpath %]</tt></td>

View file

@ -2,6 +2,8 @@
<h1>Job status</h1> <h1>Job status</h1>
<p>Below are the latest builds for each job.</p>
<table class="tablesorter"> <table class="tablesorter">
<thead> <thead>
<tr><th></th><th>Id</th><th>Job</th><th>Timestamp</th><th>Description</th></tr> <tr><th></th><th>Id</th><th>Job</th><th>Timestamp</th><th>Description</th></tr>

View file

@ -9,7 +9,7 @@
[% END %] [% END %]
</td> </td>
<td><a href="[% c.uri_for('/build' build.id) %]">[% build.id %]</a></td> <td><a href="[% c.uri_for('/build' build.id) %]">[% build.id %]</a></td>
<td><a href="[% c.uri_for('/job' build.name) %]"><tt>[% build.name %]</tt></a></td> <td><a href="[% c.uri_for('/job' build.jobname) %]"><tt>[% build.jobname %]</tt></a></td>
<td>[% date.format(build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td> <td>[% date.format(build.timestamp, '%Y-%m-%d %H:%M:%S') %]</td>
<td>[% build.description %]</td> <td>[% build.description %]</td>
</tr> </tr>

View file

@ -1,11 +1,15 @@
create table builds ( create table builds (
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)
name text not null, jobName text not null,
description text, description text,
drvPath text not null, drvPath text not null,
outPath text not null, outPath text not null,
buildStatus integer -- 0 = succeeded, 1 = failure, ... 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
); );

View file

@ -30,35 +30,48 @@ foreach my $jobName (keys %{$jobs->{item}}) {
my $outPath = $job->{outPath}; my $outPath = $job->{outPath};
my $drvPath = $job->{drvPath}; my $drvPath = $job->{drvPath};
if (scalar(@{$dbh->selectall_arrayref("select * from builds where name = ? and outPath = ?", {}, $jobName, $outPath)}) > 0) { if (scalar(@{$dbh->selectall_arrayref("select * from builds where jobName = ? and outPath = ?", {}, $jobName, $outPath)}) > 0) {
print " already done\n"; print " already done\n";
next; next;
} }
my $res = system("nix-build $jobsFile --attr $jobName"); my $isCachedBuild = 1;
my $buildStatus = 0;
my $startTime = 0;
my $stopTime = 0;
if (system("nix-store --check-validity $outPath 2> /dev/null") != 0) {
$isCachedBuild = 0;
my $buildStatus = $res == 0 ? 0 : 1; $startTime = time();
my $res = system("nix-build $jobsFile --attr $jobName");
$stopTime = time();
$buildStatus = $res == 0 ? 0 : 1;
}
$dbh->begin_work; $dbh->begin_work;
$dbh->prepare("insert into builds(timestamp, name, description, drvPath, outPath, buildStatus) values(?, ?, ?, ?, ?, ?)") $dbh->prepare("insert into builds(timestamp, jobName, description, drvPath, outPath, isCachedBuild, buildStatus, errorMsg, startTime, stopTime) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
->execute(time(), $jobName, $description, $drvPath, $outPath, $buildStatus); ->execute(time(), $jobName, $description, $drvPath, $outPath, $isCachedBuild, $buildStatus, "", $startTime, $stopTime);
my $buildId = $dbh->last_insert_id(undef, undef, undef, undef); my $buildId = $dbh->last_insert_id(undef, undef, undef, undef);
print " db id = $buildId\n"; print " db id = $buildId\n";
my $logPath = "/nix/var/log/nix/drvs/" . basename $drvPath;
if (-e $logPath) {
print " LOG $logPath\n";
$dbh->prepare("insert into buildLogs(buildId, logPhase, path, type) values(?, ?, ?, ?)")
->execute($buildId, "full", $logPath, "raw");
}
if ($buildStatus == 0) { if ($buildStatus == 0) {
$dbh->prepare("insert into buildProducts(buildId, type, subtype, path) values(?, ?, ?, ?)") $dbh->prepare("insert into buildProducts(buildId, type, subtype, path) values(?, ?, ?, ?)")
->execute($buildId, "nix-build", "", $outPath); ->execute($buildId, "nix-build", "", $outPath);
my $logPath = "/nix/var/log/nix/drvs/" . basename $drvPath;
if (-e $logPath) {
print " LOG $logPath\n";
$dbh->prepare("insert into buildLogs(buildId, logPhase, path, type) values(?, ?, ?, ?)")
->execute($buildId, "full", $logPath, "raw");
}
if (-e "$outPath/log") { if (-e "$outPath/log") {
foreach my $logPath (glob "$outPath/log/*") { foreach my $logPath (glob "$outPath/log/*") {
print " LOG $logPath\n"; print " LOG $logPath\n";