diff --git a/layerindex/tools/mark_yp_compatible_layers.py b/layerindex/tools/mark_yp_compatible_layers.py new file mode 100755 index 0000000..1d2dc32 --- /dev/null +++ b/layerindex/tools/mark_yp_compatible_layers.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 + +# Mark layers that are Yocto Project Compatible (2.0) on the AutoBuilder +# +# Copyright (C) 2017 Intel Corporation +# Author: Paul Eggleton +# Copyright (C) 2023 Konsulko Group +# Author: Tim Orling +# +# Licensed under the MIT license, see COPYING.MIT for details +# +# SPDX-License-Identifier: MIT +# +# Input json file can be for instance generated by: +# https://git.yoctoproject.org/yocto-autobuilder-helper/tree/scripts/list-yp-compatible-layers.py + +import sys +import os + +sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), '..'))) + +import argparse +from argparse import ArgumentError +from layerindex import utils +import logging +import json +from json import JSONDecodeError + +class DryRunRollbackException(Exception): + pass + +class LayerNotFoundException(Exception): + pass + +class BranchNotFoundException(Exception): + pass + +class YPCompatibleVersionNotFoundException(Exception): + pass + +logger = utils.logger_create('LayerIndexYoctoProjectCompatible') + + + +def main(): + parser = argparse.ArgumentParser(description='Mark layers that are Yocto Project Compatible (2.0)') + + layer_branch_arg_group = parser.add_argument_group() + layer_branch_arg_group.add_argument("-l", "--layer", + help = "Layer to mark as Yocto Project Compatible", + action="store", dest="layer") + layer_branch_arg_group.add_argument("-b", "--branch", + help = "Branch to mark as Yocto Project Compatible", + action="store", dest="branch") + file_or_layer_branch_arg_group = layer_branch_arg_group.add_mutually_exclusive_group() + file_or_layer_branch_arg_group.add_argument("-f", "--from-file", + help = "(Recommended) JSON file compatible with 'list-yp-compatible-layers' script from 'yocto-autobuilder-helper' to use for input", + action="store", dest="from_file") + parser.add_argument("-v", "--compatible-version", + help = "Yocto Project Compatible version", + action="store", dest="yp_compatible_version", default="2.0") + parser.add_argument("-n", "--dry-run", + help = "Don't write any data back to the database", + action="store_true", dest="dryrun") + parser.add_argument("-d", "--debug", + help = "Enable debug output", + action="store_const", const=logging.DEBUG, dest="loglevel", default=logging.INFO) + parser.add_argument("-q", "--quiet", + help = "Hide all output except error messages", + action="store_const", const=logging.ERROR, dest="loglevel") + + args = parser.parse_args() + + utils.setup_django() + import settings + from layerindex.models import Branch, LayerBranch, LayerItem, YPCompatibleVersion + from django.db import transaction + + logger.setLevel(args.loglevel) + + def update_from_layer_branch(layer, branch, yp_compatible_version, dryrun): + try: + with transaction.atomic(): + try: + layer_id=LayerItem.objects.filter(name__exact=layer)[0].id + except IndexError: + raise LayerNotFoundException( f'Layer {layer} not found in layerindex ddatabase') + try: + branch_id=Branch.objects.filter(name__exact=branch)[0].id + except IndexError: + raise BranchNotFoundException( f'Branch {branch} not found in layerindex database') + try: + yp_compatible_version_instance=YPCompatibleVersion.objects.filter(name__exact=yp_compatible_version)[0] + except IndexError: + raise YPCompatibleVersionNotFoundException( f' Yocto Project Compatible Version {yp_compatible_version} not found in layerindex database') + for layerbranch in LayerBranch.objects.filter(layer=layer_id,branch=branch_id): + logger.debug(' BEFORE: Yocto Project Compatible %s %s:%s' % (layerbranch.yp_compatible_version, layerbranch.layer, layerbranch.branch)) + layerbranch.yp_compatible_version = yp_compatible_version_instance + layerbranch.save() + logger.info('Yocto Project Compatible %s %s:%s' % (layerbranch.yp_compatible_version, layerbranch.layer, layerbranch.branch)) + + if dryrun: + raise DryRunRollbackException() + except DryRunRollbackException: + pass + + def update_from_json_file( from_file, yp_compatible_version, dryrun ): + try: + with open(from_file) as fp: + input_dict = json.load(fp) + for job in input_dict: + for branch in input_dict[job]: + try: + for layer in input_dict[job][branch]: + try: + update_from_layer_branch( layer, branch, yp_compatible_version, dryrun ) + except LayerNotFoundException as err: + logger.warning( f"{err}" ) + pass + except BranchNotFoundException as err: + logger.warning( f"{err}" ) + pass + except DryRunRollbackException: + pass + except FileNotFoundError as err: + logger.critical( f"{err}: File {from_file} not found" ) + sys.exit(1) + except JSONDecodeError as err: + logger.critical( f"{err}: JSONDecodeError loading file {from_file}" ) + sys.exit(1) + + if args.layer and args.branch and not args.from_file: + update_from_layer_branch( layer=args.layer, branch=args.branch, yp_compatible_version=args.yp_compatible_version, dryrun=args.dryrun ) + elif args.from_file and not ( args.branch or args.layer ): + update_from_json_file( from_file=args.from_file, yp_compatible_version=args.yp_compatible_version, dryrun=args.dryrun ) + + sys.exit(0) + + +if __name__ == "__main__": + main() +