bitbake: toasterui: proper exit code on toaster errors

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>
This commit is contained in:
Alexandru DAMIAN 2015-05-01 16:20:33 +01:00 committed by Richard Purdie
parent 4a711028c7
commit 7759cd4931
4 changed files with 19 additions and 18 deletions

View File

@ -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))

View 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):

View 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

View 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")