diff mbox series

[layerindex-web] layerindex/tools: add mark_yp_compatible_layers.py

Message ID 20231102231446.27165-1-tim.orling@konsulko.com
State New
Headers show
Series [layerindex-web] layerindex/tools: add mark_yp_compatible_layers.py | expand

Commit Message

Tim Orling Nov. 2, 2023, 11:14 p.m. UTC
Add a script which can either mark one --layer --branch or
use data in a --from-file to mark multiple layer:branch objects
as Yocto Project Compatible.

The --from-file is a json file that is compatible with or which
can be generated by:

yocto-autobuilder-helper/scripts/list-yp-compatible-layers.py

[YOCTO #15093]

Signed-off-by: Tim Orling <tim.orling@konsulko.com>
---
 layerindex/tools/mark_yp_compatible_layers.py | 142 ++++++++++++++++++
 1 file changed, 142 insertions(+)
 create mode 100755 layerindex/tools/mark_yp_compatible_layers.py
diff mbox series

Patch

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 <paul.eggleton@linux.intel.com>
+# Copyright (C) 2023 Konsulko Group
+# Author: Tim Orling <tim.orling@konsulko.com>
+#
+# 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()
+