summaryrefslogtreecommitdiffstats
path: root/bitbake/bin/toaster-eventreplay
blob: 80967a093406122ba1ebe2bb383ba135b137989f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python3
# 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
"""

import os
import sys
import json
import pickle
import codecs

from collections import namedtuple

# mangle syspath to allow easy import of modules
from os.path import join, dirname, abspath
sys.path.insert(0, join(dirname(dirname(abspath(__file__))), 'lib'))

import bb.cooker
from bb.ui import toasterui

class EventPlayer:
    """Emulate a connection to a bitbake server."""

    def __init__(self, eventfile, variables):
        self.eventfile = eventfile
        self.variables = variables
        self.eventmask = []

    def waitEvent(self, _timeout):
        """Read event from the file."""
        line = self.eventfile.readline().strip()
        if not line:
            return
        try:
            event_str = json.loads(line)['vars'].encode('utf-8')
            event = pickle.loads(codecs.decode(event_str, 'base64'))
            event_name = "%s.%s" % (event.__module__, event.__class__.__name__)
            if event_name not in self.eventmask:
                return
            return event
        except ValueError as err:
            print("Failed loading ", line)
            raise err

    def runCommand(self, command_line):
        """Emulate running a command on the server."""
        name = command_line[0]

        if name == "getVariable":
            var_name = command_line[1]
            variable = self.variables.get(var_name)
            if variable:
                return variable['v'], None
            return None, "Missing variable %s" % var_name

        elif name == "getAllKeysWithFlags":
            dump = {}
            flaglist = command_line[1]
            for key, val in self.variables.items():
                try:
                    if not key.startswith("__"):
                        dump[key] = {
                            'v': val['v'],
                            'history' : val['history'],
                        }
                        for flag in flaglist:
                            dump[key][flag] = val[flag]
                except Exception as err:
                    print(err)
            return (dump, None)

        elif name == 'setEventMask':
            self.eventmask = command_line[-1]
            return True, None

        else:
            raise Exception("Command %s not implemented" % command_line[0])

    def getEventHandle(self):
        """
        This method is called by toasterui.
        The return value is passed to self.runCommand but not used there.
        """
        pass

def main(argv):
    with open(argv[-1]) as eventfile:
        # load variables from the first line
        variables = json.loads(eventfile.readline().strip())['allvariables']

        params = namedtuple('ConfigParams', ['observe_only'])(True)
        player = EventPlayer(eventfile, variables)

        return toasterui.main(player, player, params)

# run toaster ui on our mock bitbake class
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: %s <event file>" % os.path.basename(sys.argv[0]))
        sys.exit(1)

    sys.exit(main(sys.argv))