blob: bab8e388f55ad140893a94d828b0a809ee2203f1 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001{% extends "basebuildpage.html" %}
2{% load humanize %}
3{% load projecttags %}
4
5{% block parentbreadcrumb %}
6{{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"}})
7{% endblock %}
8
9{% block buildinfomain %}
10<!-- page title -->
11<div class="row-fluid span10">
12 <div class="page-header">
13 <h1>{{build.target_set.all|dictsort:"target"|join:", "}} {{build.machine}}</h1>
14 </div>
15</div>
16
17<!-- build result bar -->
18<div class="row-fluid span10 pull-right">
19 <div class="alert {%if build.outcome == build.SUCCEEDED%}alert-success{%elif build.outcome == build.FAILED%}alert-error{%else%}alert-info{%endif%}">
20 <div class="row-fluid lead">
21 <span class="pull-left"><strong>
22 {%if build.outcome == build.SUCCEEDED%}Completed{%elif build.outcome == build.FAILED%}Failed{%else%}{%endif%}
23 </strong> on
24 {{build.completed_on|date:"d/m/y H:i"}}
25</span>
26{% if build.warnings.count or build.errors.count %}
27&nbsp;with
28{% endif %}
29{%if build.outcome == build.SUCCEEDED or build.outcome == build.FAILED %}
30{% if build.errors.count %}
31 <span > <i class="icon-minus-sign red"></i><strong><a href="#errors" class="error show-errors"> {{build.errors.count}} error{{build.errors.count|pluralize}}</a></strong></span>
32{% endif %}
33{% if build.warnings.count %}
34{% if build.errors.count %}
35 and
36{% endif %}
37 <span > <i class="icon-warning-sign yellow"></i><strong><a href="#warnings" class="warning show-warnings"> {{build.warnings.count}} warning{{build.warnings.count|pluralize}}</a></strong></span>
38{% endif %}
39 <span class="pull-right">Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent_seconds|sectohms }}</a>
40 <a class="btn {%if build.outcome == build.SUCCEEDED%}btn-success{%else%}btn-danger{%endif%} pull-right log" href="{% url 'build_artifact' build.id "cookerlog" build.id %}">Download build log</a>
41 </span>
42
43{%endif%}
44 </div>
45 {% if build.toaster_exceptions.count > 0 %}
46 <div class="row">
47 <small class="pull-right">
48 <i class="icon-question-sign get-help get-help-blue" title="" data-original-title="Toaster exceptions do not affect your build: only the operation of Toaster"></i>
49 <a class="show-exceptions" href="#exceptions">Toaster threw {{build.toaster_exceptions.count}} exception{{build.toaster_exceptions.count|pluralize}}</a>
50 </small>
51 </div>
52 {% endif %}
53 </div>
54</div>
55
56{% if build.errors.count %}
57<div class="accordion span10 pull-right" id="errors">
58 <div class="accordion-group">
59 <div class="accordion-heading">
60 <a class="accordion-toggle error toggle-errors">
61 <h2 id="error-toggle">
62 <i class="icon-minus-sign"></i>
63 {{build.errors.count}} error{{build.errors.count|pluralize}}
64 </h2>
65 </a>
66 </div>
67 <div class="accordion-body collapse in" id="collapse-errors">
68 <div class="accordion-inner">
69 <div class="span10">
70 {% for error in logmessages %}{% if error.level == 2 %}
71 <div class="alert alert-error">
72 <pre>{{error.message}}</pre>
73 </div>
74 {% endif %}
75 {% endfor %}
76 </div>
77 </div>
78 </div>
79 </div>
80</div>
81{% endif %}
82
83{%if build.outcome == build.SUCCEEDED%}
84<!-- built images -->
85{% if hasImages %}
86<div class="row-fluid span10 pull-right">
87 <h2>Images</h2>
88 {% for target in targets %}
89 {% if target.target.is_image %}
90 <div class="well dashboard-section">
91 <h3><a href="{% url 'target' build.pk target.target.pk %}">{{target.target}}</a>
92 </h3>
93 <dl class="dl-horizontal">
94 <dt>Packages included</dt>
95 <dd><a href="{% url 'target' build.pk target.target.pk %}">{{target.npkg}}</a></dd>
96 <dt>Total package size</dt>
97 <dd>{{target.pkgsz|filtered_filesizeformat}}</dd>
98 {% if target.targetHasNoImages %}
99 </dl>
100 <div class="row-fluid">
101 <div class="alert alert-info span7">
102 <p>
103 <b>This build did not create any image files</b>
104 </p>
105 <p>
106 This is probably because valid image and license manifest
107 files from a previous build already exist in your
108 <code>.../poky/build/tmp/deploy</code>
109 directory. You can
110 also <a href="{% url 'targetpkg' build.pk target.target.pk %}">view the
111 license manifest information</a> in Toaster.
112 </p>
113 </div>
114 </div>
115 {% else %}
116 <dt>
117 <i class="icon-question-sign get-help" title="The location in disk of the license manifest, a document listing all packages installed in your image and their licenses"></i>
118
119 License manifest
120 </dt>
121 <dd>
122 <a href="{% url 'targetpkg' build.pk target.target.pk %}">View in Toaster</a> |
123 <a href="{% url 'build_artifact' build.pk 'licensemanifest' target.target.pk %}">Download</a></dd>
124 <dt>
125 <i class="icon-question-sign get-help" title="Image files are stored in <code>/build/tmp/deploy/images/</code>"></i>
126 Image files
127 </dt>
128 <dd>
129 <ul>
130 {% for i in target.imageFiles %}
131 {% if build.project %}
132 <li><a href="{% url 'build_artifact' build.pk 'imagefile' i.id %}">{{i.path}}</a>
133 {% else %}
134 <li>{{i.path}}
135 {% endif %}
136 ({{i.size|filtered_filesizeformat}})</li>
137 {% endfor %}
138 </ul>
139 </dd>
140 </dl>
141 {% endif %}
142 </div>
143 {% endif %}
144 {% endfor %}
145</div>
146{% endif %}
147
148{%else%}
149<!-- error dump -->
150{%endif%}
151
152<!-- other artifacts -->
153{% if build.buildartifact_set.all.count > 0 %}
154<div class="row-fluid span10 pull-right">
155<h2>Other artifacts</h2>
156
157 <div class="well dashboard-section">
158 <dl class="dl-horizontal">
159 <dt>
160 <i class="icon-question-sign get-help" title="Build artifacts discovered in <i>tmp/deploy/images</i>. Usually kernel images and kernel modules."></i>
161 Other artifacts</dt>
162 <dd><div>
163 {% for ba in build.buildartifact_set.all|dictsort:"file_name" %}
164 <a href="{%url 'build_artifact' build.id 'buildartifact' ba.id %}">
165 {{ba.get_local_file_name}}
166 </a>
167
168 ({{ba.file_size|filtered_filesizeformat}}) <br/>
169 {% endfor %}
170 </div>
171 </dd>
172 </dl>
173 </div>
174
175</div>
176{% endif %}
177<!-- build summary -->
178<div class="row-fluid span10 pull-right">
179<h2>Build summary</h2>
180 <div class="well span4 dashboard-section" style="margin-left:0px;">
181 <h4><a href="{%url 'configuration' build.pk%}">Configuration</a></h4>
182 <dl>
183 <dt>Machine</dt><dd>{{build.machine}}</dd>
184 <dt>Distro</dt><dd>{{build.distro}}</dd>
185 <dt>Layers</dt>{% for i in build.layer_version_build.all|dictsort:"layer.name" %}<dd>{{i.layer.name}}</dd>{%endfor%}
186 </dl>
187 </div>
188 <div class="well span4 dashboard-section">
189 <h4><a href="{%url 'tasks' build.pk%}">Tasks</a></h4>
190 <dl>
191 {% query build.task_build outcome=4 order__gt=0 as exectask%}
192 {% if exectask.count > 0 %}
193 <dt>Failed tasks</dt>
194 <dd>
195 {% if exectask.count == 1 %}
196 <a class="error" href="{% url "task" build.id exectask.0.id %}">
197 {{exectask.0.recipe.name}}
198 <span class="task-name">{{exectask.0.task_name}}</span>
199 </a>
200
201 <a href="{% url 'build_artifact' build.id "tasklogfile" exectask.0.id %}">
202 <i class="icon-download-alt" title="" data-original-title="Download task log file"></i>
203 </a>
204
205 {% elif exectask.count > 1%}
206 <a class="error" href="{% url "tasks" build.id %}?filter=outcome%3A4">{{exectask.count}}</a>
207 {% endif %}
208 </dd>
209 {% endif %}
210 <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>
211 <dt>
212 Tasks executed
213 <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>
214 </dt>
215 <dd><a href="{% url 'tasks' build.pk %}?filter=task_executed%3A1&amp;count=25&amp;search=&amp;page=1&amp;orderby=order%3A%2B">{% query build.task_build task_executed=1 order__gt=0 as exectask%}{{exectask.count}}</a></dd>
216 <dt>
217 Tasks not executed
218 <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>
219 </dt>
220 <dd><a href="{% url 'tasks' build.pk %}?filter=task_executed%3A0&amp;count=25&amp;search=&amp;page=1&amp;orderby=order%3A%2B">{% query build.task_build task_executed=0 order__gt=0 as noexectask%}{{noexectask.count}}</a></dd>
221 <dt>
222 Reuse
223 <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>
224 </dt>
225 <dd>
226{% query build.task_build order__gt=0 as texec %}
227{% if noexectask.count|multiply:100|divide:texec.count < 0 %}
2280
229{% else %}
230{{noexectask.count|multiply:100|divide:texec.count}}
231{% endif %}
232%
233 </dd>
234 </dl>
235 </div>
236 <div class="well span4 dashboard-section">
237 <h4><a href="{% url 'recipes' build.pk %}">Recipes</a> & <a href="{% url 'packages' build.pk %}">Packages</a></h4>
238 <dl>
239 <dt>Recipes built</dt><dd><a href="{% url 'recipes' build.pk %}">{{recipecount}}</a></dd>
240 <dt>Packages built</dt><dd><a href="{% url 'packages' build.pk %}">{{packagecount}}</a></dd>
241 </dl>
242 </div>
243</div>
244
245{% if build.warnings.count %}
246<div class="accordion span10 pull-right" id="warnings">
247 <div class="accordion-group">
248 <div class="accordion-heading">
249 <a class="accordion-toggle warning toggle-warnings">
250 <h2 id="warning-toggle">
251 <i class="icon-warning-sign"></i>
252 {{build.warnings.count}} warning{{build.warnings.count|pluralize}}
253 </h2>
254 </a>
255 </div>
256 <div class="accordion-body collapse" id="collapse-warnings">
257 <div class="accordion-inner">
258 <div class="span10">
259 {% for warning in logmessages %}{% if warning.level == 1 %}
260 <div class="alert alert-warning">
261 <pre>{{warning.message}}</pre>
262 </div>
263 {% endif %}{% endfor %}
264 </div>
265 </div>
266 </div>
267 </div>
268</div>
269{% endif %}
270
271
272{% if build.toaster_exceptions.count > 0 %}
273<div class="accordion span10 pull-right" id="exceptions">
274 <div class="accordion-group">
275 <div class="accordion-heading">
276 <a class="accordion-toggle exception toggle-exceptions">
277 <h2 id="exception-toggle">
278 <i class="icon-warning-sign"></i>
279 {{build.toaster_exceptions.count}} Toaster exception{{build.toaster_exceptions.count|pluralize}}
280 </h2>
281 </a>
282 </div>
283 <div class="accordion-body collapse" id="collapse-exceptions">
284 <div class="accordion-inner">
285 <div class="span10">
286 {% for exception in build.toaster_exceptions %}
287 <div class="alert alert-exception">
288 <pre>{{exception.message}}</pre>
289 </div>
290 {% endfor %}
291 </div>
292 </div>
293 </div>
294 </div>
295</div>
296{% endif %}
297
298<script type="text/javascript">
299 $(document).ready(function() {
300 //show warnings section when requested from the previous page
301 if (location.href.search('#warnings') > -1) {
302 $('#collapse-warnings').addClass('in');
303 }
304 });
305</script>
306
307{% endblock %}