From 32f0665d2c5569f1c4d932f100211bf90b9cc43c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sat, 14 Mar 2009 23:56:57 +0000 Subject: [PATCH] * Allow users to change the value of a build's "keep" flag, which prevents the build output from being garbage collected. --- src/lib/Hydra/Controller/Build.pm | 24 +++++++++++++++++++++--- src/root/build.tt | 26 +++++++++++++++++++++++++- src/script/hydra_update_gc_roots.pl | 29 ++++++++++++++--------------- 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/src/lib/Hydra/Controller/Build.pm b/src/lib/Hydra/Controller/Build.pm index 64919f6b..c40e2fa0 100644 --- a/src/lib/Hydra/Controller/Build.pm +++ b/src/lib/Hydra/Controller/Build.pm @@ -214,9 +214,7 @@ sub cancel : Chained('build') PathPart Args(0) { # 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; + $build->update({finished => 1, timestamp => time}); $c->model('DB::BuildResultInfo')->create( { id => $build->id @@ -233,4 +231,24 @@ sub cancel : Chained('build') PathPart Args(0) { } +sub keep : Chained('build') PathPart Args(1) { + my ($self, $c, $newStatus) = @_; + + my $build = $c->stash->{build}; + + requireProjectOwner($c, $build->project); + + die unless $newStatus == 0 || $newStatus == 1; + + $c->model('DB')->schema->txn_do(sub { + $build->resultInfo->update({keep => int $newStatus}); + }); + + $c->flash->{buildMsg} = + $newStatus == 0 ? "Build will not be kept." : "Build will be kept."; + + $c->res->redirect($c->uri_for($self->action_for("view_build"), $c->req->captures)); +} + + 1; diff --git a/src/root/build.tt b/src/root/build.tt index 486893a7..8b5b6e9e 100644 --- a/src/root/build.tt +++ b/src/root/build.tt @@ -57,7 +57,7 @@ Build failed (see below) [% END %] - [% IF build.resultInfo.buildstatus == 3 || build.resultInfo.buildstatus == 4 %] + [% IF c.user_exists && (build.resultInfo.buildstatus == 3 || build.resultInfo.buildstatus == 4) %]
@@ -174,6 +174,30 @@ [% build.schedulingInfo.priority %] [% END %] + [% IF build.finished && build.buildproducts %] + + Availability: + + [% IF !available %] + Build output is no longer available + [% ELSIF build.resultInfo.keep %] + Build output will be kept permanently + [% IF c.user_exists %] +
+ +
+ [% END %] + [% ELSE %] + Build output is available, but may be garbage-collected + [% IF c.user_exists %] +
+ +
+ [% END %] + [% END %] + + + [% END %] diff --git a/src/script/hydra_update_gc_roots.pl b/src/script/hydra_update_gc_roots.pl index 2949a0c9..ca581e88 100755 --- a/src/script/hydra_update_gc_roots.pl +++ b/src/script/hydra_update_gc_roots.pl @@ -21,7 +21,7 @@ sub registerRoot { sub keepBuild { my ($build) = @_; - print "keeping build ", $build->id, " (", + print STDERR "keeping build ", $build->id, " (", strftime("%Y-%m-%d %H:%M:%S", localtime($build->timestamp)), ")\n"; if (isValidPath($build->outpath)) { registerRoot $build->outpath; @@ -37,16 +37,16 @@ foreach my $project ($db->resultset('Projects')->all) { # Go over all jobs in this project. - foreach my $job ($project->builds->search({}, - {select => [{distinct => 'job'}], as => ['job']})) - { - print "*** looking for builds to keep in job ", $project->name, ":", $job->job, "\n"; + foreach my $job ($project->jobs->all) { + print STDERR "*** looking for builds to keep in job ", + $project->name, ":", $job->jobset->name, ":", $job->name, "\n"; # Keep the N most recent successful builds for each job and # platform. - my @recentBuilds = $project->builds->search( - { job => $job->job - , finished => 1 + # !!! Take time into account? E.g. don't delete builds that + # are younger than N days. + my @recentBuilds = $job->builds->search( + { finished => 1 , buildStatus => 0 # == success }, { join => 'resultInfo' @@ -55,13 +55,12 @@ foreach my $project ($db->resultset('Projects')->all) { }); keepBuild $_ foreach @recentBuilds; - } # Go over all releases in this project. foreach my $releaseSet ($project->releasesets->all) { - print "*** looking for builds to keep in release set ", $project->name, ":", $releaseSet->name, "\n"; + print STDERR "*** looking for builds to keep in release set ", $project->name, ":", $releaseSet->name, "\n"; (my $primaryJob) = $releaseSet->releasesetjobs->search({isprimary => 1}); my $jobs = [$releaseSet->releasesetjobs->all]; @@ -69,7 +68,7 @@ foreach my $project ($db->resultset('Projects')->all) { # Keep all builds belonging to the most recent successful release. my $latest = getLatestSuccessfulRelease($project, $primaryJob, $jobs); if (defined $latest) { - print "keeping latest successful release ", $latest->id, " (", $latest->get_column('releasename'), ")\n"; + print STDERR "keeping latest successful release ", $latest->id, " (", $latest->get_column('releasename'), ")\n"; my $release = getRelease($latest, $jobs); keepBuild $_->{build} foreach @{$release->{jobs}}; } @@ -79,16 +78,16 @@ foreach my $project ($db->resultset('Projects')->all) { # Keep all builds that have been marked as "keep". -print "*** looking for kept builds\n"; +print STDERR "*** looking for kept builds\n"; my @buildsToKeep = $db->resultset('Builds')->search({finished => 1, keep => 1}, {join => 'resultInfo'}); keepBuild $_ foreach @buildsToKeep; # For scheduled builds, we register the derivation and the output as a GC root. -print "*** looking for scheduled builds\n"; +print STDERR "*** looking for scheduled builds\n"; foreach my $build ($db->resultset('Builds')->search({finished => 0}, {join => 'schedulingInfo'})) { if (isValidPath($build->drvpath)) { - print "keeping scheduled build ", $build->id, " (", + print STDERR "keeping scheduled build ", $build->id, " (", strftime("%Y-%m-%d %H:%M:%S", localtime($build->timestamp)), ")\n"; registerRoot $build->drvpath; registerRoot $build->outpath; @@ -99,7 +98,7 @@ foreach my $build ($db->resultset('Builds')->search({finished => 0}, {join => 's # Remove existing roots that are no longer wanted. !!! racy -print "*** removing unneeded GC roots\n"; +print STDERR "*** removing unneeded GC roots\n"; my $gcRootsDir = getGCRootsDir;