Add one-shot jobsets

There are jobsets that are evaluated only once, that is, after they've
been evaluated, they're disabled automatically.  This is primarily
useful for doing releases: for instance, doing an evaluation with
"officialRelease" set to "true" should be done only once.
This commit is contained in:
Eelco Dolstra 2013-10-11 12:01:52 +02:00
parent 0babdf3532
commit c4e39d4769
9 changed files with 36 additions and 19 deletions

View file

@ -31,11 +31,7 @@ sub overview : Chained('job') PathPart('') Args(0) {
$c->stash->{queuedBuilds} = [ $c->stash->{queuedBuilds} = [
$job->builds->search( $job->builds->search(
{ finished => 0 }, { finished => 0 },
{ join => ['project'] { order_by => ["priority DESC", "id"] }
, order_by => ["priority DESC", "id"]
, '+select' => ['project.enabled']
, '+as' => ['enabled']
}
) ]; ) ];
# If this is an aggregate job, then get its constituents. # If this is an aggregate job, then get its constituents.

View file

@ -197,14 +197,15 @@ sub updateJobset {
my ($nixExprPath, $nixExprInput) = nixExprPathFromParams $c; my ($nixExprPath, $nixExprInput) = nixExprPathFromParams $c;
my $enabled = defined $c->stash->{params}->{enabled}; my $enabled = int($c->stash->{params}->{enabled});
die if $enabled < 0 || $enabled > 2;
$jobset->update( $jobset->update(
{ name => $jobsetName { name => $jobsetName
, description => trim($c->stash->{params}->{"description"}) , description => trim($c->stash->{params}->{"description"})
, nixexprpath => $nixExprPath , nixexprpath => $nixExprPath
, nixexprinput => $nixExprInput , nixexprinput => $nixExprInput
, enabled => $enabled ? 1 : 0 , enabled => $enabled
, enableemail => defined $c->stash->{params}->{enableemail} ? 1 : 0 , enableemail => defined $c->stash->{params}->{enableemail} ? 1 : 0
, emailoverride => trim($c->stash->{params}->{emailoverride}) || "" , emailoverride => trim($c->stash->{params}->{emailoverride}) || ""
, hidden => defined $c->stash->{params}->{visible} ? 0 : 1 , hidden => defined $c->stash->{params}->{visible} ? 0 : 1

View file

@ -74,7 +74,7 @@ sub queue_GET {
$self->status_ok( $self->status_ok(
$c, $c,
entity => [$c->model('DB::Builds')->search( entity => [$c->model('DB::Builds')->search(
{finished => 0}, { join => ['project'], order_by => ["priority DESC", "id"], columns => [@buildListColumns], '+select' => ['project.enabled'], '+as' => ['enabled'] })] {finished => 0}, { order_by => ["priority DESC", "id"], columns => [@buildListColumns] })]
); );
} }

View file

@ -540,7 +540,7 @@ sub grab {
sub getTotalShares { sub getTotalShares {
my ($db) = @_; my ($db) = @_;
return $db->resultset('Jobsets')->search( return $db->resultset('Jobsets')->search(
{ 'project.enabled' => 1, 'me.enabled' => 1 }, { 'project.enabled' => 1, 'me.enabled' => { '!=' => 0 } },
{ join => 'project', select => { sum => 'schedulingshares' }, as => 'sum' })->single->get_column('sum'); { join => 'project', select => { sum => 'schedulingshares' }, as => 'sum' })->single->get_column('sum');
} }

View file

@ -49,11 +49,18 @@
<fieldset> <fieldset>
<div class="control-group"> <div class="control-group">
<label class="control-label">State</label>
<div class="controls"> <div class="controls">
<label class="checkbox"> <div class="btn-group" data-toggle="buttons-radio">
<input type="checkbox" name="enabled" [% IF jobset.enabled; 'checked="checked"'; END %]/>Enabled <input type="hidden" name="enabled" value="[% jobset.enabled %]" />
</label> <button type="button" class="btn" value="1">Enabled</button>
<button type="button" class="btn" value="2">One-shot</button>
<button type="button" class="btn" value="0">Disabled</button>
</div> </div>
</div>
</div>
<div class="control-group">
<div class="controls"> <div class="controls">
<label class="checkbox"> <label class="checkbox">
<input type="checkbox" name="visible" [% IF !jobset.hidden; 'checked="checked"'; END %]/>Visible <input type="checkbox" name="visible" [% IF !jobset.hidden; 'checked="checked"'; END %]/>Visible

View file

@ -116,6 +116,10 @@
<div id="tabs-configuration" class="tab-pane"> <div id="tabs-configuration" class="tab-pane">
<table class="info-table"> <table class="info-table">
<tr>
<th>State:</th>
<td>[% IF jobset.enabled == 0; "Disabled"; ELSIF jobset.enabled == 1; "Enabled"; ELSIF jobset.enabled == 2; "One-shot"; END %]</td>
</tr>
<tr> <tr>
<th>Description:</th> <th>Description:</th>
<td>[% HTML.escape(jobset.description) %]</td> <td>[% HTML.escape(jobset.description) %]</td>
@ -127,10 +131,6 @@
<tt>[% HTML.escape(jobset.nixexprinput) %]</tt> <tt>[% HTML.escape(jobset.nixexprinput) %]</tt>
</td> </td>
</tr> </tr>
<tr>
<th>Enabled:</th>
<td>[% jobset.enabled ? "Yes" : "No" %]</td>
</tr>
<tr> <tr>
<th>Check interval:</th> <th>Check interval:</th>
<td>[% jobset.checkinterval || "<em>disabled</em>" %]</td> <td>[% jobset.checkinterval || "<em>disabled</em>" %]</td>

View file

@ -69,7 +69,17 @@ $(document).ready(function() {
var id = e.target.toString().match(pattern)[0]; var id = e.target.toString().match(pattern)[0];
history.replaceState(null, "", id); history.replaceState(null, "", id);
}); });
}) });
/* Automatically set Bootstrap radio buttons from hidden form controls. */
$('div[data-toggle="buttons-radio"] input[type="hidden"]').map(function(){
$('button[value="' + $(this).val() + '"]', $(this).parent()).addClass('active');
});
/* Automatically update hidden form controls from Bootstrap radio buttons. */
$('div[data-toggle="buttons-radio"] .btn').click(function(){
$('input', $(this).parent()).val($(this).val());
});
}); });
var tabsLoaded = {}; var tabsLoaded = {};

View file

@ -246,6 +246,9 @@ sub checkJobsetWrapped {
print STDERR " created cached eval ", $ev->id, "\n"; print STDERR " created cached eval ", $ev->id, "\n";
$prevEval->builds->update({iscurrent => 1}) if defined $prevEval; $prevEval->builds->update({iscurrent => 1}) if defined $prevEval;
} }
# If this is a one-shot jobset, disable it now.
$jobset->update({ enabled => 0 }) if $jobset->enabled == 2;
}); });
# Store the error messages for jobs that failed to evaluate. # Store the error messages for jobs that failed to evaluate.
@ -305,7 +308,7 @@ sub checkSomeJobset {
# longest time (but don't check more often than the jobset's # longest time (but don't check more often than the jobset's
# minimal check interval). # minimal check interval).
($jobset) = $db->resultset('Jobsets')->search( ($jobset) = $db->resultset('Jobsets')->search(
{ 'project.enabled' => 1, 'me.enabled' => 1, { 'project.enabled' => 1, 'me.enabled' => { '!=' => 0 },
, 'checkinterval' => { '!=', 0 } , 'checkinterval' => { '!=', 0 }
, -or => [ 'lastcheckedtime' => undef, 'lastcheckedtime' => { '<', \ (time() . " - me.checkinterval") } ] }, , -or => [ 'lastcheckedtime' => undef, 'lastcheckedtime' => { '<', \ (time() . " - me.checkinterval") } ] },
{ join => 'project', order_by => [ 'lastcheckedtime nulls first' ], rows => 1 }) { join => 'project', order_by => [ 'lastcheckedtime nulls first' ], rows => 1 })

View file

@ -55,7 +55,7 @@ create table Jobsets (
errorTime integer, -- timestamp associated with errorMsg errorTime integer, -- timestamp associated with errorMsg
lastCheckedTime integer, -- last time the evaluator looked at this jobset lastCheckedTime integer, -- last time the evaluator looked at this jobset
triggerTime integer, -- set if we were triggered by a push event triggerTime integer, -- set if we were triggered by a push event
enabled integer not null default 1, enabled integer not null default 1, -- 0 = disabled, 1 = enabled, 2 = one-shot
enableEmail integer not null default 1, enableEmail integer not null default 1,
hidden integer not null default 0, hidden integer not null default 0,
emailOverride text not null, emailOverride text not null,