summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2015-06-11 18:27:53 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-06-26 09:27:32 +0100
commitd7c8d9558c8b600be1507212c78dde833b2bb57e (patch)
tree941c11d7e4aeca7f0c1106a39d1b8006264fbd16
parent160563532f87bd901e1cc6972fe238be87a8b63c (diff)
downloadpoky-d7c8d9558c8b600be1507212c78dde833b2bb57e.tar.gz
bitbake: toaster: fill in build data from buildrequest
This patch adds logic to complete changing the interface from showing BuildRequests to showing Build data. The BuildRequest data is now transformed in Build data with proper Toaster exceptions being recorded instead of listing problems during startup as build errors. (Bitbake rev: 51a41172d0b390370f9a38696b1ac65666ada4d2) Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/bb/ui/buildinfohelper.py16
-rw-r--r--bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py32
-rw-r--r--bitbake/lib/toaster/orm/models.py28
-rw-r--r--bitbake/lib/toaster/toastergui/templates/project.html15
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py4
5 files changed, 84 insertions, 11 deletions
diff --git a/bitbake/lib/bb/ui/buildinfohelper.py b/bitbake/lib/bb/ui/buildinfohelper.py
index 3ea842cd4b..8b63f70a07 100644
--- a/bitbake/lib/bb/ui/buildinfohelper.py
+++ b/bitbake/lib/bb/ui/buildinfohelper.py
@@ -133,7 +133,21 @@ class ORMWrapper(object):
133 logger.debug(1, "buildinfohelper: project is not specified, defaulting to %s" % prj) 133 logger.debug(1, "buildinfohelper: project is not specified, defaulting to %s" % prj)
134 134
135 135
136 build = Build.objects.create( 136 if buildrequest is not None:
137 build = buildrequest.build
138 build.machine=build_info['machine'],
139 build.distro=build_info['distro'],
140 build.distro_version=build_info['distro_version'],
141 build.completed_on=build_info['started_on'],
142 build.cooker_log_path=build_info['cooker_log_path'],
143 build.build_name=build_info['build_name'],
144 build.bitbake_version=build_info['bitbake_version']
145 build.save()
146
147 build.target_set.delete()
148
149 else:
150 build = Build.objects.create(
137 project = prj, 151 project = prj,
138 machine=build_info['machine'], 152 machine=build_info['machine'],
139 distro=build_info['distro'], 153 distro=build_info['distro'],
diff --git a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
index 920d9efcd0..da7d4af07e 100644
--- a/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
+++ b/bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py
@@ -1,6 +1,6 @@
1from django.core.management.base import NoArgsCommand, CommandError 1from django.core.management.base import NoArgsCommand, CommandError
2from django.db import transaction 2from django.db import transaction
3from orm.models import Build, ToasterSetting 3from orm.models import Build, ToasterSetting, LogMessage, Target
4from bldcontrol.bbcontroller import getBuildEnvironmentController, ShellCmdException, BuildSetupException 4from bldcontrol.bbcontroller import getBuildEnvironmentController, ShellCmdException, BuildSetupException
5from bldcontrol.models import BuildRequest, BuildEnvironment, BRError, BRVariable 5from bldcontrol.models import BuildRequest, BuildEnvironment, BRError, BRVariable
6import os 6import os
@@ -109,6 +109,36 @@ class Command(NoArgsCommand):
109 from datetime import timedelta 109 from datetime import timedelta
110 # DISABLED environments locked for more than 30 seconds - they should be unlocked 110 # DISABLED environments locked for more than 30 seconds - they should be unlocked
111 #BuildEnvironment.objects.filter(lock=BuildEnvironment.LOCK_LOCK).filter(updated__lt = timezone.now() - timedelta(seconds = 30)).update(lock = BuildEnvironment.LOCK_FREE) 111 #BuildEnvironment.objects.filter(lock=BuildEnvironment.LOCK_LOCK).filter(updated__lt = timezone.now() - timedelta(seconds = 30)).update(lock = BuildEnvironment.LOCK_FREE)
112
113
114 # update all Builds that failed to start
115
116 for br in BuildRequest.objects.filter(state = BuildRequest.REQ_FAILED):
117 br.build.outcome = Build.FAILED
118 # transpose the launch errors in ToasterExceptions
119 for brerror in br.brerror_set.all():
120 LogMessage.objects.create(build = br.build, level = LogMessage.EXCEPTION, message = brerror.errmsg)
121 br.build.save()
122
123
124
125 # update all BuildRequests without a build created
126 for br in BuildRequest.objects.filter(build = None):
127 br.build = Build.objects.create(project = br.project, completed_on = br.updated, started_on = br.created)
128 br.build.outcome = Build.REQ_FAILED
129 try:
130 br.build.machine = br.brvariable_set.get(name='MACHINE').value
131 except BRVariable.DoesNotExist:
132 pass
133 br.save()
134 # transpose target information
135 for brtarget in br.brtarget_set.all():
136 Target.objects.create(build = br.build, target= brtarget.target)
137 # transpose the launch errors in ToasterExceptions
138 for brerror in br.brerror_set.all():
139 LogMessage.objects.create(build = br.build, level = LogMessage.EXCEPTION, message = brerror.errmsg)
140
141 br.build.save()
112 pass 142 pass
113 143
114 144
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index 422f2bfd93..d97eadb592 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -201,16 +201,32 @@ class Project(models.Model):
201 commit = l.layercommit.get_vcs_reference() 201 commit = l.layercommit.get_vcs_reference()
202 print("ii Building layer ", l.layercommit.layer.name, " at vcs point ", commit) 202 print("ii Building layer ", l.layercommit.layer.name, " at vcs point ", commit)
203 BRLayer.objects.create(req = br, name = l.layercommit.layer.name, giturl = l.layercommit.layer.vcs_url, commit = commit, dirpath = l.layercommit.dirpath) 203 BRLayer.objects.create(req = br, name = l.layercommit.layer.name, giturl = l.layercommit.layer.vcs_url, commit = commit, dirpath = l.layercommit.dirpath)
204
205 br.state = BuildRequest.REQ_QUEUED
206 now = timezone.now()
207 br.build = Build.objects.create(project = self,
208 completed_on=now,
209 started_on=now,
210 )
204 for t in self.projecttarget_set.all(): 211 for t in self.projecttarget_set.all():
205 BRTarget.objects.create(req = br, target = t.target, task = t.task) 212 BRTarget.objects.create(req = br, target = t.target, task = t.task)
213 Target.objects.create(build = br.build, target = t.target)
214
206 for v in self.projectvariable_set.all(): 215 for v in self.projectvariable_set.all():
207 BRVariable.objects.create(req = br, name = v.name, value = v.value) 216 BRVariable.objects.create(req = br, name = v.name, value = v.value)
208 217
209 br.state = BuildRequest.REQ_QUEUED 218
219 try:
220 br.build.machine = self.projectvariable_set.get(name = 'MACHINE').value
221 br.build.save()
222 except ProjectVariable.DoesNotExist:
223 pass
210 br.save() 224 br.save()
211 except Exception as e: 225 except Exception as e:
212 br.delete() 226 br.delete()
213 raise e 227 import sys
228 et, ei, tb = sys.exc_info()
229 raise type(e), e, tb
214 return br 230 return br
215 231
216class Build(models.Model): 232class Build(models.Model):
@@ -250,7 +266,6 @@ class Build(models.Model):
250 return completeper 266 return completeper
251 267
252 def eta(self): 268 def eta(self):
253 from django.utils import timezone
254 eta = timezone.now() 269 eta = timezone.now()
255 completeper = self.completeper() 270 completeper = self.completeper()
256 if self.completeper() > 0: 271 if self.completeper() > 0:
@@ -266,6 +281,12 @@ class Build(models.Model):
266 def toaster_exceptions(self): 281 def toaster_exceptions(self):
267 return self.logmessage_set.filter(level=LogMessage.EXCEPTION) 282 return self.logmessage_set.filter(level=LogMessage.EXCEPTION)
268 283
284
285 def get_current_status(self):
286 if self.outcome == Build.IN_PROGRESS and self.build_name == "":
287 return "Queued"
288 return self.get_outcome_display()
289
269 def __str__(self): 290 def __str__(self):
270 return "%d %s %s" % (self.id, self.project, ",".join([t.target for t in self.target_set.all()])) 291 return "%d %s %s" % (self.id, self.project, ",".join([t.target for t in self.target_set.all()]))
271 292
@@ -299,6 +320,7 @@ class Target(models.Model):
299 search_allowed_fields = ['target', 'file_name'] 320 search_allowed_fields = ['target', 'file_name']
300 build = models.ForeignKey(Build) 321 build = models.ForeignKey(Build)
301 target = models.CharField(max_length=100) 322 target = models.CharField(max_length=100)
323 task = models.CharField(max_length=100, null=True)
302 is_image = models.BooleanField(default = False) 324 is_image = models.BooleanField(default = False)
303 image_size = models.IntegerField(default=0) 325 image_size = models.IntegerField(default=0)
304 license_manifest_path = models.CharField(max_length=500, null=True) 326 license_manifest_path = models.CharField(max_length=500, null=True)
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html
index 0f6a77b63c..1a8991fda4 100644
--- a/bitbake/lib/toaster/toastergui/templates/project.html
+++ b/bitbake/lib/toaster/toastergui/templates/project.html
@@ -114,7 +114,7 @@ vim: expandtab tabstop=2
114 114
115 <script type="text/ng-template" id="target_display"> 115 <script type="text/ng-template" id="target_display">
116 <div data-ng-switch on="t.task.length"> 116 <div data-ng-switch on="t.task.length">
117 <div data-ng-switch-when="0">{[t.target]}</div> 117 <div data-ng-switch-when="undefined">{[t.target]}</div>
118 <div data-ng-switch-default>{[t.target]}:{[t.task]}</div> 118 <div data-ng-switch-default>{[t.target]}:{[t.task]}</div>
119 </div> 119 </div>
120 </script> 120 </script>
@@ -145,13 +145,13 @@ 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="{'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
152 <case data-ng-switch-when="Failed"> 152 <case data-ng-switch-when="Failed">
153 <div class="lead span3"> 153 <div class="lead span3">
154 <a data-ng-class="{'succeeded': 'success', 'failed': 'error'}[b.status]" href="{[b.br_page_url]}"> 154 <a data-ng-class="{'Succeeded': 'success', 'Failed': 'error'}[b.status]" href="{[b.br_page_url]}">
155 <span data-ng-repeat="t in b.targets" data-ng-include src="'target_display'"></span> 155 <span data-ng-repeat="t in b.targets" data-ng-include src="'target_display'"></span>
156 </a> 156 </a>
157 </div> 157 </div>
@@ -176,12 +176,19 @@ vim: expandtab tabstop=2
176 <!-- we don't have warnings in this case --> 176 <!-- we don't have warnings in this case -->
177 </div> 177 </div>
178 <div> <span class="lead">Build time: {[b.command_time|timediff]}</span> 178 <div> <span class="lead">Build time: {[b.command_time|timediff]}</span>
179 <button class="btn pull-right" data-ng-class="{'succeeded': 'btn-success', 'failed': 'btn-danger'}[b.status]" 179 <button class="btn pull-right" data-ng-class="{'Succeeded': 'btn-success', 'Failed': 'btn-danger'}[b.status]"
180 data-ng-click="buildExistingTarget(b.targets)">Run again</button> 180 data-ng-click="buildExistingTarget(b.targets)">Run again</button>
181 181
182 </div> 182 </div>
183 </case> 183 </case>
184 184
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>
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>
189 </div>
190 <button class="btn pull-right btn-info" data-ng-click="buildCancel(b)">Cancel</button>
191 </case>
185 192
186 <case data-ng-switch-when="In Progress"> 193 <case data-ng-switch-when="In Progress">
187 <switch data-ng-switch="b.build.length"> 194 <switch data-ng-switch="b.build.length">
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 0324d17065..2336ae3bec 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -74,8 +74,8 @@ def _project_recent_build_list(prj):
74 for x in _get_latest_builds(prj): 74 for x in _get_latest_builds(prj):
75 d = { 75 d = {
76 "id": x.pk, 76 "id": x.pk,
77 "targets" : map(lambda y: {"target": y.target, "task": None }, x.target_set.all()), # TODO: create the task entry in the Target table 77 "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_outcome_display(), 78 "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)), 79 "errors": map(lambda y: {"type": y.lineno, "msg": y.message, "tb": y.pathname}, x.logmessage_set.filter(level__gte=LogMessage.WARNING)),
80 "updated": x.completed_on.strftime('%s')+"000", 80 "updated": x.completed_on.strftime('%s')+"000",
81 "command_time": (x.completed_on - x.started_on).total_seconds(), 81 "command_time": (x.completed_on - x.started_on).total_seconds(),