123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- #!/usr/bin/env python
- # ex:ts=4:sw=4:sts=4:et
- # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
- #
- # Copyright (C) 2014 Alex Damian
- #
- # This file re-uses code spread throughout other Bitbake source files.
- # As such, all other copyrights belong to their own right holders.
- #
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License version 2 as
- # published by the Free Software Foundation.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
- # with this program; if not, write to the Free Software Foundation, Inc.,
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- # This command takes a filename as a single parameter. The filename is read
- # 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
- # mangle syspath to allow easy import of modules
- sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
- 'lib'))
- import bb.cooker
- from bb.ui import toasterui
- import sys
- import logging
- import json, pickle
- class FileReadEventsServerConnection():
- """ Emulates a connection to a bitbake server that feeds
- events coming actually read from a saved log file.
- """
- class MockConnection():
- """ fill-in for the proxy to the server. we just return generic data
- """
- def __init__(self, sc):
- self._sc = sc
- def runCommand(self, commandArray):
- """ emulates running a command on the server; only read-only commands are accepted """
- command_name = commandArray[0]
- if command_name == "getVariable":
- if commandArray[1] in self._sc._variables:
- return (self._sc._variables[commandArray[1]]['v'], None)
- return (None, "Missing variable")
- elif command_name == "getAllKeysWithFlags":
- dump = {}
- flaglist = commandArray[1]
- for k in self._sc._variables.keys():
- try:
- if not k.startswith("__"):
- v = self._sc._variables[k]['v']
- dump[k] = {
- 'v' : v ,
- 'history' : self._sc._variables[k]['history'],
- }
- for d in flaglist:
- dump[k][d] = self._sc._variables[k][d]
- except Exception as e:
- print(e)
- return (dump, None)
- else:
- raise Exception("Command %s not implemented" % commandArray[0])
- def terminateServer(self):
- """ do not do anything """
- pass
- class EventReader():
- def __init__(self, sc):
- self._sc = sc
- self.firstraise = 0
- def _create_event(self, line):
- def _import_class(name):
- assert len(name) > 0
- assert "." in name, name
- components = name.strip().split(".")
- modulename = ".".join(components[:-1])
- moduleklass = components[-1]
- module = __import__(modulename, fromlist=[str(moduleklass)])
- return getattr(module, moduleklass)
- # we build a toaster event out of current event log line
- try:
- event_data = json.loads(line.strip())
- event_class = _import_class(event_data['class'])
- event_object = pickle.loads(json.loads(event_data['vars']))
- except ValueError as e:
- print("Failed loading ", line)
- raise e
- if not isinstance(event_object, event_class):
- raise Exception("Error loading objects %s class %s ", event_object, event_class)
- return event_object
- def waitEvent(self, timeout):
- nextline = self._sc._eventfile.readline()
- if len(nextline) == 0:
- # the build data ended, while toasterui still waits for events.
- # this happens when the server was abruptly stopped, so we simulate this
- self.firstraise += 1
- if self.firstraise == 1:
- raise KeyboardInterrupt()
- else:
- return None
- else:
- self._sc.lineno += 1
- return self._create_event(nextline)
- def _readVariables(self, variableline):
- self._variables = json.loads(variableline.strip())['allvariables']
- def __init__(self, file_name):
- self.connection = FileReadEventsServerConnection.MockConnection(self)
- self._eventfile = open(file_name, "r")
- # we expect to have the variable dump at the start of the file
- self.lineno = 1
- self._readVariables(self._eventfile.readline())
- self.events = FileReadEventsServerConnection.EventReader(self)
- class MockConfigParameters():
- """ stand-in for cookerdata.ConfigParameters; as we don't really config a cooker, this
- serves just to supply needed interfaces for the toaster ui to work """
- def __init__(self):
- self.observe_only = True # we can only read files
- # run toaster ui on our mock bitbake class
- if __name__ == "__main__":
- if len(sys.argv) < 2:
- 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 and set exit code to the returned value
- sys.exit(toasterui.main(mock_connection.connection, mock_connection.events, configParams))
|