]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
bitbake: toasterui: proper exit code on toaster errors
authorAlexandru DAMIAN <alexandru.damian@intel.com>
Fri, 1 May 2015 15:20:33 +0000 (16:20 +0100)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Fri, 8 May 2015 16:42:05 +0000 (17:42 +0100)
This patch modifies the toasterui to properly return the exit
code based on the errors found in the toaster itself.

The upload event file API call will not delete event logs for which
toasterui showed an error. This will facilitate debugging.

Minor enhancement in the buildinfohelper to reduce the number
of lookups on unknown layer objects (prevented testing of the patch).

(Bitbake rev: 1ddd6a9e4280a4adf971132ff1fe7ec9b3252905)

Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
bitbake/bin/toaster-eventreplay
bitbake/lib/bb/ui/buildinfohelper.py
bitbake/lib/bb/ui/toasterui.py
bitbake/lib/toaster/orm/views.py

index 624829aea0f4f65618e0eabf442c246cd1e51b57..615a7aed1501eb2f5a348b6858e898e4c4a74c9f 100755 (executable)
@@ -26,6 +26,7 @@
 # as a build eventlog, and the ToasterUI is used to process events in the file
 # and log data in the database
 
+from __future__ import print_function
 import os
 import sys, logging
 
@@ -39,12 +40,6 @@ from bb.ui import toasterui
 import sys
 import logging
 
-logger = logging.getLogger(__name__)
-console = logging.StreamHandler(sys.stdout)
-format_str = "%(levelname)s: %(message)s"
-logging.basicConfig(format=format_str)
-
-
 import json, pickle
 
 
@@ -168,12 +163,12 @@ class MockConfigParameters():
 # run toaster ui on our mock bitbake class
 if __name__ == "__main__":
     if len(sys.argv) < 2:
-        logger.error("Usage: %s event.log " % sys.argv[0])
+        print("Usage: %s event.log " % sys.argv[0])
         sys.exit(1)
 
     file_name = sys.argv[-1]
     mock_connection = FileReadEventsServerConnection(file_name)
     configParams = MockConfigParameters()
 
-    # run the main program
-    toasterui.main(mock_connection.connection, mock_connection.events, configParams)
+    # run the main program and set exit code to the returned value
+    sys.exit(toasterui.main(mock_connection.connection, mock_connection.events, configParams))
index 64bd94e5e8d657698f6298092c3bcb02c4102e7f..647d663cb5a5348c06985462736a62f4498b51fe 100644 (file)
@@ -718,12 +718,15 @@ class BuildInfoHelper(object):
                             return lvo
 
         #if we get here, we didn't read layers correctly; dump whatever information we have on the error log
-        logger.error("Could not match layer version for recipe path %s : %s" % (path, self.orm_wrapper.layer_version_objects))
+        logger.warn("Could not match layer version for recipe path %s : %s" % (path, self.orm_wrapper.layer_version_objects))
 
         #mockup the new layer
         unknown_layer, created = Layer.objects.get_or_create(name="__FIXME__unidentified_layer", local_path="/", layer_index_url="")
         unknown_layer_version_obj, created = Layer_Version.objects.get_or_create(layer = unknown_layer, build = self.internal_state['build'])
 
+        # append it so we don't run into this error again and again
+        self.orm_wrapper.layer_version_objects.append(unknown_layer_version_obj)
+
         return unknown_layer_version_obj
 
     def _get_recipe_information_from_taskfile(self, taskfile):
index f0f853be14f6084d5fd685159e2889f9bda5739a..6a7a1cd174bf17ed75d2df9d662ea3b58c889b73 100644 (file)
@@ -88,7 +88,7 @@ def main(server, eventHandler, params ):
 
     if not params.observe_only:
         logger.error("ToasterUI can only work in observer mode")
-        return
+        return 1
 
 
     main.shutdown = 0
@@ -144,7 +144,6 @@ def main(server, eventHandler, params ):
                 buildinfohelper.store_log_event(event)
                 if event.levelno >= format.ERROR:
                     errors = errors + 1
-                    return_value = 1
                 elif event.levelno == format.WARNING:
                     warnings = warnings + 1
                 # For "normal" logging conditions, don't show note logs from tasks
@@ -158,7 +157,6 @@ def main(server, eventHandler, params ):
 
             if isinstance(event, bb.build.TaskFailed):
                 buildinfohelper.update_and_store_task(event)
-                return_value = 1
                 logfile = event.logfile
                 if logfile and os.path.exists(logfile):
                     bb.error("Logfile of failure stored in: %s" % logfile)
@@ -188,7 +186,6 @@ def main(server, eventHandler, params ):
                 continue
 
             if isinstance(event, bb.event.NoProvider):
-                return_value = 1
                 errors = errors + 1
                 if event._runtime:
                     r = "R"
@@ -316,6 +313,7 @@ def main(server, eventHandler, params ):
                 continue
 
             logger.error("Unknown event: %s", event)
+            return_value += 1
 
         except EnvironmentError as ioerror:
             # ignore interrupted io
@@ -344,10 +342,13 @@ def main(server, eventHandler, params ):
             except Exception as ce:
                 logger.error("CRITICAL - Failed to to save toaster exception to the database: %s" % str(ce))
 
+            # make sure we return with an error
+            return_value += 1
             pass
 
     if interrupted:
         if return_value == 0:
-            return_value = 1
+            return_value += 1
 
+    logger.warn("Return value is %d", return_value)
     return return_value
index 97d792b99e9fc3cd40fcddf56de864584d7eac0d..61d14f937550522ef4105d3fa78cbdc6fb2ce330 100644 (file)
@@ -55,6 +55,8 @@ def eventfile(request):
     scriptenv["DATABASE_URL"] = toastermain.settings.getDATABASE_URL()
 
     # run the data loading process and return the results
-    (out, err) = subprocess.Popen([import_script, abstemppath], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=scriptenv).communicate()
-    os.remove(abstemppath)
-    return HttpResponse("%s\n%s" % (out, err), content_type="text/plain;utf8")
+    importer = subprocess.Popen([import_script, abstemppath], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=scriptenv)
+    (out, err) = importer.communicate()
+    if importer.returncode == 0:
+        os.remove(abstemppath)
+    return HttpResponse("== Retval %d\n== STDOUT\n%s\n\n== STDERR\n%s" % (importer.returncode, out, err), content_type="text/plain;utf8")