summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2015-06-17 12:27:48 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-06-26 09:27:32 +0100
commit335c975650580001b2176020c762c002bde198d6 (patch)
treea9e2907b72bbbac2ad897b7839f8114e60935038 /bitbake
parentd7c8d9558c8b600be1507212c78dde833b2bb57e (diff)
downloadpoky-335c975650580001b2176020c762c002bde198d6.tar.gz
bitbake: toaster: fixes after replacing BuildRequest with Build
This is a set of fixes that repair the interface after we switched from displaying BuildRequest data to Build data in the formerly "managed" mode. (Bitbake rev: 57f790b0c56297af8c83d5def8461bd5d61fe4af) Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/bb/ui/toasterui.py24
-rw-r--r--bitbake/lib/toaster/bldcontrol/localhostbecontroller.py2
-rw-r--r--bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py7
-rw-r--r--bitbake/lib/toaster/bldcontrol/models.py3
-rw-r--r--bitbake/lib/toaster/orm/migrations/0021_auto__chg_field_build_project__chg_field_project_bitbake_version__chg_.py5
-rw-r--r--bitbake/lib/toaster/orm/migrations/0022_auto__add_field_target_task__add_field_layer_version_local_path__del_f.py343
-rw-r--r--bitbake/lib/toaster/orm/models.py8
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/projectapp.js4
-rw-r--r--bitbake/lib/toaster/toastergui/templates/project.html4
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py6
10 files changed, 378 insertions, 28 deletions
diff --git a/bitbake/lib/bb/ui/toasterui.py b/bitbake/lib/bb/ui/toasterui.py
index 30540483c3..9c59fd07c6 100644
--- a/bitbake/lib/bb/ui/toasterui.py
+++ b/bitbake/lib/bb/ui/toasterui.py
@@ -43,7 +43,7 @@ import xmlrpclib
43 43
44featureSet = [bb.cooker.CookerFeatures.HOB_EXTRA_CACHES, bb.cooker.CookerFeatures.SEND_DEPENDS_TREE, bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING, bb.cooker.CookerFeatures.SEND_SANITYEVENTS] 44featureSet = [bb.cooker.CookerFeatures.HOB_EXTRA_CACHES, bb.cooker.CookerFeatures.SEND_DEPENDS_TREE, bb.cooker.CookerFeatures.BASEDATASTORE_TRACKING, bb.cooker.CookerFeatures.SEND_SANITYEVENTS]
45 45
46logger = logging.getLogger("BitBake") 46logger = logging.getLogger("ToasterLogger")
47interactive = sys.stdout.isatty() 47interactive = sys.stdout.isatty()
48 48
49 49
@@ -66,7 +66,6 @@ def _log_settings_from_server(server):
66 66
67 67
68def main(server, eventHandler, params ): 68def main(server, eventHandler, params ):
69
70 helper = uihelper.BBUIHelper() 69 helper = uihelper.BBUIHelper()
71 70
72 console = logging.StreamHandler(sys.stdout) 71 console = logging.StreamHandler(sys.stdout)
@@ -235,12 +234,18 @@ def main(server, eventHandler, params ):
235 if isinstance(event, (bb.event.TreeDataPreparationStarted, bb.event.TreeDataPreparationCompleted)): 234 if isinstance(event, (bb.event.TreeDataPreparationStarted, bb.event.TreeDataPreparationCompleted)):
236 continue 235 continue
237 236
238 if isinstance(event, (bb.event.BuildCompleted)): 237 if isinstance(event, (bb.event.BuildCompleted, bb.command.CommandFailed)):
238
239 if (isinstance(event, bb.command.CommandFailed)):
240 errors += 1
241 errorcode = 1
242 logger.error("Command execution failed: %s", event.error)
243
239 # update the build info helper on BuildCompleted, not on CommandXXX 244 # update the build info helper on BuildCompleted, not on CommandXXX
240 buildinfohelper.update_build_information(event, errors, warnings, taskfailures) 245 buildinfohelper.update_build_information(event, errors, warnings, taskfailures)
241 buildinfohelper.close(errorcode) 246 buildinfohelper.close(errorcode)
242 # mark the log output; controllers may kill the toasterUI after seeing this log 247 # mark the log output; controllers may kill the toasterUI after seeing this log
243 logger.info("ToasterUI build done") 248 logger.info("ToasterUI build done 1, brbe: %s" % buildinfohelper.brbe )
244 249
245 # we start a new build info 250 # we start a new build info
246 if buildinfohelper.brbe is not None: 251 if buildinfohelper.brbe is not None:
@@ -254,22 +259,13 @@ def main(server, eventHandler, params ):
254 taskfailures = [] 259 taskfailures = []
255 buildinfohelper = BuildInfoHelper(server, build_history_enabled) 260 buildinfohelper = BuildInfoHelper(server, build_history_enabled)
256 261
262 logger.info("ToasterUI build done 2")
257 continue 263 continue
258 264
259 if isinstance(event, (bb.command.CommandCompleted, 265 if isinstance(event, (bb.command.CommandCompleted,
260 bb.command.CommandFailed, 266 bb.command.CommandFailed,
261 bb.command.CommandExit)): 267 bb.command.CommandExit)):
262 errorcode = 0 268 errorcode = 0
263 if (isinstance(event, bb.command.CommandFailed)):
264 event.levelno = format.ERROR
265 event.msg = "Command Failed " + event.error
266 event.pathname = ""
267 event.lineno = 0
268 buildinfohelper.store_log_event(event)
269 errors += 1
270 errorcode = 1
271 logger.error("Command execution failed: %s", event.error)
272
273 269
274 continue 270 continue
275 271
diff --git a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
index d0f86325e9..ad0a561398 100644
--- a/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
+++ b/bitbake/lib/toaster/bldcontrol/localhostbecontroller.py
@@ -322,7 +322,7 @@ class LocalhostBEController(BuildEnvironmentController):
322 def triggerBuild(self, bitbake, layers, variables, targets): 322 def triggerBuild(self, bitbake, layers, variables, targets):
323 # set up the buid environment with the needed layers 323 # set up the buid environment with the needed layers
324 self.setLayers(bitbake, layers) 324 self.setLayers(bitbake, layers)
325 self.writeConfFile("conf/toaster-pre.conf", ) 325 self.writeConfFile("conf/toaster-pre.conf", variables)
326 self.writeConfFile("conf/toaster.conf", raw = "INHERIT+=\"toaster buildhistory\"") 326 self.writeConfFile("conf/toaster.conf", raw = "INHERIT+=\"toaster buildhistory\"")
327 327
328 # get the bb server running with the build req id and build env id 328 # get the bb server running with the build req id and build env id
diff --git a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
index da7d4af07e..bcf3b04cf0 100644
--- a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
+++ b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
@@ -6,7 +6,7 @@ from bldcontrol.models import BuildRequest, BuildEnvironment, BRError, BRVariabl
6import os 6import os
7import logging 7import logging
8 8
9logger = logging.getLogger("toaster") 9logger = logging.getLogger("ToasterScheduler")
10 10
11class Command(NoArgsCommand): 11class Command(NoArgsCommand):
12 args = "" 12 args = ""
@@ -35,7 +35,7 @@ class Command(NoArgsCommand):
35 # select the build environment and the request to build 35 # select the build environment and the request to build
36 br = self._selectBuildRequest() 36 br = self._selectBuildRequest()
37 except IndexError as e: 37 except IndexError as e:
38 # logger.debug("runbuilds: No build request") 38 #logger.debug("runbuilds: No build request")
39 return 39 return
40 try: 40 try:
41 bec = self._selectBuildEnvironment() 41 bec = self._selectBuildEnvironment()
@@ -113,10 +113,11 @@ class Command(NoArgsCommand):
113 113
114 # update all Builds that failed to start 114 # update all Builds that failed to start
115 115
116 for br in BuildRequest.objects.filter(state = BuildRequest.REQ_FAILED): 116 for br in BuildRequest.objects.filter(state = BuildRequest.REQ_FAILED, build__outcome = Build.IN_PROGRESS):
117 br.build.outcome = Build.FAILED 117 br.build.outcome = Build.FAILED
118 # transpose the launch errors in ToasterExceptions 118 # transpose the launch errors in ToasterExceptions
119 for brerror in br.brerror_set.all(): 119 for brerror in br.brerror_set.all():
120 logger.debug("Saving error %s" % brerror)
120 LogMessage.objects.create(build = br.build, level = LogMessage.EXCEPTION, message = brerror.errmsg) 121 LogMessage.objects.create(build = br.build, level = LogMessage.EXCEPTION, message = brerror.errmsg)
121 br.build.save() 122 br.build.save()
122 123
diff --git a/bitbake/lib/toaster/bldcontrol/models.py b/bitbake/lib/toaster/bldcontrol/models.py
index b789446fa1..6f408660de 100644
--- a/bitbake/lib/toaster/bldcontrol/models.py
+++ b/bitbake/lib/toaster/bldcontrol/models.py
@@ -159,3 +159,6 @@ class BRError(models.Model):
159 errtype = models.CharField(max_length=100) 159 errtype = models.CharField(max_length=100)
160 errmsg = models.TextField() 160 errmsg = models.TextField()
161 traceback = models.TextField() 161 traceback = models.TextField()
162
163 def __str__(self):
164 return "%s (%s)" % (self.errmsg, self.req)
diff --git a/bitbake/lib/toaster/orm/migrations/0021_auto__chg_field_build_project__chg_field_project_bitbake_version__chg_.py b/bitbake/lib/toaster/orm/migrations/0021_auto__chg_field_build_project__chg_field_project_bitbake_version__chg_.py
index b82cc8d21b..924a5c4a8a 100644
--- a/bitbake/lib/toaster/orm/migrations/0021_auto__chg_field_build_project__chg_field_project_bitbake_version__chg_.py
+++ b/bitbake/lib/toaster/orm/migrations/0021_auto__chg_field_build_project__chg_field_project_bitbake_version__chg_.py
@@ -105,7 +105,6 @@ class Migration(SchemaMigration):
105 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 105 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
106 'layer_index_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}), 106 'layer_index_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
107 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}), 107 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
108 'local_path': ('django.db.models.fields.FilePathField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
109 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), 108 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
110 'summary': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}), 109 'summary': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}),
111 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), 110 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
@@ -124,6 +123,7 @@ class Migration(SchemaMigration):
124 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 123 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
125 'layer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'layer_version_layer'", 'to': u"orm['orm.Layer']"}), 124 'layer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'layer_version_layer'", 'to': u"orm['orm.Layer']"}),
126 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}), 125 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
126 'local_path': ('django.db.models.fields.FilePathField', [], {'default': "'/'", 'max_length': '1024'}),
127 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}), 127 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
128 'project': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Project']", 'null': 'True'}), 128 'project': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Project']", 'null': 'True'}),
129 'up_branch': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Branch']", 'null': 'True'}), 129 'up_branch': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Branch']", 'null': 'True'}),
@@ -229,7 +229,7 @@ class Migration(SchemaMigration):
229 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'}) 229 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
230 }, 230 },
231 u'orm.recipe': { 231 u'orm.recipe': {
232 'Meta': {'unique_together': "(('layer_version', 'file_path'),)", 'object_name': 'Recipe'}, 232 'Meta': {'unique_together': "(('layer_version', 'file_path', 'pathflags'),)", 'object_name': 'Recipe'},
233 'bugtracker': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}), 233 'bugtracker': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
234 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 234 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
235 'file_path': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}), 235 'file_path': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}),
@@ -239,6 +239,7 @@ class Migration(SchemaMigration):
239 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipe_layer_version'", 'to': u"orm['orm.Layer_Version']"}), 239 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipe_layer_version'", 'to': u"orm['orm.Layer_Version']"}),
240 'license': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), 240 'license': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
241 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), 241 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
242 'pathflags': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
242 'section': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), 243 'section': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
243 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}), 244 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
244 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), 245 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
diff --git a/bitbake/lib/toaster/orm/migrations/0022_auto__add_field_target_task__add_field_layer_version_local_path__del_f.py b/bitbake/lib/toaster/orm/migrations/0022_auto__add_field_target_task__add_field_layer_version_local_path__del_f.py
new file mode 100644
index 0000000000..3dec3912eb
--- /dev/null
+++ b/bitbake/lib/toaster/orm/migrations/0022_auto__add_field_target_task__add_field_layer_version_local_path__del_f.py
@@ -0,0 +1,343 @@
1# -*- coding: utf-8 -*-
2from south.utils import datetime_utils as datetime
3from south.db import db
4from south.v2 import SchemaMigration
5from django.db import models
6
7
8class Migration(SchemaMigration):
9
10 def forwards(self, orm):
11 # Adding field 'Target.task'
12 db.add_column(u'orm_target', 'task',
13 self.gf('django.db.models.fields.CharField')(max_length=100, null=True),
14 keep_default=False)
15
16
17
18
19
20 def backwards(self, orm):
21 # Deleting field 'Target.task'
22 db.delete_column(u'orm_target', 'task')
23
24
25 models = {
26 u'orm.bitbakeversion': {
27 'Meta': {'object_name': 'BitbakeVersion'},
28 'branch': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
29 'dirpath': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
30 'giturl': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
31 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
32 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
33 },
34 u'orm.branch': {
35 'Meta': {'unique_together': "(('layer_source', 'name'), ('layer_source', 'up_id'))", 'object_name': 'Branch'},
36 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
37 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'True', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
38 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
39 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
40 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
41 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
42 },
43 u'orm.build': {
44 'Meta': {'object_name': 'Build'},
45 'bitbake_version': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
46 'build_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
47 'completed_on': ('django.db.models.fields.DateTimeField', [], {}),
48 'cooker_log_path': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
49 'distro': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
50 'distro_version': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
51 'errors_no': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
52 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
53 'machine': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
54 'outcome': ('django.db.models.fields.IntegerField', [], {'default': '2'}),
55 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
56 'started_on': ('django.db.models.fields.DateTimeField', [], {}),
57 'timespent': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
58 'warnings_no': ('django.db.models.fields.IntegerField', [], {'default': '0'})
59 },
60 u'orm.buildartifact': {
61 'Meta': {'object_name': 'BuildArtifact'},
62 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
63 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '100'}),
64 'file_size': ('django.db.models.fields.IntegerField', [], {}),
65 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
66 },
67 u'orm.helptext': {
68 'Meta': {'object_name': 'HelpText'},
69 'area': ('django.db.models.fields.IntegerField', [], {}),
70 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'helptext_build'", 'to': u"orm['orm.Build']"}),
71 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
72 'key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
73 'text': ('django.db.models.fields.TextField', [], {})
74 },
75 u'orm.layer': {
76 'Meta': {'unique_together': "(('layer_source', 'up_id'), ('layer_source', 'name'))", 'object_name': 'Layer'},
77 'description': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}),
78 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
79 'layer_index_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),
80 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
81 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
82 'summary': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True'}),
83 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
84 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'}),
85 'vcs_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
86 'vcs_web_file_base_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
87 'vcs_web_tree_base_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'}),
88 'vcs_web_url': ('django.db.models.fields.URLField', [], {'default': 'None', 'max_length': '200', 'null': 'True'})
89 },
90 u'orm.layer_version': {
91 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'Layer_Version'},
92 'branch': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
93 'build': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'layer_version_build'", 'null': 'True', 'to': u"orm['orm.Build']"}),
94 'commit': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
95 'dirpath': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
96 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
97 'layer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'layer_version_layer'", 'to': u"orm['orm.Layer']"}),
98 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
99 'local_path': ('django.db.models.fields.FilePathField', [], {'default': "'/'", 'max_length': '1024'}),
100 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
101 'project': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Project']", 'null': 'True'}),
102 'up_branch': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.Branch']", 'null': 'True'}),
103 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
104 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
105 },
106 u'orm.layersource': {
107 'Meta': {'unique_together': "(('sourcetype', 'apiurl'),)", 'object_name': 'LayerSource'},
108 'apiurl': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True'}),
109 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
110 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '63'}),
111 'sourcetype': ('django.db.models.fields.IntegerField', [], {})
112 },
113 u'orm.layerversiondependency': {
114 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'LayerVersionDependency'},
115 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependees'", 'to': u"orm['orm.Layer_Version']"}),
116 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
117 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
118 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'dependencies'", 'to': u"orm['orm.Layer_Version']"}),
119 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
120 },
121 u'orm.logmessage': {
122 'Meta': {'object_name': 'LogMessage'},
123 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
124 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
125 'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
126 'lineno': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
127 'message': ('django.db.models.fields.CharField', [], {'max_length': '240'}),
128 'pathname': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
129 'task': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Task']", 'null': 'True', 'blank': 'True'})
130 },
131 u'orm.machine': {
132 'Meta': {'unique_together': "(('layer_source', 'up_id'),)", 'object_name': 'Machine'},
133 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
134 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
135 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
136 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer_Version']"}),
137 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
138 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
139 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'})
140 },
141 u'orm.package': {
142 'Meta': {'object_name': 'Package'},
143 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
144 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
145 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
146 'installed_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}),
147 'installed_size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
148 'license': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}),
149 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
150 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Recipe']", 'null': 'True'}),
151 'revision': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}),
152 'section': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}),
153 'size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
154 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
155 'version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
156 },
157 u'orm.package_dependency': {
158 'Meta': {'object_name': 'Package_Dependency'},
159 'dep_type': ('django.db.models.fields.IntegerField', [], {}),
160 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'package_dependencies_target'", 'to': u"orm['orm.Package']"}),
161 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
162 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'package_dependencies_source'", 'to': u"orm['orm.Package']"}),
163 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']", 'null': 'True'})
164 },
165 u'orm.package_file': {
166 'Meta': {'object_name': 'Package_File'},
167 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
168 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buildfilelist_package'", 'to': u"orm['orm.Package']"}),
169 'path': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
170 'size': ('django.db.models.fields.IntegerField', [], {})
171 },
172 u'orm.project': {
173 'Meta': {'object_name': 'Project'},
174 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']", 'null': 'True'}),
175 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
176 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
177 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
178 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']", 'null': 'True'}),
179 'short_description': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
180 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
181 'user_id': ('django.db.models.fields.IntegerField', [], {'null': 'True'})
182 },
183 u'orm.projectlayer': {
184 'Meta': {'unique_together': "(('project', 'layercommit'),)", 'object_name': 'ProjectLayer'},
185 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
186 'layercommit': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Layer_Version']", 'null': 'True'}),
187 'optional': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
188 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"})
189 },
190 u'orm.projecttarget': {
191 'Meta': {'object_name': 'ProjectTarget'},
192 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
193 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
194 'target': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
195 'task': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
196 },
197 u'orm.projectvariable': {
198 'Meta': {'object_name': 'ProjectVariable'},
199 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
200 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
201 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Project']"}),
202 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
203 },
204 u'orm.recipe': {
205 'Meta': {'unique_together': "(('layer_version', 'file_path', 'pathflags'),)", 'object_name': 'Recipe'},
206 'bugtracker': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
207 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
208 'file_path': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}),
209 'homepage': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
210 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
211 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['orm.LayerSource']", 'null': 'True'}),
212 'layer_version': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recipe_layer_version'", 'to': u"orm['orm.Layer_Version']"}),
213 'license': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
214 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
215 'pathflags': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
216 'section': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
217 'summary': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
218 'up_date': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
219 'up_id': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True'}),
220 'version': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
221 },
222 u'orm.recipe_dependency': {
223 'Meta': {'object_name': 'Recipe_Dependency'},
224 'dep_type': ('django.db.models.fields.IntegerField', [], {}),
225 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'r_dependencies_depends'", 'to': u"orm['orm.Recipe']"}),
226 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
227 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'r_dependencies_recipe'", 'to': u"orm['orm.Recipe']"})
228 },
229 u'orm.release': {
230 'Meta': {'object_name': 'Release'},
231 'bitbake_version': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.BitbakeVersion']"}),
232 'branch_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50'}),
233 'description': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
234 'helptext': ('django.db.models.fields.TextField', [], {'null': 'True'}),
235 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
236 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'})
237 },
238 u'orm.releasedefaultlayer': {
239 'Meta': {'object_name': 'ReleaseDefaultLayer'},
240 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
241 'layer_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '100'}),
242 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']"})
243 },
244 u'orm.releaselayersourcepriority': {
245 'Meta': {'unique_together': "(('release', 'layer_source'),)", 'object_name': 'ReleaseLayerSourcePriority'},
246 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
247 'layer_source': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.LayerSource']"}),
248 'priority': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
249 'release': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Release']"})
250 },
251 u'orm.target': {
252 'Meta': {'object_name': 'Target'},
253 'build': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Build']"}),
254 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
255 'image_size': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
256 'is_image': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
257 'license_manifest_path': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True'}),
258 'target': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
259 'task': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
260 },
261 u'orm.target_file': {
262 'Meta': {'object_name': 'Target_File'},
263 'directory': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'directory_set'", 'null': 'True', 'to': u"orm['orm.Target_File']"}),
264 'group': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
265 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
266 'inodetype': ('django.db.models.fields.IntegerField', [], {}),
267 'owner': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
268 'path': ('django.db.models.fields.FilePathField', [], {'max_length': '100'}),
269 'permission': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
270 'size': ('django.db.models.fields.IntegerField', [], {}),
271 'sym_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'symlink_set'", 'null': 'True', 'to': u"orm['orm.Target_File']"}),
272 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
273 },
274 u'orm.target_image_file': {
275 'Meta': {'object_name': 'Target_Image_File'},
276 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '254'}),
277 'file_size': ('django.db.models.fields.IntegerField', [], {}),
278 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
279 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
280 },
281 u'orm.target_installed_package': {
282 'Meta': {'object_name': 'Target_Installed_Package'},
283 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
284 'package': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'buildtargetlist_package'", 'to': u"orm['orm.Package']"}),
285 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['orm.Target']"})
286 },
287 u'orm.task': {
288 'Meta': {'ordering': "('order', 'recipe')", 'unique_together': "(('build', 'recipe', 'task_name'),)", 'object_name': 'Task'},
289 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_build'", 'to': u"orm['orm.Build']"}),
290 'cpu_usage': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '8', 'decimal_places': '2'}),
291 'disk_io': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
292 'elapsed_time': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '8', 'decimal_places': '2'}),
293 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
294 'line_number': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
295 'logfile': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
296 'message': ('django.db.models.fields.CharField', [], {'max_length': '240'}),
297 'order': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
298 'outcome': ('django.db.models.fields.IntegerField', [], {'default': '-1'}),
299 'path_to_sstate_obj': ('django.db.models.fields.FilePathField', [], {'max_length': '500', 'blank': 'True'}),
300 'recipe': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'to': u"orm['orm.Recipe']"}),
301 'script_type': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
302 'source_url': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'}),
303 'sstate_checksum': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
304 'sstate_result': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
305 'task_executed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
306 'task_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
307 'work_directory': ('django.db.models.fields.FilePathField', [], {'max_length': '255', 'blank': 'True'})
308 },
309 u'orm.task_dependency': {
310 'Meta': {'object_name': 'Task_Dependency'},
311 'depends_on': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_dependencies_depends'", 'to': u"orm['orm.Task']"}),
312 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
313 'task': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_dependencies_task'", 'to': u"orm['orm.Task']"})
314 },
315 u'orm.toastersetting': {
316 'Meta': {'object_name': 'ToasterSetting'},
317 'helptext': ('django.db.models.fields.TextField', [], {}),
318 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
319 'name': ('django.db.models.fields.CharField', [], {'max_length': '63'}),
320 'value': ('django.db.models.fields.CharField', [], {'max_length': '255'})
321 },
322 u'orm.variable': {
323 'Meta': {'object_name': 'Variable'},
324 'build': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'variable_build'", 'to': u"orm['orm.Build']"}),
325 'changed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
326 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
327 'human_readable_name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
328 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
329 'variable_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
330 'variable_value': ('django.db.models.fields.TextField', [], {'blank': 'True'})
331 },
332 u'orm.variablehistory': {
333 'Meta': {'object_name': 'VariableHistory'},
334 'file_name': ('django.db.models.fields.FilePathField', [], {'max_length': '255'}),
335 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
336 'line_number': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
337 'operation': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
338 'value': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
339 'variable': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'vhistory'", 'to': u"orm['orm.Variable']"})
340 }
341 }
342
343 complete_apps = ['orm']
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index d97eadb592..e93629b7ba 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -283,8 +283,9 @@ class Build(models.Model):
283 283
284 284
285 def get_current_status(self): 285 def get_current_status(self):
286 if self.outcome == Build.IN_PROGRESS and self.build_name == "": 286 from bldcontrol.models import BuildRequest
287 return "Queued" 287 if self.outcome == Build.IN_PROGRESS and self.buildrequest.state != BuildRequest.REQ_INPROGRESS:
288 return self.buildrequest.get_state_display()
288 return self.get_outcome_display() 289 return self.get_outcome_display()
289 290
290 def __str__(self): 291 def __str__(self):
@@ -1168,6 +1169,9 @@ class LogMessage(models.Model):
1168 pathname = models.FilePathField(max_length=255, blank=True) 1169 pathname = models.FilePathField(max_length=255, blank=True)
1169 lineno = models.IntegerField(null=True) 1170 lineno = models.IntegerField(null=True)
1170 1171
1172 def __str__(self):
1173 return "%s %s %s" % (self.get_level_display(), self.message, self.build)
1174
1171def invalidate_cache(**kwargs): 1175def invalidate_cache(**kwargs):
1172 from django.core.cache import cache 1176 from django.core.cache import cache
1173 try: 1177 try:
diff --git a/bitbake/lib/toaster/toastergui/static/js/projectapp.js b/bitbake/lib/toaster/toastergui/static/js/projectapp.js
index 40e2e1fffa..ea44bf34f1 100644
--- a/bitbake/lib/toaster/toastergui/static/js/projectapp.js
+++ b/bitbake/lib/toaster/toastergui/static/js/projectapp.js
@@ -132,8 +132,8 @@ projectApp.filter('timediff', function() {
132 var seconds = parseInt(input); 132 var seconds = parseInt(input);
133 var minutes = Math.floor(seconds / 60); 133 var minutes = Math.floor(seconds / 60);
134 seconds = seconds - minutes * 60; 134 seconds = seconds - minutes * 60;
135 var hours = Math.floor(seconds / 3600); 135 var hours = Math.floor(minutes / 60);
136 seconds = seconds - hours * 3600; 136 minutes = minutes - hours * 60;
137 return pad(hours) + ":" + pad(minutes) + ":" + pad(seconds); 137 return pad(hours) + ":" + pad(minutes) + ":" + pad(seconds);
138 }; 138 };
139}); 139});
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html
index 1a8991fda4..b5d97cb419 100644
--- a/bitbake/lib/toaster/toastergui/templates/project.html
+++ b/bitbake/lib/toaster/toastergui/templates/project.html
@@ -145,7 +145,7 @@ vim: expandtab tabstop=2
145 145
146 <a id="buildslist"></a> 146 <a id="buildslist"></a>
147 <h2 class="air" data-ng-if="builds.length">Latest builds</h2> 147 <h2 class="air" data-ng-if="builds.length">Latest builds</h2>
148 <div class="animate-repeat alert" data-ng-repeat="b in builds track by b.id" data-ng-class="{'Queued':'alert-info', 'In Progress':'alert-info', 'Succeeded':'alert-success', 'Failed':'alert-error'}[b.status]"> 148 <div class="animate-repeat alert" data-ng-repeat="b in builds track by b.id" data-ng-class="{'queued':'alert-info', 'In Progress':'alert-info', 'Succeeded':'alert-success', 'Failed':'alert-error'}[b.status]">
149 <div class="row-fluid"> 149 <div class="row-fluid">
150 <switch data-ng-switch="b.status"> 150 <switch data-ng-switch="b.status">
151 151
@@ -182,7 +182,7 @@ vim: expandtab tabstop=2
182 </div> 182 </div>
183 </case> 183 </case>
184 184
185 <case data-ng-switch-when="Queued"> 185 <case data-ng-switch-when="queued">
186 <div class="lead span5"> <span data-ng-repeat="t in b.targets" data-ng-include src="'target_display'"></span> </div> 186 <div class="lead span5"> <span data-ng-repeat="t in b.targets" data-ng-include src="'target_display'"></span> </div>
187 <div class="span4 lead" >Build queued 187 <div class="span4 lead" >Build queued
188 <i title="This build will start as soon as a build server is available" class="icon-question-sign get-help get-help-blue heading-help" data-toggle="tooltip"></i> 188 <i title="This build will start as soon as a build server is available" class="icon-question-sign get-help get-help-blue heading-help" data-toggle="tooltip"></i>
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 2336ae3bec..00b1387d63 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -64,7 +64,9 @@ def _get_latest_builds(prj=None):
64 if prj is not None: 64 if prj is not None:
65 queryset = queryset.filter(project = prj) 65 queryset = queryset.filter(project = prj)
66 66
67 return itertools.chain(queryset.filter(outcome__lt=Build.IN_PROGRESS).order_by("-pk")[:3], queryset.filter(outcome=Build.IN_PROGRESS).order_by("-pk")) 67 return itertools.chain(
68 queryset.filter(outcome=Build.IN_PROGRESS).order_by("-pk"),
69 queryset.filter(outcome__lt=Build.IN_PROGRESS).order_by("-pk")[:3] )
68 70
69 71
70# a JSON-able dict of recent builds; for use in the Project page, xhr_ updates, and other places, as needed 72# a JSON-able dict of recent builds; for use in the Project page, xhr_ updates, and other places, as needed
@@ -76,7 +78,7 @@ def _project_recent_build_list(prj):
76 "id": x.pk, 78 "id": x.pk,
77 "targets" : map(lambda y: {"target": y.target, "task": y.task }, x.target_set.all()), # TODO: create the task entry in the Target table 79 "targets" : map(lambda y: {"target": y.target, "task": y.task }, x.target_set.all()), # TODO: create the task entry in the Target table
78 "status": x.get_current_status(), 80 "status": x.get_current_status(),
79 "errors": map(lambda y: {"type": y.lineno, "msg": y.message, "tb": y.pathname}, x.logmessage_set.filter(level__gte=LogMessage.WARNING)), 81 "errors": map(lambda y: {"type": y.lineno, "msg": y.message, "tb": y.pathname}, (x.logmessage_set.filter(level__gte=LogMessage.WARNING)|x.logmessage_set.filter(level=LogMessage.EXCEPTION))),
80 "updated": x.completed_on.strftime('%s')+"000", 82 "updated": x.completed_on.strftime('%s')+"000",
81 "command_time": (x.completed_on - x.started_on).total_seconds(), 83 "command_time": (x.completed_on - x.started_on).total_seconds(),
82 "br_page_url": reverse('buildrequestdetails', args=(x.project.id, x.pk) ), 84 "br_page_url": reverse('buildrequestdetails', args=(x.project.id, x.pk) ),