123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- #!/usr/bin/env python3
- # bblock
- # lock/unlock task to latest signature
- #
- # Copyright (c) 2023 BayLibre, SAS
- # Author: Julien Stepahn <jstephan@baylibre.com>
- #
- # SPDX-License-Identifier: GPL-2.0-only
- #
- import os
- import sys
- import logging
- scripts_path = os.path.dirname(os.path.realpath(__file__))
- lib_path = scripts_path + "/lib"
- sys.path = sys.path + [lib_path]
- import scriptpath
- scriptpath.add_bitbake_lib_path()
- import bb.tinfoil
- import bb.msg
- import argparse_oe
- myname = os.path.basename(sys.argv[0])
- logger = bb.msg.logger_create(myname)
- def getTaskSignatures(tinfoil, pn, tasks):
- tinfoil.set_event_mask(
- [
- "bb.event.GetTaskSignatureResult",
- "logging.LogRecord",
- "bb.command.CommandCompleted",
- "bb.command.CommandFailed",
- ]
- )
- ret = tinfoil.run_command("getTaskSignatures", pn, tasks)
- 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.GetTaskSignatureResult):
- sig = event.sig
- elif isinstance(event, logging.LogRecord):
- logger.handle(event)
- else:
- logger.error("No result returned from getTaskSignatures command")
- sys.exit(2)
- return sig
- def parseRecipe(tinfoil, recipe):
- try:
- tinfoil.parse_recipes()
- d = tinfoil.parse_recipe(recipe)
- except Exception:
- logger.error("Failed to get recipe info for: %s" % recipe)
- sys.exit(1)
- return d
- def bblockDump(lockfile):
- try:
- with open(lockfile, "r") as lockfile:
- for line in lockfile:
- print(line.strip())
- except IOError:
- return 1
- return 0
- def bblockReset(lockfile, pns, package_archs, tasks):
- if not pns:
- logger.info("Unlocking all recipes")
- try:
- os.remove(lockfile)
- except FileNotFoundError:
- pass
- else:
- logger.info("Unlocking {pns}".format(pns=pns))
- tmp_lockfile = lockfile + ".tmp"
- with open(lockfile, "r") as infile, open(tmp_lockfile, "w") as outfile:
- for line in infile:
- if not (
- any(element in line for element in pns)
- and any(element in line for element in package_archs.split())
- ):
- outfile.write(line)
- else:
- if tasks and not any(element in line for element in tasks):
- outfile.write(line)
- os.remove(lockfile)
- os.rename(tmp_lockfile, lockfile)
- def main():
- parser = argparse_oe.ArgumentParser(description="Lock and unlock a recipe")
- parser.add_argument("pn", nargs="*", help="Space separated list of recipe to lock")
- parser.add_argument(
- "-t",
- "--tasks",
- help="Comma separated list of tasks",
- type=lambda s: [
- task if task.startswith("do_") else "do_" + task for task in s.split(",")
- ],
- )
- parser.add_argument(
- "-r",
- "--reset",
- action="store_true",
- help="Unlock pn recipes, or all recipes if pn is empty",
- )
- parser.add_argument(
- "-d",
- "--dump",
- action="store_true",
- help="Dump generated bblock.conf file",
- )
- global_args, unparsed_args = parser.parse_known_args()
- with bb.tinfoil.Tinfoil() as tinfoil:
- tinfoil.prepare(config_only=True)
- package_archs = tinfoil.config_data.getVar("PACKAGE_ARCHS")
- builddir = tinfoil.config_data.getVar("TOPDIR")
- lockfile = "{builddir}/conf/bblock.conf".format(builddir=builddir)
- if global_args.dump:
- bblockDump(lockfile)
- return 0
- if global_args.reset:
- bblockReset(lockfile, global_args.pn, package_archs, global_args.tasks)
- return 0
- with open(lockfile, "a") as lockfile:
- s = ""
- if lockfile.tell() == 0:
- s = "# Generated by bblock\n"
- s += 'SIGGEN_LOCKEDSIGS_TASKSIG_CHECK = "info"\n'
- s += 'SIGGEN_LOCKEDSIGS_TYPES += "${PACKAGE_ARCHS}"\n'
- s += "\n"
- for pn in global_args.pn:
- d = parseRecipe(tinfoil, pn)
- package_arch = d.getVar("PACKAGE_ARCH")
- siggen_locked_sigs_package_arch = d.getVar(
- "SIGGEN_LOCKEDSIGS_{package_arch}".format(package_arch=package_arch)
- )
- sigs = getTaskSignatures(tinfoil, [pn], global_args.tasks)
- for sig in sigs:
- new_entry = "{pn}:{taskname}:{sig}".format(
- pn=sig[0], taskname=sig[1], sig=sig[2]
- )
- if (
- siggen_locked_sigs_package_arch
- and not new_entry in siggen_locked_sigs_package_arch
- ) or not siggen_locked_sigs_package_arch:
- s += 'SIGGEN_LOCKEDSIGS_{package_arch} += "{new_entry}"\n'.format(
- package_arch=package_arch, new_entry=new_entry
- )
- lockfile.write(s)
- return 0
- if __name__ == "__main__":
- try:
- ret = main()
- except Exception:
- ret = 1
- import traceback
- traceback.print_exc()
- sys.exit(ret)
|