1#!/usr/bin/env python3 2# 3# Copyright (C) 2014 Alex Damian 4# 5# SPDX-License-Identifier: GPL-2.0-only 6# 7# This file re-uses code spread throughout other Bitbake source files. 8# As such, all other copyrights belong to their own right holders. 9# 10 11""" 12This command takes a filename as a single parameter. The filename is read 13as a build eventlog, and the ToasterUI is used to process events in the file 14and log data in the database 15""" 16 17import os 18import sys 19import json 20import pickle 21import codecs 22import warnings 23warnings.simplefilter("default") 24 25from collections import namedtuple 26 27# mangle syspath to allow easy import of modules 28from os.path import join, dirname, abspath 29sys.path.insert(0, join(dirname(dirname(abspath(__file__))), 'lib')) 30 31import bb.cooker 32from bb.ui import toasterui 33 34class EventPlayer: 35 """Emulate a connection to a bitbake server.""" 36 37 def __init__(self, eventfile, variables): 38 self.eventfile = eventfile 39 self.variables = variables 40 self.eventmask = [] 41 42 def waitEvent(self, _timeout): 43 """Read event from the file.""" 44 line = self.eventfile.readline().strip() 45 if not line: 46 return 47 try: 48 event_str = json.loads(line)['vars'].encode('utf-8') 49 event = pickle.loads(codecs.decode(event_str, 'base64')) 50 event_name = "%s.%s" % (event.__module__, event.__class__.__name__) 51 if event_name not in self.eventmask: 52 return 53 return event 54 except ValueError as err: 55 print("Failed loading ", line) 56 raise err 57 58 def runCommand(self, command_line): 59 """Emulate running a command on the server.""" 60 name = command_line[0] 61 62 if name == "getVariable": 63 var_name = command_line[1] 64 variable = self.variables.get(var_name) 65 if variable: 66 return variable['v'], None 67 return None, "Missing variable %s" % var_name 68 69 elif name == "getAllKeysWithFlags": 70 dump = {} 71 flaglist = command_line[1] 72 for key, val in self.variables.items(): 73 try: 74 if not key.startswith("__"): 75 dump[key] = { 76 'v': val['v'], 77 'history' : val['history'], 78 } 79 for flag in flaglist: 80 dump[key][flag] = val[flag] 81 except Exception as err: 82 print(err) 83 return (dump, None) 84 85 elif name == 'setEventMask': 86 self.eventmask = command_line[-1] 87 return True, None 88 89 else: 90 raise Exception("Command %s not implemented" % command_line[0]) 91 92 def getEventHandle(self): 93 """ 94 This method is called by toasterui. 95 The return value is passed to self.runCommand but not used there. 96 """ 97 pass 98 99def main(argv): 100 with open(argv[-1]) as eventfile: 101 # load variables from the first line 102 variables = json.loads(eventfile.readline().strip())['allvariables'] 103 104 params = namedtuple('ConfigParams', ['observe_only'])(True) 105 player = EventPlayer(eventfile, variables) 106 107 return toasterui.main(player, player, params) 108 109# run toaster ui on our mock bitbake class 110if __name__ == "__main__": 111 if len(sys.argv) != 2: 112 print("Usage: %s <event file>" % os.path.basename(sys.argv[0])) 113 sys.exit(1) 114 115 sys.exit(main(sys.argv)) 116