diff options
-rw-r--r-- | bitbake/lib/bb/ui/buildinfohelper.py | 16 | ||||
-rw-r--r-- | bitbake/lib/toaster/bldcontrol/management/commands/runbuilds.py | 32 | ||||
-rw-r--r-- | bitbake/lib/toaster/orm/models.py | 28 | ||||
-rw-r--r-- | bitbake/lib/toaster/toastergui/templates/project.html | 15 | ||||
-rwxr-xr-x | bitbake/lib/toaster/toastergui/views.py | 4 |
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 @@ | |||
1 | from django.core.management.base import NoArgsCommand, CommandError | 1 | from django.core.management.base import NoArgsCommand, CommandError |
2 | from django.db import transaction | 2 | from django.db import transaction |
3 | from orm.models import Build, ToasterSetting | 3 | from orm.models import Build, ToasterSetting, LogMessage, Target |
4 | from bldcontrol.bbcontroller import getBuildEnvironmentController, ShellCmdException, BuildSetupException | 4 | from bldcontrol.bbcontroller import getBuildEnvironmentController, ShellCmdException, BuildSetupException |
5 | from bldcontrol.models import BuildRequest, BuildEnvironment, BRError, BRVariable | 5 | from bldcontrol.models import BuildRequest, BuildEnvironment, BRError, BRVariable |
6 | import os | 6 | import 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 | ||
216 | class Build(models.Model): | 232 | class 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(), |