forked from lix-project/hydra
* Allow scheduled builds to be cancelled. They're not removed from
the database, just marked as cancelled, because otherwise the scheduler would just add them again.
This commit is contained in:
parent
11360c7aa8
commit
dca6b943d0
|
@ -30,7 +30,7 @@ sub view_build : Chained('build') PathPart('') Args(0) {
|
||||||
$c->stash->{curTime} = time;
|
$c->stash->{curTime} = time;
|
||||||
$c->stash->{available} = isValidPath $build->outpath;
|
$c->stash->{available} = isValidPath $build->outpath;
|
||||||
$c->stash->{drvAvailable} = isValidPath $build->drvpath;
|
$c->stash->{drvAvailable} = isValidPath $build->drvpath;
|
||||||
$c->stash->{flashMsg} = $c->flash->{afterRestart};
|
$c->stash->{flashMsg} = $c->flash->{buildMsg};
|
||||||
|
|
||||||
if (!$build->finished && $build->schedulingInfo->busy) {
|
if (!$build->finished && $build->schedulingInfo->busy) {
|
||||||
my $logfile = $build->schedulingInfo->logfile;
|
my $logfile = $build->schedulingInfo->logfile;
|
||||||
|
@ -156,17 +156,19 @@ sub nix : Chained('build') PathPart('nix') CaptureArgs(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sub restart : Chained('build') PathPart('restart') Args(0) {
|
sub restart : Chained('build') PathPart Args(0) {
|
||||||
my ($self, $c) = @_;
|
my ($self, $c) = @_;
|
||||||
|
|
||||||
my $build = $c->stash->{build};
|
my $build = $c->stash->{build};
|
||||||
|
|
||||||
requireProjectOwner($c, $build->project);
|
requireProjectOwner($c, $build->project);
|
||||||
|
|
||||||
error($c, "This build cannot be restarted.")
|
|
||||||
unless $build->finished && $build->resultInfo->buildstatus == 3;
|
|
||||||
|
|
||||||
$c->model('DB')->schema->txn_do(sub {
|
$c->model('DB')->schema->txn_do(sub {
|
||||||
|
error($c, "This build cannot be restarted.")
|
||||||
|
unless $build->finished &&
|
||||||
|
($build->resultInfo->buildstatus == 3 ||
|
||||||
|
$build->resultInfo->buildstatus == 4);
|
||||||
|
|
||||||
$build->finished(0);
|
$build->finished(0);
|
||||||
$build->timestamp(time());
|
$build->timestamp(time());
|
||||||
$build->update;
|
$build->update;
|
||||||
|
@ -181,7 +183,41 @@ sub restart : Chained('build') PathPart('restart') Args(0) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$c->flash->{afterRestart} = "Build has been restarted.";
|
$c->flash->{buildMsg} = "Build has been restarted.";
|
||||||
|
|
||||||
|
$c->res->redirect($c->uri_for($self->action_for("view_build"), $c->req->captures));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub cancel : Chained('build') PathPart Args(0) {
|
||||||
|
my ($self, $c) = @_;
|
||||||
|
|
||||||
|
my $build = $c->stash->{build};
|
||||||
|
|
||||||
|
requireProjectOwner($c, $build->project);
|
||||||
|
|
||||||
|
$c->model('DB')->schema->txn_do(sub {
|
||||||
|
error($c, "This build cannot be cancelled.")
|
||||||
|
if $build->finished || $build->schedulingInfo->busy;
|
||||||
|
|
||||||
|
# !!! Actually, it would be nice to be able to cancel busy
|
||||||
|
# builds as well, but we would have to send a signal or
|
||||||
|
# something to the build process.
|
||||||
|
|
||||||
|
$build->finished(1);
|
||||||
|
$build->timestamp(time());
|
||||||
|
$build->update;
|
||||||
|
|
||||||
|
$c->model('DB::BuildResultInfo')->create(
|
||||||
|
{ id => $build->id
|
||||||
|
, iscachedbuild => 0
|
||||||
|
, buildstatus => 4 # = cancelled
|
||||||
|
});
|
||||||
|
|
||||||
|
$build->schedulingInfo->delete;
|
||||||
|
});
|
||||||
|
|
||||||
|
$c->flash->{buildMsg} = "Build has been cancelled.";
|
||||||
|
|
||||||
$c->res->redirect($c->uri_for($self->action_for("view_build"), $c->req->captures));
|
$c->res->redirect($c->uri_for($self->action_for("view_build"), $c->req->captures));
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,17 @@
|
||||||
[% ELSIF build.resultInfo.buildstatus == 2 %]
|
[% ELSIF build.resultInfo.buildstatus == 2 %]
|
||||||
<img src="/static/images/failure.gif" alt="Failed" />
|
<img src="/static/images/failure.gif" alt="Failed" />
|
||||||
<span class="error">A dependency of the build failed</span>
|
<span class="error">A dependency of the build failed</span>
|
||||||
|
[% ELSIF build.resultInfo.buildstatus == 4 %]
|
||||||
|
<img src="/static/images/failure.gif" alt="Failed" />
|
||||||
|
<span class="error">Cancelled by user</span>
|
||||||
[% ELSE %]
|
[% ELSE %]
|
||||||
<img src="/static/images/failure.gif" alt="Failed" />
|
<img src="/static/images/failure.gif" alt="Failed" />
|
||||||
<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 %]
|
||||||
|
[% IF build.resultInfo.buildstatus == 3 || build.resultInfo.buildstatus == 4 %]
|
||||||
<form action="[% c.uri_for('/build' build.id 'restart') %]" method="post" class="inline">
|
<form action="[% c.uri_for('/build' build.id 'restart') %]" method="post" class="inline">
|
||||||
<button id="delete-project" type="submit">Restart</button>
|
<button id="restart" type="submit">Restart</button>
|
||||||
</form>
|
</form>
|
||||||
[% END %]
|
[% END %]
|
||||||
[% ELSIF build.schedulingInfo.busy %]
|
[% ELSIF build.schedulingInfo.busy %]
|
||||||
|
@ -53,6 +58,11 @@
|
||||||
since [% PROCESS renderDateTime timestamp = build.schedulingInfo.starttime %]
|
since [% PROCESS renderDateTime timestamp = build.schedulingInfo.starttime %]
|
||||||
[% ELSE %]
|
[% ELSE %]
|
||||||
<strong>Scheduled to be built</strong>
|
<strong>Scheduled to be built</strong>
|
||||||
|
[% IF c.user_exists %]
|
||||||
|
<form action="[% c.uri_for('/build' build.id 'cancel') %]" method="post" class="inline">
|
||||||
|
<button id="cancel" type="submit">Cancel</button>
|
||||||
|
</form>
|
||||||
|
[% END %]
|
||||||
[% END %]
|
[% END %]
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -116,44 +126,45 @@
|
||||||
<th>Time added:</th>
|
<th>Time added:</th>
|
||||||
<td>[% PROCESS renderDateTime timestamp = build.timestamp %]</td>
|
<td>[% PROCESS renderDateTime timestamp = build.timestamp %]</td>
|
||||||
</tr>
|
</tr>
|
||||||
[% IF build.finished %]
|
[% IF build.finished && build.resultInfo.buildstatus != 4 %]
|
||||||
<tr>
|
|
||||||
<th>Build started:</th>
|
|
||||||
<td>[% IF build.resultInfo.starttime %][% PROCESS renderDateTime timestamp = build.resultInfo.starttime %][% ELSE %]<em>(cached build)</em>[% END %]</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Build finished:</th>
|
|
||||||
<td>[% IF build.resultInfo.stoptime %][% PROCESS renderDateTime timestamp = build.resultInfo.stoptime %][% ELSE %]<em>(cached build)</em>[% END %]</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th>Duration (seconds):</th>
|
|
||||||
<td>
|
|
||||||
[% IF build.resultInfo.iscachedbuild %]
|
|
||||||
<em>(cached build)</em>
|
|
||||||
[% ELSE %]
|
|
||||||
[% build.resultInfo.stoptime - build.resultInfo.starttime %]
|
|
||||||
[% END %]
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
[% IF build.resultInfo.logfile %]
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>Logfile:</th>
|
<th>Build started:</th>
|
||||||
|
<td>[% IF build.resultInfo.starttime %][% PROCESS renderDateTime timestamp = build.resultInfo.starttime %][% ELSE %]<em>(cached build)</em>[% END %]</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Build finished:</th>
|
||||||
|
<td>[% IF build.resultInfo.stoptime %][% PROCESS renderDateTime timestamp = build.resultInfo.stoptime %][% ELSE %]<em>(cached build)</em>[% END %]</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Duration (seconds):</th>
|
||||||
<td>
|
<td>
|
||||||
<a href="[% c.uri_for('/build' build.id 'log') %]"><strong>Available</strong></a>
|
[% IF build.resultInfo.iscachedbuild %]
|
||||||
|
<em>(cached build)</em>
|
||||||
|
[% ELSE %]
|
||||||
|
[% build.resultInfo.stoptime - build.resultInfo.starttime %]
|
||||||
|
[% END %]
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
[% IF build.resultInfo.logfile %]
|
||||||
|
<tr>
|
||||||
|
<th>Logfile:</th>
|
||||||
|
<td>
|
||||||
|
<a href="[% c.uri_for('/build' build.id 'log') %]"><strong>Available</strong></a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
[% END %]
|
||||||
[% END %]
|
[% END %]
|
||||||
[% ELSE %]
|
[% IF !build.finished %]
|
||||||
<tr>
|
<tr>
|
||||||
<th>Priority:</th>
|
<th>Priority:</th>
|
||||||
<td>[% build.schedulingInfo.priority %]</td>
|
<td>[% build.schedulingInfo.priority %]</td>
|
||||||
</tr>
|
</tr>
|
||||||
[% IF build.schedulingInfo.busy %]
|
[% IF build.schedulingInfo.busy %]
|
||||||
<tr>
|
<tr>
|
||||||
<th>Logfile:</th>
|
<th>Logfile:</th>
|
||||||
<td><tt>[% build.schedulingInfo.logfile %]</tt></td>
|
<td><tt>[% build.schedulingInfo.logfile %]</tt></td>
|
||||||
</tr>
|
</tr>
|
||||||
[% END %]
|
[% END %]
|
||||||
[% END %]
|
[% END %]
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ create table BuildResultInfo (
|
||||||
-- 1 = build of this derivation failed
|
-- 1 = build of this derivation failed
|
||||||
-- 2 = build of some dependency failed
|
-- 2 = build of some dependency failed
|
||||||
-- 3 = other failure (see errorMsg)
|
-- 3 = other failure (see errorMsg)
|
||||||
|
-- 4 = build cancelled (removed from queue; never built)
|
||||||
buildStatus integer,
|
buildStatus integer,
|
||||||
|
|
||||||
errorMsg text, -- error message in case of a Nix failure
|
errorMsg text, -- error message in case of a Nix failure
|
||||||
|
|
Loading…
Reference in a new issue