forked from lix-project/hydra
Add a jobset eval action to restart all aborted/cancelled builds
This commit is contained in:
parent
85d51074b9
commit
052bab169d
5 changed files with 52 additions and 37 deletions
|
@ -437,18 +437,11 @@ sub nix : Chained('buildChain') PathPart('nix') CaptureArgs(0) {
|
||||||
|
|
||||||
sub restart : Chained('buildChain') PathPart Args(0) {
|
sub restart : Chained('buildChain') 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);
|
||||||
|
my $n = restartBuilds($c->model('DB')->schema, $c->model('DB::Builds')->search({ id => $build->id }));
|
||||||
error($c, "This build cannot be restarted.")
|
error($c, "This build cannot be restarted.") if $n != 1;
|
||||||
unless $build->finished && -f $build->drvpath;
|
|
||||||
|
|
||||||
restartBuild($c->model('DB')->schema, $build);
|
|
||||||
|
|
||||||
$c->flash->{successMsg} = "Build has been restarted.";
|
$c->flash->{successMsg} = "Build has been restarted.";
|
||||||
|
|
||||||
$c->res->redirect($c->uri_for($self->action_for("build"), $c->req->captures));
|
$c->res->redirect($c->uri_for($self->action_for("build"), $c->req->captures));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,16 @@ sub cancel : Chained('eval') PathPart('cancel') Args(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub restart_aborted : Chained('eval') PathPart('restart-aborted') Args(0) {
|
||||||
|
my ($self, $c) = @_;
|
||||||
|
requireProjectOwner($c, $c->stash->{eval}->project);
|
||||||
|
my $builds = $c->stash->{eval}->builds->search({ finished => 1, buildstatus => { -in => [3, 4] } });
|
||||||
|
my $n = restartBuilds($c->model('DB')->schema, $builds);
|
||||||
|
$c->flash->{successMsg} = "$n builds have been restarted.";
|
||||||
|
$c->res->redirect($c->uri_for($c->controller('JobsetEval')->action_for('view'), $c->req->captures));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# Hydra::Base::Controller::NixChannel needs this.
|
# Hydra::Base::Controller::NixChannel needs this.
|
||||||
sub nix : Chained('eval') PathPart('channel') CaptureArgs(0) {
|
sub nix : Chained('eval') PathPart('channel') CaptureArgs(0) {
|
||||||
my ($self, $c) = @_;
|
my ($self, $c) = @_;
|
||||||
|
|
|
@ -553,29 +553,4 @@ sub checkBuild {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
sub restartBuild {
|
1;
|
||||||
my ($db, $build) = @_;
|
|
||||||
|
|
||||||
txn_do($db, sub {
|
|
||||||
my @paths;
|
|
||||||
push @paths, $build->drvpath;
|
|
||||||
push @paths, $_->drvpath foreach $build->buildsteps;
|
|
||||||
|
|
||||||
my $r = `nix-store --clear-failed-paths @paths`;
|
|
||||||
|
|
||||||
$build->update(
|
|
||||||
{ finished => 0
|
|
||||||
, busy => 0
|
|
||||||
, locker => ""
|
|
||||||
, iscachedbuild => 0
|
|
||||||
});
|
|
||||||
|
|
||||||
$build->buildproducts->delete;
|
|
||||||
|
|
||||||
# Reset the stats for the evals to which this build belongs.
|
|
||||||
# !!! Should do this in a trigger.
|
|
||||||
foreach my $m ($build->jobsetevalmembers->all) {
|
|
||||||
$m->eval->update({nrsucceeded => undef});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ use File::Basename;
|
||||||
use Config::General;
|
use Config::General;
|
||||||
use Hydra::Helper::CatalystUtils;
|
use Hydra::Helper::CatalystUtils;
|
||||||
use Hydra::Model::DB;
|
use Hydra::Model::DB;
|
||||||
|
use Nix::Store;
|
||||||
|
|
||||||
our @ISA = qw(Exporter);
|
our @ISA = qw(Exporter);
|
||||||
our @EXPORT = qw(
|
our @EXPORT = qw(
|
||||||
|
@ -22,7 +23,7 @@ our @EXPORT = qw(
|
||||||
pathIsInsidePrefix
|
pathIsInsidePrefix
|
||||||
captureStdoutStderr run grab
|
captureStdoutStderr run grab
|
||||||
getTotalShares
|
getTotalShares
|
||||||
cancelBuilds);
|
cancelBuilds restartBuilds);
|
||||||
|
|
||||||
|
|
||||||
sub getHydraHome {
|
sub getHydraHome {
|
||||||
|
@ -561,4 +562,39 @@ sub cancelBuilds($$) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub restartBuilds($$) {
|
||||||
|
my ($db, $builds) = @_;
|
||||||
|
my $n = 0;
|
||||||
|
|
||||||
|
txn_do($db, sub {
|
||||||
|
my @paths;
|
||||||
|
|
||||||
|
$builds = $builds->search({ finished => 1 });
|
||||||
|
foreach my $build ($builds->all) {
|
||||||
|
next if !isValidPath($build->drvpath);
|
||||||
|
push @paths, $build->drvpath;
|
||||||
|
push @paths, $_->drvpath foreach $build->buildsteps;
|
||||||
|
|
||||||
|
$build->update(
|
||||||
|
{ finished => 0
|
||||||
|
, busy => 0
|
||||||
|
, locker => ""
|
||||||
|
, iscachedbuild => 0
|
||||||
|
});
|
||||||
|
$n++;
|
||||||
|
|
||||||
|
# Reset the stats for the evals to which this build belongs.
|
||||||
|
# !!! Should do this in a trigger.
|
||||||
|
$build->jobsetevals->update({nrsucceeded => undef});
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clear Nix's negative failure cache.
|
||||||
|
# FIXME: Add this to the API.
|
||||||
|
system("nix-store", "--clear-failed-paths", @paths);
|
||||||
|
});
|
||||||
|
|
||||||
|
return $n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -43,6 +43,7 @@ c.uri_for(c.controller('JobsetEval').action_for('view'),
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('release'), [eval.id]) %]">Create a release from this evaluation</a></li>
|
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('release'), [eval.id]) %]">Create a release from this evaluation</a></li>
|
||||||
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('cancel'), [eval.id]) %]">Cancel all scheduled builds</a></li>
|
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('cancel'), [eval.id]) %]">Cancel all scheduled builds</a></li>
|
||||||
|
<li><a href="[% c.uri_for(c.controller('JobsetEval').action_for('restart_aborted'), [eval.id]) %]">Restart all aborted builds</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
Loading…
Reference in a new issue