hydra-server: Support logs in S3
This commit is contained in:
@ -7,7 +7,13 @@
|
||||
[%
|
||||
isAggregate = constituents.size > 0;
|
||||
busy = 0;
|
||||
FOR step IN steps; IF step.busy; busy = 1; END; END;
|
||||
building = 0;
|
||||
FOR step IN steps;
|
||||
IF step.busy;
|
||||
busy = 1;
|
||||
IF step.drvpath == build.drvpath; building = 1; END;
|
||||
END;
|
||||
END;
|
||||
%]
|
||||
|
||||
[% BLOCK renderOutputs %]
|
||||
@ -207,7 +213,8 @@ FOR step IN steps; IF step.busy; busy = 1; END; END;
|
||||
<td>[% IF cachedBuild; INCLUDE renderFullBuildLink build=cachedBuild; ELSE %]<em>unknown</em>[% END %]</td>
|
||||
</tr>
|
||||
[% END %]
|
||||
[% IF (!isAggregate || !build.ischannel) && build.finished; actualBuild = build.iscachedbuild ? cachedBuild : build %]
|
||||
[% actualBuild = build.iscachedbuild ? cachedBuild : build %]
|
||||
[% IF (!isAggregate || !build.ischannel) && build.finished; %]
|
||||
[% IF actualBuild %]
|
||||
<tr>
|
||||
<th>Duration:</th>
|
||||
@ -219,13 +226,13 @@ FOR step IN steps; IF step.busy; busy = 1; END; END;
|
||||
<td>[% INCLUDE renderDateTime timestamp = build.stoptime; %]</td>
|
||||
</tr>
|
||||
[% END %]
|
||||
[% IF (!isAggregate || !build.ischannel) && buildLogExists(build) %]
|
||||
[% IF (!build.finished && building) || (build.finished && (!isAggregate || !build.ischannel) && buildLogExists(build)) %]
|
||||
<tr>
|
||||
<th>Logfile:</th>
|
||||
<td>
|
||||
<a class="btn btn-mini" href="[% c.uri_for('/build' build.id 'log') %]">pretty</a>
|
||||
<a class="btn btn-mini" href="[% c.uri_for('/build' build.id 'log' 'raw') %]">raw</a>
|
||||
<a class="btn btn-mini" href="[% c.uri_for('/build' build.id 'log' 'tail-reload') %]">tail</a>
|
||||
<a class="btn btn-mini" href="[% c.uri_for('/build' actualBuild.id 'log') %]">pretty</a>
|
||||
<a class="btn btn-mini" href="[% c.uri_for('/build' actualBuild.id 'log' 'raw') %]">raw</a>
|
||||
<a class="btn btn-mini" href="[% c.uri_for('/build' actualBuild.id 'log' 'tail') %]">tail</a>
|
||||
</td>
|
||||
</tr>
|
||||
[% END %]
|
||||
|
@ -465,7 +465,7 @@ BLOCK renderEvals %]
|
||||
|
||||
|
||||
BLOCK renderLogLinks %]
|
||||
(<a [% IF inRow %]class="row-link"[% END %] href="[% url %]">log</a>, <a href="[% "$url/raw" %]">raw</a>, <a href="[% "$url/tail-reload" %]">tail</a>)
|
||||
(<a [% IF inRow %]class="row-link"[% END %] href="[% url %]">log</a>, <a href="[% "$url/raw" %]">raw</a>, <a href="[% "$url/tail" %]">tail</a>)
|
||||
[% END;
|
||||
|
||||
|
||||
|
@ -2,14 +2,48 @@
|
||||
[% PROCESS common.tt %]
|
||||
|
||||
<p>
|
||||
This is the build log of derivation <tt>[% IF step; step.drvpath; ELSE; build.drvpath; END %]</tt>.
|
||||
Below
|
||||
[% IF tail %]
|
||||
are the last lines of
|
||||
[% ELSE %]
|
||||
is
|
||||
[% END %]
|
||||
the build log of derivation <tt>[% IF step; step.drvpath; ELSE; build.drvpath; END %]</tt>.
|
||||
[% IF step && step.machine %]
|
||||
It was built on <tt>[% step.machine %]</tt>.
|
||||
[% END %]
|
||||
[% IF tail %]
|
||||
The <a href="[% step ? c.uri_for('/build' build.id 'nixlog' step.stepnr)
|
||||
: c.uri_for('/build' build.id 'log') %]">full log</a> is also available.
|
||||
[% END %]
|
||||
</p>
|
||||
|
||||
<pre class="taillog" id="contents">
|
||||
[% HTML.escape(logtext) %]
|
||||
<pre class="log" id="contents">
|
||||
<em>Loading...</em>
|
||||
</pre>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
requestPlainFile({
|
||||
url: "[% HTML.escape(log_uri) %]",
|
||||
dataType: "text",
|
||||
type: 'GET',
|
||||
success: function (log_data) {
|
||||
|
||||
[% IF tail %]
|
||||
/* The server may give us a full log (e.g. if the log is in
|
||||
S3). So extract the last lines. */
|
||||
log_data = log_data.split("\n").slice(-[%tail%]).join("\n");
|
||||
[% END %]
|
||||
|
||||
$("#contents").text(log_data);
|
||||
},
|
||||
error: function () {
|
||||
bootbox.alert("The log file is not available.");
|
||||
$("#contents").text("(Unavailable)");
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
[% END %]
|
||||
|
@ -42,7 +42,7 @@
|
||||
<td><tt>[% INCLUDE renderFullJobName project=step.project jobset=step.jobset job=step.job %]</tt></td>
|
||||
<td><tt>[% step.system %]</tt></td>
|
||||
<td><a href="[% c.uri_for('/build' step.build) %]">[% step.build %]</a></td>
|
||||
<td><a class="row-link" href="[% c.uri_for('/build' step.build 'nixlog' step.stepnr 'tail-reload') %]">[% step.stepnr %]</a></td>
|
||||
<td><a class="row-link" href="[% c.uri_for('/build' step.build 'nixlog' step.stepnr 'tail') %]">[% step.stepnr %]</a></td>
|
||||
<td><tt>[% step.drvpath.match('-(.*)').0 %]</tt></td>
|
||||
<td style="width: 10em">[% INCLUDE renderDuration duration = curTime - step.starttime %] </td>
|
||||
</tr>
|
||||
|
@ -1,39 +0,0 @@
|
||||
[% WRAPPER layout.tt title="Log of " _ (step ? " step $step.stepnr of " : "") _ "build ${build.id} of job $build.project.name:$build.jobset.name:$build.job.name" %]
|
||||
[% PROCESS common.tt %]
|
||||
|
||||
[% project = build.project %]
|
||||
[% jobset = build.jobset %]
|
||||
[% job = build.job %]
|
||||
|
||||
<p>Below are the last 50 log lines. The <a href="[% c.uri_for('/build' build.id 'log') %]">full log</a> is also available.</p>
|
||||
|
||||
[% IF reload %]
|
||||
<script>
|
||||
function scrollDown() {
|
||||
$("#contents").scrollTop($("#contents").get(0).scrollHeight);
|
||||
}
|
||||
|
||||
function injectTail() {
|
||||
$.ajax({
|
||||
url: "[% url %]",
|
||||
dataType: "text",
|
||||
success: function (tail) {
|
||||
$("#contents").text(tail);
|
||||
scrollDown();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
scrollDown();
|
||||
injectTail();
|
||||
setInterval(injectTail, 5000);
|
||||
});
|
||||
</script>
|
||||
[% END %]
|
||||
|
||||
<pre class="taillog" id="contents">
|
||||
[% HTML.escape(contents) %]
|
||||
</pre>
|
||||
|
||||
[% END %]
|
@ -119,7 +119,7 @@ span.keep-whitespace {
|
||||
max-width: none; /* don't apply responsive design to status images */
|
||||
}
|
||||
|
||||
pre.log, pre.taillog {
|
||||
pre.log {
|
||||
line-height: 1.2em;
|
||||
}
|
||||
|
||||
|
@ -120,24 +120,48 @@ function escapeHTML(s) {
|
||||
return $('<div/>').text(s).html();
|
||||
};
|
||||
|
||||
function requestFile(args) {
|
||||
if (!"error" in args) {
|
||||
args.error = function(data) {
|
||||
json = {};
|
||||
try {
|
||||
if (data.responseText)
|
||||
json = $.parseJSON(data.responseText);
|
||||
} catch (err) {
|
||||
}
|
||||
if (json.error)
|
||||
bootbox.alert(escapeHTML(json.error));
|
||||
else if (data.responseText)
|
||||
bootbox.alert("Server error: " + escapeHTML(data.responseText));
|
||||
else
|
||||
bootbox.alert("Unknown server error!");
|
||||
if (args.postError) args.postError(data);
|
||||
};
|
||||
}
|
||||
return $.ajax(args);
|
||||
};
|
||||
|
||||
function requestJSON(args) {
|
||||
args.dataType = 'json';
|
||||
args.error = function(data) {
|
||||
json = {};
|
||||
try {
|
||||
if (data.responseText)
|
||||
json = $.parseJSON(data.responseText);
|
||||
} catch (err) {
|
||||
requestFile(args);
|
||||
};
|
||||
|
||||
function requestPlainFile(args) {
|
||||
args.dataType = 'text';
|
||||
/* Remove the X-Requested-With header, which would turn trigger
|
||||
CORS checks for this request.
|
||||
http://stackoverflow.com/a/24719409/6747243
|
||||
*/
|
||||
args.xhr = function() {
|
||||
var xhr = jQuery.ajaxSettings.xhr();
|
||||
var setRequestHeader = xhr.setRequestHeader;
|
||||
xhr.setRequestHeader = function(name, value) {
|
||||
if (name == 'X-Requested-With') return;
|
||||
setRequestHeader.call(this, name, value);
|
||||
}
|
||||
if (json.error)
|
||||
bootbox.alert(escapeHTML(json.error));
|
||||
else if (data.responseText)
|
||||
bootbox.alert("Server error: " + escapeHTML(data.responseText));
|
||||
else
|
||||
bootbox.alert("Unknown server error!");
|
||||
if (args.postError) args.postError(data);
|
||||
return xhr;
|
||||
};
|
||||
return $.ajax(args);
|
||||
requestFile(args);
|
||||
};
|
||||
|
||||
function redirectJSON(args) {
|
||||
|
@ -25,7 +25,7 @@ order of descending finish time.</p>
|
||||
<td><tt>[% step.drvpath.match('-(.*).drv').0 %]</tt></td>
|
||||
<td><tt>[% INCLUDE renderFullJobNameOfBuild build=step.build %]</tt></td>
|
||||
<td><a href="[% c.uri_for('/build' step.build.id) %]">[% step.build.id %]</a></td>
|
||||
<td><a class="row-link" href="[% c.uri_for('/build' step.build.id 'nixlog' step.stepnr 'tail-reload') %]">[% step.stepnr %]</a></td>
|
||||
<td><a class="row-link" href="[% c.uri_for('/build' step.build.id 'nixlog' step.stepnr 'tail') %]">[% step.stepnr %]</a></td>
|
||||
<td>[% INCLUDE renderRelativeDate timestamp=step.stoptime %]</td>
|
||||
<td style="width: 10em">[% INCLUDE renderDuration duration = step.stoptime - step.starttime %] </td>
|
||||
<td><tt>[% INCLUDE renderMachineName machine=step.machine %]</tt></td>
|
||||
|
Reference in New Issue
Block a user