Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 6 additions & 35 deletions subprojects/hydra/lib/Hydra/Controller/Build.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use warnings;
use base 'Hydra::Base::Controller::NixChannel';
use Hydra::Helper::Nix;
use Hydra::Helper::CatalystUtils;
use Hydra::Helper::LogEndpoints;
use File::Basename;
use File::LibMagic;
use File::stat;
Expand Down Expand Up @@ -133,17 +134,13 @@ sub constituents_GET {
}


sub view_nixlog : Chained('buildChain') PathPart('nixlog') {
# Redirect old /build/:id/nixlog/:stepnr[/:mode] URLs to new canonical paths
sub nixlog_redirect : Chained('buildChain') PathPart('nixlog') {
my ($self, $c, $stepnr, $mode) = @_;

my $step = $c->stash->{build}->buildsteps->find({stepnr => $stepnr});
notFound($c, "Build doesn't have a build step $stepnr.") if !defined $step;

$c->stash->{step} = $step;

my $drvPath = $step->drvpath;
my $log_uri = $c->uri_for($c->controller('Root')->action_for("log"), [WWW::Form::UrlEncoded::PP::url_encode(basename($drvPath))]);
showLog($c, $mode, $log_uri);
my @path = ('/build', $c->stash->{id}, 'step', $stepnr, 'log');
push @path, $mode if defined $mode;
$c->res->redirect($c->uri_for(@path), 301);
}


Expand All @@ -166,32 +163,6 @@ sub view_runcommandlog : Chained('buildChain') PathPart('runcommandlog') {
}


sub showLog {
my ($c, $mode, $log_uri) = @_;
$mode //= "pretty";

if ($mode eq "pretty") {
$c->stash->{log_uri} = $log_uri;
$c->stash->{template} = 'log.tt';
}

elsif ($mode eq "raw") {
$c->res->redirect($log_uri);
}

elsif ($mode eq "tail") {
my $lines = 50;
$c->stash->{log_uri} = $log_uri . "?tail=$lines";
$c->stash->{tail} = $lines;
$c->stash->{template} = 'log.tt';
}

else {
error($c, "Unknown log display mode '$mode'.");
}
}


sub defaultUriForProduct {
my ($self, $c, $product, @path) = @_;
my $x = $product->productnr
Expand Down
38 changes: 38 additions & 0 deletions subprojects/hydra/lib/Hydra/Controller/BuildStep.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package Hydra::Controller::BuildStep;

use utf8;
use strict;
use warnings;
use base 'Hydra::Base::Controller::REST';
use Hydra::Helper::CatalystUtils;
use Hydra::Helper::LogEndpoints;
use File::Basename;
use WWW::Form::UrlEncoded::PP qw();


sub buildStepChain :Chained('/build/buildChain') :PathPart('step') :CaptureArgs(1) {
my ($self, $c, $stepnr) = @_;

my $step = $c->stash->{build}->buildsteps->find({stepnr => $stepnr});
notFound($c, "Build doesn't have a build step $stepnr.") if !defined $step;

$c->stash->{step} = $step;
}


sub buildStep : Chained('buildStepChain') PathPart('') Args(0) {
my ($self, $c) = @_;
$c->stash->{template} = 'build-step.tt';
}


sub view_nixlog : Chained('buildStepChain') PathPart('log') {
my ($self, $c, $mode) = @_;

my $drvPath = $c->stash->{step}->drvpath;
my $log_uri = $c->uri_for($c->controller('Root')->action_for("log"), [WWW::Form::UrlEncoded::PP::url_encode(basename($drvPath))]);
showLog($c, $mode, $log_uri);
}


1;
36 changes: 36 additions & 0 deletions subprojects/hydra/lib/Hydra/Helper/LogEndpoints.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package Hydra::Helper::LogEndpoints;

use strict;
use warnings;
use Exporter;
use Hydra::Helper::CatalystUtils;

our @ISA = qw(Exporter);
our @EXPORT = qw(showLog);

sub showLog {
my ($c, $mode, $log_uri) = @_;
$mode //= "pretty";

if ($mode eq "pretty") {
$c->stash->{log_uri} = $log_uri;
$c->stash->{template} = 'log.tt';
}

elsif ($mode eq "raw") {
$c->res->redirect($log_uri);
}

elsif ($mode eq "tail") {
my $lines = 50;
$c->stash->{log_uri} = $log_uri . "?tail=$lines";
$c->stash->{tail} = $lines;
$c->stash->{template} = 'log.tt';
}

else {
error($c, "Unknown log display mode '$mode'.");
}
}

1;
79 changes: 79 additions & 0 deletions subprojects/hydra/root/build-common.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
[% BLOCK renderLogButtons %]
<a class="btn btn-secondary btn-sm" [% HTML.attributes(href => url) %]>pretty</a>
<a class="btn btn-secondary btn-sm" [% HTML.attributes(href => url _ "/raw") %]>raw</a>
<a class="btn btn-secondary btn-sm" [% HTML.attributes(href => url _ "/tail") %]>tail</a>
[% END %]

[% BLOCK renderOutputs %]
[% start=1; FOREACH output IN outputs %]
[% IF !start %],<br/>[% END; start=0; output.path %]
[% END %]
[% END %]

[% BLOCK renderOutputsTable %]
<table class="info-table">
[% FOREACH output IN outputs %]
<tr>
<th><tt>[% output.name | html %]</tt></th>
<td><tt>[% IF output.path; output.path | html; ELSE %]<em>n/a</em>[% END %]</tt></td>
</tr>
[% END %]
</table>
[% END; %]

[% BLOCK renderStepDuration %]
[% IF step.busy == 0 %]
[% IF step.stoptime %]
[% INCLUDE renderDuration duration = step.stoptime - step.starttime %]
[% ELSE %]
<em>n/a</em>
[% END %]
[% ELSIF build.finished %]
[% INCLUDE renderDuration duration = build.stoptime - step.starttime %]
[% ELSE %]
[% INCLUDE renderDuration duration = curTime - step.starttime %]
[% END %]
[% END %]

[% BLOCK renderStepMachine %]
[% IF step.busy != 0 || ((step.machine || step.starttime) && (step.status == 0 || step.status == 1 || step.status == 3 || step.status == 4 || step.status == 7)) %]
[% INCLUDE renderMachineName machine=step.machine %]
[% ELSE %]
<em>n/a</em>
[% END %]
[% END %]

[% BLOCK renderStepStatus %]
[% IF step.busy != 0 %]
[% INCLUDE renderBusyStatus %]
[% ELSIF step.status == 0 %]
[% IF step.isnondeterministic %]
<span class="warn">Succeeded with non-determistic result</span>
[% ELSE %]
Succeeded
[% END %]
[% IF step.timesbuilt && step.timesbuilt > 1 %]
([% step.timesbuilt %] times)
[% END %]
[% ELSIF step.status == 3 %]
<span class="error">Aborted</span>[% IF step.errormsg %]: <em>[% HTML.escape(step.errormsg) %]</em>[% END %]
[% ELSIF step.status == 4 %]
<span class="error">Cancelled</span>
[% ELSIF step.status == 7 %]
<span class="error">Timed out</span>
[% ELSIF step.status == 8 %]
<span class="error">Cached failure</span>
[% ELSIF step.status == 9 %]
<span class="error">Unsupported system type</span>
[% ELSIF step.status == 10 %]
<span class="error">Log limit exceeded</span>
[% ELSIF step.status == 11 %]
<span class="error">Output limit exceeded</span>
[% ELSIF step.status == 12 %]
<span class="error">Non-determinism detected</span>[% IF step.timesbuilt %] after [% HTML.escape(step.timesbuilt) %] times[% END %]
[% ELSIF step.errormsg %]
<span class="error">Failed</span>: <em>[% HTML.escape(step.errormsg) %]</em>
[% ELSE %]
<span class="error">Failed</span>
[% END %]
[% END %]
61 changes: 61 additions & 0 deletions subprojects/hydra/root/build-step.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
[%
buildUrl = c.uri_for('/build', build.id);
%]
[% WRAPPER layout.tt
title="Step ${step.stepnr} of build ${build.id} of job " _ makeNameTextForJob(build.jobset, job)
titleHTML="Step ${step.stepnr}"
_ " of <a href=\"$buildUrl\">build ${build.id}</a>"
_ " of job " _ linkToJob(build.jobset, job)
%]
[% PROCESS common.tt %]
[% PROCESS "build-common.tt" %]
[% USE HTML %]

[% logUrl = c.uri_for('/build' build.id 'step' step.stepnr 'log') %]
[% has_log = buildStepLogExists(step) %]

<table class="info-table">
<tr>
<th>Type:</th>
<td>[% IF step.type == 0 %]Build[% ELSE %]Substitution[% END %]</td>
</tr>
<tr>
<th>Derivation:</th>
<td><tt>[% step.drvpath | html %]</tt></td>
</tr>
<tr>
<th>Output store paths:</th>
<td>[% INCLUDE renderOutputsTable outputs=step.buildstepoutputs %]</td>
</tr>
[% IF step.system %]
<tr>
<th>System:</th>
<td><tt>[% step.system | html %]</tt></td>
</tr>
[% END %]
<tr>
<th>Machine:</th>
<td>[% INCLUDE renderStepMachine %]</td>
</tr>
<tr>
<th>Duration:</th>
<td>[% INCLUDE renderStepDuration %]</td>
</tr>
<tr>
<th>Status:</th>
<td>
[% INCLUDE renderStepStatus %]
[% IF step.propagatedfrom %]
(propagated from [% INCLUDE renderBuildIdLink id=step.propagatedfrom.get_column('id') %])
[% END %]
</td>
</tr>
[% IF has_log %]
<tr>
<th>Logfile:</th>
<td>[% INCLUDE renderLogButtons url=logUrl %]</td>
</tr>
[% END %]
</table>

[% END %]
Loading