]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
toaster: display Toaster exceptions and other fixes
authorAlexandru DAMIAN <alexandru.damian@intel.com>
Tue, 25 Nov 2014 10:12:46 +0000 (10:12 +0000)
committerAlexandru DAMIAN <alexandru.damian@intel.com>
Thu, 27 Nov 2014 17:04:52 +0000 (17:04 +0000)
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.

Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
lib/bb/ui/buildinfohelper.py
lib/bb/ui/toasterui.py
lib/toaster/bldcontrol/management/commands/checksettings.py
lib/toaster/orm/models.py
lib/toaster/toastergui/static/js/libtoaster.js
lib/toaster/toastergui/templates/base.html
lib/toaster/toastergui/templates/builddashboard.html
lib/toaster/toastergui/views.py

index a907a0337beb1296b442db8d6893126132334d70..a3401ceda9a64846f0fafb970812b7db7097fa96 100644 (file)
@@ -381,7 +381,7 @@ class ORMWrapper(object):
                 searchname = pkgpnmap[p]['OPKGN']
 
             packagedict[p]['object'], created = Package.objects.get_or_create( build = build_obj, name = searchname )
-            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]
+            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]
                 # fill in everything we can from the runtime-reverse package data
                 try:
                     packagedict[p]['object'].recipe = recipes[pkgpnmap[p]['PN']]
@@ -462,7 +462,7 @@ class ORMWrapper(object):
         if 'OPKGN' in package_info.keys():
             pname = package_info['OPKGN']
 
-        bp_object = Package.objects.create( build = build_obj,
+        bp_object, created = Package.objects.get_or_create( build = build_obj,
                                        name = pname )
 
         bp_object.installed_name = package_info['PKG']
@@ -1043,6 +1043,15 @@ class BuildInfoHelper(object):
         mockevent.lineno = -1
         self.store_log_event(mockevent)
 
+    def store_log_exception(self, text, backtrace = ""):
+        mockevent = MockEvent()
+        mockevent.levelno = -1
+        mockevent.msg = text
+        mockevent.pathname = backtrace
+        mockevent.lineno = -1
+        self.store_log_event(mockevent)
+
+
     def store_log_event(self, event):
         if event.levelno < format.WARNING:
             return
@@ -1078,6 +1087,8 @@ class BuildInfoHelper(object):
             log_information['level'] = LogMessage.ERROR
         elif event.levelno == format.WARNING:
             log_information['level'] = LogMessage.WARNING
+        elif event.levelno == -1:   # toaster self-logging
+            log_information['level'] = -1
         else:
             log_information['level'] = LogMessage.INFO
 
index b9e8029da1880c0057e8d655860245ee3f0b0df5..9bd04df1c6846c87b15c9c9bf7f5655113bc3242 100644 (file)
@@ -299,12 +299,13 @@ def main(server, eventHandler, params ):
             logger.error(e)
             import traceback
             exception_data = traceback.format_exc()
+            print(exception_data)
 
             # save them to database, if possible; if it fails, we already logged to console.
             try:
-                buildinfohelper.store_log_error("%s\n%s" % (str(e), exception_data))
-            except Exception:
-                pass
+                buildinfohelper.store_log_exception("%s\n%s" % (str(e), exception_data))
+            except Exception as ce:
+                print("CRITICAL: failed to to save toaster exception to the database: %s" % str(ce))
 
             pass
 
index cd604eba7e432102fb42870168ff439f80fc826d..96d2d516912c82929b00bfc9b315cd0b3208e71d 100644 (file)
@@ -139,4 +139,12 @@ class Command(NoArgsCommand):
             ToasterSetting.objects.filter(name = 'DEFAULT_RELEASE').delete()
             ToasterSetting.objects.get_or_create(name = 'DEFAULT_RELEASE', value = '')
 
+        # we are just starting up. we must not have any builds in progress, or build environments taken
+        for b in BuildRequest.objects.filter(state = BuildRequest.REQ_INPROGRESS):
+            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")
+
+        BuildRequest.objects.filter(state = BuildRequest.REQ_INPROGRESS).update(state = BuildRequest.REQ_FAILED)
+
+        BuildEnvironment.objects.update(lock = BuildEnvironment.LOCK_FREE)
+
         return 0
index 364b2158147177589352f18b760f8398b3d124ef..34d37542e1054d3e20b42061c3a7353eaed916d8 100644 (file)
@@ -178,6 +178,11 @@ class Build(models.Model):
         tgts = Target.objects.filter(build_id = self.id).order_by( 'target' );
         return( tgts );
 
+    @property
+    def toaster_exceptions(self):
+        return self.logmessage_set.filter(level=LogMessage.EXCEPTION)
+
+
 class ProjectTarget(models.Model):
     project = models.ForeignKey(Project)
     target = models.CharField(max_length=100)
@@ -966,13 +971,15 @@ class HelpText(models.Model):
     text = models.TextField()
 
 class LogMessage(models.Model):
+    EXCEPTION = -1      # used to signal self-toaster-exceptions
     INFO = 0
     WARNING = 1
     ERROR = 2
 
     LOG_LEVEL = ( (INFO, "info"),
             (WARNING, "warn"),
-            (ERROR, "error") )
+            (ERROR, "error"),
+            (EXCEPTION, "toaster exception"))
 
     build = models.ForeignKey(Build)
     task  = models.ForeignKey(Task, blank = True, null=True)
index 4983ef6f6dbc6c767dc1df157c9043faa12d2d6a..8e76ecb85afb93196dceca1fcf7aa860fb7137a4 100644 (file)
@@ -252,6 +252,13 @@ $(document).ready(function() {
     $('.toggle-warnings').click(function() {
         $('#collapse-warnings').toggleClass('in');
     });
+    $('.show-exceptions').click(function() {
+        $('#collapse-exceptions').addClass('in');
+    });
+    $('.toggle-exceptions').click(function() {
+        $('#collapse-exceptions').toggleClass('in');
+    });
+
     //show warnings section when requested from the previous page
     if (location.href.search('#warnings') > -1) {
         $('#collapse-warnings').addClass('in');
index f457b91dcede2c627a8fa0ad77ba714976a4c769..8170a3db88e0348254442d12291377ad2b0b6019 100644 (file)
@@ -8,7 +8,7 @@
 <link rel="stylesheet" href="{% static 'css/font-awesome.min.css' %}" type='text/css'>
 <link rel="stylesheet" href="{% static 'css/prettify.css' %}" type='text/css'>
 <link rel="stylesheet" href="{% static 'css/default.css' %}" type='text/css'>
-<link rel="stylesheet" href="assets/css/jquery-ui-1.10.3.custom.min.css" type='text/css'>
+
 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
 <script src="{% static 'js/jquery-2.0.3.min.js' %}">
index 2aa7b6bcfbecb8ffe6b6bd18fe8f58a5ef8857ef..e68209430571662762a25fc66ef62594cbcc11b9 100644 (file)
             <span class="pull-right">Build time: <a href="{% url 'buildtime' build.pk %}">{{ build.timespent|sectohms }}</a></span>
 {%endif%}
     </div>
+    {% if build.toaster_exceptions.count > 0 %}
+    <div class="row">
+        <small class="pull-right">
+               <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>
+               <a class="show-exceptions" href="#exceptions">Toaster threw {{build.toaster_exceptions.count}} exception{{build.toaster_exceptions.count|pluralize}}</a>
+       </small>
+    </div>
+    {% endif %}
   </div>
 </div>
 
 </div>
 {% endif %}
 
+
+{% if build.toaster_exceptions.count > 0 %}
+<div class="accordion span10 pull-right" id="exceptions">
+  <div class="accordion-group">
+    <div class="accordion-heading">
+      <a class="accordion-toggle exception toggle-exceptions">
+        <h2 id="exception-toggle">
+          <i class="icon-warning-sign"></i>
+          {{build.toaster_exceptions.count}} Toaster exception{{build.toaster_exceptions.count|pluralize}}
+        </h2>
+      </a>
+    </div>
+    <div class="accordion-body collapse" id="collapse-exceptions">
+      <div class="accordion-inner">
+        <div class="span10">
+          {% for exception in build.toaster_exceptions %}
+            <div class="alert alert-exception">
+              <pre>{{exception.message}}</pre>
+            </div>
+          {% endfor %}
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+{% endif %}
+
 <script type="text/javascript">
     $(document).ready(function() {
         //show warnings section when requested from the previous page
index 11c373a84d310b44534bbe7654ead77ab3dedf6e..b13f3e813a91fd743784a84382acf555a2de4064 100755 (executable)
@@ -461,7 +461,7 @@ def builddashboard( request, build_id ):
     template = "builddashboard.html"
     if Build.objects.filter( pk=build_id ).count( ) == 0 :
         return redirect( builds )
-    build = Build.objects.filter( pk = build_id )[ 0 ];
+    build = Build.objects.get( pk = build_id );
     layerVersionId = Layer_Version.objects.filter( build = build_id );
     recipeCount = Recipe.objects.filter( layer_version__id__in = layerVersionId ).count( );
     tgts = Target.objects.filter( build_id = build_id ).order_by( 'target' );