xref: /OK3568_Linux_fs/yocto/bitbake/bin/toaster-eventreplay (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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