aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilo Casagrande <milo.casagrande@linaro.org>2015-01-20 12:14:14 +0100
committerMilo Casagrande <milo.casagrande@linaro.org>2015-01-20 12:14:14 +0100
commitb71aaba97c0d684111edab4cc80302da0bb342d6 (patch)
tree4dcd8cfb07261e10359ff28fc73c9310e5f291dc
parentdec4cb63e4c9bead118ae5932e27f4c69ca31b01 (diff)
Add new builds view.
* Add view to show all builds for job+kernel+defconfig. Change-Id: I47fa30a4d4de2d22578b3aa38cb0fcde0ac8fa7e
-rw-r--r--app/dashboard/static/js/linaro-boots-all-job-kernel-defconfig-0.0.1.js362
-rw-r--r--app/dashboard/templates/boots-all-job-kernel-defconfig.html59
-rw-r--r--app/dashboard/utils/route.py8
-rw-r--r--app/dashboard/views/boot.py22
4 files changed, 451 insertions, 0 deletions
diff --git a/app/dashboard/static/js/linaro-boots-all-job-kernel-defconfig-0.0.1.js b/app/dashboard/static/js/linaro-boots-all-job-kernel-defconfig-0.0.1.js
new file mode 100644
index 0000000..3a35de7
--- /dev/null
+++ b/app/dashboard/static/js/linaro-boots-all-job-kernel-defconfig-0.0.1.js
@@ -0,0 +1,362 @@
+var jobName = $('#job-name').val();
+var kernelName = $('#kernel-name').val();
+var defconfigFull = $('#defconfig-full').val();
+var pageLen = $('#page-len').val();
+var searchFilter = $('#search-filter').val();
+var fileServer = $('#file-server').val();
+
+function populateBootsTable(data) {
+ 'use strict';
+ var localData = data.result,
+ dataLen = localData.length,
+ table = null;
+
+ if (dataLen > 0) {
+ table = $('#boots-table').dataTable({
+ 'dom': '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"' +
+ '<"length-menu"l>>' +
+ '<"col-xs-12 col-sm-12 col-md-4 col-lg-4 col-lg-offset-2"f>r' +
+ '<"col-xs-12 col-sm-12 col-md-12 col-lg-12"t>>' +
+ '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"i>' +
+ '<"col-xs-12 col-sm-12 col-md-6 col-lg-6"p>>',
+ 'language': {
+ 'lengthMenu': '_MENU_&nbsp;<strong>boot reports ' +
+ 'per page</strong>',
+ 'zeroRecords': '<h4>No boot reports to display.</h4>',
+ 'search': '<div id="search-area" class="input-group">' +
+ '<span class="input-group-addon">' +
+ '<i class="fa fa-search"></i></span>_INPUT_</div>'
+ },
+ 'initComplete': function(settings, data) {
+ $('#table-loading').remove();
+ $('#table-div').fadeIn('slow', 'linear');
+
+ var api = this.api();
+
+ if (pageLen !== undefined && pageLen !== null) {
+ if (pageLen.length > 0) {
+ pageLen = Number(pageLen);
+ if (isNaN(pageLen)) {
+ pageLen = 25;
+ }
+
+ api.page.len(pageLen).draw();
+ }
+ }
+
+ if (searchFilter !== null && searchFilter !== undefined) {
+ if (searchFilter.length > 0) {
+ api.search(searchFilter, true).draw();
+ }
+ }
+ },
+ 'lengthMenu': [25, 50, 75, 100],
+ 'deferRender': true,
+ 'ordering': true,
+ 'processing': true,
+ 'stateDuration': -1,
+ 'stateSave': true,
+ 'order': [5, 'desc'],
+ 'search': {
+ 'regex': true,
+ 'smart': true
+ },
+ 'data': localData,
+ 'columns': [
+ {
+ 'data': '_id',
+ 'visible': false,
+ 'searchable': false,
+ 'orderable': false
+ },
+ {
+ 'data': 'board',
+ 'title': 'Board Model',
+ 'render': function(data, type, object) {
+ return '<a class="table-link" href="/boot/' + data +
+ '/job/' + jobName + '/kernel/' +
+ kernelName + '/">' + data + '</a>';
+ }
+ },
+ {
+ 'data': 'lab_name',
+ 'title': 'Lab Name',
+ 'render': function(data, type, object) {
+ return '<a class="table-link" href="/boot/all/lab/' +
+ data + '/">' + data + '</a>';
+ }
+ },
+ {
+ 'data': 'boot_result_description',
+ 'title': 'Failure Reason',
+ 'type': 'string',
+ 'render': function(data, type, object) {
+ var display = '',
+ status = object.status;
+ if (data !== null && status !== 'PASS') {
+ if (data.length > 45) {
+ display = '<span rel="tooltip" ' +
+ 'data-toggle="tooltip"' +
+ 'title="' + data + '">' +
+ data.slice(0, 46) + '&hellip;</span>';
+ } else {
+ display = data;
+ }
+ }
+ return display;
+ }
+ },
+ {
+ 'data': 'boot_log',
+ 'title': 'Boot Log',
+ 'type': 'string',
+ 'render': function(data, type, object) {
+ var arch = object.arch,
+ fileServerUrl = object.file_server_url,
+ fileServerResource = object.file_server_resource,
+ defconfigFull = object.defconfig_full,
+ labName = object.lab_name,
+ logPath = null,
+ fileServerUri = null,
+ pathUrl = null,
+ uriPath = null,
+ bootLog = data,
+ bootLogHtml = object.boot_log_html,
+ display = '';
+
+ if (fileServerUrl !== null &&
+ fileServerUrl !== undefined) {
+ fileServer = fileServerUrl;
+ }
+
+ if (fileServerResource !== null &&
+ fileServerResource !== undefined) {
+ pathUrl = fileServerResource;
+ } else {
+ pathUrl = jobName + '/' + kernelName + '/' +
+ arch + '-' + defconfigFull + '/';
+ }
+
+ fileServerUri = new URI(fileServer);
+ uriPath = fileServerUri.path() + '/' + pathUrl;
+
+ if (bootLog !== null) {
+ if (bootLog.search(labName) === -1) {
+ logPath = uriPath + '/' + labName + '/' +
+ bootLog;
+ } else {
+ logPath = uriPath + '/' + bootLog;
+ }
+ display += '<span rel="tooltip" ' +
+ 'data-toggle="tooltip" ' +
+ 'title="View raw text boot log"><a href="' +
+ fileServerUri
+ .path(logPath)
+ .normalizePath().href() +
+ '">txt' +
+ '&nbsp;<i class="fa fa-external-link">' +
+ '</i></a></span>';
+ }
+
+ if (bootLogHtml !== null) {
+ if (bootLog !== null) {
+ display += '&nbsp;&mdash;&nbsp;';
+ }
+ if (bootLogHtml.search(labName) === -1) {
+ logPath = uriPath + '/' + labName + '/' +
+ bootLogHtml;
+ } else {
+ logPath = uriPath + '/' + bootLogHtml;
+ }
+ display += '<span rel="tooltip" ' +
+ 'data-toggle="tooltip" ' +
+ 'title="View HTML boot log"><a href="' +
+ fileServerUri
+ .path(logPath)
+ .normalizePath().href() +
+ '">html&nbsp;<i class="fa fa-external-link">' +
+ '</i></a></span>';
+ }
+ return display;
+ }
+ },
+ {
+ 'data': 'created_on',
+ 'title': 'Date',
+ 'type': 'date',
+ 'className': 'pull-center',
+ 'render': function(data) {
+ var created = new Date(data.$date);
+ return created.getCustomISODate();
+ }
+ },
+ {
+ 'data': 'status',
+ 'title': 'Status',
+ 'type': 'string',
+ 'className': 'pull-center',
+ 'render': function(data) {
+ var displ;
+ switch (data) {
+ case 'PASS':
+ displ = '<span rel="tooltip" ' +
+ 'data-toggle="tooltip"' +
+ 'title="Boot completed">' +
+ '<span class="label label-success">' +
+ '<i class="fa fa-check"></i></span>' +
+ '</span>';
+ break;
+ case 'FAIL':
+ displ = '<span rel="tooltip" ' +
+ 'data-toggle="tooltip"' +
+ 'title="Boot failed">' +
+ '<span class="label label-danger">' +
+ '<i class="fa fa-exclamation-triangle">' +
+ '</i></span></span>';
+ break;
+ case 'OFFLINE':
+ displ = '<span rel="tooltip"' +
+ 'data-toggle="tooltip"' +
+ 'title="Board offline"' +
+ '<span class="label label-info">' +
+ '<i class="fa fa-power-off">' +
+ '</i></span></span>';
+ break;
+ default:
+ displ = '<span rel="tooltip" ' +
+ 'data-toggle="tooltip"' +
+ 'title="Unknown status">' +
+ '<span class="label label-warning">' +
+ '<i class="fa fa-question">' +
+ '</i></span></span>';
+ break;
+ }
+ return displ;
+ }
+ },
+ {
+ 'data': 'board',
+ 'title': '',
+ 'orderable': false,
+ 'searchable': false,
+ 'className': 'pull-center',
+ 'render': function(data, type, object) {
+ var lab = object.lab_name;
+
+ return '<span rel="tooltip" data-toggle="tooltip"' +
+ 'title="Details for board&nbsp;' + data +
+ '&nbsp;with&nbsp;' +
+ jobName + '&dash;' + kernelName + '&dash;' +
+ defconfigFull +
+ '&nbsp;&dash;&nbsp;(' + lab + ')' +
+ '"><a href="/boot/' + data + '/job/' + jobName +
+ '/kernel/' + kernelName + '/defconfig/' +
+ defconfigFull +
+ '/lab/' + lab + '/?_id=' + object._id.$oid + '">' +
+ '<i class="fa fa-search"></i></a></span>';
+ }
+ }
+ ]
+ });
+
+ $(document).on('click', '#labtable tbody tr', function() {
+ var localTable = table.fnGetData(this),
+ location = '#';
+ if (localTable) {
+ location = '/boot/' + localTable.board + '/job/' +
+ localTable.job + '/kernel/' + localTable.kernel +
+ '/defconfig/' + localTable.defconfig_full + '/lab/' +
+ localTable.lab_name + '/';
+ if (localTable._id !== null) {
+ location += '?_id=' + localTable._id.$oid;
+ }
+ window.location = location;
+ }
+ });
+
+ $('#search-area > .input-sm').attr('placeholder', 'Filter the results');
+ $('.input-sm').keyup(function(key) {
+ // Remove focus from input when Esc is pressed.
+ if (key.keyCode === 27) {
+ $(this).blur();
+ }
+ });
+ } else {
+ $('#table-loading').remove();
+ JSBase.replaceContentByID(
+ '#table-div',
+ '<strong>No boot reports found.</strong>');
+ }
+}
+
+function ajaxDeferredFailed() {
+ 'use strict';
+ $('#table-loading').remove();
+ JSBase.replaceContentByID(
+ '#table-div',
+ '<strong>Error loading data.</strong>');
+}
+
+$(document).ready(function() {
+ 'use strict';
+ $('#li-boot').addClass('active');
+ $('#table-div').hide();
+
+ var ajaxDeferredCall = null,
+ ajaxData = null,
+ errorReason = 'Error loading boot reports data';
+
+ JSBase.replaceContentByID(
+ '#dd-tree',
+ '<span rel="tooltip" data-toggle="tooltip" ' +
+ 'title="Boot details for&nbsp;' + jobName + '">' +
+ '<a href="/boot/all/job/' + jobName + '">' + jobName +
+ '</a></span>' +
+ '&nbsp;&mdash;&nbsp;' +
+ '<span rel="tooltip" data-toggle="tooltip" ' +
+ 'title="Details for job&nbsp;' + jobName +
+ '"><a href="/job/' + jobName +
+ '"><i class="fa fa-sitemap"></i></a></span>'
+ );
+ JSBase.replaceContentByID(
+ '#dd-git-describe',
+ '<span rel="tooltip" data-toggle="tooltip" ' +
+ 'title="Boot report details for&nbsp;' + jobName +
+ '&nbsp;&dash;&nbsp;' +
+ kernelName + '"><a href="/boot/all/job/' + jobName +
+ '/kernel/' + kernelName + '">' + kernelName +
+ '</a></span>' +
+ '&nbsp;&mdash;&nbsp;' +
+ '<span rel="tooltip" data-toggle="tooltip" ' +
+ 'title="Details for build&nbsp;' + jobName +
+ '&nbsp;&dash;&nbsp;' +
+ kernelName + '"><a href="/build/' + jobName +
+ '/kernel/' + kernelName +
+ '"><i class="fa fa-cube"></i></a></span>'
+ );
+ JSBase.replaceContentByID(
+ '#dd-defconfig',
+ defconfigFull + '&nbsp;&mdash;&nbsp;' +
+ '<span rel="tooltip" data-toggle="tooltip" title="' +
+ 'Details for build&nbsp;' + jobName + '&nbsp;&dash;&nbsp;' +
+ kernelName + '&nbsp;&dash;&nbsp;' + defconfigFull + '">' +
+ '<a href="/build/' + jobName + '/kernel/' + kernelName + '/defconfig/' +
+ defconfigFull + '/"><i class="fa fa-cube"></i></a></span>'
+ );
+
+ ajaxData = {
+ 'job': jobName,
+ 'kernel': kernelName,
+ 'defconfig_full': defconfigFull
+ };
+ ajaxDeferredCall = JSBase.createDeferredCall(
+ '/_ajax/boot',
+ 'GET',
+ ajaxData,
+ null,
+ ajaxDeferredFailed,
+ errorReason
+ );
+
+ $.when(ajaxDeferredCall).done(populateBootsTable);
+});
diff --git a/app/dashboard/templates/boots-all-job-kernel-defconfig.html b/app/dashboard/templates/boots-all-job-kernel-defconfig.html
new file mode 100644
index 0000000..149cf88
--- /dev/null
+++ b/app/dashboard/templates/boots-all-job-kernel-defconfig.html
@@ -0,0 +1,59 @@
+{%- extends "base.html" %}
+{%- block meta -%}
+ <meta name="csrf-token" content="{{ csrf_token_r() }}">
+{%- endblock %}
+{%- block title %}{{ page_title|safe }}{%- endblock %}
+{%- block head %}
+{{ super() }}
+<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/plug-ins/9dcbecd42ad/integration/bootstrap/3/dataTables.bootstrap.css">
+{%- endblock %}
+{%- block content %}
+<div class="row">
+ <div class="page-header">
+ <h3>{{ body_title|safe }}</h3>
+ </div>
+ <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
+ <dl class="dl-horizontal">
+ <dt>Tree</dt>
+ <dd id="dd-tree" class="loading-content">
+ <i class="fa fa-cog fa-spin"></i>&nbsp;loading&hellip;
+ </dd>
+ <dt>Git describe</dt>
+ <dd id="dd-git-describe" class="loading-content">
+ <i class="fa fa-cog fa-spin"></i>&nbsp;loading&hellip;
+ </dd>
+ <dt>Defconfig</dt>
+ <dd id="dd-defconfig" class="loading-content">
+ <i class="fa fa-cog fa-spin"></i>&nbsp;loading&hellip;
+ </dd>
+ </dl>
+ </div>
+</div>
+<div class="row" id="boot-reports">
+ <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
+ <div id="table-loading" class="pull-center">
+ <i class="fa fa-cog fa-2x fa-spin"></i>&nbsp;loading&hellip;
+ </div>
+ {%- if is_mobile %}
+ <div class="table-responsive" id="table-div">
+ {%- else %}
+ <div class="table" id="table-div">
+ {%- endif %}
+ <table class="table table-hover table-striped table-condensed clickable-table big-table" id="boots-table">
+ </table>
+ </div>
+ </div>
+</div>
+<input type="hidden" id="file-server" value="{{ config['FILE_SERVER_URL'] }}">
+<input type="hidden" id="job-name" value="{{ job }}">
+<input type="hidden" id="kernel-name" value="{{ kernel }}">
+<input type="hidden" id="defconfig-full" value="{{ defconfig }}">
+<input type="hidden" id="search-filter" value="{{ search_filter }}">
+<input type="hidden" id="page-len" value="{{ page_len }}">
+{%- endblock %}
+{%- block scripts %}
+{{ super() }}
+<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/datatables/1.10.3/js/jquery.dataTables.min.js"></script>
+<script type="text/javascript" src="//cdn.datatables.net/plug-ins/9dcbecd42ad/integration/bootstrap/3/dataTables.bootstrap.js"></script>
+<script type="text/javascript" src="/static/js/linaro-boots-all-job-kernel-defconfig-0.0.1.js"></script>
+{%- endblock %} \ No newline at end of file
diff --git a/app/dashboard/utils/route.py b/app/dashboard/utils/route.py
index 644e57e..76ee1f1 100644
--- a/app/dashboard/utils/route.py
+++ b/app/dashboard/utils/route.py
@@ -103,6 +103,14 @@ def init():
)
add_rule(
(
+ "/boot/all/job/<string:job>/kernel/<string:kernel>/"
+ "defconfig/<string:defconfig>/"
+ ),
+ view_func=vboot.BootAllJobKernelDefconfigView.as_view("boot-all-jkd"),
+ methods=["GET"]
+ )
+ add_rule(
+ (
"/boot/<string:board>/job/<string:job>/kernel/<string:kernel>/"
"defconfig/<string:defconfig>/"
),
diff --git a/app/dashboard/views/boot.py b/app/dashboard/views/boot.py
index a902b90..bf7d8bf 100644
--- a/app/dashboard/views/boot.py
+++ b/app/dashboard/views/boot.py
@@ -44,6 +44,28 @@ class BootAllView(BootGeneralView):
)
+class BootAllJobKernelDefconfigView(BootGeneralView):
+ def dispatch_request(self, **kwargs):
+
+ page_title = self.BOOT_PAGES_TITLE + ""
+ body_title = (
+ "Boot reports for &#171;%(job)s - %(kernel)s&#187;&nbsp;"
+ "<small>(%(defconfig)s)</small>" % kwargs
+ )
+ search_filter, page_len = get_search_parameters(request)
+
+ return render_template(
+ "boots-all-job-kernel-defconfig.html",
+ page_title=page_title,
+ body_title=body_title,
+ job=kwargs["job"],
+ kernel=kwargs["kernel"],
+ defconfig=kwargs["defconfig"],
+ search_filter=search_filter,
+ page_len=page_len
+ )
+
+
class BootDefconfigView(BootGeneralView):
def dispatch_request(self, **kwargs):