Jobset page: Add a new tab to show job status in a matrix

This commit is contained in:
Eelco Dolstra 2013-08-28 09:59:02 +00:00
parent 82e073d043
commit 410060ec8a
5 changed files with 105 additions and 19 deletions

View file

@ -52,7 +52,7 @@ sub overview : Chained('job') PathPart('') Args(0) {
foreach my $b (@constituents) {
my $jobName = $b->get_column('job');
$aggregates->{$b->get_column('aggregate')}->{constituents}->{$jobName} =
{ id => $b->id, finished => $b->finished, buildstatus => $b->buildstatus};
{ id => $b->id, finished => $b->finished, buildstatus => $b->buildstatus };
$constituentJobs{$jobName} = 1;
}

View file

@ -155,24 +155,54 @@ sub jobs_tab : Chained('jobsetChain') PathPart('jobs-tab') Args(0) {
{ hasnewbuilds => 1 }, { rows => 1, order_by => ["id desc"] })->single;
my %activeJobs;
$c->stash->{activeJobs} = {};
if (defined $latestEval) {
foreach my $build ($latestEval->builds->search({}, { order_by => ["job"], select => ["job"] })) {
my $job = $build->get_column("job");
if (!defined $activeJobs{$job}) {
$activeJobs{$job} = 1;
push @{$c->stash->{activeJobs}}, $job;
$c->stash->{activeJobs}->{$job} = 1;
}
}
}
foreach my $job ($c->stash->{jobset}->jobs->search({}, { order_by => ["name"] })) {
if (!defined $activeJobs{$job->name}) {
push @{$c->stash->{inactiveJobs}}, $job->name;
}
push @{$c->stash->{jobs}}, $job->name;
}
}
sub job_status_tab : Chained('jobsetChain') PathPart('job-status-tab') Args(0) {
my ($self, $c) = @_;
$c->stash->{template} = 'jobset-job-status-tab.tt';
$c->stash->{filter} = $c->request->params->{filter} // "";
my @evals = $c->stash->{jobset}->jobsetevals->search({ hasnewbuilds => 1}, { order_by => "id desc", rows => 20 });
my $evals = {};
my %jobs;
my $nrBuilds = 0;
foreach my $eval (@evals) {
my @builds = $eval->builds->search(
{ job => { ilike => "%" . $c->stash->{filter} . "%" } },
{ columns => ['id', 'job', 'finished', 'buildstatus'] });
foreach my $b (@builds) {
my $jobName = $b->get_column('job');
$evals->{$eval->id}->{$jobName} =
{ id => $b->id, finished => $b->finished, buildstatus => $b->buildstatus };
$jobs{$jobName} = 1;
$nrBuilds++;
}
last if $nrBuilds >= 10000;
}
$c->stash->{evals} = $evals;
$c->stash->{jobs} = [sort (keys %jobs)];
}
# Hydra::Base::Controller::ListBuilds needs this.
sub get_builds : Chained('jobsetChain') PathPart('') CaptureArgs(0) {
my ($self, $c) = @_;

View file

@ -0,0 +1,49 @@
[% PROCESS common.tt; USE Math %]
<form class="form-search" id="filter-jobs">
<input name="filter" type="text" class="input-large search-query" placeholder="Filter jobs..." [% HTML.attributes(value => filter) %]></input>
</form>
<script>
$('#filter-jobs').submit(function() {
$('#tabs-job-status').load("[% c.uri_for('/jobset' project.name jobset.name "job-status-tab") %]", $('#filter-jobs').serialize(), function(response, status, xhr) {
if (status == "error") {
$('#[% tabName %]').html("<div class='alert alert-error'>Error loading tab: " + xhr.status + " " + xhr.statusText + "</div>");
}
});
return false;
});
</script>
[% IF jobs.size == 0 %]
<div class="alert">There are no matching jobs.</div>
[% ELSE %]
[% evalIds = evals.keys.nsort.reverse %]
<table class="table table-striped table-condensed table-header-rotated">
<thead>
<tr>
<th style="width: 1em;">Job</th>
[% FOREACH eval IN evalIds %]
<th class="rotate-45">
<div><span>
<a href="[% c.uri_for('/eval' eval) %]">[% eval %]</a>
</span></div></th>
[% END %]
</tr>
</thead>
<tbody>
[% FOREACH j IN jobs-%]
<tr>
<th>[% INCLUDE renderJobName project=project.name jobset=jobset.name job=j %]</th>
[% FOREACH eval IN evalIds %]
<td>[% r = evals.$eval.$j; IF r.id %]<a href="[% c.uri_for('/build' r.id) %]">[% INCLUDE renderBuildStatusIcon size=16 build=r %]</a>[% END %]</td>
[% END %]
</tr>
[% END %]
</tbody>
</table>
[% END %]

View file

@ -1,15 +1,19 @@
[% PROCESS common.tt %]
<p>This jobset currently contains the following [% activeJobs.size %] jobs:
<blockquote>
[% IF activeJobs.size == 0 %]<em>(none)</em>[% END %]
[% FOREACH j IN activeJobs %][% INCLUDE renderJobName project=project.name jobset=jobset.name job=j %]<br/>[% END %]
</blockquote>
</p>
[% IF jobs.size == 0 %]
<div class="alert">This jobset has no jobs yet.</div>
[% ELSE %]
<div class="well well-small">Below is the list of all [% jobs.size
%] jobs that have ever existed in this jobset. Jobs that are no
longer part of the jobset (i.e., that don't appear in the latest
evaluation of the jobset) are <span class="muted">grayed out</span>.</div>
<p>This jobset used to contain the following [% inactiveJobs.size %] jobs:
<blockquote>
[% IF inactiveJobs.size == 0 %]<em>(none)</em>[% END %]
[% FOREACH j IN inactiveJobs %][% INCLUDE renderJobName project=project.name jobset=jobset.name job=j %]<br/>[% END %]
</blockquote>
</p>
<table class="table table-striped table-condensed">
<thead>
<tr><th>Job name</th></tr>
</thead>
<tbody>
[% FOREACH j IN jobs %]<tr><td><span class="[% IF !activeJobs.$j %]muted override-link[% END %]">[% INCLUDE renderJobName project=project.name jobset=jobset.name job=j %]</span></td></tr>[% END %]
</tbody>
</table>
[% END %]

View file

@ -43,9 +43,10 @@
<ul class="nav nav-tabs">
<li class="active"><a href="#tabs-evaluations" data-toggle="tab">Evaluations</a></li>
[% IF jobset.errormsg %]
<li><a href="#tabs-errors" data-toggle="tab"><img src="/static/images/error_16.png" /> Evaluation errors</a></li>
<li><a href="#tabs-errors" data-toggle="tab"><span class="text-warning">Evaluation errors</span></a></li>
[% END %]
<li><a href="#tabs-jobs" data-toggle="tab">Jobs</a></li>
<li><a href="#tabs-job-status" data-toggle="tab">Job status</a></li>
<li><a href="#tabs-jobs" data-toggle="tab">All jobs</a></li>
<li><a href="#tabs-configuration" data-toggle="tab">Configuration</a></li>
</ul>
@ -140,6 +141,8 @@
[% INCLUDE makeLazyTab tabName="tabs-jobs" uri=c.uri_for('/jobset' project.name jobset.name "jobs-tab") %]
[% INCLUDE makeLazyTab tabName="tabs-job-status" uri=c.uri_for('/jobset' project.name jobset.name "job-status-tab") %]
</div>
[% END %]