Also split it out to a new div -- there are now 3 lines per RunCommandLog -- the first saying when it started, the second saying how long it ran for (or has been running), and the third with the buttons for the pretty, raw, and tail versions of the log.
611 lines
24 KiB
Plaintext
611 lines
24 KiB
Plaintext
[% WRAPPER layout.tt
|
|
title="Build $id of job " _ makeNameTextForJob(jobset, job)
|
|
titleHTML="Build $id of job " _ linkToJob(jobset, job)
|
|
%]
|
|
[% PROCESS common.tt %]
|
|
[% PROCESS "product-list.tt" %]
|
|
[% USE HTML %]
|
|
[% USE Date %]
|
|
|
|
[%
|
|
isAggregate = constituents.size > 0;
|
|
busy = 0;
|
|
building = 0;
|
|
FOR step IN steps;
|
|
IF step.busy;
|
|
busy = 1;
|
|
IF step.drvpath == build.drvpath; building = 1; END;
|
|
END;
|
|
END;
|
|
%]
|
|
|
|
[% BLOCK renderOutputs %]
|
|
[% start=1; FOREACH output IN outputs %]
|
|
[% IF !start %],<br/>[% END; start=0; output.path %]
|
|
[% END %]
|
|
[% END %]
|
|
|
|
[% BLOCK renderBuildSteps %]
|
|
<table class="table table-striped table-condensed clickable-rows">
|
|
<thead>
|
|
<tr><th>Nr</th><th>What</th><th>Duration</th><th>Machine</th><th>Status</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
[% FOREACH step IN steps %]
|
|
[% IF ( type == "All" ) || ( type == "Failed" && step.busy == 0 && step.status != 0 ) || ( type == "Running" && step.busy != 0 ) %]
|
|
[% has_log = seen.${step.drvpath} ? 0 : buildStepLogExists(step);
|
|
seen.${step.drvpath} = 1;
|
|
log = c.uri_for('/build' build.id 'nixlog' step.stepnr); %]
|
|
<tr>
|
|
<td>[% step.stepnr %]</td>
|
|
<td>
|
|
[% IF step.type == 0 %]
|
|
Build of <tt>[% INCLUDE renderOutputs outputs=step.buildstepoutputs %]</tt>
|
|
[% ELSE %]
|
|
Substitution of <tt>[% INCLUDE renderOutputs outputs=step.buildstepoutputs %]</tt>
|
|
[% END %]
|
|
</td>
|
|
<td>
|
|
[% 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 %]
|
|
</td>
|
|
<td>[% 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 %]</td>
|
|
<td class="step-status">
|
|
[% IF step.busy != 0 %]
|
|
[% IF step.busy == 1 %]
|
|
<strong>Preparing</strong>
|
|
[% ELSIF step.busy == 10 %]
|
|
<strong>Connecting</strong>
|
|
[% ELSIF step.busy == 20 %]
|
|
<strong>Sending inputs</strong>
|
|
[% ELSIF step.busy == 30 %]
|
|
<strong>Building</strong>
|
|
[% ELSIF step.busy == 40 %]
|
|
<strong>Receiving outputs</strong>
|
|
[% ELSIF step.busy == 50 %]
|
|
<strong>Post-processing</strong>
|
|
[% ELSE %]
|
|
<strong>Unknown state</strong>
|
|
[% END %]
|
|
[% 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 [% 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 %]
|
|
[%%] [%+ IF has_log; INCLUDE renderLogLinks url=log inRow=1; END %]
|
|
[%+ IF step.propagatedfrom; %](propagated from [% INCLUDE renderBuildIdLink id=step.propagatedfrom.get_column('id') %])[% END %]
|
|
</td>
|
|
</tr>
|
|
[% END %]
|
|
[% END %]
|
|
</tbody>
|
|
</table>
|
|
[% END %]
|
|
|
|
<ul class="nav nav-tabs">
|
|
<li class="nav-item dropdown">
|
|
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" area-haspopup="true" aria-expanded="false">Actions</a>
|
|
<div class="dropdown-menu">
|
|
[% IF eval.nixexprinput || eval.flake %]
|
|
<a class="dropdown-item" href="#reproduce" data-toggle="modal">Reproduce locally</a>
|
|
[% END %]
|
|
[% IF c.user_exists %]
|
|
[% IF available %]
|
|
[% IF build.keep %]
|
|
<a class="dropdown-item" href="[% c.uri_for('/build' build.id 'keep' 0) %]">Unkeep</a>
|
|
[% ELSE %]
|
|
<a class="dropdown-item" href="[% c.uri_for('/build' build.id 'keep' 1) %]">Keep</a>
|
|
[% END %]
|
|
[% END %]
|
|
[% IF build.finished %]
|
|
<a class="dropdown-item" href="[% c.uri_for('/build' build.id 'restart') %]">Restart</a>
|
|
[% ELSE %]
|
|
<a class="dropdown-item" href="[% c.uri_for('/build' build.id 'cancel') %]">Cancel</a>
|
|
<a class="dropdown-item" href="[% c.uri_for('/build' build.id 'bump') %]">Bump up</a>
|
|
[% END %]
|
|
[% END %]
|
|
</div>
|
|
</li>
|
|
|
|
<li class="nav-item"><a class="nav-link active" href="#tabs-summary" data-toggle="tab">Summary</a></li>
|
|
[% IF isAggregate %]<li class="nav-item"><a class="nav-link" href="#tabs-constituents" data-toggle="tab">Constituents</a></li>[% END %]
|
|
<li class="nav-item"><a class="nav-link" href="#tabs-details" data-toggle="tab">Details</a></li>
|
|
<li class="nav-item"><a class="nav-link" href="#tabs-buildinputs" data-toggle="tab">Inputs</a></li>
|
|
[% IF steps.size() > 0 %]<li class="nav-item"><a class="nav-link" href="#tabs-buildsteps" data-toggle="tab">Build Steps</a></li>[% END %]
|
|
[% IF build.dependents %]<li class="nav-item"><a class="nav-link" href="#tabs-usedby" data-toggle="tab">Used By</a></li>[% END%]
|
|
[% IF drvAvailable %]<li class="nav-item"><a class="nav-link" href="#tabs-build-deps" data-toggle="tab">Build Dependencies</a></li>[% END %]
|
|
[% IF localStore && available %]<li class="nav-item"><a class="nav-link" href="#tabs-runtime-deps" data-toggle="tab">Runtime Dependencies</a></li>[% END %]
|
|
[% IF runcommandlogs.size() > 0 %]<li class="nav-item"><a class="nav-link" href="#tabs-runcommandlogs" data-toggle="tab">RunCommand Logs</a></li>[% END %]
|
|
</ul>
|
|
|
|
<div id="generic-tabs" class="tab-content">
|
|
|
|
<div id="tabs-summary" class="tab-pane active">
|
|
|
|
<table>
|
|
<tr>
|
|
<td>
|
|
[% INCLUDE renderBuildStatusIcon size=128 build=build %]
|
|
</td>
|
|
<td>
|
|
<table class="info-table">
|
|
<tr>
|
|
<th>Build ID:</th>
|
|
<td>[% build.id %]</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Status:</th>
|
|
<td>
|
|
[% INCLUDE renderStatus build=build icon=0 busy=busy %]
|
|
[% IF isAggregate;
|
|
nrConstituents = 0;
|
|
nrFinished = 0;
|
|
nrFailedConstituents = 0;
|
|
FOREACH b IN constituents;
|
|
nrConstituents = nrConstituents + 1;
|
|
IF b.finished; nrFinished = nrFinished + 1; END;
|
|
IF b.finished && b.buildstatus != 0; nrFailedConstituents = nrFailedConstituents + 1; END;
|
|
END;
|
|
%];
|
|
[%+ IF nrFinished == nrConstituents && nrFailedConstituents == 0 %]
|
|
all [% nrConstituents %] constituent builds succeeded
|
|
[% ELSE %]
|
|
[% nrFailedConstituents %] out of [% nrConstituents %] constituent builds failed
|
|
[% IF nrFinished < nrConstituents %]
|
|
([% nrConstituents - nrFinished %] still pending)
|
|
[% END %]
|
|
[% END %]
|
|
[% END %]
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<th>System:</th>
|
|
<td><tt>[% build.system %]</tt></td>
|
|
</tr>
|
|
[% IF build.releasename %]
|
|
<tr>
|
|
<th>Release name:</th>
|
|
<td><tt>[% HTML.escape(build.releasename) %]</tt></td>
|
|
</tr>
|
|
[% ELSE %]
|
|
<tr>
|
|
<th>Nix name:</th>
|
|
<td><tt>[% build.nixname %]</tt></td>
|
|
</tr>
|
|
[% END %]
|
|
[% IF eval %]
|
|
<tr>
|
|
<th>Part of:</th>
|
|
<td>
|
|
<a href="[% c.uri_for(c.controller('JobsetEval').action_for('view'), [eval.id]) %]">evaluation [% eval.id %]</a>
|
|
[% IF nrEvals > 1 +%] (and <a href="[% c.uri_for('/build' build.id 'evals') %]">[% nrEvals - 1 %] others</a>)[% END %]
|
|
</td>
|
|
</tr>
|
|
[% END %]
|
|
[% IF build.iscachedbuild %]
|
|
<tr>
|
|
<th>Cached from:</th>
|
|
<td>[% IF cachedBuild; INCLUDE renderFullBuildLink build=cachedBuild; ELSE %]<em>unknown</em>[% END %]</td>
|
|
</tr>
|
|
[% END %]
|
|
[% actualBuild = build.iscachedbuild ? cachedBuild : build %]
|
|
[% IF (!isAggregate || !build.ischannel) && build.finished; %]
|
|
[% IF actualBuild %]
|
|
<tr>
|
|
<th>Duration:</th>
|
|
<td>[% INCLUDE renderDuration duration = actualBuild.stoptime - actualBuild.starttime %]</td>
|
|
</tr>
|
|
[% END %]
|
|
<tr>
|
|
<th>Finished at:</th>
|
|
<td>[% INCLUDE renderDateTime timestamp = build.stoptime; %]</td>
|
|
</tr>
|
|
[% END %]
|
|
[% IF (!build.finished && building) || (build.finished && (!isAggregate || !build.ischannel) && buildLogExists(build)) %]
|
|
<tr>
|
|
<th>Logfile:</th>
|
|
<td>
|
|
[% actualLog = cachedBuildStep ? c.uri_for('/build' cachedBuild.id 'nixlog' cachedBuildStep.stepnr) : c.uri_for('/build' build.id 'log') %]
|
|
<a class="btn btn-secondary btn-sm" href="[%actualLog%]">pretty</a>
|
|
<a class="btn btn-secondary btn-sm" href="[%actualLog%]/raw">raw</a>
|
|
<a class="btn btn-secondary btn-sm" href="[%actualLog%]/tail">tail</a>
|
|
</td>
|
|
</tr>
|
|
[% END %]
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
[% IF build.ischannel || (build.buildproducts && !isAggregate) %]
|
|
|
|
<h3>Build products</h3>
|
|
|
|
[% IF !available %]
|
|
<p class="error">Note: this build is no longer available.</p>
|
|
[% END %]
|
|
|
|
[% INCLUDE renderProductList latestRoot=['/job' build.project.name build.jobset.name build.job 'latest'] %]
|
|
|
|
[% END %]
|
|
|
|
[% IF busy %]
|
|
<h3>Running build steps</h3>
|
|
[% INCLUDE renderBuildSteps type="Running" %]
|
|
[% END %]
|
|
|
|
[% IF build.finished %]
|
|
|
|
[% IF steps && build.buildstatus != 0 && build.buildstatus != 4 && build.buildstatus != 6 %]
|
|
<h3>Failed build steps</h3>
|
|
[% INCLUDE renderBuildSteps type="Failed" %]
|
|
[% END %]
|
|
|
|
[% IF otherEval %]
|
|
<h3>Changes</h3>
|
|
[% INCLUDE renderInputDiff inputs2=eval.jobsetevalinputs inputs1=otherEval.jobsetevalinputs %]
|
|
[% END %]
|
|
|
|
[% IF prevSuccessfulBuild %]
|
|
<h3>Previous builds</h3>
|
|
<table class="table table-striped table-condensed">
|
|
<thead>
|
|
<th>Last successful build [% INCLUDE renderDateTime timestamp = prevSuccessfulBuild.timestamp %]</th>
|
|
[% IF prevSuccessfulBuild && firstBrokenBuild && firstBrokenBuild.id != build.id %]
|
|
<th>First broken build [% INCLUDE renderDateTime timestamp = firstBrokenBuild.timestamp %]
|
|
</th>
|
|
[% END %]
|
|
<th>This build [% INCLUDE renderDateTime timestamp = build.timestamp %]
|
|
</th>
|
|
</thead>
|
|
<tr>
|
|
<td valign="center">[% INCLUDE renderBuildStatusIcon build=prevSuccessfulBuild size=32 %] [% INCLUDE renderBuildLink build=prevSuccessfulBuild %]</td>
|
|
[% IF prevSuccessfulBuild && firstBrokenBuild && firstBrokenBuild.id != build.id %]
|
|
<td valign="center">[% INCLUDE renderBuildStatusIcon build=firstBrokenBuild size=32 %] [% INCLUDE renderBuildLink build=firstBrokenBuild %]</td>
|
|
[% END %]
|
|
<td>[% INCLUDE renderBuildStatusIcon build=build size=32 %] [% INCLUDE renderBuildLink build=build %]</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td>
|
|
[% IF prevSuccessfulBuild && firstBrokenBuild && firstBrokenBuild.id != build.id %]
|
|
<td>[% INCLUDE renderInputDiff inputs1=prevSuccessfulBuild.inputs inputs2=firstBrokenBuild.inputs %]</td>
|
|
[% END %]
|
|
</tr>
|
|
</table>
|
|
[% END %]
|
|
|
|
[% END %]
|
|
|
|
</div>
|
|
|
|
[% IF isAggregate %]
|
|
|
|
<div id="tabs-constituents" class="tab-pane">
|
|
|
|
<p>This build is an aggregate of the following builds:</p>
|
|
|
|
[% INCLUDE renderBuildList builds=constituents hideProjectName=1 hideJobsetName=1 %]
|
|
|
|
</div>
|
|
|
|
[% END %]
|
|
|
|
<div id="tabs-details" class="tab-pane">
|
|
|
|
<table class="info-table">
|
|
<tr>
|
|
<th>Queued at:</th>
|
|
<td>[% INCLUDE renderDateTime timestamp = build.timestamp %]</td>
|
|
</tr>
|
|
[% IF build.finished && !build.iscachedbuild %]
|
|
<tr>
|
|
<th>Build started:</th>
|
|
<td>[% INCLUDE renderDateTime timestamp = build.starttime %]</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Build finished:</th>
|
|
<td>[% INCLUDE renderDateTime timestamp = build.stoptime %]</td>
|
|
</tr>
|
|
[% END %]
|
|
[% IF !build.finished %]
|
|
<tr>
|
|
<th>Priority:</th>
|
|
<td>[% build.priority %]</td>
|
|
</tr>
|
|
[% END %]
|
|
[% IF eval.nixexprinput %]
|
|
<tr>
|
|
<th>Nix expression:</th>
|
|
<td>file <tt>[% HTML.escape(eval.nixexprpath) %]</tt> in input <tt>[% HTML.escape(eval.nixexprinput) %]</tt></td>
|
|
</tr>
|
|
[% END %]
|
|
<tr>
|
|
<th>Nix name:</th>
|
|
<td><tt>[% build.nixname %]</tt></td>
|
|
</tr>
|
|
<tr>
|
|
<th>Short description:</th>
|
|
<td>[% IF build.description %][% HTML.escape(build.description) %][% ELSE %]<em>not given</em>[% END %]</td>
|
|
</tr>
|
|
<tr>
|
|
<th>License:</th>
|
|
<td>[% IF build.license %][% HTML.escape(build.license) %][% ELSE %]<em>not given</em>[% END %]</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Homepage:</th>
|
|
<td>[% IF build.homepage %]<a [% HTML.attributes(href => build.homepage) %]>[% HTML.escape(build.homepage) %]</a>[% ELSE %]<em>not given</em>[% END %]</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Maintainer(s):</th>
|
|
<td>[% IF build.maintainers %][% HTML.escape(build.maintainers) %][% ELSE %]<em>not given</em>[% END %]</td>
|
|
</tr>
|
|
<tr>
|
|
<th>System:</th>
|
|
<td><tt>[% build.system %]</tt></td>
|
|
</tr>
|
|
<tr>
|
|
<th>Derivation store path:</th>
|
|
<td><tt>[% build.drvpath %]</tt></td>
|
|
</tr>
|
|
<tr>
|
|
<th>Output store paths:</th>
|
|
<td><tt>[% INCLUDE renderOutputs outputs=build.buildoutputs %]</tt></td>
|
|
</tr>
|
|
[% chartsURL = c.uri_for('/job' build.project.name build.jobset.name build.job) _ "#tabs-charts" %]
|
|
[% IF build.finished && build.closuresize %]
|
|
<tr>
|
|
<th>Closure size:</th>
|
|
<td>[% mibs(build.closuresize / (1024 * 1024)) %] MiB
|
|
(<a href="[%chartsURL%]">history</a>)</td>
|
|
</tr>
|
|
[% END %]
|
|
[% IF build.finished && build.closuresize %]
|
|
<tr>
|
|
<th>Output size:</th>
|
|
<td>[% mibs(build.size / (1024 * 1024)) %] MiB
|
|
(<a href="[%chartsURL%]">history</a>)</td>
|
|
</tr>
|
|
[% END %]
|
|
[% IF build.finished && build.buildproducts %]
|
|
<tr>
|
|
<th>Availability:</th>
|
|
<td>
|
|
[% IF !available %]
|
|
<em>Build output is no longer available</em>
|
|
[% ELSIF build.keep %]
|
|
<em>Build output will be kept permanently</em>
|
|
[% ELSE %]
|
|
<em>Build output is available, but may be garbage-collected</em>
|
|
[% END %]
|
|
</td>
|
|
</tr>
|
|
[% END %]
|
|
</table>
|
|
|
|
[% IF build.finished && build.buildmetrics %]
|
|
<h3>Metrics</h3>
|
|
|
|
<table class="table table-small table-striped table-hover clickable-rows">
|
|
<thead>
|
|
<tr><th>Name</th><th>Value</th><th></th></tr>
|
|
</thead>
|
|
<tbody>
|
|
[% FOREACH metric IN build.buildmetrics %]
|
|
<tr>
|
|
<td><tt><a class="row-link" [% HTML.attributes(href => c.uri_for('/job' project.name jobset.name job 'metric' metric.name)) %]">[%HTML.escape(metric.name)%]</a></tt></td>
|
|
<td style="text-align: right">[%metric.value%]</td>
|
|
<td>[%metric.unit%]</td>
|
|
</tr>
|
|
[% END %]
|
|
</tbody>
|
|
</table>
|
|
[% END %]
|
|
|
|
</div>
|
|
|
|
<div id="tabs-buildinputs" class="tab-pane">
|
|
|
|
[% IF build.inputs && build.inputs.size > 0 %]
|
|
|
|
[% INCLUDE renderInputs inputs=build.inputs %]
|
|
|
|
[% ELSIF eval %]
|
|
|
|
[% INCLUDE renderInputs inputs=eval.jobsetevalinputs %]
|
|
|
|
[% END %]
|
|
|
|
</div>
|
|
|
|
[% IF steps %]
|
|
<div id="tabs-buildsteps" class="tab-pane">
|
|
[% INCLUDE renderBuildSteps type="All" %]
|
|
</div>
|
|
[% END %]
|
|
|
|
[% IF build.dependents %]
|
|
<div id="tabs-usedby" class="tab-pane">
|
|
|
|
<p>The following builds have used this build as an input:</p>
|
|
|
|
<table class="table table-condensed table-striped">
|
|
<thead>
|
|
<tr><th>Build</th><th>Input name</th><th>System</th><th>Timestamp</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
[% FOREACH input IN build.dependents %]
|
|
<tr>
|
|
<td>[% INCLUDE renderFullBuildLink build=input.build %]</td>
|
|
<td><tt>[% input.name %]</tt></td>
|
|
<td><tt>[% input.build.system %]</tt></td>
|
|
<td>[% INCLUDE renderDateTime timestamp = input.build.timestamp %]</td>
|
|
</tr>
|
|
[% END %]
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
[% END %]
|
|
|
|
[% IF drvAvailable %]
|
|
[% INCLUDE makeLazyTab tabName="tabs-build-deps" uri=c.uri_for('/build' build.id 'build-deps') %]
|
|
[% END %]
|
|
|
|
[% IF available %]
|
|
[% INCLUDE makeLazyTab tabName="tabs-runtime-deps" uri=c.uri_for('/build' build.id 'runtime-deps') %]
|
|
[% END %]
|
|
|
|
<div id="tabs-runcommandlogs" class="tab-pane">
|
|
<div class="d-flex flex-column">
|
|
[% FOREACH runcommandlog IN runcommandlogs %]
|
|
<div class="p-2 border-bottom">
|
|
<div class="d-flex flex-row">
|
|
<div class="d-flex flex-column" style="padding: 10px; width: 50px;">
|
|
[% IF runcommandlog.did_succeed() %]
|
|
<img src="[% c.uri_for("/static/images/emojione-check-2714.svg") %]" height="30" width="30" title="Succeeded" alt="Succeeded" class="build-status" />
|
|
[% ELSIF runcommandlog.is_running() %]
|
|
|
|
[% ELSE %]
|
|
<img src="[% c.uri_for("/static/images/emojione-red-x-274c.svg") %]" height="30" width="30" title="Failed" alt="Failed" class="build-status" />
|
|
[% END %]
|
|
</div>
|
|
|
|
<div class="d-flex flex-column mr-auto align-self-center">
|
|
<div><tt>[% runcommandlog.command | html%]</tt></div>
|
|
<div>
|
|
[% IF not runcommandlog.is_running() %]
|
|
[% IF runcommandlog.did_fail_with_signal() %]
|
|
Exit signal: [% runcommandlog.signal %]
|
|
[% IF runcommandlog.core_dumped %]
|
|
(Core Dumped)
|
|
[% END %]
|
|
[% ELSIF runcommandlog.did_fail_with_exec_error() %]
|
|
Exec error: [% runcommandlog.error_number %]
|
|
[% ELSIF not runcommandlog.did_succeed() %]
|
|
Exit code: [% runcommandlog.exit_code %]
|
|
[% END %]
|
|
[% END %]
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex flex-column align-items-end">
|
|
[% IF runcommandlog.start_time != undef %]
|
|
<div>Started at [% INCLUDE renderDateTime timestamp = runcommandlog.start_time; %]</div>
|
|
<div class="d-flex flex-column align-items-end">
|
|
[% IF runcommandlog.end_time != undef %]
|
|
Ran for [% INCLUDE renderDuration duration = runcommandlog.end_time - runcommandlog.start_time %]
|
|
[% IF runcommandlog.uuid != undef %]
|
|
[% runLog = c.uri_for('/build', build.id, 'runcommandlog', runcommandlog.uuid) %]
|
|
<div>
|
|
<a class="btn btn-secondary btn-sm" href="[% runLog %]">pretty</a>
|
|
<a class="btn btn-secondary btn-sm" href="[% runLog %]/raw">raw</a>
|
|
<a class="btn btn-secondary btn-sm" href="[% runLog %]/tail">tail</a>
|
|
</div>
|
|
[% END %]
|
|
[% ELSE %]
|
|
Running for [% INCLUDE renderDuration duration = curTime - runcommandlog.start_time %]
|
|
[% IF runcommandlog.uuid != undef %]
|
|
[% runLog = c.uri_for('/build', build.id, 'runcommandlog', runcommandlog.uuid) %]
|
|
<div>
|
|
<a class="btn btn-secondary btn-sm" href="[% runLog %]">pretty</a>
|
|
<a class="btn btn-secondary btn-sm" href="[% runLog %]/raw">raw</a>
|
|
<a class="btn btn-secondary btn-sm" href="[% runLog %]/tail">tail</a>
|
|
</div>
|
|
[% END %]
|
|
[% END %]
|
|
</div>
|
|
[% ELSE %]
|
|
<div>Pending</div>
|
|
[% END %]
|
|
</div>
|
|
</div>
|
|
</div>
|
|
[% END %]
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="reproduce" class="modal hide fade" tabindex="-1" role="dialog" aria-hidden="true">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content">
|
|
[% url = c.uri_for('/build' build.id 'reproduce') %]
|
|
|
|
<div class="modal-header">
|
|
<h3>Reproduce this build</h3>
|
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
[% IF eval.flake %]
|
|
|
|
<p>If you have <a href='https://nixos.org/nix/download.html'>Nix
|
|
installed</a>, you can reproduce this build on your own machine by
|
|
running the following command:</p>
|
|
|
|
<div class="card bg-light"><div class="card-body p-2"><code>
|
|
<span class="shell-prompt"># </span>nix build [% HTML.escape(eval.flake) %]#hydraJobs.[% HTML.escape(job) %]
|
|
</code></div></div>
|
|
|
|
[% ELSE %]
|
|
|
|
<p>If you have <a href='https://nixos.org/nix/download.html'>Nix
|
|
installed</a>, you can reproduce this build on your own machine by
|
|
downloading <a [% HTML.attributes(href => url) %]>a script</a>
|
|
that checks out all inputs of the build and then invokes Nix to
|
|
perform the build.</p>
|
|
|
|
<p>To download and execute the script from the command line, run the
|
|
following command:</p>
|
|
|
|
<div class="card bg-light"><div class="card-body p-2"><code>
|
|
<span class="shell-prompt"># </span>curl <a [% HTML.attributes(href => url) %]>[% HTML.escape(url) %]</a> | bash
|
|
</code></div></div>
|
|
|
|
[% END %]
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
[% END %]
|