summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster')
-rw-r--r--bitbake/lib/toaster/orm/migrations/0013_recipe_parse_progress_fields.py24
-rw-r--r--bitbake/lib/toaster/orm/migrations/0014_allow_empty_buildname.py19
-rw-r--r--bitbake/lib/toaster/orm/models.py17
-rw-r--r--bitbake/lib/toaster/toastergui/api.py10
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/mrbsection.js50
-rw-r--r--bitbake/lib/toaster/toastergui/templates/mrb_section.html112
6 files changed, 163 insertions, 69 deletions
diff --git a/bitbake/lib/toaster/orm/migrations/0013_recipe_parse_progress_fields.py b/bitbake/lib/toaster/orm/migrations/0013_recipe_parse_progress_fields.py
new file mode 100644
index 0000000000..cc5c96d2dd
--- /dev/null
+++ b/bitbake/lib/toaster/orm/migrations/0013_recipe_parse_progress_fields.py
@@ -0,0 +1,24 @@
1# -*- coding: utf-8 -*-
2from __future__ import unicode_literals
3
4from django.db import migrations, models
5
6
7class Migration(migrations.Migration):
8
9 dependencies = [
10 ('orm', '0012_use_release_instead_of_up_branch'),
11 ]
12
13 operations = [
14 migrations.AddField(
15 model_name='build',
16 name='recipes_parsed',
17 field=models.IntegerField(default=0),
18 ),
19 migrations.AddField(
20 model_name='build',
21 name='recipes_to_parse',
22 field=models.IntegerField(default=1),
23 ),
24 ]
diff --git a/bitbake/lib/toaster/orm/migrations/0014_allow_empty_buildname.py b/bitbake/lib/toaster/orm/migrations/0014_allow_empty_buildname.py
new file mode 100644
index 0000000000..4749a14b26
--- /dev/null
+++ b/bitbake/lib/toaster/orm/migrations/0014_allow_empty_buildname.py
@@ -0,0 +1,19 @@
1# -*- coding: utf-8 -*-
2from __future__ import unicode_literals
3
4from django.db import migrations, models
5
6
7class Migration(migrations.Migration):
8
9 dependencies = [
10 ('orm', '0013_recipe_parse_progress_fields'),
11 ]
12
13 operations = [
14 migrations.AlterField(
15 model_name='build',
16 name='build_name',
17 field=models.CharField(default='', max_length=100),
18 ),
19 ]
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index 2df6d4910a..4641736add 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -397,9 +397,15 @@ class Build(models.Model):
397 completed_on = models.DateTimeField() 397 completed_on = models.DateTimeField()
398 outcome = models.IntegerField(choices=BUILD_OUTCOME, default=IN_PROGRESS) 398 outcome = models.IntegerField(choices=BUILD_OUTCOME, default=IN_PROGRESS)
399 cooker_log_path = models.CharField(max_length=500) 399 cooker_log_path = models.CharField(max_length=500)
400 build_name = models.CharField(max_length=100) 400 build_name = models.CharField(max_length=100, default='')
401 bitbake_version = models.CharField(max_length=50) 401 bitbake_version = models.CharField(max_length=50)
402 402
403 # number of recipes to parse for this build
404 recipes_to_parse = models.IntegerField(default=1)
405
406 # number of recipes parsed so far for this build
407 recipes_parsed = models.IntegerField(default=0)
408
403 @staticmethod 409 @staticmethod
404 def get_recent(project=None): 410 def get_recent(project=None):
405 """ 411 """
@@ -615,6 +621,13 @@ class Build(models.Model):
615 else: 621 else:
616 return False 622 return False
617 623
624 def is_parsing(self):
625 """
626 True if the build is still parsing recipes
627 """
628 return self.outcome == Build.IN_PROGRESS and \
629 self.recipes_parsed < self.recipes_to_parse
630
618 def get_state(self): 631 def get_state(self):
619 """ 632 """
620 Get the state of the build; one of 'Succeeded', 'Failed', 'In Progress', 633 Get the state of the build; one of 'Succeeded', 'Failed', 'In Progress',
@@ -628,6 +641,8 @@ class Build(models.Model):
628 return 'Cancelling'; 641 return 'Cancelling';
629 elif self.is_queued(): 642 elif self.is_queued():
630 return 'Queued' 643 return 'Queued'
644 elif self.is_parsing():
645 return 'Parsing'
631 else: 646 else:
632 return self.get_outcome_text() 647 return self.get_outcome_text()
633 648
diff --git a/bitbake/lib/toaster/toastergui/api.py b/bitbake/lib/toaster/toastergui/api.py
index aa3cbd83b2..b57f670ba3 100644
--- a/bitbake/lib/toaster/toastergui/api.py
+++ b/bitbake/lib/toaster/toastergui/api.py
@@ -87,7 +87,7 @@ class XhrBuildRequest(View):
87 br.save() 87 br.save()
88 88
89 except BuildRequest.DoesNotExist: 89 except BuildRequest.DoesNotExist:
90 return error_response('No such build id %s' % i) 90 return error_response('No such build request id %s' % i)
91 91
92 return error_response('ok') 92 return error_response('ok')
93 93
@@ -256,6 +256,14 @@ class MostRecentBuildsView(View):
256 build['id'] = build_obj.pk 256 build['id'] = build_obj.pk
257 build['dashboard_url'] = dashboard_url 257 build['dashboard_url'] = dashboard_url
258 258
259 buildrequest_id = None
260 if hasattr(build_obj, 'buildrequest'):
261 buildrequest_id = build_obj.buildrequest.pk
262 build['buildrequest_id'] = buildrequest_id
263
264 build['recipes_parsed_percentage'] = \
265 int((build_obj.recipes_parsed / build_obj.recipes_to_parse) * 100)
266
259 tasks_complete_percentage = 0 267 tasks_complete_percentage = 0
260 if build_obj.outcome in (Build.SUCCEEDED, Build.FAILED): 268 if build_obj.outcome in (Build.SUCCEEDED, Build.FAILED):
261 tasks_complete_percentage = 100 269 tasks_complete_percentage = 100
diff --git a/bitbake/lib/toaster/toastergui/static/js/mrbsection.js b/bitbake/lib/toaster/toastergui/static/js/mrbsection.js
index d8c3bf7750..e7fbf01731 100644
--- a/bitbake/lib/toaster/toastergui/static/js/mrbsection.js
+++ b/bitbake/lib/toaster/toastergui/static/js/mrbsection.js
@@ -33,8 +33,8 @@ function mrbSectionInit(ctx){
33 return buildData[build.id] || {}; 33 return buildData[build.id] || {};
34 } 34 }
35 35
36 // returns true if a build's state changed to "Succeeded" or "Failed" 36 // returns true if a build's state changed to "Succeeded", "Failed"
37 // from some other value 37 // or "Cancelled" from some other value
38 function buildFinished(build) { 38 function buildFinished(build) {
39 var cached = getCached(build); 39 var cached = getCached(build);
40 return cached.state && 40 return cached.state &&
@@ -49,12 +49,18 @@ function mrbSectionInit(ctx){
49 return (cached.state !== build.state); 49 return (cached.state !== build.state);
50 } 50 }
51 51
52 // returns true if the complete_percentage changed 52 // returns true if the tasks_complete_percentage changed
53 function progressChanged(build) { 53 function tasksProgressChanged(build) {
54 var cached = getCached(build); 54 var cached = getCached(build);
55 return (cached.tasks_complete_percentage !== build.tasks_complete_percentage); 55 return (cached.tasks_complete_percentage !== build.tasks_complete_percentage);
56 } 56 }
57 57
58 // returns true if the number of recipes parsed/to parse changed
59 function recipeProgressChanged(build) {
60 var cached = getCached(build);
61 return (cached.recipes_parsed_percentage !== build.recipes_parsed_percentage);
62 }
63
58 function refreshMostRecentBuilds(){ 64 function refreshMostRecentBuilds(){
59 libtoaster.getMostRecentBuilds( 65 libtoaster.getMostRecentBuilds(
60 libtoaster.ctx.mostRecentBuildsUrl, 66 libtoaster.ctx.mostRecentBuildsUrl,
@@ -68,10 +74,6 @@ function mrbSectionInit(ctx){
68 var colourClass; 74 var colourClass;
69 var elements; 75 var elements;
70 76
71 // classes on the parent which signify the build state and affect
72 // the colour of the container for the build
73 var buildStateClasses = 'alert-info alert-success alert-danger';
74
75 for (var i = 0; i < data.length; i++) { 77 for (var i = 0; i < data.length; i++) {
76 build = data[i]; 78 build = data[i];
77 79
@@ -91,31 +93,25 @@ function mrbSectionInit(ctx){
91 container = $(selector); 93 container = $(selector);
92 94
93 container.html(html); 95 container.html(html);
94
95 // style the outermost container for this build to reflect
96 // the new build state (red, green, blue);
97 // NB class set here should be in buildStateClasses
98 colourClass = 'alert-info';
99 if (build.state == 'Succeeded') {
100 colourClass = 'alert-success';
101 }
102 else if (build.state == 'Failed') {
103 colourClass = 'alert-danger';
104 }
105
106 elements = $('[data-latest-build-result="' + build.id + '"]');
107 elements.removeClass(buildStateClasses);
108 elements.addClass(colourClass);
109 } 96 }
110 else if (progressChanged(build)) { 97 else if (tasksProgressChanged(build)) {
111 // update the progress text 98 // update the task progress text
112 selector = '#build-pc-done-' + build.id; 99 selector = '#build-pc-done-' + build.id;
113 $(selector).html(build.tasks_complete_percentage); 100 $(selector).html(build.tasks_complete_percentage);
114 101
115 // update the progress bar 102 // update the task progress bar
116 selector = '#build-pc-done-bar-' + build.id; 103 selector = '#build-pc-done-bar-' + build.id;
117 $(selector).width(build.tasks_complete_percentage + '%'); 104 $(selector).width(build.tasks_complete_percentage + '%');
118 } 105 }
106 else if (recipeProgressChanged(build)) {
107 // update the recipe progress text
108 selector = '#recipes-parsed-percentage-' + build.id;
109 $(selector).html(build.recipes_parsed_percentage);
110
111 // update the recipe progress bar
112 selector = '#recipes-parsed-percentage-bar-' + build.id;
113 $(selector).width(build.recipes_parsed_percentage + '%');
114 }
119 115
120 buildData[build.id] = build; 116 buildData[build.id] = build;
121 } 117 }
@@ -128,6 +124,6 @@ function mrbSectionInit(ctx){
128 ); 124 );
129 } 125 }
130 126
131 window.setInterval(refreshMostRecentBuilds, 1000); 127 window.setInterval(refreshMostRecentBuilds, 1500);
132 refreshMostRecentBuilds(); 128 refreshMostRecentBuilds();
133} 129}
diff --git a/bitbake/lib/toaster/toastergui/templates/mrb_section.html b/bitbake/lib/toaster/toastergui/templates/mrb_section.html
index 302b4b0da4..880485d45f 100644
--- a/bitbake/lib/toaster/toastergui/templates/mrb_section.html
+++ b/bitbake/lib/toaster/toastergui/templates/mrb_section.html
@@ -26,7 +26,9 @@
26 <div class="row project-name"> 26 <div class="row project-name">
27 <div class="col-md-12"> 27 <div class="col-md-12">
28 <small> 28 <small>
29 <a class="alert-link text-uppercase" href={% project_url build.project %}>{{build.project.name}}</a> 29 <a class="alert-link text-uppercase" href="{% project_url build.project %}">
30 {{build.project.name}}
31 </a>
30 </small> 32 </small>
31 </div> 33 </div>
32 </div> 34 </div>
@@ -52,14 +54,18 @@
52 <%:targets_abbreviated%> 54 <%:targets_abbreviated%>
53 </span> 55 </span>
54 </a> 56 </a>
55 <%else%> 57 <%else targets_abbreviated !== ''%>
56 <span data-toggle="tooltip" data-role="targets-text" title="Recipes: <%:targets%>"> 58 <span data-toggle="tooltip" data-role="targets-text" title="Recipes: <%:targets%>">
57 <%:targets_abbreviated%> 59 <%:targets_abbreviated%>
58 </span> 60 </span>
61 <%else%>
62 ...targets not yet available...
59 <%/if%> 63 <%/if%>
60 </div> 64 </div>
61 65
62 <%if state == 'Queued'%> 66 <%if state == 'Parsing'%>
67 <%include tmpl='#parsing-recipes-build-template'/%>
68 <%else state == 'Queued'%>
63 <%include tmpl='#queued-build-template'/%> 69 <%include tmpl='#queued-build-template'/%>
64 <%else state == 'Succeeded' || state == 'Failed'%> 70 <%else state == 'Succeeded' || state == 'Failed'%>
65 <%include tmpl='#succeeded-or-failed-build-template'/%> 71 <%include tmpl='#succeeded-or-failed-build-template'/%>
@@ -75,21 +81,38 @@
75<!-- queued build --> 81<!-- queued build -->
76<script id="queued-build-template" type="text/x-jsrender"> 82<script id="queued-build-template" type="text/x-jsrender">
77 <div class="col-md-5"> 83 <div class="col-md-5">
84 <span class="glyphicon glyphicon-question-sign get-help get-help-blue" title="This build is waiting for
85the build directory to become available"></span>
86
78 Build queued 87 Build queued
79 </div> 88 </div>
80 89
81 <div class="col-md-4"> 90 <div class="col-md-4">
82 <%if is_default_project_build%> 91 <!-- cancel button -->
83 <!-- no cancel icon --> 92 <%include tmpl='#cancel-template'/%>
84 <span class="glyphicon glyphicon-question-sign get-help get-help-blue pull-right" title="Builds in this project cannot be cancelled from Toaster: they can only be cancelled from the command line"></span> 93 </div>
85 <%else%> 94</script>
86 <!-- cancel button --> 95
87 <span class="cancel-build-btn pull-right alert-link" 96<!-- parsing recipes build -->
88 data-buildrequest-id="<%:id%>" data-request-url="<%:cancel_url%>"> 97<script id="parsing-recipes-build-template" type="text/x-jsrender">
89 <span class="glyphicon glyphicon-remove-circle"></span> 98 <!-- progress bar and parse completion percentage -->
90 Cancel 99 <div data-role="build-status" class="col-md-4 col-md-offset-1 progress-info">
91 </span> 100 <!-- progress bar -->
92 <%/if%> 101 <div class="progress">
102 <div id="recipes-parsed-percentage-bar-<%:id%>"
103 style="width: <%:recipes_parsed_percentage%>%;"
104 class="progress-bar">
105 </div>
106 </div>
107 </div>
108
109 <div class="col-md-4 progress-info">
110 <!-- parse completion percentage -->
111 <span class="glyphicon glyphicon-question-sign get-help get-help-blue" title="BitBake is parsing the layers required for your build"></span>
112
113 Parsing <span id="recipes-parsed-percentage-<%:id%>"><%:recipes_parsed_percentage%></span>% complete
114
115 <%include tmpl='#cancel-template'/%>
93 </div> 116 </div>
94</script> 117</script>
95 118
@@ -110,17 +133,9 @@
110 <!-- task completion percentage --> 133 <!-- task completion percentage -->
111 <span id="build-pc-done-<%:id%>"><%:tasks_complete_percentage%></span>% of 134 <span id="build-pc-done-<%:id%>"><%:tasks_complete_percentage%></span>% of
112 tasks complete 135 tasks complete
113 <%if is_default_project_build%> 136
114 <!-- no cancel icon --> 137 <!-- cancel button -->
115 <span class="glyphicon glyphicon-question-sign get-help get-help-blue pull-right" title="Builds in this project cannot be cancelled from Toaster: they can only be cancelled from the command line"></span> 138 <%include tmpl='#cancel-template'/%>
116 <%else%>
117 <!-- cancel button -->
118 <span class="cancel-build-btn pull-right alert-link"
119 data-buildrequest-id="<%:id%>" data-request-url="<%:cancel_url%>">
120 <span class="glyphicon glyphicon-remove-circle"></span>
121 Cancel
122 </span>
123 <%/if%>
124 </div> 139 </div>
125</script> 140</script>
126 141
@@ -162,19 +177,8 @@
162 <div class="col-md-3"> 177 <div class="col-md-3">
163 Build time: <a class="alert-link" href="<%:buildtime_url%>"><%:buildtime%></a> 178 Build time: <a class="alert-link" href="<%:buildtime_url%>"><%:buildtime%></a>
164 179
165 <%if is_default_project_build%> 180 <!-- rebuild button -->
166 <!-- info icon --> 181 <%include tmpl='#rebuild-template'/%>
167 <span class="pull-right glyphicon glyphicon-question-sign get-help <%if state == 'Success'%>get-help-green<%else state == 'Failed'%>get-help-red<%else%>get-help-blue<%/if%>"
168 title="Builds in this project cannot be started from Toaster: they are started from the command line">
169 </span>
170 <%else%>
171 <!-- rebuild button -->
172 <span class="rebuild-btn alert-link <%if state == 'Success'%>success<%else state == 'Failed'%>danger<%else%>info<%/if%> pull-right"
173 data-request-url="<%:rebuild_url%>" data-target='<%:build_targets_json%>'>
174 <span class="glyphicon glyphicon-repeat"></span>
175 Rebuild
176 </span>
177 <%/if%>
178 </div> 182 </div>
179</script> 183</script>
180 184
@@ -187,12 +191,40 @@
187 191
188 <!-- rebuild button --> 192 <!-- rebuild button -->
189 <div class="col-md-3"> 193 <div class="col-md-3">
190 <span class="info pull-right rebuild-btn alert-link" 194 <%include tmpl='#rebuild-template'/%>
195 </div>
196</script>
197
198<!-- rebuild button or no rebuild icon -->
199<script id="rebuild-template" type="text/x-jsrender">
200 <%if is_default_project_build%>
201 <!-- no rebuild info icon -->
202 <span class="pull-right glyphicon glyphicon-question-sign get-help <%if state == 'Success'%>get-help-green<%else state == 'Failed'%>get-help-red<%else%>get-help-blue<%/if%>"
203 title="Builds in this project cannot be started from Toaster: they are started from the command line">
204 </span>
205 <%else%>
206 <!-- rebuild button -->
207 <span class="rebuild-btn alert-link <%if state == 'Success'%>success<%else state == 'Failed'%>danger<%else%>info<%/if%> pull-right"
191 data-request-url="<%:rebuild_url%>" data-target='<%:build_targets_json%>'> 208 data-request-url="<%:rebuild_url%>" data-target='<%:build_targets_json%>'>
192 <span class="glyphicon glyphicon-repeat"></span> 209 <span class="glyphicon glyphicon-repeat"></span>
193 Rebuild 210 Rebuild
194 </span> 211 </span>
195 </div> 212 <%/if%>
213</script>
214
215<!-- cancel button or no cancel icon -->
216<script id="cancel-template" type="text/x-jsrender">
217 <%if is_default_project_build%>
218 <!-- no cancel icon -->
219 <span class="glyphicon glyphicon-question-sign get-help get-help-blue pull-right" title="Builds in this project cannot be cancelled from Toaster: they can only be cancelled from the command line"></span>
220 <%else%>
221 <!-- cancel button -->
222 <span class="cancel-build-btn pull-right alert-link"
223 data-buildrequest-id="<%:buildrequest_id%>" data-request-url="<%:cancel_url%>">
224 <span class="glyphicon glyphicon-remove-circle"></span>
225 Cancel
226 </span>
227 <%/if%>
196</script> 228</script>
197 229
198<script> 230<script>