summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorRavi Chintakunta <ravi.chintakunta@timesys.com>2014-01-10 16:43:24 -0500
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-01-27 21:01:06 +0000
commit47d19237ef6c492f7c2226952f8094d853893754 (patch)
tree5cbb90139b6bbd56638bfa8c3978c2a048868e4d /bitbake
parent84b239086dbd53c59d51f4e0779767a72af02d2b (diff)
downloadpoky-47d19237ef6c492f7c2226952f8094d853893754.tar.gz
bitbake: toaster: All Tasks Feature with sorting and filtering
- Fixed the all tasks view and template to match the UI design and use the new basetable code. - Added a method to views to add sort order icon to the view context. - Default sort order when the page is loaded is displayed with the sort icon - Filtering of columns (Bitbake rev: b2f8de082c3ae41eb44e6ccdc283849b64d0b0f2) Signed-off-by: Ravi Chintakunta <ravi.chintakunta@timesys.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/toaster/toastergui/templates/task.html74
-rw-r--r--bitbake/lib/toaster/toastergui/templates/tasks.html67
-rw-r--r--bitbake/lib/toaster/toastergui/views.py124
3 files changed, 185 insertions, 80 deletions
diff --git a/bitbake/lib/toaster/toastergui/templates/task.html b/bitbake/lib/toaster/toastergui/templates/task.html
deleted file mode 100644
index 6af2c51277..0000000000
--- a/bitbake/lib/toaster/toastergui/templates/task.html
+++ /dev/null
@@ -1,74 +0,0 @@
1{% extends "basebuildpage.html" %}
2
3{% block localbreadcrumb %}
4<li>Tasks</li>
5{% endblock %}
6
7{% block buildinfomain %}
8{% include "basetable_top.html" %}
9
10
11 {% if not objects %}
12 <p>No tasks were executed in this build!</p>
13 {% else %}
14
15 <tr>
16 <th>Order</th>
17 <th>Task</th>
18 <th>Recipe Version</th>
19 <th>Task Type</th>
20 <th>Checksum</th>
21 <th>Outcome</th>
22 <th>Message</th>
23 <th>Time</th>
24 <th>CPU usage</th>
25 <th>Disk I/O</th>
26 <th>Script type</th>
27 <th>Filesystem</th>
28 <th>Depends</th>
29 </tr>
30
31 {% for task in objects %}
32
33 <tr class="data">
34 <td>{{task.order}}</td>
35 <td><a name="{{task.recipe.name}}.{{task.task_name}}">
36 <a href="{% url "layer_versions_recipes" task.recipe.layer_version_id %}#{{task.recipe.name}}">{{task.recipe.name}}</a>.{{task.task_name}}</a></td>
37 <td>{{task.recipe.version}}</td>
38
39 {% if task.task_executed %}
40 <td>Executed</td>
41 {% else %}
42 <td>Prebuilt</td>
43 {% endif %}
44
45 <td>{{task.sstate_checksum}}</td>
46 <td>{{task.get_outcome_display}}{% if task.provider %}</br>(by <a href="#{{task.provider.recipe.name}}.{{task.provider.task_name}}">{{task.provider.recipe.name}}.{{task.provider.task_name}}</a>){% endif %}</td>
47 <td><p>{{task.message}}</td>
48 <td>{{task.elapsed_time}}</td>
49 <td>{{task.cpu_usage}}</td>
50 <td>{{task.disk_io}}</td>
51 <td>{{task.get_script_type_display}}</td>
52 <td> <table>
53<tr><td> Recipe</td><td><a target="_fileview" href="file:///{{task.recipe.file_path}}">{{task.recipe.file_path}}</a></td></tr>
54<tr><td> Source</td><td><a target="_fileview" href="file:///{{task.file_name}}">{{task.file_name}}:{{task.line_number}}</a></td></tr>
55<tr><td> Workdir</td><td><a target="_fileview" href="file:///{{task.work_directory}}">{{task.work_directory}}</a></td></tr>
56<tr><td> Log</td><td><a target="_fileview" href="file:///{{task.logfile}}">{{task.logfile}}</a><br/></td></tr>
57</table>
58 </td>
59 <td>
60 <div style="height: 3em; overflow:auto">
61 {% for tt in task.task_dependencies_task.all %}
62 <a href="#{{tt.depends_on.recipe.name}}.{{tt.depends_on.task_name}}">
63 {{tt.depends_on.recipe.name}}.{{tt.depends_on.task_name}}</a><br/>
64 {% endfor %}
65 </div>
66 </td>
67 </tr>
68
69 {% endfor %}
70
71 {% endif %}
72
73{% include "basetable_bottom.html" %}
74{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/templates/tasks.html b/bitbake/lib/toaster/toastergui/templates/tasks.html
new file mode 100644
index 0000000000..6831f106c0
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/templates/tasks.html
@@ -0,0 +1,67 @@
1{% extends "basebuildpage.html" %}
2{% load projecttags %}
3{% block localbreadcrumb %}
4<li>All tasks</li>
5{% endblock %}
6
7{% block buildinfomain %}
8<div class="span10">
9<div class="page-header">
10<h1> Tasks </h1>
11</div>
12{% include "basetable_top.html" %}
13
14
15 {% if not objects %}
16 <p>No tasks were executed in this build!</p>
17 {% else %}
18 {% for task in objects %}
19 <tr {{ task|task_color }} >
20 <td class="order">
21 <a href="{%url "task" build.pk task.pk%} ">{{task.order}}</a>
22 </td>
23 <td class="recipe_name" >
24 <a href="{% url "recipe" build.pk task.recipe.pk %}">{{task.recipe.name}}</a>
25 </td>
26 <td class="recipe_version">
27 <a href="{% url "recipe" build.pk task.recipe.pk %}">{{task.recipe.version}}</a>
28 </td>
29 <td class="task_name">
30 <a href="{%url "task" build.pk task.pk%} ">{{task.task_name}}</a>
31 </td>
32 <td class="executed">
33 <a href="{%url "task" build.pk task.pk%} ">
34 {% if task.task_executed %}
35 Executed
36 {% else %}
37 Not executed
38 {% endif %}
39 </a>
40 </td>
41 <td class="outcome">
42 <a href="{%url "task" build.pk task.pk%} ">{{task.get_outcome_display}}</a>
43 </td>
44 <td class="cache_attempt">
45 <a href="{%url "task" build.pk task.pk%} ">{{task.get_sstate_result_display|format_none_and_zero}}</a>
46 </td>
47 <td class="time_taken">
48 {{task.elapsed_time|format_none_and_zero}}
49 </td>
50 <td class="cpu_used">
51 {{task.cpu_usage|format_none_and_zero}}
52 </td>
53 <td class="disk_io">
54 {{task.disk_io|format_none_and_zero}}
55 </td>
56 <td class="task_log">
57 {{task.logfile}}
58 </td>
59 </tr>
60
61 {% endfor %}
62
63 {% endif %}
64
65{% include "basetable_bottom.html" %}
66</div>
67{% endblock %}
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 1604bb6bc4..ab8b938cdd 100644
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -109,6 +109,14 @@ def _get_toggle_order(request, orderkey, reverse = False):
109 else: 109 else:
110 return "%s:-" % orderkey if request.GET.get('orderby', "") == "%s:+" % orderkey else "%s:+" % orderkey 110 return "%s:-" % orderkey if request.GET.get('orderby', "") == "%s:+" % orderkey else "%s:+" % orderkey
111 111
112def _get_toggle_order_icon(request, orderkey):
113 if request.GET.get('orderby', "") == "%s:+"%orderkey:
114 return "down"
115 elif request.GET.get('orderby', "") == "%s:-"%orderkey:
116 return "up"
117 else:
118 return None
119
112# we check that the input comes in a valid form that we can recognize 120# we check that the input comes in a valid form that we can recognize
113def _validate_input(input, model): 121def _validate_input(input, model):
114 122
@@ -390,8 +398,8 @@ def _find_task_provider(task):
390 return None 398 return None
391 399
392def tasks(request, build_id): 400def tasks(request, build_id):
393 template = 'task.html' 401 template = 'tasks.html'
394 mandatory_parameters = { 'count': 100, 'page' : 1}; 402 mandatory_parameters = { 'count': 25, 'page' : 1, 'orderby':'order:+'};
395 retval = _verify_parameters( request.GET, mandatory_parameters ) 403 retval = _verify_parameters( request.GET, mandatory_parameters )
396 if retval: 404 if retval:
397 return _redirect_parameters( 'tasks', request.GET, mandatory_parameters, build_id = build_id) 405 return _redirect_parameters( 'tasks', request.GET, mandatory_parameters, build_id = build_id)
@@ -401,11 +409,115 @@ def tasks(request, build_id):
401 409
402 tasks = _build_page_range(Paginator(queryset, request.GET.get('count', 100)),request.GET.get('page', 1)) 410 tasks = _build_page_range(Paginator(queryset, request.GET.get('count', 100)),request.GET.get('page', 1))
403 411
404 for t in tasks: 412# Per Belen - do not show the covering task
405 if t.outcome == Task.OUTCOME_COVERED: 413# for t in tasks:
406 t.provider = _find_task_provider(t) 414# if t.outcome == Task.OUTCOME_COVERED:
415# t.provider = _find_task_provider(t)
416
417 context = { 'objectname': 'tasks',
418 'build': Build.objects.filter(pk=build_id)[0],
419 'objects': tasks,
420 'tablecols':[
421 {
422 'name':'Order',
423 'qhelp':'The running sequence of each task in the build',
424 'orderfield': _get_toggle_order(request, "order"),
425 'ordericon':_get_toggle_order_icon(request, "order"),
426 },
427 {
428 'name':'Recipe',
429 'qhelp':'The name of the recipe to which each task applies',
430# 'orderfield': _get_toggle_order(request, "recipe"),
431 'ordericon':_get_toggle_order_icon(request, "recipe"),
432 },
433 {
434 'name':'Recipe version',
435 'qhelp':'The version of the recipe to which each task applies',
436 'clclass': 'recipe_version',
437 'hidden' : 1,
438 },
439 {
440 'name':'Task',
441 'qhelp':'The name of the task',
442 'orderfield': _get_toggle_order(request, "task_name"),
443 'ordericon':_get_toggle_order_icon(request, "task_name"),
444 },
445 {
446 'name':'Executed',
447 'qhelp':"This value tells you if a task had to run in order to generate the task output (executed), or if the output was provided by another task and therefore the task didn't need to run (not executed)",
448 'orderfield': _get_toggle_order(request, "task_executed"),
449 'ordericon':_get_toggle_order_icon(request, "task_executed"),
450 'filter' : {
451 'class' : 'executed',
452 'label': 'Show:',
453 'options' : [
454 ('Executed Tasks', 'task_executed:1'),
455 ('Not Executed Tasks', 'task_executed:0'),
456 ]
457 }
458
459 },
460 {
461 'name':'Outcome',
462 'qhelp':'This column tells you if executed tasks succeeded, failed or restored output from the <code>sstate-cache</code> directory or mirrors. It also tells you why not executed tasks did not need to run',
463 'orderfield': _get_toggle_order(request, "outcome"),
464 'ordericon':_get_toggle_order_icon(request, "outcome"),
465 'filter' : {
466 'class' : 'outcome',
467 'label': 'Show:',
468 'options' : [
469 ('Succeeded Tasks', 'outcome:%d'%Task.OUTCOME_SUCCESS),
470 ('Failed Tasks', 'outcome:%d'%Task.OUTCOME_FAILED),
471 ('Cached Tasks', 'outcome:%d'%Task.OUTCOME_CACHED),
472 ('Prebuilt Tasks', 'outcome:%d'%Task.OUTCOME_PREBUILT),
473 ('Covered Tasks', 'outcome:%d'%Task.OUTCOME_COVERED),
474 ('Empty Tasks', 'outcome:%d'%Task.OUTCOME_NA),
475 ]
476 }
407 477
408 context = {'build': Build.objects.filter(pk=build_id)[0], 'objects': tasks} 478 },
479 {
480 'name':'Cache attempt',
481 'qhelp':'This column tells you if a task tried to restore output from the <code>sstate-cache</code> directory or mirrors, and what was the result: Succeeded, Failed or File not in cache',
482 'orderfield': _get_toggle_order(request, "sstate_result"),
483 'ordericon':_get_toggle_order_icon(request, "sstate_result"),
484 'filter' : {
485 'class' : 'cache_attempt',
486 'label': 'Show:',
487 'options' : [
488 ('Tasks with cache attempts', 'sstate_result:%d'%Task.SSTATE_NA),
489 ("Tasks with 'File not in cache' attempts", 'sstate_result:%d'%Task.SSTATE_MISS),
490 ("Tasks with 'Failed' cache attempts", 'sstate_result:%d'%Task.SSTATE_FAILED),
491 ("Tasks with 'Succeeded' cache attempts", 'sstate_result:%d'%Task.SSTATE_RESTORED),
492 ]
493 }
494
495 },
496 {
497 'name':'Time (secs)',
498 'qhelp':'How long it took the task to finish, expressed in seconds',
499 'clclass': 'time_taken',
500 'hidden' : 1,
501 },
502 {
503 'name':'CPU usage',
504 'qhelp':'Task CPU utilisation, expressed as a percentage',
505 'clclass': 'cpu_used',
506 'hidden' : 1,
507 },
508 {
509 'name':'Disk I/O (ms)',
510 'qhelp':'Number of miliseconds the task spent doing disk input and output',
511 'clclass': 'disk_io',
512 'hidden' : 1,
513 },
514 {
515 'name':'Log',
516 'qhelp':'The location in disk of the task log file',
517 'clclass': 'task_log',
518 'hidden' : 1,
519 },
520 ]}
409 521
410 return render(request, template, context) 522 return render(request, template, context)
411 523