From dca6b943d04aefe43196435193300a188488679b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 6 Mar 2009 12:49:01 +0000 Subject: [PATCH] * 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. --- src/lib/Hydra/Controller/Build.pm | 48 ++++++++++++++++--- src/root/build.tt | 79 ++++++++++++++++++------------- src/sql/hydra.sql | 1 + 3 files changed, 88 insertions(+), 40 deletions(-) diff --git a/src/lib/Hydra/Controller/Build.pm b/src/lib/Hydra/Controller/Build.pm index 6e87d028..d68382e7 100644 --- a/src/lib/Hydra/Controller/Build.pm +++ b/src/lib/Hydra/Controller/Build.pm @@ -30,7 +30,7 @@ sub view_build : Chained('build') PathPart('') Args(0) { $c->stash->{curTime} = time; $c->stash->{available} = isValidPath $build->outpath; $c->stash->{drvAvailable} = isValidPath $build->drvpath; - $c->stash->{flashMsg} = $c->flash->{afterRestart}; + $c->stash->{flashMsg} = $c->flash->{buildMsg}; if (!$build->finished && $build->schedulingInfo->busy) { 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 $build = $c->stash->{build}; 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 { + error($c, "This build cannot be restarted.") + unless $build->finished && + ($build->resultInfo->buildstatus == 3 || + $build->resultInfo->buildstatus == 4); + $build->finished(0); $build->timestamp(time()); $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)); } diff --git a/src/root/build.tt b/src/root/build.tt index ddc4578b..14fafeae 100644 --- a/src/root/build.tt +++ b/src/root/build.tt @@ -40,12 +40,17 @@ [% ELSIF build.resultInfo.buildstatus == 2 %] Failed A dependency of the build failed + [% ELSIF build.resultInfo.buildstatus == 4 %] + Failed + Cancelled by user [% ELSE %] Failed Build failed (see below) + [% END %] + [% IF build.resultInfo.buildstatus == 3 || build.resultInfo.buildstatus == 4 %]
- +
[% END %] [% ELSIF build.schedulingInfo.busy %] @@ -53,6 +58,11 @@ since [% PROCESS renderDateTime timestamp = build.schedulingInfo.starttime %] [% ELSE %] Scheduled to be built + [% IF c.user_exists %] +
+ +
+ [% END %] [% END %] @@ -116,44 +126,45 @@ Time added: [% PROCESS renderDateTime timestamp = build.timestamp %] - [% IF build.finished %] - - Build started: - [% IF build.resultInfo.starttime %][% PROCESS renderDateTime timestamp = build.resultInfo.starttime %][% ELSE %](cached build)[% END %] - - - Build finished: - [% IF build.resultInfo.stoptime %][% PROCESS renderDateTime timestamp = build.resultInfo.stoptime %][% ELSE %](cached build)[% END %] - - - Duration (seconds): - - [% IF build.resultInfo.iscachedbuild %] - (cached build) - [% ELSE %] - [% build.resultInfo.stoptime - build.resultInfo.starttime %] - [% END %] - - - [% IF build.resultInfo.logfile %] + [% IF build.finished && build.resultInfo.buildstatus != 4 %] - Logfile: + Build started: + [% IF build.resultInfo.starttime %][% PROCESS renderDateTime timestamp = build.resultInfo.starttime %][% ELSE %](cached build)[% END %] + + + Build finished: + [% IF build.resultInfo.stoptime %][% PROCESS renderDateTime timestamp = build.resultInfo.stoptime %][% ELSE %](cached build)[% END %] + + + Duration (seconds): - Available + [% IF build.resultInfo.iscachedbuild %] + (cached build) + [% ELSE %] + [% build.resultInfo.stoptime - build.resultInfo.starttime %] + [% END %] + [% IF build.resultInfo.logfile %] + + Logfile: + + Available + + + [% END %] [% END %] - [% ELSE %] - - Priority: - [% build.schedulingInfo.priority %] - - [% IF build.schedulingInfo.busy %] - - Logfile: - [% build.schedulingInfo.logfile %] - - [% END %] + [% IF !build.finished %] + + Priority: + [% build.schedulingInfo.priority %] + + [% IF build.schedulingInfo.busy %] + + Logfile: + [% build.schedulingInfo.logfile %] + + [% END %] [% END %] diff --git a/src/sql/hydra.sql b/src/sql/hydra.sql index 918e191e..196adc2e 100644 --- a/src/sql/hydra.sql +++ b/src/sql/hydra.sql @@ -61,6 +61,7 @@ create table BuildResultInfo ( -- 1 = build of this derivation failed -- 2 = build of some dependency failed -- 3 = other failure (see errorMsg) + -- 4 = build cancelled (removed from queue; never built) buildStatus integer, errorMsg text, -- error message in case of a Nix failure