forked from lix-project/hydra
Add an action to cancel all builds in a jobset eval
This commit is contained in:
parent
3e54f0a6ab
commit
7818bb75ed
|
@ -34,12 +34,12 @@ sub machines : Chained('admin') PathPart('machines') Args(0) {
|
||||||
|
|
||||||
sub clear_queue_non_current : Chained('admin') PathPart('clear-queue-non-current') Args(0) {
|
sub clear_queue_non_current : Chained('admin') PathPart('clear-queue-non-current') Args(0) {
|
||||||
my ($self, $c) = @_;
|
my ($self, $c) = @_;
|
||||||
my $time = time();
|
my $builds = $c->model('DB::Builds')->search(
|
||||||
$c->model('DB::Builds')->search(
|
|
||||||
{ finished => 0, busy => 0
|
{ finished => 0, busy => 0
|
||||||
, id => { -not_in => \ "select build from JobsetEvalMembers where eval in (select max(id) from JobsetEvals where hasNewBuilds = 1 group by project, jobset)" }
|
, id => { -not_in => \ "select build from JobsetEvalMembers where eval in (select max(id) from JobsetEvals where hasNewBuilds = 1 group by project, jobset)" }
|
||||||
}, {})
|
});
|
||||||
->update({ finished => 1, buildstatus => 4, starttime => $time, stoptime => $time });
|
my $n = cancelBuilds($c->model('DB')->schema, $builds);
|
||||||
|
$c->flash->{successMsg} = "$n builds have been cancelled.";
|
||||||
$c->res->redirect($c->request->referer // "/admin");
|
$c->res->redirect($c->request->referer // "/admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,6 @@ sub build_GET {
|
||||||
$c->stash->{template} = 'build.tt';
|
$c->stash->{template} = 'build.tt';
|
||||||
$c->stash->{available} = all { isValidPath($_->path) } $build->buildoutputs->all;
|
$c->stash->{available} = all { isValidPath($_->path) } $build->buildoutputs->all;
|
||||||
$c->stash->{drvAvailable} = isValidPath $build->drvpath;
|
$c->stash->{drvAvailable} = isValidPath $build->drvpath;
|
||||||
$c->stash->{flashMsg} = $c->flash->{buildMsg};
|
|
||||||
|
|
||||||
if (!$build->finished && $build->busy) {
|
if (!$build->finished && $build->busy) {
|
||||||
$c->stash->{logtext} = read_file($build->logfile, err_mode => 'quiet') // "";
|
$c->stash->{logtext} = read_file($build->logfile, err_mode => 'quiet') // "";
|
||||||
|
@ -448,7 +447,7 @@ sub restart : Chained('buildChain') PathPart Args(0) {
|
||||||
|
|
||||||
restartBuild($c->model('DB')->schema, $build);
|
restartBuild($c->model('DB')->schema, $build);
|
||||||
|
|
||||||
$c->flash->{buildMsg} = "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));
|
||||||
}
|
}
|
||||||
|
@ -456,30 +455,11 @@ sub restart : Chained('buildChain') PathPart Args(0) {
|
||||||
|
|
||||||
sub cancel : Chained('buildChain') PathPart Args(0) {
|
sub cancel : 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 = cancelBuilds($c->model('DB')->schema, $c->model('DB::Builds')->search({ id => $build->id }));
|
||||||
txn_do($c->model('DB')->schema, sub {
|
error($c, "This build cannot be cancelled.") if $n != 1;
|
||||||
error($c, "This build cannot be cancelled.")
|
$c->flash->{successMsg} = "Build has been cancelled.";
|
||||||
if $build->finished || $build->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.
|
|
||||||
|
|
||||||
my $time = time();
|
|
||||||
$build->update(
|
|
||||||
{ finished => 1, busy => 0
|
|
||||||
, iscachedbuild => 0, buildstatus => 4 # = cancelled
|
|
||||||
, starttime => $time
|
|
||||||
, stoptime => $time
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$c->flash->{buildMsg} = "Build has been cancelled.";
|
|
||||||
|
|
||||||
$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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +480,7 @@ sub keep : Chained('buildChain') PathPart Args(1) {
|
||||||
$build->update({keep => $keep});
|
$build->update({keep => $keep});
|
||||||
});
|
});
|
||||||
|
|
||||||
$c->flash->{buildMsg} =
|
$c->flash->{successMsg} =
|
||||||
$keep ? "Build will be kept." : "Build will not be kept.";
|
$keep ? "Build will be kept." : "Build will not be kept.";
|
||||||
|
|
||||||
$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));
|
||||||
|
@ -530,7 +510,7 @@ sub add_to_release : Chained('buildChain') PathPart('add-to-release') Args(0) {
|
||||||
|
|
||||||
$release->releasemembers->create({build => $build->id, description => $build->description});
|
$release->releasemembers->create({build => $build->id, description => $build->description});
|
||||||
|
|
||||||
$c->flash->{buildMsg} = "Build added to project <tt>$releaseName</tt>.";
|
$c->flash->{successMsg} = "Build added to project <tt>$releaseName</tt>.";
|
||||||
|
|
||||||
$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));
|
||||||
}
|
}
|
||||||
|
@ -607,7 +587,7 @@ sub clone_submit : Chained('buildChain') PathPart('clone/submit') Args(0) {
|
||||||
|
|
||||||
error($c, "This build has already been performed.") unless $newBuild;
|
error($c, "This build has already been performed.") unless $newBuild;
|
||||||
|
|
||||||
$c->flash->{buildMsg} = "Build " . $newBuild->id . " added to the queue.";
|
$c->flash->{successMsg} = "Build " . $newBuild->id . " added to the queue.";
|
||||||
|
|
||||||
$c->res->redirect($c->uri_for($c->controller('Root')->action_for('queue')));
|
$c->res->redirect($c->uri_for($c->controller('Root')->action_for('queue')));
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,15 @@ sub release : Chained('eval') PathPart('release') Args(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub cancel : Chained('eval') PathPart('cancel') Args(0) {
|
||||||
|
my ($self, $c) = @_;
|
||||||
|
requireProjectOwner($c, $c->stash->{eval}->project);
|
||||||
|
my $n = cancelBuilds($c->model('DB')->schema, $c->stash->{eval}->builds);
|
||||||
|
$c->flash->{successMsg} = "$n builds have been cancelled.";
|
||||||
|
$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) = @_;
|
||||||
|
|
|
@ -21,7 +21,8 @@ our @EXPORT = qw(
|
||||||
getEvals getMachines
|
getEvals getMachines
|
||||||
pathIsInsidePrefix
|
pathIsInsidePrefix
|
||||||
captureStdoutStderr run grab
|
captureStdoutStderr run grab
|
||||||
getTotalShares);
|
getTotalShares
|
||||||
|
cancelBuilds);
|
||||||
|
|
||||||
|
|
||||||
sub getHydraHome {
|
sub getHydraHome {
|
||||||
|
@ -43,11 +44,12 @@ sub getHydraConfig {
|
||||||
# doesn't work.
|
# doesn't work.
|
||||||
sub txn_do {
|
sub txn_do {
|
||||||
my ($db, $coderef) = @_;
|
my ($db, $coderef) = @_;
|
||||||
|
my $res;
|
||||||
while (1) {
|
while (1) {
|
||||||
eval {
|
eval {
|
||||||
$db->txn_do($coderef);
|
$res = $db->txn_do($coderef);
|
||||||
};
|
};
|
||||||
last if !$@;
|
return $res if !$@;
|
||||||
die $@ unless $@ =~ "database is locked";
|
die $@ unless $@ =~ "database is locked";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -542,4 +544,21 @@ sub getTotalShares {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub cancelBuilds($$) {
|
||||||
|
my ($db, $builds) = @_;
|
||||||
|
return txn_do($db, sub {
|
||||||
|
$builds = $builds->search({ finished => 0, busy => 0 });
|
||||||
|
my $n = $builds->count;
|
||||||
|
my $time = time();
|
||||||
|
$builds->update(
|
||||||
|
{ finished => 1,
|
||||||
|
, iscachedbuild => 0, buildstatus => 4 # = cancelled
|
||||||
|
, starttime => $time
|
||||||
|
, stoptime => $time
|
||||||
|
});
|
||||||
|
return $n;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -42,6 +42,7 @@ c.uri_for(c.controller('JobsetEval').action_for('view'),
|
||||||
</a>
|
</a>
|
||||||
<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>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
class = "" %]
|
class = "" %]
|
||||||
[% INCLUDE menuItem
|
[% INCLUDE menuItem
|
||||||
uri = c.uri_for(c.controller('Admin').action_for('clear_queue_non_current'))
|
uri = c.uri_for(c.controller('Admin').action_for('clear_queue_non_current'))
|
||||||
title = "Clear all non-running old builds from queue"
|
title = "Clear scheduled non-current builds from queue"
|
||||||
confirmmsg = "Are you sure you want to clear the queue?"
|
confirmmsg = "Are you sure you want to clear the queue?"
|
||||||
class = "" %]
|
class = "" %]
|
||||||
[% INCLUDE menuItem
|
[% INCLUDE menuItem
|
||||||
|
|
Loading…
Reference in a new issue