Files
poky/bitbake/bin/bitbake-diffsigs
Alexander Kanavin 2b399a01b5 bitbake: bitbake: enable python warnings at the first opportunity
We really do want to see those, as they tend to turn into
hard errors eventually, as what happened with collections
vs collections.abc in python 3.10.

(Bitbake rev: bc43fbb86361a21dc2d5deb910810c5a77fdabe8)

Signed-off-by: Alexander Kanavin <alex@linutronix.de>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2021-09-19 11:33:14 +01:00

7.6 KiB
Executable File

#!/usr/bin/env python3

bitbake-diffsigs / bitbake-dumpsig

BitBake task signature data dump and comparison utility

Copyright (C) 2012-2013, 2017 Intel Corporation

SPDX-License-Identifier: GPL-2.0-only

import os import sys import warnings warnings.simplefilter("default") import argparse import logging import pickle

sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))

import bb.tinfoil import bb.siggen import bb.msg

myname = os.path.basename(sys.argv[0]) logger = bb.msg.logger_create(myname)

is_dump = myname == 'bitbake-dumpsig'

def find_siginfo(tinfoil, pn, taskname, sigs=None): result = None tinfoil.set_event_mask(['bb.event.FindSigInfoResult', 'logging.LogRecord', 'bb.command.CommandCompleted', 'bb.command.CommandFailed']) ret = tinfoil.run_command('findSigInfo', pn, taskname, sigs) if ret: while True: event = tinfoil.wait_event(1) if event: if isinstance(event, bb.command.CommandCompleted): break elif isinstance(event, bb.command.CommandFailed): logger.error(str(event)) sys.exit(2) elif isinstance(event, bb.event.FindSigInfoResult): result = event.result elif isinstance(event, logging.LogRecord): logger.handle(event) else: logger.error('No result returned from findSigInfo command') sys.exit(2) return result

def find_siginfo_task(bbhandler, pn, taskname, sig1=None, sig2=None): """ Find the most recent signature files for the specified PN/task """

if not taskname.startswith('do_'):
    taskname = 'do_%s' % taskname

if sig1 and sig2:
    sigfiles = find_siginfo(bbhandler, pn, taskname, [sig1, sig2])
    if len(sigfiles) == 0:
        logger.error('No sigdata files found matching %s %s matching either %s or %s' % (pn, taskname, sig1, sig2))
        sys.exit(1)
    elif not sig1 in sigfiles:
        logger.error('No sigdata files found matching %s %s with signature %s' % (pn, taskname, sig1))
        sys.exit(1)
    elif not sig2 in sigfiles:
        logger.error('No sigdata files found matching %s %s with signature %s' % (pn, taskname, sig2))
        sys.exit(1)
    latestfiles = [sigfiles[sig1], sigfiles[sig2]]
else:
    filedates = find_siginfo(bbhandler, pn, taskname)
    latestfiles = sorted(filedates.keys(), key=lambda f: filedates[f])[-2:]
    if not latestfiles:
        logger.error('No sigdata files found matching %s %s' % (pn, taskname))
        sys.exit(1)

return latestfiles

Define recursion callback

def recursecb(key, hash1, hash2): hashes = [hash1, hash2] hashfiles = find_siginfo(tinfoil, key, None, hashes)

recout = []
if len(hashfiles) == 0:
    recout.append("Unable to find matching sigdata for %s with hashes %s or %s" % (key, hash1, hash2))
elif not hash1 in hashfiles:
    recout.append("Unable to find matching sigdata for %s with hash %s" % (key, hash1))
elif not hash2 in hashfiles:
    recout.append("Unable to find matching sigdata for %s with hash %s" % (key, hash2))
else:
    out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb, color=color)
    for change in out2:
        for line in change.splitlines():
            recout.append('    ' + line)

return recout

parser = argparse.ArgumentParser( description=("Dumps" if is_dump else "Compares") + " siginfo/sigdata files written out by BitBake")

parser.add_argument('-D', '--debug', help='Enable debug output', action='store_true')

if is_dump: parser.add_argument("-t", "--task", help="find the signature data file for the last run of the specified task", action="store", dest="taskargs", nargs=2, metavar=('recipename', 'taskname'))

parser.add_argument("sigdatafile1",
        help="Signature file to dump. Not used when using -t/--task.",
        action="store", nargs='?', metavar="sigdatafile")

else: parser.add_argument('-c', '--color', help='Colorize the output (where %(metavar)s is %(choices)s)', choices=['auto', 'always', 'never'], default='auto', metavar='color')

parser.add_argument('-d', '--dump',
        help='Dump the last signature data instead of comparing (equivalent to using bitbake-dumpsig)',
        action='store_true')

parser.add_argument("-t", "--task",
        help="find the signature data files for the last two runs of the specified task and compare them",
        action="store", dest="taskargs", nargs=2, metavar=('recipename', 'taskname'))

parser.add_argument("-s", "--signature",
        help="With -t/--task, specify the signatures to look for instead of taking the last two",
        action="store", dest="sigargs", nargs=2, metavar=('fromsig', 'tosig'))

parser.add_argument("sigdatafile1",
        help="First signature file to compare (or signature file to dump, if second not specified). Not used when using -t/--task.",
        action="store", nargs='?')

parser.add_argument("sigdatafile2",
        help="Second signature file to compare",
        action="store", nargs='?')

options = parser.parse_args() if is_dump: options.color = 'never' options.dump = True options.sigdatafile2 = None options.sigargs = None

if options.debug: logger.setLevel(logging.DEBUG)

color = (options.color == 'always' or (options.color == 'auto' and sys.stdout.isatty()))

if options.taskargs: with bb.tinfoil.Tinfoil() as tinfoil: tinfoil.prepare(config_only=True) if not options.dump and options.sigargs: files = find_siginfo_task(tinfoil, options.taskargs[0], options.taskargs[1], options.sigargs[0], options.sigargs[1]) else: files = find_siginfo_task(tinfoil, options.taskargs[0], options.taskargs[1])

    if options.dump:
        logger.debug("Signature file: %s" % files[-1])
        output = bb.siggen.dump_sigfile(files[-1])
    else:
        if len(files) < 2:
            logger.error('Only one matching sigdata file found for the specified task (%s %s)' % (options.taskargs[0], options.taskargs[1]))
            sys.exit(1)

        # Recurse into signature comparison
        logger.debug("Signature file (previous): %s" % files[-2])
        logger.debug("Signature file (latest): %s" % files[-1])
        output = bb.siggen.compare_sigfiles(files[-2], files[-1], recursecb, color=color)

else: if options.sigargs: logger.error('-s/--signature can only be used together with -t/--task') sys.exit(1) try: if not options.dump and options.sigdatafile1 and options.sigdatafile2: with bb.tinfoil.Tinfoil() as tinfoil: tinfoil.prepare(config_only=True) output = bb.siggen.compare_sigfiles(options.sigdatafile1, options.sigdatafile2, recursecb, color=color) elif options.sigdatafile1: output = bb.siggen.dump_sigfile(options.sigdatafile1) else: logger.error('Must specify signature file(s) or -t/--task') parser.print_help() sys.exit(1) except IOError as e: logger.error(str(e)) sys.exit(1) except (pickle.UnpicklingError, EOFError): logger.error('Invalid signature data - ensure you are specifying sigdata/siginfo files') sys.exit(1)

if output: print('\n'.join(output))