1{% extends "basebuildpage.html" %} 2{% load humanize %} 3{% load projecttags %} 4{% load field_values_filter %} 5 6{% block title %} {{build.get_sorted_target_list|field_values:"target"|join:", "}} {{build.machine}} - {{build.project.name}} - Toaster {% endblock %} 7{% block parentbreadcrumb %} 8{% if build.get_sorted_target_list.count > 0 %} 9 {{build.get_sorted_target_list.0.target}} 10{% endif %} 11 12{%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"}}) 13{% endblock %} 14 15{% block buildinfomain %} 16<!-- page title --> 17<div class="{% if build.started %}col-md-10{% else %}col-md-12{% endif %}"> 18 <div class="page-header build-data"> 19 <h1>{{build.get_sorted_target_list|field_values:"target"|join:", "}} {{build.machine}}</h1> 20 </div> 21 22<!-- build result bar --> 23 <div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-danger{%else%}alert-info{%endif%}"> 24 <span><strong>{%if build.outcome == build.SUCCEEDED%}Completed{%elif build.outcome == build.FAILED%}Failed{%else%}{%endif%}</strong> on {{build.completed_on|date:"d/m/y H:i"}}</span> 25 {% if build.warnings.count or build.errors.count %} 26 <span>with</span> 27 {% endif %} 28 {%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %} 29 {% if build.errors.count %} 30 <a href="#errors" class="alert-link show-errors"> {{build.errors.count}} error{{build.errors.count|pluralize}}</a> 31 {% endif %} 32 {% if build.warnings.count %} 33 {% if build.errors.count %}and{% endif %} 34 <a href="#warnings" class="show-warnings"> {{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a> 35 {% endif %} 36 {% if build.cooker_log_path %} 37 <a class="pull-right log" href="{% url 'build_artifact' build.id "cookerlog" build.id %}">Download build log</a> 38 {% endif %} 39 <span class="pull-right"> 40 Build time: 41 <span data-build-field="buildtime"> 42 {% if build.outcome == build.SUCCEEDED %} 43 <a href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }}</a> 44 {% else %} 45 {{ build.timespent_seconds|sectohms }} 46 {% endif %} 47 </span> 48 </span> 49 50 {%endif%} 51</div> 52 53{% if build.errors.count %} 54 <div class="panel panel-default" id="errors"> 55 <div class="panel-heading"> 56 <h2 class="panel-title"> 57 <span class="glyphicon glyphicon-minus-sign"></span> 58 <a data-toggle="collapse" href="#error-info" id="error-toggle"> 59 {{build.errors.count}} error{{build.errors.count|pluralize}} 60 </a> 61 </h2> 62 </div> 63 <div class="panel-collapse collapse in" id="error-info"> 64 <div class="panel-body"> 65 <div class="{% if build.started %}col-md-10{% else %}col-md-12{% endif %}"> 66 {% for error in build.errors %} 67 <div class="alert alert-danger" data-log-message-id="{{error.pk}}"> 68 <pre>{{error.message}}</pre> 69 </div> 70 {% endfor %} 71 </div> 72 </div> 73 </div> 74 </div> 75{% endif %} 76 77{%if build.outcome == build.SUCCEEDED%} 78<!-- built images --> 79 {% if hasArtifacts %} 80 <h2 data-heading="build-artifacts">Build artifacts</h2> 81 {% for target in targets %} 82 {% if target.target.is_image %} 83 <div class="well well-transparent dashboard-section" data-artifacts-for-target="{{target.target.pk}}"> 84 {% if target.npkg > 0 %} 85 <h3> 86 <a href="{% url 'target' build.pk target.target.pk %}" data-link="target-packages"> 87 {{target.target.target}} 88 </a> 89 </h3> 90 <dl class="dl-horizontal"> 91 <dt>Packages included</dt> 92 <dd> 93 <a href="{% url 'target' build.pk target.target.pk %}"> 94 <span data-value="target-package-count">{{target.npkg}}</span> 95 </a> 96 </dd> 97 <dt>Total package size</dt> 98 <dd> 99 <span data-value="target-package-size">{{target.pkgsz|filtered_filesizeformat}}</span> 100 </dd> 101 </dl> 102 {% else %} 103 <h3>{{target.target.target}}</h3> 104 {% endif %} 105 106 {% if target.targetHasImages %} 107 <dl class="dl-horizontal"> 108 <dt> 109 Manifests 110 </dt> 111 112 <dd> 113 <a data-link="license-manifest" href="{% url 'build_artifact' build.pk 'licensemanifest' target.target.pk %}">License manifest</a> 114 </dd> 115 116 {% if target.target.package_manifest_path %} 117 <dd> 118 <a data-link="package-manifest" href="{% url 'build_artifact' build.pk 'packagemanifest' target.target.pk %}">Package manifest</a> 119 </dd> 120 {% endif %} 121 </dl> 122 123 <dl class="dl-horizontal"> 124 <dt> 125 <span class="glyphicon glyphicon-question-sign get-help" title="Image files are stored in <code>build/tmp/deploy/images/</code>"></span> 126 Image files 127 </dt> 128 <dd> 129 <ul class="list-unstyled" data-links="image-artifacts"> 130 {% for i in target.imageFiles|dictsort:"suffix" %} 131 <li> 132 <a href="{% url 'build_artifact' build.pk 'imagefile' i.id %}"> 133 {{i.suffix}} 134 </a> 135 ({{i.size|filtered_filesizeformat}}) 136 </li> 137 {% endfor %} 138 </ul> 139 </dd> 140 <dt> 141 Kernel artifacts 142 </dt> 143 <dd> 144 <ul class="list-unstyled" data-links="kernel-artifacts"> 145 {% for artifact in target.target_kernel_artifacts|dictsort:"basename" %} 146 <li> 147 <a href="{% url 'build_artifact' build.id 'targetkernelartifact' artifact.id %}">{{artifact.basename}}</a> 148 ({{artifact.file_size|filtered_filesizeformat}}) 149 </li> 150 {% endfor %} 151 </ul> 152 </dd> 153 </dl> 154 {% endif %} 155 {% if target.target_sdk_artifacts_count > 0 %} 156 <dl class="dl-horizontal"> 157 <dt> 158 SDK artifacts 159 </dt> 160 <dd> 161 <ul class="list-unstyled" data-links="sdk-artifacts"> 162 {% for artifact in target.target_sdk_artifacts|dictsort:"basename" %} 163 <li> 164 <a href="{% url 'build_artifact' build.id 'targetsdkartifact' artifact.id %}">{{artifact.basename}}</a> 165 ({{artifact.file_size|filtered_filesizeformat}}) 166 </li> 167 {% endfor %} 168 </ul> 169 </dd> 170 </dl> 171 {% endif %} 172 </div> 173 {% endif %} 174 {% endfor %} 175 {% endif %} 176 177{%else%} 178<!-- error dump --> 179{%endif%} 180 181<!-- other artifacts --> 182{% if build.buildartifact_set.all.count > 0 %} 183<h2>Other artifacts</h2> 184 185 <div class="well well-transparent dashboard-section"> 186 <dl class="dl-horizontal"> 187 <dt> 188 <span class="glyphicon glyphicon-question-sign get-help" title="Build artifacts discovered in <i>tmp/deploy/images</i>. Usually kernel images and kernel modules."></span> 189 Other artifacts</dt> 190 <dd><div> 191 {% for ba in build.buildartifact_set.all|dictsort:"file_name" %} 192 <a href="{%url 'build_artifact' build.id 'buildartifact' ba.id %}"> 193 {{ba.get_basename}} 194 </a> 195 196 ({{ba.file_size|filtered_filesizeformat}}) <br/> 197 {% endfor %} 198 </div> 199 </dd> 200 </dl> 201 </div> 202 203{% endif %} 204 205{% if build.started %} 206 <!-- build summary --> 207 <h2 data-role="build-summary-heading">Build summary</h2> 208 <div class="row"> 209 <div class="col-md-4 dashboard-section"> 210 <div class="well well-transparent"> 211 <h3><a href="{%url 'configuration' build.pk%}">Configuration</a></h3> 212 <dl> 213 <dt>Machine</dt><dd>{{build.machine}}</dd> 214 <dt>Distro</dt><dd>{{build.distro}}</dd> 215 <dt>Layers</dt><dd><ul class="list-unstyled">{% for i in build.layer_version_build.all|dictsort:"layer.name" %}<li>{{i.layer.name}}</li>{%endfor%}</ul></dd> 216 </dl> 217 </div> 218 </div> 219 <div class="col-md-4 dashboard-section"> 220 <div class="well well-transparent"> 221 <h3><a href="{%url 'tasks' build.pk%}">Tasks</a></h3> 222 <dl> 223 {% query build.task_build outcome=4 order__gt=0 as exectask%} 224 {% if exectask.count > 0 %} 225 <dt>Failed tasks</dt> 226 <dd> 227 {% if exectask.count == 1 %} 228 <a class="text-danger" href="{% url "task" build.id exectask.0.id %}"> 229 {{exectask.0.recipe.name}} 230 <span class="task-name">{{exectask.0.task_name}}</span> 231 </a> 232 233 <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}"> 234 <span class="glyphicon glyphicon-download-alt get-help" title="Download task log file"></i> 235 </a> 236 237 {% elif exectask.count > 1%} 238 <a class="text-danger" href="{% url "tasks" build.id %}?limit=25&page=1&orderby=order&filter=task_outcome:failed&default_orderby=order&filter_value=on&">{{exectask.count}}</a> 239 {% endif %} 240 </dd> 241 {% endif %} 242 <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> 243 <dt> 244 Tasks executed 245 <span class="glyphicon glyphicon-question-sign get-help" title="'Executed' tasks are those that need to be run in order to generate the task output"></span> 246 </dt> 247 <dd><a href="{% url 'tasks' build.pk %}?limit=25&page=1&orderby=order&filter=execution_outcome:executed&default_orderby=order&filter_value=on&">{% query build.task_build task_executed=1 order__gt=0 as exectask%}{{exectask.count}}</a></dd> 248 <dt> 249 Tasks not executed 250 <span class="glyphicon glyphicon-question-sign get-help" title="'Not executed' tasks don't need to run because their outcome is provided by another task"></span> 251 </dt> 252 <dd><a href="{% url 'tasks' build.pk %}?limit=25&page=1&orderby=order&filter=execution_outcome:not_executed&default_orderby=order&filter_value=on&">{% query build.task_build task_executed=0 order__gt=0 as noexectask%}{{noexectask.count}}</a></dd> 253 <dt> 254 Reuse 255 <span class="glyphicon glyphicon-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"></span> 256 </dt> 257 <dd> 258 {% query build.task_build order__gt=0 as texec %} 259 {% if noexectask.count|multiply:100|divide:texec.count < 0 %} 260 0 261 {% else %} 262 {{noexectask.count|multiply:100|divide:texec.count}} 263 {% endif %} 264 % 265 </dd> 266 </dl> 267 </div> 268 </div> 269 <div class="col-md-4 dashboard-section"> 270 <div class="well well-transparent"> 271 <h3><a href="{% url 'recipes' build.pk %}">Recipes</a> & <a href="{% url 'packages' build.pk %}">Packages</a></h3> 272 <dl> 273 <dt>Recipes built</dt><dd><a href="{% url 'recipes' build.pk %}">{{recipecount}}</a></dd> 274 <dt>Packages built</dt><dd><a href="{% url 'packages' build.pk %}">{{packagecount}}</a></dd> 275 </dl> 276 </div> 277 </div> 278 </div> 279{% endif %} <!-- end build summary --> 280 281{% if build.warnings.count %} 282 <div class="panel panel-default" id="warnings"> 283 <div class="panel-heading"> 284 <h2 class="panel-title"> 285 <span class="glyphicon glyphicon-warning-sign"></span> 286 <a id="warning-toggle" href="#warning-info" data-toggle="collapse">{{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a> 287 </h2> 288 </div> 289 <div class="panel-collapse collapse" id="warning-info"> 290 <div class="panel-body"> 291 <div class="{% if build.started %}col-md-10{% else %}col-md-12{% endif %}"> 292 {% for warning in logmessages %}{% if warning.level == 1 %} 293 <div class="alert alert-warning" data-log-message-id="{{warning.pk}}"> 294 <pre>{{warning.message}}</pre> 295 </div> 296 {% endif %}{% endfor %} 297 </div> 298 </div> 299 </div> 300 </div> 301{% endif %} 302 303</div> <!-- end 10 column row --> 304 305<script type="text/javascript"> 306 $(document).ready(function() { 307 //show warnings section when requested from the previous page 308 if (location.href.search('#warnings') > -1) { 309 $('#warning-info').addClass('in'); 310 } 311 312 //show warnings section when requested from the build outcome 313 $(".show-warnings").click(function() { 314 $('#warning-info').addClass('in'); 315 }); 316 }); 317</script> 318 319{% endblock %} 320