xref: /openbmc/openbmc/poky/bitbake/lib/bb/event.py (revision 705982a5)
1eb8dc403SDave Cobbley"""
2eb8dc403SDave CobbleyBitBake 'Event' implementation
3eb8dc403SDave Cobbley
4eb8dc403SDave CobbleyClasses and functions for manipulating 'events' in the
5eb8dc403SDave CobbleyBitBake build tools.
6eb8dc403SDave Cobbley"""
7eb8dc403SDave Cobbley
8eb8dc403SDave Cobbley# Copyright (C) 2003, 2004  Chris Larson
9eb8dc403SDave Cobbley#
10c342db35SBrad Bishop# SPDX-License-Identifier: GPL-2.0-only
11eb8dc403SDave Cobbley#
12eb8dc403SDave Cobbley
13eb8dc403SDave Cobbleyimport ast
14c9f7865aSAndrew Geisslerimport atexit
15c9f7865aSAndrew Geisslerimport collections
16c9f7865aSAndrew Geisslerimport logging
17c9f7865aSAndrew Geisslerimport pickle
18c9f7865aSAndrew Geisslerimport sys
19eb8dc403SDave Cobbleyimport threading
20c9f7865aSAndrew Geisslerimport traceback
21eb8dc403SDave Cobbley
22eb8dc403SDave Cobbleyimport bb.exceptions
23c9f7865aSAndrew Geisslerimport bb.utils
24eb8dc403SDave Cobbley
25eb8dc403SDave Cobbley# This is the pid for which we should generate the event. This is set when
26eb8dc403SDave Cobbley# the runqueue forks off.
27eb8dc403SDave Cobbleyworker_pid = 0
28eb8dc403SDave Cobbleyworker_fire = None
29eb8dc403SDave Cobbley
30eb8dc403SDave Cobbleylogger = logging.getLogger('BitBake.Event')
31eb8dc403SDave Cobbley
32eb8dc403SDave Cobbleyclass Event(object):
33eb8dc403SDave Cobbley    """Base class for events"""
34eb8dc403SDave Cobbley
35eb8dc403SDave Cobbley    def __init__(self):
36eb8dc403SDave Cobbley        self.pid = worker_pid
37eb8dc403SDave Cobbley
38eb8dc403SDave Cobbley
39eb8dc403SDave Cobbleyclass HeartbeatEvent(Event):
40eb8dc403SDave Cobbley    """Triggered at regular time intervals of 10 seconds. Other events can fire much more often
41eb8dc403SDave Cobbley       (runQueueTaskStarted when there are many short tasks) or not at all for long periods
42eb8dc403SDave Cobbley       of time (again runQueueTaskStarted, when there is just one long-running task), so this
437e0e3c0cSAndrew Geissler       event is more suitable for doing some task-independent work occasionally."""
44eb8dc403SDave Cobbley    def __init__(self, time):
45eb8dc403SDave Cobbley        Event.__init__(self)
46eb8dc403SDave Cobbley        self.time = time
47eb8dc403SDave Cobbley
48eb8dc403SDave CobbleyRegistered        = 10
49eb8dc403SDave CobbleyAlreadyRegistered = 14
50eb8dc403SDave Cobbley
51eb8dc403SDave Cobbleydef get_class_handlers():
52eb8dc403SDave Cobbley    return _handlers
53eb8dc403SDave Cobbley
54eb8dc403SDave Cobbleydef set_class_handlers(h):
55eb8dc403SDave Cobbley    global _handlers
56eb8dc403SDave Cobbley    _handlers = h
57eb8dc403SDave Cobbley
58eb8dc403SDave Cobbleydef clean_class_handlers():
59c9f7865aSAndrew Geissler    return collections.OrderedDict()
60eb8dc403SDave Cobbley
61eb8dc403SDave Cobbley# Internal
62eb8dc403SDave Cobbley_handlers = clean_class_handlers()
63eb8dc403SDave Cobbley_ui_handlers = {}
64eb8dc403SDave Cobbley_ui_logfilters = {}
65eb8dc403SDave Cobbley_ui_handler_seq = 0
66eb8dc403SDave Cobbley_event_handler_map = {}
67eb8dc403SDave Cobbley_catchall_handlers = {}
68eb8dc403SDave Cobbley_eventfilter = None
69eb8dc403SDave Cobbley_uiready = False
70eb8dc403SDave Cobbley_thread_lock = threading.Lock()
71517393d9SAndrew Geissler_heartbeat_enabled = False
726aa7eec5SAndrew Geissler_should_exit = threading.Event()
73eb8dc403SDave Cobbley
74eb8dc403SDave Cobbleydef enable_threadlock():
75517393d9SAndrew Geissler    # Always needed now
76517393d9SAndrew Geissler    return
77eb8dc403SDave Cobbley
78eb8dc403SDave Cobbleydef disable_threadlock():
79517393d9SAndrew Geissler    # Always needed now
80517393d9SAndrew Geissler    return
81517393d9SAndrew Geissler
82517393d9SAndrew Geisslerdef enable_heartbeat():
83517393d9SAndrew Geissler    global _heartbeat_enabled
84517393d9SAndrew Geissler    _heartbeat_enabled = True
85517393d9SAndrew Geissler
86517393d9SAndrew Geisslerdef disable_heartbeat():
87517393d9SAndrew Geissler    global _heartbeat_enabled
88517393d9SAndrew Geissler    _heartbeat_enabled = False
89eb8dc403SDave Cobbley
906aa7eec5SAndrew Geissler#
916aa7eec5SAndrew Geissler# In long running code, this function should be called periodically
926aa7eec5SAndrew Geissler# to check if we should exit due to an interuption (.e.g Ctrl+C from the UI)
936aa7eec5SAndrew Geissler#
946aa7eec5SAndrew Geisslerdef check_for_interrupts(d):
956aa7eec5SAndrew Geissler    global _should_exit
966aa7eec5SAndrew Geissler    if _should_exit.is_set():
976aa7eec5SAndrew Geissler        bb.warn("Exiting due to interrupt.")
986aa7eec5SAndrew Geissler        raise bb.BBHandledException()
996aa7eec5SAndrew Geissler
100eb8dc403SDave Cobbleydef execute_handler(name, handler, event, d):
101eb8dc403SDave Cobbley    event.data = d
102eb8dc403SDave Cobbley    try:
103517393d9SAndrew Geissler        ret = handler(event, d)
104eb8dc403SDave Cobbley    except (bb.parse.SkipRecipe, bb.BBHandledException):
105eb8dc403SDave Cobbley        raise
106eb8dc403SDave Cobbley    except Exception:
107eb8dc403SDave Cobbley        etype, value, tb = sys.exc_info()
108eb8dc403SDave Cobbley        logger.error("Execution of event handler '%s' failed" % name,
109eb8dc403SDave Cobbley                        exc_info=(etype, value, tb.tb_next))
110eb8dc403SDave Cobbley        raise
111eb8dc403SDave Cobbley    except SystemExit as exc:
112eb8dc403SDave Cobbley        if exc.code != 0:
113eb8dc403SDave Cobbley            logger.error("Execution of event handler '%s' failed" % name)
114eb8dc403SDave Cobbley        raise
115eb8dc403SDave Cobbley    finally:
116eb8dc403SDave Cobbley        del event.data
117517393d9SAndrew Geissler
118eb8dc403SDave Cobbley
119eb8dc403SDave Cobbleydef fire_class_handlers(event, d):
120eb8dc403SDave Cobbley    if isinstance(event, logging.LogRecord):
121eb8dc403SDave Cobbley        return
122eb8dc403SDave Cobbley
123eb8dc403SDave Cobbley    eid = str(event.__class__)[8:-2]
124eb8dc403SDave Cobbley    evt_hmap = _event_handler_map.get(eid, {})
125eb8dc403SDave Cobbley    for name, handler in list(_handlers.items()):
126eb8dc403SDave Cobbley        if name in _catchall_handlers or name in evt_hmap:
127eb8dc403SDave Cobbley            if _eventfilter:
128eb8dc403SDave Cobbley                if not _eventfilter(name, handler, event, d):
129eb8dc403SDave Cobbley                    continue
13095ac1b8dSAndrew Geissler            if d is not None and not name in (d.getVar("__BBHANDLERS_MC") or set()):
1319b4d8b0eSAndrew Geissler                continue
132eb8dc403SDave Cobbley            execute_handler(name, handler, event, d)
133eb8dc403SDave Cobbley
134eb8dc403SDave Cobbleyui_queue = []
135eb8dc403SDave Cobbley@atexit.register
136eb8dc403SDave Cobbleydef print_ui_queue():
13796ff1984SBrad Bishop    global ui_queue
138eb8dc403SDave Cobbley    """If we're exiting before a UI has been spawned, display any queued
139eb8dc403SDave Cobbley    LogRecords to the console."""
140eb8dc403SDave Cobbley    logger = logging.getLogger("BitBake")
141eb8dc403SDave Cobbley    if not _uiready:
142eb8dc403SDave Cobbley        from bb.msg import BBLogFormatter
1431a4b7ee2SBrad Bishop        # Flush any existing buffered content
14478b72798SAndrew Geissler        try:
1451a4b7ee2SBrad Bishop            sys.stdout.flush()
14678b72798SAndrew Geissler        except:
14778b72798SAndrew Geissler            pass
14878b72798SAndrew Geissler        try:
1491a4b7ee2SBrad Bishop            sys.stderr.flush()
15078b72798SAndrew Geissler        except:
15178b72798SAndrew Geissler            pass
152eb8dc403SDave Cobbley        stdout = logging.StreamHandler(sys.stdout)
153eb8dc403SDave Cobbley        stderr = logging.StreamHandler(sys.stderr)
154eb8dc403SDave Cobbley        formatter = BBLogFormatter("%(levelname)s: %(message)s")
155eb8dc403SDave Cobbley        stdout.setFormatter(formatter)
156eb8dc403SDave Cobbley        stderr.setFormatter(formatter)
157eb8dc403SDave Cobbley
158eb8dc403SDave Cobbley        # First check to see if we have any proper messages
159eb8dc403SDave Cobbley        msgprint = False
160eb8dc403SDave Cobbley        msgerrs = False
161eb8dc403SDave Cobbley
162eb8dc403SDave Cobbley        # Should we print to stderr?
163eb8dc403SDave Cobbley        for event in ui_queue[:]:
164eb8dc403SDave Cobbley            if isinstance(event, logging.LogRecord) and event.levelno >= logging.WARNING:
165eb8dc403SDave Cobbley                msgerrs = True
166eb8dc403SDave Cobbley                break
167eb8dc403SDave Cobbley
168eb8dc403SDave Cobbley        if msgerrs:
169eb8dc403SDave Cobbley            logger.addHandler(stderr)
170eb8dc403SDave Cobbley        else:
171eb8dc403SDave Cobbley            logger.addHandler(stdout)
172eb8dc403SDave Cobbley
173eb8dc403SDave Cobbley        for event in ui_queue[:]:
174eb8dc403SDave Cobbley            if isinstance(event, logging.LogRecord):
175eb8dc403SDave Cobbley                if event.levelno > logging.DEBUG:
176eb8dc403SDave Cobbley                    logger.handle(event)
177eb8dc403SDave Cobbley                    msgprint = True
178eb8dc403SDave Cobbley
179eb8dc403SDave Cobbley        # Nope, so just print all of the messages we have (including debug messages)
180eb8dc403SDave Cobbley        if not msgprint:
181eb8dc403SDave Cobbley            for event in ui_queue[:]:
182eb8dc403SDave Cobbley                if isinstance(event, logging.LogRecord):
183eb8dc403SDave Cobbley                    logger.handle(event)
184eb8dc403SDave Cobbley        if msgerrs:
185eb8dc403SDave Cobbley            logger.removeHandler(stderr)
186eb8dc403SDave Cobbley        else:
187eb8dc403SDave Cobbley            logger.removeHandler(stdout)
18896ff1984SBrad Bishop        ui_queue = []
189eb8dc403SDave Cobbley
190eb8dc403SDave Cobbleydef fire_ui_handlers(event, d):
191eb8dc403SDave Cobbley    global _thread_lock
192eb8dc403SDave Cobbley
193eb8dc403SDave Cobbley    if not _uiready:
194eb8dc403SDave Cobbley        # No UI handlers registered yet, queue up the messages
195eb8dc403SDave Cobbley        ui_queue.append(event)
196eb8dc403SDave Cobbley        return
197eb8dc403SDave Cobbley
198517393d9SAndrew Geissler    with bb.utils.lock_timeout(_thread_lock):
199eb8dc403SDave Cobbley        errors = []
200eb8dc403SDave Cobbley        for h in _ui_handlers:
201eb8dc403SDave Cobbley            #print "Sending event %s" % event
202eb8dc403SDave Cobbley            try:
203eb8dc403SDave Cobbley                 if not _ui_logfilters[h].filter(event):
204eb8dc403SDave Cobbley                     continue
205eb8dc403SDave Cobbley                 # We use pickle here since it better handles object instances
206eb8dc403SDave Cobbley                 # which xmlrpc's marshaller does not. Events *must* be serializable
207eb8dc403SDave Cobbley                 # by pickle.
208eb8dc403SDave Cobbley                 if hasattr(_ui_handlers[h].event, "sendpickle"):
209eb8dc403SDave Cobbley                    _ui_handlers[h].event.sendpickle((pickle.dumps(event)))
210eb8dc403SDave Cobbley                 else:
211eb8dc403SDave Cobbley                    _ui_handlers[h].event.send(event)
212eb8dc403SDave Cobbley            except:
213eb8dc403SDave Cobbley                errors.append(h)
214eb8dc403SDave Cobbley        for h in errors:
215eb8dc403SDave Cobbley            del _ui_handlers[h]
216eb8dc403SDave Cobbley
217eb8dc403SDave Cobbleydef fire(event, d):
218eb8dc403SDave Cobbley    """Fire off an Event"""
219eb8dc403SDave Cobbley
220eb8dc403SDave Cobbley    # We can fire class handlers in the worker process context and this is
221eb8dc403SDave Cobbley    # desired so they get the task based datastore.
222eb8dc403SDave Cobbley    # UI handlers need to be fired in the server context so we defer this. They
223eb8dc403SDave Cobbley    # don't have a datastore so the datastore context isn't a problem.
224eb8dc403SDave Cobbley
225eb8dc403SDave Cobbley    fire_class_handlers(event, d)
226eb8dc403SDave Cobbley    if worker_fire:
227eb8dc403SDave Cobbley        worker_fire(event, d)
228eb8dc403SDave Cobbley    else:
229eb8dc403SDave Cobbley        # If messages have been queued up, clear the queue
230eb8dc403SDave Cobbley        global _uiready, ui_queue
231eb8dc403SDave Cobbley        if _uiready and ui_queue:
232eb8dc403SDave Cobbley            for queue_event in ui_queue:
233eb8dc403SDave Cobbley                fire_ui_handlers(queue_event, d)
234eb8dc403SDave Cobbley            ui_queue = []
235eb8dc403SDave Cobbley        fire_ui_handlers(event, d)
236eb8dc403SDave Cobbley
237eb8dc403SDave Cobbleydef fire_from_worker(event, d):
238eb8dc403SDave Cobbley    fire_ui_handlers(event, d)
239eb8dc403SDave Cobbley
240eb8dc403SDave Cobbleynoop = lambda _: None
2419b4d8b0eSAndrew Geisslerdef register(name, handler, mask=None, filename=None, lineno=None, data=None):
242eb8dc403SDave Cobbley    """Register an Event handler"""
243eb8dc403SDave Cobbley
24495ac1b8dSAndrew Geissler    if data is not None and data.getVar("BB_CURRENT_MC"):
2459b4d8b0eSAndrew Geissler        mc = data.getVar("BB_CURRENT_MC")
24690fd73cbSAndrew Geissler        name = '%s%s' % (mc.replace('-', '_'), name)
2479b4d8b0eSAndrew Geissler
248eb8dc403SDave Cobbley    # already registered
249eb8dc403SDave Cobbley    if name in _handlers:
25095ac1b8dSAndrew Geissler        if data is not None:
25195ac1b8dSAndrew Geissler            bbhands_mc = (data.getVar("__BBHANDLERS_MC") or set())
25295ac1b8dSAndrew Geissler            bbhands_mc.add(name)
25395ac1b8dSAndrew Geissler            data.setVar("__BBHANDLERS_MC", bbhands_mc)
254eb8dc403SDave Cobbley        return AlreadyRegistered
255eb8dc403SDave Cobbley
256eb8dc403SDave Cobbley    if handler is not None:
257eb8dc403SDave Cobbley        # handle string containing python code
258eb8dc403SDave Cobbley        if isinstance(handler, str):
259517393d9SAndrew Geissler            tmp = "def %s(e, d):\n%s" % (name, handler)
260*705982a5SPatrick Williams            # Inject empty lines to make code match lineno in filename
261*705982a5SPatrick Williams            if lineno is not None:
262*705982a5SPatrick Williams                tmp = "\n" * (lineno-1) + tmp
263eb8dc403SDave Cobbley            try:
264eb8dc403SDave Cobbley                code = bb.methodpool.compile_cache(tmp)
265eb8dc403SDave Cobbley                if not code:
266eb8dc403SDave Cobbley                    if filename is None:
267517393d9SAndrew Geissler                        filename = "%s(e, d)" % name
268eb8dc403SDave Cobbley                    code = compile(tmp, filename, "exec", ast.PyCF_ONLY_AST)
269eb8dc403SDave Cobbley                    code = compile(code, filename, "exec")
270eb8dc403SDave Cobbley                    bb.methodpool.compile_cache_add(tmp, code)
271eb8dc403SDave Cobbley            except SyntaxError:
272eb8dc403SDave Cobbley                logger.error("Unable to register event handler '%s':\n%s", name,
273eb8dc403SDave Cobbley                             ''.join(traceback.format_exc(limit=0)))
274eb8dc403SDave Cobbley                _handlers[name] = noop
275eb8dc403SDave Cobbley                return
276eb8dc403SDave Cobbley            env = {}
277eb8dc403SDave Cobbley            bb.utils.better_exec(code, env)
278eb8dc403SDave Cobbley            func = bb.utils.better_eval(name, env)
279eb8dc403SDave Cobbley            _handlers[name] = func
280eb8dc403SDave Cobbley        else:
281eb8dc403SDave Cobbley            _handlers[name] = handler
282eb8dc403SDave Cobbley
283eb8dc403SDave Cobbley        if not mask or '*' in mask:
284eb8dc403SDave Cobbley            _catchall_handlers[name] = True
285eb8dc403SDave Cobbley        else:
286eb8dc403SDave Cobbley            for m in mask:
287eb8dc403SDave Cobbley                if _event_handler_map.get(m, None) is None:
288eb8dc403SDave Cobbley                    _event_handler_map[m] = {}
289eb8dc403SDave Cobbley                _event_handler_map[m][name] = True
290eb8dc403SDave Cobbley
29195ac1b8dSAndrew Geissler        if data is not None:
29295ac1b8dSAndrew Geissler            bbhands_mc = (data.getVar("__BBHANDLERS_MC") or set())
29395ac1b8dSAndrew Geissler            bbhands_mc.add(name)
2949b4d8b0eSAndrew Geissler            data.setVar("__BBHANDLERS_MC", bbhands_mc)
2959b4d8b0eSAndrew Geissler
296eb8dc403SDave Cobbley        return Registered
297eb8dc403SDave Cobbley
2989b4d8b0eSAndrew Geisslerdef remove(name, handler, data=None):
299eb8dc403SDave Cobbley    """Remove an Event handler"""
30095ac1b8dSAndrew Geissler    if data is not None:
3019b4d8b0eSAndrew Geissler        if data.getVar("BB_CURRENT_MC"):
3029b4d8b0eSAndrew Geissler            mc = data.getVar("BB_CURRENT_MC")
30390fd73cbSAndrew Geissler            name = '%s%s' % (mc.replace('-', '_'), name)
3049b4d8b0eSAndrew Geissler
305eb8dc403SDave Cobbley    _handlers.pop(name)
306eb8dc403SDave Cobbley    if name in _catchall_handlers:
307eb8dc403SDave Cobbley        _catchall_handlers.pop(name)
308eb8dc403SDave Cobbley    for event in _event_handler_map.keys():
309eb8dc403SDave Cobbley        if name in _event_handler_map[event]:
310eb8dc403SDave Cobbley            _event_handler_map[event].pop(name)
311eb8dc403SDave Cobbley
31295ac1b8dSAndrew Geissler    if data is not None:
31395ac1b8dSAndrew Geissler        bbhands_mc = (data.getVar("__BBHANDLERS_MC") or set())
3149b4d8b0eSAndrew Geissler        if name in bbhands_mc:
3159b4d8b0eSAndrew Geissler            bbhands_mc.remove(name)
3169b4d8b0eSAndrew Geissler            data.setVar("__BBHANDLERS_MC", bbhands_mc)
3179b4d8b0eSAndrew Geissler
318eb8dc403SDave Cobbleydef get_handlers():
319eb8dc403SDave Cobbley    return _handlers
320eb8dc403SDave Cobbley
321eb8dc403SDave Cobbleydef set_handlers(handlers):
322eb8dc403SDave Cobbley    global _handlers
323eb8dc403SDave Cobbley    _handlers = handlers
324eb8dc403SDave Cobbley
325eb8dc403SDave Cobbleydef set_eventfilter(func):
326eb8dc403SDave Cobbley    global _eventfilter
327eb8dc403SDave Cobbley    _eventfilter = func
328eb8dc403SDave Cobbley
329eb8dc403SDave Cobbleydef register_UIHhandler(handler, mainui=False):
330517393d9SAndrew Geissler    with bb.utils.lock_timeout(_thread_lock):
331eb8dc403SDave Cobbley        bb.event._ui_handler_seq = bb.event._ui_handler_seq + 1
332eb8dc403SDave Cobbley        _ui_handlers[_ui_handler_seq] = handler
333eb8dc403SDave Cobbley        level, debug_domains = bb.msg.constructLogOptions()
334eb8dc403SDave Cobbley        _ui_logfilters[_ui_handler_seq] = UIEventFilter(level, debug_domains)
335eb8dc403SDave Cobbley        if mainui:
336eb8dc403SDave Cobbley            global _uiready
337eb8dc403SDave Cobbley            _uiready = _ui_handler_seq
338eb8dc403SDave Cobbley        return _ui_handler_seq
339eb8dc403SDave Cobbley
340eb8dc403SDave Cobbleydef unregister_UIHhandler(handlerNum, mainui=False):
341eb8dc403SDave Cobbley    if mainui:
342eb8dc403SDave Cobbley        global _uiready
343eb8dc403SDave Cobbley        _uiready = False
344517393d9SAndrew Geissler    with bb.utils.lock_timeout(_thread_lock):
345eb8dc403SDave Cobbley        if handlerNum in _ui_handlers:
346eb8dc403SDave Cobbley            del _ui_handlers[handlerNum]
347eb8dc403SDave Cobbley    return
348eb8dc403SDave Cobbley
349eb8dc403SDave Cobbleydef get_uihandler():
350eb8dc403SDave Cobbley    if _uiready is False:
351eb8dc403SDave Cobbley        return None
352eb8dc403SDave Cobbley    return _uiready
353eb8dc403SDave Cobbley
354eb8dc403SDave Cobbley# Class to allow filtering of events and specific filtering of LogRecords *before* we put them over the IPC
355eb8dc403SDave Cobbleyclass UIEventFilter(object):
356eb8dc403SDave Cobbley    def __init__(self, level, debug_domains):
357eb8dc403SDave Cobbley        self.update(None, level, debug_domains)
358eb8dc403SDave Cobbley
359eb8dc403SDave Cobbley    def update(self, eventmask, level, debug_domains):
360eb8dc403SDave Cobbley        self.eventmask = eventmask
361eb8dc403SDave Cobbley        self.stdlevel = level
362eb8dc403SDave Cobbley        self.debug_domains = debug_domains
363eb8dc403SDave Cobbley
364eb8dc403SDave Cobbley    def filter(self, event):
365eb8dc403SDave Cobbley        if isinstance(event, logging.LogRecord):
366eb8dc403SDave Cobbley            if event.levelno >= self.stdlevel:
367eb8dc403SDave Cobbley                return True
368eb8dc403SDave Cobbley            if event.name in self.debug_domains and event.levelno >= self.debug_domains[event.name]:
369eb8dc403SDave Cobbley                return True
370eb8dc403SDave Cobbley            return False
371eb8dc403SDave Cobbley        eid = str(event.__class__)[8:-2]
372eb8dc403SDave Cobbley        if self.eventmask and eid not in self.eventmask:
373eb8dc403SDave Cobbley            return False
374eb8dc403SDave Cobbley        return True
375eb8dc403SDave Cobbley
376eb8dc403SDave Cobbleydef set_UIHmask(handlerNum, level, debug_domains, mask):
377eb8dc403SDave Cobbley    if not handlerNum in _ui_handlers:
378eb8dc403SDave Cobbley        return False
379eb8dc403SDave Cobbley    if '*' in mask:
380eb8dc403SDave Cobbley        _ui_logfilters[handlerNum].update(None, level, debug_domains)
381eb8dc403SDave Cobbley    else:
382eb8dc403SDave Cobbley        _ui_logfilters[handlerNum].update(mask, level, debug_domains)
383eb8dc403SDave Cobbley    return True
384eb8dc403SDave Cobbley
385eb8dc403SDave Cobbleydef getName(e):
386eb8dc403SDave Cobbley    """Returns the name of a class or class instance"""
38782c905dcSAndrew Geissler    if getattr(e, "__name__", None) is None:
388eb8dc403SDave Cobbley        return e.__class__.__name__
389eb8dc403SDave Cobbley    else:
390eb8dc403SDave Cobbley        return e.__name__
391eb8dc403SDave Cobbley
392eb8dc403SDave Cobbleyclass OperationStarted(Event):
393eb8dc403SDave Cobbley    """An operation has begun"""
394eb8dc403SDave Cobbley    def __init__(self, msg = "Operation Started"):
395eb8dc403SDave Cobbley        Event.__init__(self)
396eb8dc403SDave Cobbley        self.msg = msg
397eb8dc403SDave Cobbley
398eb8dc403SDave Cobbleyclass OperationCompleted(Event):
399eb8dc403SDave Cobbley    """An operation has completed"""
400eb8dc403SDave Cobbley    def __init__(self, total, msg = "Operation Completed"):
401eb8dc403SDave Cobbley        Event.__init__(self)
402eb8dc403SDave Cobbley        self.total = total
403eb8dc403SDave Cobbley        self.msg = msg
404eb8dc403SDave Cobbley
405eb8dc403SDave Cobbleyclass OperationProgress(Event):
406eb8dc403SDave Cobbley    """An operation is in progress"""
407eb8dc403SDave Cobbley    def __init__(self, current, total, msg = "Operation in Progress"):
408eb8dc403SDave Cobbley        Event.__init__(self)
409eb8dc403SDave Cobbley        self.current = current
410eb8dc403SDave Cobbley        self.total = total
411eb8dc403SDave Cobbley        self.msg = msg + ": %s/%s" % (current, total);
412eb8dc403SDave Cobbley
413eb8dc403SDave Cobbleyclass ConfigParsed(Event):
414eb8dc403SDave Cobbley    """Configuration Parsing Complete"""
415eb8dc403SDave Cobbley
416eb8dc403SDave Cobbleyclass MultiConfigParsed(Event):
417eb8dc403SDave Cobbley    """Multi-Config Parsing Complete"""
418eb8dc403SDave Cobbley    def __init__(self, mcdata):
419eb8dc403SDave Cobbley        self.mcdata = mcdata
420eb8dc403SDave Cobbley        Event.__init__(self)
421eb8dc403SDave Cobbley
422eb8dc403SDave Cobbleyclass RecipeEvent(Event):
423eb8dc403SDave Cobbley    def __init__(self, fn):
424eb8dc403SDave Cobbley        self.fn = fn
425eb8dc403SDave Cobbley        Event.__init__(self)
426eb8dc403SDave Cobbley
427eb8dc403SDave Cobbleyclass RecipePreFinalise(RecipeEvent):
4281a4b7ee2SBrad Bishop    """ Recipe Parsing Complete but not yet finalised"""
429eb8dc403SDave Cobbley
4301e34c2d0SAndrew Geisslerclass RecipePostKeyExpansion(RecipeEvent):
4311e34c2d0SAndrew Geissler    """ Recipe Parsing Complete but not yet finalised"""
4321e34c2d0SAndrew Geissler
4331e34c2d0SAndrew Geissler
434eb8dc403SDave Cobbleyclass RecipeTaskPreProcess(RecipeEvent):
435eb8dc403SDave Cobbley    """
436eb8dc403SDave Cobbley    Recipe Tasks about to be finalised
437eb8dc403SDave Cobbley    The list of tasks should be final at this point and handlers
438eb8dc403SDave Cobbley    are only able to change interdependencies
439eb8dc403SDave Cobbley    """
440eb8dc403SDave Cobbley    def __init__(self, fn, tasklist):
441eb8dc403SDave Cobbley        self.fn = fn
442eb8dc403SDave Cobbley        self.tasklist = tasklist
443eb8dc403SDave Cobbley        Event.__init__(self)
444eb8dc403SDave Cobbley
445eb8dc403SDave Cobbleyclass RecipeParsed(RecipeEvent):
446eb8dc403SDave Cobbley    """ Recipe Parsing Complete """
447eb8dc403SDave Cobbley
448eb8dc403SDave Cobbleyclass BuildBase(Event):
449eb8dc403SDave Cobbley    """Base class for bitbake build events"""
450eb8dc403SDave Cobbley
451eb8dc403SDave Cobbley    def __init__(self, n, p, failures = 0):
452eb8dc403SDave Cobbley        self._name = n
453eb8dc403SDave Cobbley        self._pkgs = p
454eb8dc403SDave Cobbley        Event.__init__(self)
455eb8dc403SDave Cobbley        self._failures = failures
456eb8dc403SDave Cobbley
457eb8dc403SDave Cobbley    def getPkgs(self):
458eb8dc403SDave Cobbley        return self._pkgs
459eb8dc403SDave Cobbley
460eb8dc403SDave Cobbley    def setPkgs(self, pkgs):
461eb8dc403SDave Cobbley        self._pkgs = pkgs
462eb8dc403SDave Cobbley
463eb8dc403SDave Cobbley    def getName(self):
464eb8dc403SDave Cobbley        return self._name
465eb8dc403SDave Cobbley
466eb8dc403SDave Cobbley    def setName(self, name):
467eb8dc403SDave Cobbley        self._name = name
468eb8dc403SDave Cobbley
469eb8dc403SDave Cobbley    def getFailures(self):
470eb8dc403SDave Cobbley        """
471eb8dc403SDave Cobbley        Return the number of failed packages
472eb8dc403SDave Cobbley        """
473eb8dc403SDave Cobbley        return self._failures
474eb8dc403SDave Cobbley
475eb8dc403SDave Cobbley    pkgs = property(getPkgs, setPkgs, None, "pkgs property")
476eb8dc403SDave Cobbley    name = property(getName, setName, None, "name property")
477eb8dc403SDave Cobbley
478eb8dc403SDave Cobbleyclass BuildInit(BuildBase):
479eb8dc403SDave Cobbley    """buildFile or buildTargets was invoked"""
480eb8dc403SDave Cobbley    def __init__(self, p=[]):
481eb8dc403SDave Cobbley        name = None
482eb8dc403SDave Cobbley        BuildBase.__init__(self, name, p)
483eb8dc403SDave Cobbley
484eb8dc403SDave Cobbleyclass BuildStarted(BuildBase, OperationStarted):
485eb8dc403SDave Cobbley    """Event when builds start"""
486eb8dc403SDave Cobbley    def __init__(self, n, p, failures = 0):
487eb8dc403SDave Cobbley        OperationStarted.__init__(self, "Building Started")
488eb8dc403SDave Cobbley        BuildBase.__init__(self, n, p, failures)
489eb8dc403SDave Cobbley
490eb8dc403SDave Cobbleyclass BuildCompleted(BuildBase, OperationCompleted):
491eb8dc403SDave Cobbley    """Event when builds have completed"""
492eb8dc403SDave Cobbley    def __init__(self, total, n, p, failures=0, interrupted=0):
493eb8dc403SDave Cobbley        if not failures:
494eb8dc403SDave Cobbley            OperationCompleted.__init__(self, total, "Building Succeeded")
495eb8dc403SDave Cobbley        else:
496eb8dc403SDave Cobbley            OperationCompleted.__init__(self, total, "Building Failed")
497eb8dc403SDave Cobbley        self._interrupted = interrupted
498eb8dc403SDave Cobbley        BuildBase.__init__(self, n, p, failures)
499eb8dc403SDave Cobbley
500eb8dc403SDave Cobbleyclass DiskFull(Event):
5017e0e3c0cSAndrew Geissler    """Disk full case build halted"""
502eb8dc403SDave Cobbley    def __init__(self, dev, type, freespace, mountpoint):
503eb8dc403SDave Cobbley        Event.__init__(self)
504eb8dc403SDave Cobbley        self._dev = dev
505eb8dc403SDave Cobbley        self._type = type
506eb8dc403SDave Cobbley        self._free = freespace
507eb8dc403SDave Cobbley        self._mountpoint = mountpoint
508eb8dc403SDave Cobbley
509eb8dc403SDave Cobbleyclass DiskUsageSample:
510eb8dc403SDave Cobbley    def __init__(self, available_bytes, free_bytes, total_bytes):
511eb8dc403SDave Cobbley        # Number of bytes available to non-root processes.
512eb8dc403SDave Cobbley        self.available_bytes = available_bytes
513eb8dc403SDave Cobbley        # Number of bytes available to root processes.
514eb8dc403SDave Cobbley        self.free_bytes = free_bytes
515eb8dc403SDave Cobbley        # Total capacity of the volume.
516eb8dc403SDave Cobbley        self.total_bytes = total_bytes
517eb8dc403SDave Cobbley
518eb8dc403SDave Cobbleyclass MonitorDiskEvent(Event):
519eb8dc403SDave Cobbley    """If BB_DISKMON_DIRS is set, then this event gets triggered each time disk space is checked.
520eb8dc403SDave Cobbley       Provides information about devices that are getting monitored."""
521eb8dc403SDave Cobbley    def __init__(self, disk_usage):
522eb8dc403SDave Cobbley        Event.__init__(self)
523eb8dc403SDave Cobbley        # hash of device root path -> DiskUsageSample
524eb8dc403SDave Cobbley        self.disk_usage = disk_usage
525eb8dc403SDave Cobbley
526eb8dc403SDave Cobbleyclass NoProvider(Event):
527eb8dc403SDave Cobbley    """No Provider for an Event"""
528eb8dc403SDave Cobbley
529eb8dc403SDave Cobbley    def __init__(self, item, runtime=False, dependees=None, reasons=None, close_matches=None):
530eb8dc403SDave Cobbley        Event.__init__(self)
531eb8dc403SDave Cobbley        self._item = item
532eb8dc403SDave Cobbley        self._runtime = runtime
533eb8dc403SDave Cobbley        self._dependees = dependees
534eb8dc403SDave Cobbley        self._reasons = reasons
535eb8dc403SDave Cobbley        self._close_matches = close_matches
536eb8dc403SDave Cobbley
537eb8dc403SDave Cobbley    def getItem(self):
538eb8dc403SDave Cobbley        return self._item
539eb8dc403SDave Cobbley
540eb8dc403SDave Cobbley    def isRuntime(self):
541eb8dc403SDave Cobbley        return self._runtime
542eb8dc403SDave Cobbley
543eb8dc403SDave Cobbley    def __str__(self):
544eb8dc403SDave Cobbley        msg = ''
545eb8dc403SDave Cobbley        if self._runtime:
546eb8dc403SDave Cobbley            r = "R"
547eb8dc403SDave Cobbley        else:
548eb8dc403SDave Cobbley            r = ""
549eb8dc403SDave Cobbley
550eb8dc403SDave Cobbley        extra = ''
551eb8dc403SDave Cobbley        if not self._reasons:
552eb8dc403SDave Cobbley            if self._close_matches:
55382c905dcSAndrew Geissler                extra = ". Close matches:\n  %s" % '\n  '.join(sorted(set(self._close_matches)))
554eb8dc403SDave Cobbley
555eb8dc403SDave Cobbley        if self._dependees:
556eb8dc403SDave Cobbley            msg = "Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)%s" % (r, self._item, ", ".join(self._dependees), r, extra)
557eb8dc403SDave Cobbley        else:
558eb8dc403SDave Cobbley            msg = "Nothing %sPROVIDES '%s'%s" % (r, self._item, extra)
559eb8dc403SDave Cobbley        if self._reasons:
560eb8dc403SDave Cobbley            for reason in self._reasons:
561eb8dc403SDave Cobbley                msg += '\n' + reason
562eb8dc403SDave Cobbley        return msg
563eb8dc403SDave Cobbley
564eb8dc403SDave Cobbley
565eb8dc403SDave Cobbleyclass MultipleProviders(Event):
566eb8dc403SDave Cobbley    """Multiple Providers"""
567eb8dc403SDave Cobbley
568eb8dc403SDave Cobbley    def  __init__(self, item, candidates, runtime = False):
569eb8dc403SDave Cobbley        Event.__init__(self)
570eb8dc403SDave Cobbley        self._item = item
571eb8dc403SDave Cobbley        self._candidates = candidates
572eb8dc403SDave Cobbley        self._is_runtime = runtime
573eb8dc403SDave Cobbley
574eb8dc403SDave Cobbley    def isRuntime(self):
575eb8dc403SDave Cobbley        """
576eb8dc403SDave Cobbley        Is this a runtime issue?
577eb8dc403SDave Cobbley        """
578eb8dc403SDave Cobbley        return self._is_runtime
579eb8dc403SDave Cobbley
580eb8dc403SDave Cobbley    def getItem(self):
581eb8dc403SDave Cobbley        """
582eb8dc403SDave Cobbley        The name for the to be build item
583eb8dc403SDave Cobbley        """
584eb8dc403SDave Cobbley        return self._item
585eb8dc403SDave Cobbley
586eb8dc403SDave Cobbley    def getCandidates(self):
587eb8dc403SDave Cobbley        """
588eb8dc403SDave Cobbley        Get the possible Candidates for a PROVIDER.
589eb8dc403SDave Cobbley        """
590eb8dc403SDave Cobbley        return self._candidates
591eb8dc403SDave Cobbley
592eb8dc403SDave Cobbley    def __str__(self):
593eb8dc403SDave Cobbley        msg = "Multiple providers are available for %s%s (%s)" % (self._is_runtime and "runtime " or "",
594eb8dc403SDave Cobbley                            self._item,
595eb8dc403SDave Cobbley                            ", ".join(self._candidates))
596eb8dc403SDave Cobbley        rtime = ""
597eb8dc403SDave Cobbley        if self._is_runtime:
598eb8dc403SDave Cobbley            rtime = "R"
599eb8dc403SDave Cobbley        msg += "\nConsider defining a PREFERRED_%sPROVIDER entry to match %s" % (rtime, self._item)
600eb8dc403SDave Cobbley        return msg
601eb8dc403SDave Cobbley
602eb8dc403SDave Cobbleyclass ParseStarted(OperationStarted):
603eb8dc403SDave Cobbley    """Recipe parsing for the runqueue has begun"""
604eb8dc403SDave Cobbley    def __init__(self, total):
605eb8dc403SDave Cobbley        OperationStarted.__init__(self, "Recipe parsing Started")
606eb8dc403SDave Cobbley        self.total = total
607eb8dc403SDave Cobbley
608eb8dc403SDave Cobbleyclass ParseCompleted(OperationCompleted):
609eb8dc403SDave Cobbley    """Recipe parsing for the runqueue has completed"""
610eb8dc403SDave Cobbley    def __init__(self, cached, parsed, skipped, masked, virtuals, errors, total):
611eb8dc403SDave Cobbley        OperationCompleted.__init__(self, total, "Recipe parsing Completed")
612eb8dc403SDave Cobbley        self.cached = cached
613eb8dc403SDave Cobbley        self.parsed = parsed
614eb8dc403SDave Cobbley        self.skipped = skipped
615eb8dc403SDave Cobbley        self.virtuals = virtuals
616eb8dc403SDave Cobbley        self.masked = masked
617eb8dc403SDave Cobbley        self.errors = errors
618eb8dc403SDave Cobbley        self.sofar = cached + parsed
619eb8dc403SDave Cobbley
620eb8dc403SDave Cobbleyclass ParseProgress(OperationProgress):
621eb8dc403SDave Cobbley    """Recipe parsing progress"""
622eb8dc403SDave Cobbley    def __init__(self, current, total):
623eb8dc403SDave Cobbley        OperationProgress.__init__(self, current, total, "Recipe parsing")
624eb8dc403SDave Cobbley
625eb8dc403SDave Cobbley
626eb8dc403SDave Cobbleyclass CacheLoadStarted(OperationStarted):
627eb8dc403SDave Cobbley    """Loading of the dependency cache has begun"""
628eb8dc403SDave Cobbley    def __init__(self, total):
629eb8dc403SDave Cobbley        OperationStarted.__init__(self, "Loading cache Started")
630eb8dc403SDave Cobbley        self.total = total
631eb8dc403SDave Cobbley
632eb8dc403SDave Cobbleyclass CacheLoadProgress(OperationProgress):
633eb8dc403SDave Cobbley    """Cache loading progress"""
634eb8dc403SDave Cobbley    def __init__(self, current, total):
635eb8dc403SDave Cobbley        OperationProgress.__init__(self, current, total, "Loading cache")
636eb8dc403SDave Cobbley
637eb8dc403SDave Cobbleyclass CacheLoadCompleted(OperationCompleted):
638eb8dc403SDave Cobbley    """Cache loading is complete"""
639eb8dc403SDave Cobbley    def __init__(self, total, num_entries):
640eb8dc403SDave Cobbley        OperationCompleted.__init__(self, total, "Loading cache Completed")
641eb8dc403SDave Cobbley        self.num_entries = num_entries
642eb8dc403SDave Cobbley
643eb8dc403SDave Cobbleyclass TreeDataPreparationStarted(OperationStarted):
644eb8dc403SDave Cobbley    """Tree data preparation started"""
645eb8dc403SDave Cobbley    def __init__(self):
646eb8dc403SDave Cobbley        OperationStarted.__init__(self, "Preparing tree data Started")
647eb8dc403SDave Cobbley
648eb8dc403SDave Cobbleyclass TreeDataPreparationProgress(OperationProgress):
649eb8dc403SDave Cobbley    """Tree data preparation is in progress"""
650eb8dc403SDave Cobbley    def __init__(self, current, total):
651eb8dc403SDave Cobbley        OperationProgress.__init__(self, current, total, "Preparing tree data")
652eb8dc403SDave Cobbley
653eb8dc403SDave Cobbleyclass TreeDataPreparationCompleted(OperationCompleted):
654eb8dc403SDave Cobbley    """Tree data preparation completed"""
655eb8dc403SDave Cobbley    def __init__(self, total):
656eb8dc403SDave Cobbley        OperationCompleted.__init__(self, total, "Preparing tree data Completed")
657eb8dc403SDave Cobbley
658eb8dc403SDave Cobbleyclass DepTreeGenerated(Event):
659eb8dc403SDave Cobbley    """
660eb8dc403SDave Cobbley    Event when a dependency tree has been generated
661eb8dc403SDave Cobbley    """
662eb8dc403SDave Cobbley
663eb8dc403SDave Cobbley    def __init__(self, depgraph):
664eb8dc403SDave Cobbley        Event.__init__(self)
665eb8dc403SDave Cobbley        self._depgraph = depgraph
666eb8dc403SDave Cobbley
667eb8dc403SDave Cobbleyclass TargetsTreeGenerated(Event):
668eb8dc403SDave Cobbley    """
669eb8dc403SDave Cobbley    Event when a set of buildable targets has been generated
670eb8dc403SDave Cobbley    """
671eb8dc403SDave Cobbley    def __init__(self, model):
672eb8dc403SDave Cobbley        Event.__init__(self)
673eb8dc403SDave Cobbley        self._model = model
674eb8dc403SDave Cobbley
675eb8dc403SDave Cobbleyclass ReachableStamps(Event):
676eb8dc403SDave Cobbley    """
677eb8dc403SDave Cobbley    An event listing all stamps reachable after parsing
678eb8dc403SDave Cobbley    which the metadata may use to clean up stale data
679eb8dc403SDave Cobbley    """
680eb8dc403SDave Cobbley
681eb8dc403SDave Cobbley    def __init__(self, stamps):
682eb8dc403SDave Cobbley        Event.__init__(self)
683eb8dc403SDave Cobbley        self.stamps = stamps
684eb8dc403SDave Cobbley
68595ac1b8dSAndrew Geisslerclass StaleSetSceneTasks(Event):
68695ac1b8dSAndrew Geissler    """
68795ac1b8dSAndrew Geissler    An event listing setscene tasks which are 'stale' and will
68895ac1b8dSAndrew Geissler    be rerun. The metadata may use to clean up stale data.
68995ac1b8dSAndrew Geissler    tasks is a mapping of tasks and matching stale stamps.
69095ac1b8dSAndrew Geissler    """
69195ac1b8dSAndrew Geissler
69295ac1b8dSAndrew Geissler    def __init__(self, tasks):
69395ac1b8dSAndrew Geissler        Event.__init__(self)
69495ac1b8dSAndrew Geissler        self.tasks = tasks
69595ac1b8dSAndrew Geissler
696eb8dc403SDave Cobbleyclass FilesMatchingFound(Event):
697eb8dc403SDave Cobbley    """
698eb8dc403SDave Cobbley    Event when a list of files matching the supplied pattern has
699eb8dc403SDave Cobbley    been generated
700eb8dc403SDave Cobbley    """
701eb8dc403SDave Cobbley    def __init__(self, pattern, matches):
702eb8dc403SDave Cobbley        Event.__init__(self)
703eb8dc403SDave Cobbley        self._pattern = pattern
704eb8dc403SDave Cobbley        self._matches = matches
705eb8dc403SDave Cobbley
706eb8dc403SDave Cobbleyclass ConfigFilesFound(Event):
707eb8dc403SDave Cobbley    """
708eb8dc403SDave Cobbley    Event when a list of appropriate config files has been generated
709eb8dc403SDave Cobbley    """
710eb8dc403SDave Cobbley    def __init__(self, variable, values):
711eb8dc403SDave Cobbley        Event.__init__(self)
712eb8dc403SDave Cobbley        self._variable = variable
713eb8dc403SDave Cobbley        self._values = values
714eb8dc403SDave Cobbley
715eb8dc403SDave Cobbleyclass ConfigFilePathFound(Event):
716eb8dc403SDave Cobbley    """
717eb8dc403SDave Cobbley    Event when a path for a config file has been found
718eb8dc403SDave Cobbley    """
719eb8dc403SDave Cobbley    def __init__(self, path):
720eb8dc403SDave Cobbley        Event.__init__(self)
721eb8dc403SDave Cobbley        self._path = path
722eb8dc403SDave Cobbley
723eb8dc403SDave Cobbleyclass MsgBase(Event):
724eb8dc403SDave Cobbley    """Base class for messages"""
725eb8dc403SDave Cobbley
726eb8dc403SDave Cobbley    def __init__(self, msg):
727eb8dc403SDave Cobbley        self._message = msg
728eb8dc403SDave Cobbley        Event.__init__(self)
729eb8dc403SDave Cobbley
730eb8dc403SDave Cobbleyclass MsgDebug(MsgBase):
731eb8dc403SDave Cobbley    """Debug Message"""
732eb8dc403SDave Cobbley
733eb8dc403SDave Cobbleyclass MsgNote(MsgBase):
734eb8dc403SDave Cobbley    """Note Message"""
735eb8dc403SDave Cobbley
736eb8dc403SDave Cobbleyclass MsgWarn(MsgBase):
737eb8dc403SDave Cobbley    """Warning Message"""
738eb8dc403SDave Cobbley
739eb8dc403SDave Cobbleyclass MsgError(MsgBase):
740eb8dc403SDave Cobbley    """Error Message"""
741eb8dc403SDave Cobbley
742eb8dc403SDave Cobbleyclass MsgFatal(MsgBase):
743eb8dc403SDave Cobbley    """Fatal Message"""
744eb8dc403SDave Cobbley
745eb8dc403SDave Cobbleyclass MsgPlain(MsgBase):
746eb8dc403SDave Cobbley    """General output"""
747eb8dc403SDave Cobbley
748eb8dc403SDave Cobbleyclass LogExecTTY(Event):
749eb8dc403SDave Cobbley    """Send event containing program to spawn on tty of the logger"""
750eb8dc403SDave Cobbley    def __init__(self, msg, prog, sleep_delay, retries):
751eb8dc403SDave Cobbley        Event.__init__(self)
752eb8dc403SDave Cobbley        self.msg = msg
753eb8dc403SDave Cobbley        self.prog = prog
754eb8dc403SDave Cobbley        self.sleep_delay = sleep_delay
755eb8dc403SDave Cobbley        self.retries = retries
756eb8dc403SDave Cobbley
757eb8dc403SDave Cobbleyclass LogHandler(logging.Handler):
758eb8dc403SDave Cobbley    """Dispatch logging messages as bitbake events"""
759eb8dc403SDave Cobbley
760eb8dc403SDave Cobbley    def emit(self, record):
761eb8dc403SDave Cobbley        if record.exc_info:
762eb8dc403SDave Cobbley            etype, value, tb = record.exc_info
763eb8dc403SDave Cobbley            if hasattr(tb, 'tb_next'):
764eb8dc403SDave Cobbley                tb = list(bb.exceptions.extract_traceback(tb, context=3))
765eb8dc403SDave Cobbley            # Need to turn the value into something the logging system can pickle
766eb8dc403SDave Cobbley            record.bb_exc_info = (etype, value, tb)
767eb8dc403SDave Cobbley            record.bb_exc_formatted = bb.exceptions.format_exception(etype, value, tb, limit=5)
768eb8dc403SDave Cobbley            value = str(value)
769eb8dc403SDave Cobbley            record.exc_info = None
770eb8dc403SDave Cobbley        fire(record, None)
771eb8dc403SDave Cobbley
772eb8dc403SDave Cobbley    def filter(self, record):
773eb8dc403SDave Cobbley        record.taskpid = worker_pid
774eb8dc403SDave Cobbley        return True
775eb8dc403SDave Cobbley
776eb8dc403SDave Cobbleyclass MetadataEvent(Event):
777eb8dc403SDave Cobbley    """
778eb8dc403SDave Cobbley    Generic event that target for OE-Core classes
7797e0e3c0cSAndrew Geissler    to report information during asynchronous execution
780eb8dc403SDave Cobbley    """
781eb8dc403SDave Cobbley    def __init__(self, eventtype, eventdata):
782eb8dc403SDave Cobbley        Event.__init__(self)
783eb8dc403SDave Cobbley        self.type = eventtype
784eb8dc403SDave Cobbley        self._localdata = eventdata
785eb8dc403SDave Cobbley
786eb8dc403SDave Cobbleyclass ProcessStarted(Event):
787eb8dc403SDave Cobbley    """
788eb8dc403SDave Cobbley    Generic process started event (usually part of the initial startup)
789eb8dc403SDave Cobbley    where further progress events will be delivered
790eb8dc403SDave Cobbley    """
791eb8dc403SDave Cobbley    def __init__(self, processname, total):
792eb8dc403SDave Cobbley        Event.__init__(self)
793eb8dc403SDave Cobbley        self.processname = processname
794eb8dc403SDave Cobbley        self.total = total
795eb8dc403SDave Cobbley
796eb8dc403SDave Cobbleyclass ProcessProgress(Event):
797eb8dc403SDave Cobbley    """
798eb8dc403SDave Cobbley    Generic process progress event (usually part of the initial startup)
799eb8dc403SDave Cobbley    """
800eb8dc403SDave Cobbley    def __init__(self, processname, progress):
801eb8dc403SDave Cobbley        Event.__init__(self)
802eb8dc403SDave Cobbley        self.processname = processname
803eb8dc403SDave Cobbley        self.progress = progress
804eb8dc403SDave Cobbley
805eb8dc403SDave Cobbleyclass ProcessFinished(Event):
806eb8dc403SDave Cobbley    """
807eb8dc403SDave Cobbley    Generic process finished event (usually part of the initial startup)
808eb8dc403SDave Cobbley    """
809eb8dc403SDave Cobbley    def __init__(self, processname):
810eb8dc403SDave Cobbley        Event.__init__(self)
811eb8dc403SDave Cobbley        self.processname = processname
812eb8dc403SDave Cobbley
813eb8dc403SDave Cobbleyclass SanityCheck(Event):
814eb8dc403SDave Cobbley    """
815eb8dc403SDave Cobbley    Event to run sanity checks, either raise errors or generate events as return status.
816eb8dc403SDave Cobbley    """
817eb8dc403SDave Cobbley    def __init__(self, generateevents = True):
818eb8dc403SDave Cobbley        Event.__init__(self)
819eb8dc403SDave Cobbley        self.generateevents = generateevents
820eb8dc403SDave Cobbley
821eb8dc403SDave Cobbleyclass SanityCheckPassed(Event):
822eb8dc403SDave Cobbley    """
823eb8dc403SDave Cobbley    Event to indicate sanity check has passed
824eb8dc403SDave Cobbley    """
825eb8dc403SDave Cobbley
826eb8dc403SDave Cobbleyclass SanityCheckFailed(Event):
827eb8dc403SDave Cobbley    """
828eb8dc403SDave Cobbley    Event to indicate sanity check has failed
829eb8dc403SDave Cobbley    """
830eb8dc403SDave Cobbley    def __init__(self, msg, network_error=False):
831eb8dc403SDave Cobbley        Event.__init__(self)
832eb8dc403SDave Cobbley        self._msg = msg
833eb8dc403SDave Cobbley        self._network_error = network_error
834eb8dc403SDave Cobbley
835eb8dc403SDave Cobbleyclass NetworkTest(Event):
836eb8dc403SDave Cobbley    """
837eb8dc403SDave Cobbley    Event to run network connectivity tests, either raise errors or generate events as return status.
838eb8dc403SDave Cobbley    """
839eb8dc403SDave Cobbley    def __init__(self, generateevents = True):
840eb8dc403SDave Cobbley        Event.__init__(self)
841eb8dc403SDave Cobbley        self.generateevents = generateevents
842eb8dc403SDave Cobbley
843eb8dc403SDave Cobbleyclass NetworkTestPassed(Event):
844eb8dc403SDave Cobbley    """
845eb8dc403SDave Cobbley    Event to indicate network test has passed
846eb8dc403SDave Cobbley    """
847eb8dc403SDave Cobbley
848eb8dc403SDave Cobbleyclass NetworkTestFailed(Event):
849eb8dc403SDave Cobbley    """
850eb8dc403SDave Cobbley    Event to indicate network test has failed
851eb8dc403SDave Cobbley    """
852eb8dc403SDave Cobbley
853eb8dc403SDave Cobbleyclass FindSigInfoResult(Event):
854eb8dc403SDave Cobbley    """
855eb8dc403SDave Cobbley    Event to return results from findSigInfo command
856eb8dc403SDave Cobbley    """
857eb8dc403SDave Cobbley    def __init__(self, result):
858eb8dc403SDave Cobbley        Event.__init__(self)
859eb8dc403SDave Cobbley        self.result = result
8608e7b46e2SPatrick Williams
861220dafdbSAndrew Geisslerclass GetTaskSignatureResult(Event):
862220dafdbSAndrew Geissler    """
863220dafdbSAndrew Geissler    Event to return results from GetTaskSignatures command
864220dafdbSAndrew Geissler    """
865220dafdbSAndrew Geissler    def __init__(self, sig):
866220dafdbSAndrew Geissler        Event.__init__(self)
867220dafdbSAndrew Geissler        self.sig = sig
868220dafdbSAndrew Geissler
8698e7b46e2SPatrick Williamsclass ParseError(Event):
8708e7b46e2SPatrick Williams    """
8718e7b46e2SPatrick Williams    Event to indicate parse failed
8728e7b46e2SPatrick Williams    """
8738e7b46e2SPatrick Williams    def __init__(self, msg):
8748e7b46e2SPatrick Williams        super().__init__()
8758e7b46e2SPatrick Williams        self._msg = msg
876