Files
poky/bitbake/bin/bitbake-diffsigs
Peter Kjellerstedt 9fe7a69535 bitbake: bitbake-diffsigs: Add debug support
Currently shows the name of the signature files that were found when
--task is used.

(Bitbake rev: 751b06c25d22eea8240f9429cb49874082245e52)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2017-03-23 13:19:50 +00:00

5.2 KiB
Executable File

#!/usr/bin/env python3

bitbake-diffsigs

BitBake task signature data comparison utility

Copyright (C) 2012-2013 Intel Corporation

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.

import os import sys import warnings import fnmatch import optparse 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

def logger_create(name, output=sys.stderr): logger = logging.getLogger(name) console = logging.StreamHandler(output) format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") if output.isatty(): format.enable_color() console.setFormatter(format) logger.addHandler(console) logger.setLevel(logging.INFO) return logger

logger = logger_create('bitbake-diffsigs')

def find_compare_task(bbhandler, pn, taskname): """ Find the most recent signature files for the specified PN/task and compare them """

def get_hashval(siginfo):
    if siginfo.endswith('.siginfo'):
        return siginfo.rpartition(':')[2].partition('_')[0]
    else:
        return siginfo.rpartition('.')[2]

if not hasattr(bb.siggen, 'find_siginfo'):
    logger.error('Metadata does not support finding signature data files')
    sys.exit(1)

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

filedates = bb.siggen.find_siginfo(pn, taskname, None, bbhandler.config_data)
latestfiles = sorted(filedates.keys(), key=lambda f: filedates[f])[-3:]
if not latestfiles:
    logger.error('No sigdata files found matching %s %s' % (pn, taskname))
    sys.exit(1)
elif len(latestfiles) < 2:
    logger.error('Only one matching sigdata file found for the specified task (%s %s)' % (pn, taskname))
    sys.exit(1)
else:
    # It's possible that latestfiles contain 3 elements and the first two have the same hash value.
    # In this case, we delete the second element.
    # The above case is actually the most common one. Because we may have sigdata file and siginfo
    # file having the same hash value. Comparing such two files makes no sense.
    if len(latestfiles) == 3:
        hash0 = get_hashval(latestfiles[0])
        hash1 = get_hashval(latestfiles[1])
        if hash0 == hash1:
            latestfiles.pop(1)

    # Define recursion callback
    def recursecb(key, hash1, hash2):
        hashes = [hash1, hash2]
        hashfiles = bb.siggen.find_siginfo(key, None, hashes, bbhandler.config_data)

        recout = []
        if len(hashfiles) == 2:
            out2 = bb.siggen.compare_sigfiles(hashfiles[hash1], hashfiles[hash2], recursecb)
            recout.extend(list('  ' + l for l in out2))
        else:
            recout.append("Unable to find matching sigdata for %s with hashes %s or %s" % (key, hash1, hash2))

        return recout

    # Recurse into signature comparison
    logger.debug("Signature file (previous): %s" % latestfiles[0])
    logger.debug("Signature file (latest): %s" % latestfiles[1])
    output = bb.siggen.compare_sigfiles(latestfiles[0], latestfiles[1], recursecb)
    if output:
        print('\n'.join(output))
sys.exit(0)

parser = optparse.OptionParser( description = "Compares siginfo/sigdata files written out by BitBake", usage = """ %prog -t recipename taskname %prog sigdatafile1 sigdatafile2 %prog sigdatafile1""")

parser.add_option("-D", "--debug", help = "enable debug", action = "store_true", dest="debug", default = False)

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

options, args = parser.parse_args(sys.argv)

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

if options.taskargs: with bb.tinfoil.Tinfoil() as tinfoil: tinfoil.prepare(config_only=True) find_compare_task(tinfoil, options.taskargs[0], options.taskargs[1]) else: if len(args) == 1: parser.print_help() else: try: if len(args) == 2: output = bb.siggen.dump_sigfile(sys.argv[1]) else: output = bb.siggen.compare_sigfiles(sys.argv[1], sys.argv[2]) 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))