[Toaster] [PATCH 1/2] toaster: adjust build dashboard for failed builds

Elliot Smith elliot.smith at intel.com
Thu Mar 17 04:40:25 PDT 2016


Remove the side bar and build details modules for failed builds.

Modify templates so that the span is moved out of the individual
elements and into the container. This makes it simpler to change
the width of the main container, depending on whether the
build failed or not (which in turn hides or shows the left-hand
menu).

[YOCTO #8443]

Signed-off-by: Elliot Smith <elliot.smith at intel.com>
---
 bitbake/lib/toaster/orm/models.py                  |  15 ++
 .../toastergui/templates/basebuildpage.html        | 148 +++++++++---------
 .../toastergui/templates/builddashboard.html       | 174 +++++++++++----------
 bitbake/lib/toaster/toastergui/views.py            |   1 +
 4 files changed, 177 insertions(+), 161 deletions(-)

diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index 3c98c0b..1d69c24 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -516,6 +516,21 @@ class Build(models.Model):
 
         return target_labels
 
+    def started(self):
+        """
+        As build variables are only added for a build when its BuildStarted event
+        is received, a build with no build variables is counted as
+        "in preparation" and not properly started yet. This method
+        will return False if a build has no build variables (it never properly
+        started), or True otherwise.
+
+        Note that this is a temporary workaround for the fact that we don't
+        have a fine-grained state variable on a build which would allow us
+        to record "in progress" (BuildStarted received) vs. "in preparation".
+        """
+        variables = Variable.objects.filter(build=self)
+        return len(variables) > 0
+
     def get_current_status(self):
         """
         get the status string from the build request if the build
diff --git a/bitbake/lib/toaster/toastergui/templates/basebuildpage.html b/bitbake/lib/toaster/toastergui/templates/basebuildpage.html
index ff9433e..7762210 100644
--- a/bitbake/lib/toaster/toastergui/templates/basebuildpage.html
+++ b/bitbake/lib/toaster/toastergui/templates/basebuildpage.html
@@ -2,89 +2,81 @@
 {% load projecttags %}
 {% load project_url_tag %}
 {% load humanize %}
-{% block pagecontent %}
 
+{% block pagecontent %}
+  <!-- Breadcrumbs -->
+  <div class="section">
+    <ul class="breadcrumb" id="breadcrumb">
+      <li><a href="{% project_url build.project %}">{{build.project.name}}</a></li>
+      {% if not build.project.is_default %}
+        <li><a href="{% url 'projectbuilds' build.project.id %}">Builds</a></li>
+      {% endif %}
+      <li>
+        {% block parentbreadcrumb %}
+          <a href="{%url 'builddashboard' build.pk%}">
+            {{build.get_sorted_target_list.0.target}} {%if build.target_set.all.count > 1%}(+{{build.target_set.all.count|add:"-1"}}){%endif%} {{build.machine}} ({{build.completed_on|date:"d/m/y H:i"}})
+          </a>
+        {% endblock %}
+      </li>
+      {% block localbreadcrumb %}{% endblock %}
+    </ul>
+    <script>
+    $( function () {
+      $('#breadcrumb > li').append('<span class="divider">→</span>');
+      $('#breadcrumb > li:last').addClass("active");
+      $('#breadcrumb > li:last > span').remove();
+    });
+    </script>
+  </div>
 
- <div class="">
-<!-- Breadcrumbs -->
-    <div class="section">
-        <ul class="breadcrumb" id="breadcrumb">
-            <li><a href="{% project_url build.project %}">{{build.project.name}}</a></li>
-            {% if not build.project.is_default %}
-                <li><a href="{% url 'projectbuilds' build.project.id %}">Builds</a></li>
-            {% endif %}
-            <li>
-            {% block parentbreadcrumb %}
-            <a href="{%url 'builddashboard' build.pk%}">
-              {{build.get_sorted_target_list.0.target}} {%if build.target_set.all.count > 1%}(+{{build.target_set.all.count|add:"-1"}}){%endif%} {{build.machine}} ({{build.completed_on|date:"d/m/y H:i"}})
-            </a>
+  <div class="row-fluid">
+    {% if build.started %}
+      <!-- begin left sidebar container for builds which properly started -->
+      <div id="nav" class="span2">
+        <ul class="nav nav-list well">
+          <li {% if request.resolver_match.url_name == 'builddashboard'  %}class="active"{% endif %}>
+            <a class="nav-parent" href="{% url 'builddashboard' build.pk %}">Build summary</a>
+          </li>
+          {% if build.target_set.all.0.is_image and build.outcome == 0 %}
+            <li class="nav-header">Images</li>
+            {% block nav-target %}
+              {% for t in build.get_sorted_target_list %}
+                <li><a href="{% url 'target' build.pk t.pk %}">{{t.target}}</a><li>
+              {% endfor %}
             {% endblock %}
-            </li>
-            {% block localbreadcrumb %}{% endblock %}
+          {% endif %}
+          <li class="nav-header">Build</li>
+          {% block nav-configuration %}
+            <li><a href="{% url 'configuration' build.pk %}">Configuration</a></li>
+          {% endblock %}
+          {% block nav-tasks %}
+            <li><a href="{% url 'tasks' build.pk %}">Tasks</a></li>
+          {% endblock %}
+          {% block nav-recipes %}
+            <li><a href="{% url 'recipes' build.pk %}">Recipes</a></li>
+          {% endblock %}
+          {% block nav-packages %}
+            <li><a href="{% url 'packages' build.pk %}">Packages</a></li>
+          {% endblock %}
+            <li class="nav-header">Performance</li>
+          {% block nav-buildtime %}
+            <li><a href="{% url 'buildtime' build.pk %}">Time</a></li>
+          {% endblock %}
+          {% block nav-cputime %}
+            <li><a href="{% url 'cputime' build.pk %}">CPU time</a></li>
+          {% endblock %}
+          {% block nav-diskio %}
+            <li><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li>
+          {% endblock %}
         </ul>
-        <script>
-        $( function () {
-            $('#breadcrumb > li').append('<span class="divider">→</span>');
-            $('#breadcrumb > li:last').addClass("active");
-            $('#breadcrumb > li:last > span').remove();
-        });
-        </script>
-    </div>
-
-    <div class="row-fluid">
-
-        <!-- begin left sidebar container -->
-        <div id="nav" class="span2">
-            <ul class="nav nav-list well">
-              <li
-                {% if request.resolver_match.url_name == 'builddashboard'  %}
-                  class="active"
-                {% endif %} >
-                <a class="nav-parent" href="{% url 'builddashboard' build.pk %}">Build summary</a>
-              </li>
-              {% if build.target_set.all.0.is_image and build.outcome == 0 %}
-                <li class="nav-header">Images</li>
-                {% block nav-target %}
-                  {% for t in build.get_sorted_target_list %}
-                    <li><a href="{% url 'target' build.pk t.pk %}">{{t.target}}</a><li>
-                  {% endfor %}
-                {% endblock %}
-              {% endif %}
-              <li class="nav-header">Build</li>
-              {% block nav-configuration %}
-                  <li><a href="{% url 'configuration' build.pk %}">Configuration</a></li>
-              {% endblock %}
-              {% block nav-tasks %}
-                  <li><a href="{% url 'tasks' build.pk %}">Tasks</a></li>
-              {% endblock %}
-              {% block nav-recipes %}
-                  <li><a href="{% url 'recipes' build.pk %}">Recipes</a></li>
-              {% endblock %}
-              {% block nav-packages %}
-                  <li><a href="{% url 'packages' build.pk %}">Packages</a></li>
-              {% endblock %}
-                  <li class="nav-header">Performance</li>
-              {% block nav-buildtime %}
-                  <li><a href="{% url 'buildtime' build.pk %}">Time</a></li>
-              {% endblock %}
-              {% block nav-cputime %}
-                  <li><a href="{% url 'cputime' build.pk %}">CPU time</a></li>
-              {% endblock %}
-              {% block nav-diskio %}
-                  <li><a href="{% url 'diskio' build.pk %}">Disk I/O</a></li>
-              {% endblock %}
-            </ul>
-        </div>
-        <!-- end left sidebar container -->
-
-        <!-- Begin right container -->
-        {% block buildinfomain %}{% endblock %}
-        <!-- End right container -->
-
+      </div>
+      <!-- end left sidebar container -->
+    {% endif %}
 
+    <!-- Begin right container; we need span10 if we are showing the left side-bar -->
+    <div class="{% if build.started %}span10{% else %}row-fluid{% endif %}">
+      {% block buildinfomain %}{% endblock %}
     </div>
+    <!-- End right container -->
   </div>
-
-
 {% endblock %}
-
diff --git a/bitbake/lib/toaster/toastergui/templates/builddashboard.html b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
index a0da71e..b0c3d99 100644
--- a/bitbake/lib/toaster/toastergui/templates/builddashboard.html
+++ b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
@@ -13,14 +13,14 @@
 
 {% block buildinfomain %}
 <!-- page title -->
-<div class="row-fluid span10">
+<div class="row-fluid">
  <div class="page-header">
      <h1>{{build.target_set.all|dictsort:"target"|join:", "}} {{build.machine}}</h1>
  </div>
 </div>
 
 <!-- build result bar -->
-<div class="row-fluid span10 pull-right">
+<div class="row-fluid pull-right">
   <div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%}">
     <div class="row-fluid lead">
             <span class="pull-left"><strong>
@@ -53,7 +53,7 @@
 </div>
 
 {% if build.errors.count %}
-<div class="accordion span10 pull-right" id="errors">
+<div class="accordion pull-right row-fluid" id="errors">
   <div class="accordion-group">
     <div class="accordion-heading">
             <a class="accordion-toggle error toggle-errors">
@@ -65,13 +65,11 @@
     </div>
     <div class="accordion-body collapse in" id="collapse-errors">
       <div class="accordion-inner">
-        <div class="span10">
-          {% for error in build.errors %}
-            <div class="alert alert-error" data-error="{{ error.id }}">
-              <pre>{{error.message}}</pre>
-            </div>
-          {% endfor %}
-        </div>
+        {% for error in build.errors %}
+          <div class="alert alert-error" data-error="{{ error.id }}">
+            <pre>{{error.message}}</pre>
+          </div>
+        {% endfor %}
       </div>
     </div>
   </div>
@@ -81,7 +79,7 @@
 {%if build.outcome == build.SUCCEEDED%}
 <!-- built images -->
 {% if hasImages %}
-<div class="row-fluid span10 pull-right">
+<div class="row-fluid pull-right">
     <h2>Images</h2>
     {% for target in targets %}
         {% if target.target.is_image %}
@@ -149,7 +147,7 @@
 
 <!-- other artifacts -->
 {% if build.buildartifact_set.all.count > 0 %}
-<div class="row-fluid span10 pull-right">
+<div class="row-fluid pull-right">
 <h2>Other artifacts</h2>
 
     <div class="well dashboard-section">
@@ -172,107 +170,117 @@
 
 </div>
 {% endif %}
-<!-- build summary -->
-<div class="row-fluid span10 pull-right">
-<h2>Build summary</h2>
+
+{% if build.outcome == Build.SUCCEEDED %}
+  <!-- build summary -->
+  <div class="row-fluid pull-right">
+    <h2>Build summary</h2>
     <div class="well span4 dashboard-section" style="margin-left:0px;">
-        <h4><a href="{%url 'configuration' build.pk%}">Configuration</a></h4>
-            <dl>
+      <h4><a href="{%url 'configuration' build.pk%}">Configuration</a></h4>
+      <dl>
         <dt>Machine</dt><dd>{{build.machine}}</dd>
         <dt>Distro</dt><dd>{{build.distro}}</dd>
-        <dt>Layers</dt>{% for i in build.layer_version_build.all|dictsort:"layer.name" %}<dd>{{i.layer.name}}</dd>{%endfor%}
-            </dl>
+        <dt>Layers</dt>
+        {% for i in build.layer_version_build.all|dictsort:"layer.name" %}
+          <dd>{{i.layer.name}}</dd>
+        {% endfor %}
+      </dl>
     </div>
     <div class="well span4 dashboard-section">
-        <h4><a href="{%url 'tasks' build.pk%}">Tasks</a></h4>
-            <dl>
-            {% query build.task_build outcome=4 order__gt=0 as exectask%}
-            {% if exectask.count > 0 %}
-                <dt>Failed tasks</dt>
-                <dd>
-                {% if exectask.count == 1 %}
-                    <a class="error" href="{% url "task" build.id exectask.0.id %}">
-                        {{exectask.0.recipe.name}}
-                        <span class="task-name">{{exectask.0.task_name}}</span>
-                    </a>
+      <h4><a href="{%url 'tasks' build.pk%}">Tasks</a></h4>
+      <dl>
+        {% query build.task_build outcome=4 order__gt=0 as exectask %}
+        {% if exectask.count > 0 %}
+          <dt>Failed tasks</dt>
+          <dd>
+            {% if exectask.count == 1 %}
+              <a class="error" href="{% url "task" build.id exectask.0.id %}">
+                {{exectask.0.recipe.name}}
+                <span class="task-name">{{exectask.0.task_name}}</span>
+              </a>
 
-                        <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}">
-                            <i class="icon-download-alt" title="" data-original-title="Download task log file"></i>
-                        </a>
+              <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}">
+                <i class="icon-download-alt" title="" data-original-title="Download task log file"></i>
+              </a>
 
-                {% elif exectask.count > 1%}
-                    <a class="error" href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}}</a>
-                {% endif %}
-                </dd>
+            {% elif exectask.count > 1%}
+              <a class="error" href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}}</a>
             {% endif %}
-        <dt>Total number of tasks</dt><dd><a href="{% url 'tasks' build.pk %}">{% query build.task_build order__gt=0 as alltasks %}{{alltasks.count}}</a></dd>
+          </dd>
+        {% endif %}
+        <dt>Total number of tasks</dt>
+        <dd><a href="{% url 'tasks' build.pk %}">{% query build.task_build order__gt=0 as alltasks %}{{alltasks.count}}</a></dd>
         <dt>
-            Tasks executed
-            <i class="icon-question-sign get-help" title="'Executed' tasks are those that need to be run in order to generate the task output"></i>
+          Tasks executed
+          <i class="icon-question-sign get-help" title="'Executed' tasks are those that need to be run in order to generate the task output"></i>
         </dt>
         <dd><a href="{% url 'tasks' build.pk %}?filter=task_executed%3A1&count=25&search=&page=1&orderby=order%3A%2B">{% query build.task_build task_executed=1 order__gt=0 as exectask%}{{exectask.count}}</a></dd>
         <dt>
-            Tasks not executed
-            <i class="icon-question-sign get-help" title="'Not executed' tasks don't need to run because their outcome is provided by another task"></i>
+          Tasks not executed
+          <i class="icon-question-sign get-help" title="'Not executed' tasks don't need to run because their outcome is provided by another task"></i>
         </dt>
         <dd><a href="{% url 'tasks' build.pk %}?filter=task_executed%3A0&count=25&search=&page=1&orderby=order%3A%2B">{% query build.task_build task_executed=0 order__gt=0 as noexectask%}{{noexectask.count}}</a></dd>
         <dt>
-            Reuse
-            <i class="icon-question-sign get-help" title="The percentage of 'not executed' tasks over the total number of tasks, which is a measure of the efficiency of your build"></i>
+          Reuse
+          <i class="icon-question-sign get-help" title="The percentage of 'not executed' tasks over the total number of tasks, which is a measure of the efficiency of your build"></i>
         </dt>
         <dd>
-{% query build.task_build order__gt=0 as texec %}
-{% if noexectask.count|multiply:100|divide:texec.count < 0 %}
-0
-{% else %}
-{{noexectask.count|multiply:100|divide:texec.count}}
-{% endif %}
-%
+          {% query build.task_build order__gt=0 as texec %}
+          {% if noexectask.count|multiply:100|divide:texec.count < 0 %}
+            0
+          {% else %}
+            {{noexectask.count|multiply:100|divide:texec.count}}
+          {% endif %}
+          %
         </dd>
-            </dl>
+      </dl>
     </div>
     <div class="well span4 dashboard-section">
-        <h4><a href="{% url 'recipes' build.pk %}">Recipes</a> & <a href="{% url 'packages' build.pk %}">Packages</a></h4>
-            <dl>
-        <dt>Recipes built</dt><dd><a href="{% url 'recipes' build.pk %}">{{recipecount}}</a></dd>
-        <dt>Packages built</dt><dd><a href="{% url 'packages' build.pk %}">{{packagecount}}</a></dd>
-            </dl>
+      <h4><a href="{% url 'recipes' build.pk %}">Recipes</a> & <a href="{% url 'packages' build.pk %}">Packages</a></h4>
+      <dl>
+        <dt>Recipes built</dt>
+        <dd><a href="{% url 'recipes' build.pk %}">{{recipecount}}</a></dd>
+        <dt>Packages built</dt>
+        <dd><a href="{% url 'packages' build.pk %}">{{packagecount}}</a></dd>
+      </dl>
     </div>
-</div>
+  </div>
+  <!-- end build summary -->
+{% endif %}
 
 {% if build.warnings.count %}
-<div class="accordion span10 pull-right" id="warnings">
-  <div class="accordion-group">
-    <div class="accordion-heading">
-      <a class="accordion-toggle warning toggle-warnings">
-        <h2 id="warning-toggle">
-          <i class="icon-warning-sign"></i>
-          {{build.warnings.count}} warning{{build.warnings.count|pluralize}}
-        </h2>
-      </a>
-    </div>
-    <div class="accordion-body collapse" id="collapse-warnings">
-      <div class="accordion-inner">
-        <div class="span10">
-          {% for warning in logmessages %}{% if warning.level == 1 %}
-            <div class="alert alert-warning">
-              <pre>{{warning.message}}</pre>
-            </div>
-          {% endif %}{% endfor %}
+  <div class="accordion pull-right" id="warnings">
+    <div class="accordion-group">
+      <div class="accordion-heading">
+        <a class="accordion-toggle warning toggle-warnings">
+          <h2 id="warning-toggle">
+            <i class="icon-warning-sign"></i>
+            {{build.warnings.count}} warning{{build.warnings.count|pluralize}}
+          </h2>
+        </a>
+      </div>
+      <div class="accordion-body collapse" id="collapse-warnings">
+        <div class="accordion-inner">
+          <div class="span10">
+            {% for warning in logmessages %}{% if warning.level == 1 %}
+              <div class="alert alert-warning">
+                <pre>{{warning.message}}</pre>
+              </div>
+            {% endif %}{% endfor %}
+          </div>
         </div>
       </div>
     </div>
   </div>
-</div>
 {% endif %}
 
 <script type="text/javascript">
-    $(document).ready(function() {
-        //show warnings section when requested from the previous page
-        if (location.href.search('#warnings') > -1) {
-            $('#collapse-warnings').addClass('in');
-        }
-    });
+  $(document).ready(function() {
+    //show warnings section when requested from the previous page
+    if (location.href.search('#warnings') > -1) {
+      $('#collapse-warnings').addClass('in');
+    }
+  });
 </script>
 
 {% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 85ca9be..f94fb1c 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -506,6 +506,7 @@ def builddashboard( request, build_id ):
 
     context = {
             'build'           : build,
+            'Build'           : Build,
             'hasImages'       : hasImages,
             'ntargets'        : ntargets,
             'targets'         : targets,
-- 
Elliot Smith
Software Engineer
Intel OTC

---------------------------------------------------------------------
Intel Corporation (UK) Limited
Registered No. 1134945 (England)
Registered Office: Pipers Way, Swindon SN3 1RJ
VAT No: 860 2173 47

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.



More information about the toaster mailing list