summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2014-11-25 10:12:46 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-11-28 14:02:58 +0000
commitaf1f9fda8b295d277a6967453b2d03e43474ab68 (patch)
tree0e6f9ab6194767449872e6bc0e4011026e4cc042
parent707a960ffa20d6093ff787084e0b0f50a7b8305e (diff)
downloadpoky-af1f9fda8b295d277a6967453b2d03e43474ab68.tar.gz
bitbake: toaster: display Toaster exceptions and other fixes
Changing ToasterUI to log toaster exceptions on a different level than build errors. Updating the build dashboard to show Toaster exceptions. We add extra logging to console for exceptions. Fixed a problem where packages database entries were created instead of being looked up in the database, conficting with entries created to satisfy dependency information. Toaster now checks for invalid states at startup and performs needed cleanups. Removed loading reference to jquery-ui.min.css as we do not have this file. (Bitbake rev: 2378812bc24d433125fb940f110154f0ce638448) 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.py15
-rw-r--r--bitbake/lib/bb/ui/toasterui.py7
-rw-r--r--bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py8
-rw-r--r--bitbake/lib/toaster/orm/models.py9
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/libtoaster.js7
-rw-r--r--bitbake/lib/toaster/toastergui/templates/base.html2
-rw-r--r--bitbake/lib/toaster/toastergui/templates/builddashboard.html35
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py2
8 files changed, 77 insertions, 8 deletions
diff --git a/bitbake/lib/bb/ui/buildinfohelper.py b/bitbake/lib/bb/ui/buildinfohelper.py
index a907a0337b..a3401ceda9 100644
--- a/bitbake/lib/bb/ui/buildinfohelper.py
+++ b/bitbake/lib/bb/ui/buildinfohelper.py
@@ -381,7 +381,7 @@ class ORMWrapper(object):
381 searchname = pkgpnmap[p]['OPKGN'] 381 searchname = pkgpnmap[p]['OPKGN']
382 382
383 packagedict[p]['object'], created = Package.objects.get_or_create( build = build_obj, name = searchname ) 383 packagedict[p]['object'], created = Package.objects.get_or_create( build = build_obj, name = searchname )
384 if created or package[p]['object'].size == -1: # save the data anyway we can, not just if it was not created here; bug [YOCTO #6887] 384 if created or packagedict[p]['object'].size == -1: # save the data anyway we can, not just if it was not created here; bug [YOCTO #6887]
385 # fill in everything we can from the runtime-reverse package data 385 # fill in everything we can from the runtime-reverse package data
386 try: 386 try:
387 packagedict[p]['object'].recipe = recipes[pkgpnmap[p]['PN']] 387 packagedict[p]['object'].recipe = recipes[pkgpnmap[p]['PN']]
@@ -462,7 +462,7 @@ class ORMWrapper(object):
462 if 'OPKGN' in package_info.keys(): 462 if 'OPKGN' in package_info.keys():
463 pname = package_info['OPKGN'] 463 pname = package_info['OPKGN']
464 464
465 bp_object = Package.objects.create( build = build_obj, 465 bp_object, created = Package.objects.get_or_create( build = build_obj,
466 name = pname ) 466 name = pname )
467 467
468 bp_object.installed_name = package_info['PKG'] 468 bp_object.installed_name = package_info['PKG']
@@ -1043,6 +1043,15 @@ class BuildInfoHelper(object):
1043 mockevent.lineno = -1 1043 mockevent.lineno = -1
1044 self.store_log_event(mockevent) 1044 self.store_log_event(mockevent)
1045 1045
1046 def store_log_exception(self, text, backtrace = ""):
1047 mockevent = MockEvent()
1048 mockevent.levelno = -1
1049 mockevent.msg = text
1050 mockevent.pathname = backtrace
1051 mockevent.lineno = -1
1052 self.store_log_event(mockevent)
1053
1054
1046 def store_log_event(self, event): 1055 def store_log_event(self, event):
1047 if event.levelno < format.WARNING: 1056 if event.levelno < format.WARNING:
1048 return 1057 return
@@ -1078,6 +1087,8 @@ class BuildInfoHelper(object):
1078 log_information['level'] = LogMessage.ERROR 1087 log_information['level'] = LogMessage.ERROR
1079 elif event.levelno == format.WARNING: 1088 elif event.levelno == format.WARNING:
1080 log_information['level'] = LogMessage.WARNING 1089 log_information['level'] = LogMessage.WARNING
1090 elif event.levelno == -1: # toaster self-logging
1091 log_information['level'] = -1
1081 else: 1092 else:
1082 log_information['level'] = LogMessage.INFO 1093 log_information['level'] = LogMessage.INFO
1083 1094
diff --git a/bitbake/lib/bb/ui/toasterui.py b/bitbake/lib/bb/ui/toasterui.py
index b9e8029da1..9bd04df1c6 100644
--- a/bitbake/lib/bb/ui/toasterui.py
+++ b/bitbake/lib/bb/ui/toasterui.py
@@ -299,12 +299,13 @@ def main(server, eventHandler, params ):
299 logger.error(e) 299 logger.error(e)
300 import traceback 300 import traceback
301 exception_data = traceback.format_exc() 301 exception_data = traceback.format_exc()
302 print(exception_data)
302 303
303 # save them to database, if possible; if it fails, we already logged to console. 304 # save them to database, if possible; if it fails, we already logged to console.
304 try: 305 try:
305 buildinfohelper.store_log_error("%s\n%s" % (str(e), exception_data)) 306 buildinfohelper.store_log_exception("%s\n%s" % (str(e), exception_data))
306 except Exception: 307 except Exception as ce:
307 pass 308 print("CRITICAL: failed to to save toaster exception to the database: %s" % str(ce))
308 309
309 pass 310 pass
310 311
diff --git a/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py b/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
index cd604eba7e..96d2d51691 100644
--- a/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
+++ b/bitbake/lib/toaster/bldcontrol/management/commands/checksettings.py
@@ -139,4 +139,12 @@ class Command(NoArgsCommand):
139 ToasterSetting.objects.filter(name = 'DEFAULT_RELEASE').delete() 139 ToasterSetting.objects.filter(name = 'DEFAULT_RELEASE').delete()
140 ToasterSetting.objects.get_or_create(name = 'DEFAULT_RELEASE', value = '') 140 ToasterSetting.objects.get_or_create(name = 'DEFAULT_RELEASE', value = '')
141 141
142 # we are just starting up. we must not have any builds in progress, or build environments taken
143 for b in BuildRequest.objects.filter(state = BuildRequest.REQ_INPROGRESS):
144 BRError.objects.create(req = b, errtype = "toaster", errmsg = "Toaster found this build IN PROGRESS while Toaster started up. This is an inconsistent state, and the build was marked as failed")
145
146 BuildRequest.objects.filter(state = BuildRequest.REQ_INPROGRESS).update(state = BuildRequest.REQ_FAILED)
147
148 BuildEnvironment.objects.update(lock = BuildEnvironment.LOCK_FREE)
149
142 return 0 150 return 0
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index 364b215814..34d37542e1 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -178,6 +178,11 @@ class Build(models.Model):
178 tgts = Target.objects.filter(build_id = self.id).order_by( 'target' ); 178 tgts = Target.objects.filter(build_id = self.id).order_by( 'target' );
179 return( tgts ); 179 return( tgts );
180 180
181 @property
182 def toaster_exceptions(self):
183 return self.logmessage_set.filter(level=LogMessage.EXCEPTION)
184
185
181class ProjectTarget(models.Model): 186class ProjectTarget(models.Model):
182 project = models.ForeignKey(Project) 187 project = models.ForeignKey(Project)
183 target = models.CharField(max_length=100) 188 target = models.CharField(max_length=100)
@@ -966,13 +971,15 @@ class HelpText(models.Model):
966 text = models.TextField() 971 text = models.TextField()
967 972
968class LogMessage(models.Model): 973class LogMessage(models.Model):
974 EXCEPTION = -1 # used to signal self-toaster-exceptions
969 INFO = 0 975 INFO = 0
970 WARNING = 1 976 WARNING = 1
971 ERROR = 2 977 ERROR = 2
972 978
973 LOG_LEVEL = ( (INFO, "info"), 979 LOG_LEVEL = ( (INFO, "info"),
974 (WARNING, "warn"), 980 (WARNING, "warn"),
975 (ERROR, "error") ) 981 (ERROR, "error"),
982 (EXCEPTION, "toaster exception"))
976 983
977 build = models.ForeignKey(Build) 984 build = models.ForeignKey(Build)
978 task = models.ForeignKey(Task, blank = True, null=True) 985 task = models.ForeignKey(Task, blank = True, null=True)
diff --git a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
index 4983ef6f6d..8e76ecb85a 100644
--- a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
+++ b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
@@ -252,6 +252,13 @@ $(document).ready(function() {
252 $('.toggle-warnings').click(function() { 252 $('.toggle-warnings').click(function() {
253 $('#collapse-warnings').toggleClass('in'); 253 $('#collapse-warnings').toggleClass('in');
254 }); 254 });
255 $('.show-exceptions').click(function() {
256 $('#collapse-exceptions').addClass('in');
257 });
258 $('.toggle-exceptions').click(function() {
259 $('#collapse-exceptions').toggleClass('in');
260 });
261
255 //show warnings section when requested from the previous page 262 //show warnings section when requested from the previous page
256 if (location.href.search('#warnings') > -1) { 263 if (location.href.search('#warnings') > -1) {
257 $('#collapse-warnings').addClass('in'); 264 $('#collapse-warnings').addClass('in');
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html
index f457b91dce..8170a3db88 100644
--- a/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/bitbake/lib/toaster/toastergui/templates/base.html
@@ -8,7 +8,7 @@
8<link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}" type='text/css'> 8<link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}" type='text/css'>
9<link rel="stylesheet" href="{% static 'css/prettify.css' %}" type='text/css'> 9<link rel="stylesheet" href="{% static 'css/prettify.css' %}" type='text/css'>
10<link rel="stylesheet" href="{% static 'css/default.css' %}" type='text/css'> 10<link rel="stylesheet" href="{% static 'css/default.css' %}" type='text/css'>
11<link rel="stylesheet" href="assets/css/jquery-ui-1.10.3.custom.min.css" type='text/css'> 11
12<meta name="viewport" content="width=device-width, initial-scale=1.0" /> 12<meta name="viewport" content="width=device-width, initial-scale=1.0" />
13<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> 13<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
14<script src="{% static 'js/jquery-2.0.3.min.js' %}"> 14<script src="{% static 'js/jquery-2.0.3.min.js' %}">
diff --git a/bitbake/lib/toaster/toastergui/templates/builddashboard.html b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
index 2aa7b6bcfb..e682094305 100644
--- a/bitbake/lib/toaster/toastergui/templates/builddashboard.html
+++ b/bitbake/lib/toaster/toastergui/templates/builddashboard.html
@@ -39,6 +39,14 @@
39 <span class="pull-right">Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a></span> 39 <span class="pull-right">Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a></span>
40{%endif%} 40{%endif%}
41 </div> 41 </div>
42 {% if build.toaster_exceptions.count > 0 %}
43 <div class="row">
44 <small class="pull-right">
45 <i class="icon-question-sign get-help get-help-blue" title="" data-original-title="Toaster exceptions do not affect your build: only the operation of Toaster"></i>
46 <a class="show-exceptions" href="#exceptions">Toaster threw {{build.toaster_exceptions.count}} exception{{build.toaster_exceptions.count|pluralize}}</a>
47 </small>
48 </div>
49 {% endif %}
42 </div> 50 </div>
43</div> 51</div>
44 52
@@ -223,6 +231,33 @@
223</div> 231</div>
224{% endif %} 232{% endif %}
225 233
234
235{% if build.toaster_exceptions.count > 0 %}
236<div class="accordion span10 pull-right" id="exceptions">
237 <div class="accordion-group">
238 <div class="accordion-heading">
239 <a class="accordion-toggle exception toggle-exceptions">
240 <h2 id="exception-toggle">
241 <i class="icon-warning-sign"></i>
242 {{build.toaster_exceptions.count}} Toaster exception{{build.toaster_exceptions.count|pluralize}}
243 </h2>
244 </a>
245 </div>
246 <div class="accordion-body collapse" id="collapse-exceptions">
247 <div class="accordion-inner">
248 <div class="span10">
249 {% for exception in build.toaster_exceptions %}
250 <div class="alert alert-exception">
251 <pre>{{exception.message}}</pre>
252 </div>
253 {% endfor %}
254 </div>
255 </div>
256 </div>
257 </div>
258</div>
259{% endif %}
260
226<script type="text/javascript"> 261<script type="text/javascript">
227 $(document).ready(function() { 262 $(document).ready(function() {
228 //show warnings section when requested from the previous page 263 //show warnings section when requested from the previous page
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index 11c373a84d..b13f3e813a 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -461,7 +461,7 @@ def builddashboard( request, build_id ):
461 template = "builddashboard.html" 461 template = "builddashboard.html"
462 if Build.objects.filter( pk=build_id ).count( ) == 0 : 462 if Build.objects.filter( pk=build_id ).count( ) == 0 :
463 return redirect( builds ) 463 return redirect( builds )
464 build = Build.objects.filter( pk = build_id )[ 0 ]; 464 build = Build.objects.get( pk = build_id );
465 layerVersionId = Layer_Version.objects.filter( build = build_id ); 465 layerVersionId = Layer_Version.objects.filter( build = build_id );
466 recipeCount = Recipe.objects.filter( layer_version__id__in = layerVersionId ).count( ); 466 recipeCount = Recipe.objects.filter( layer_version__id__in = layerVersionId ).count( );
467 tgts = Target.objects.filter( build_id = build_id ).order_by( 'target' ); 467 tgts = Target.objects.filter( build_id = build_id ).order_by( 'target' );