From 329cd9bb6fe43ab050c0e1da3aa96ff5519ebcde Mon Sep 17 00:00:00 2001 From: Patrick Vogelaar Date: Thu, 9 Mar 2023 08:48:29 +0100 Subject: [PATCH] feat(coreos-supported-pkgs): add script and support file The script passes all recipes in meta-layers that are 'active' in the bblayers.conf. It list all packages based on the package name PN that are supported by CoreOS or either have a dependency on a supported package. --- .../conf/distro/includes/coreos-support.inc | 13 ++ scripts/coreos-supported-pkgs.py | 159 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 layers/meta-belden-coreos/conf/distro/includes/coreos-support.inc create mode 100644 scripts/coreos-supported-pkgs.py diff --git a/layers/meta-belden-coreos/conf/distro/includes/coreos-support.inc b/layers/meta-belden-coreos/conf/distro/includes/coreos-support.inc new file mode 100644 index 0000000..aa3f8d1 --- /dev/null +++ b/layers/meta-belden-coreos/conf/distro/includes/coreos-support.inc @@ -0,0 +1,13 @@ + +COREOS_RECIPE_MAINTAINER:pn-networkmanager = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-openssh = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-podman = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-swupdate = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-linux-netmodule = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-u-boot = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-efibootguard = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-systemd = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-iproute2 = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-ethtool = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-glibc = "Team CoreOS" +COREOS_RECIPE_MAINTAINER:pn-busybox = "Team CoreOS" diff --git a/scripts/coreos-supported-pkgs.py b/scripts/coreos-supported-pkgs.py new file mode 100644 index 0000000..3e06002 --- /dev/null +++ b/scripts/coreos-supported-pkgs.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2023 Hirschmann Automation and Control GmbH +# +# - list all recipes that are supported by the CoreOS team + +import sys +import optparse +import os +import re + +scripts_path = os.path.abspath(os.path.dirname(os.path.abspath(sys.argv[0]))) +# Add the path if we have own libs +lib_path = os.path.abspath(scripts_path + '/../lib') +sys.path = sys.path + [lib_path] +# Add the OE lib path +lib_path = os.path.abspath(scripts_path + '/../layers/openembedded-core/scripts/lib') +sys.path = sys.path + [lib_path] + +import scriptpath + +# For importing the following modules +bitbakepath = scriptpath.add_bitbake_lib_path() +if not bitbakepath: + sys.stderr.write("Unable to find bitbake by searching parent directory of this script or PATH\n") + sys.exit(1) + +import bb.cooker +import bb.providers +import bb.tinfoil +from pprint import pprint + +def get_fnlist(bbhandler, pkg_pn): + ''' Get all recipe file names ''' + (latest_versions, preferred_versions, required_versions) = bb.providers.findProviders(bbhandler.config_data, bbhandler.cooker.recipecaches[''], pkg_pn) + + fn_list = [] + for pn in sorted(pkg_pn): + # use the preferred version + fn_list.append(preferred_versions[pn][1]) + + return fn_list + + +def get_recipesdata(bbhandler): + ''' Get data of all available recipes ''' + pkg_pn = bbhandler.cooker.recipecaches[''].pkg_pn + + pkg_dict = {} + supported_pkg_dict = {} + for fn in get_fnlist(bbhandler, pkg_pn): + data = bbhandler.parse_recipe_file(fn) + maintainer = data.getVar("COREOS_RECIPE_MAINTAINER") + pn = data.getVar("PN") + packages = data.getVar("PACKAGES") + packages += data.getVar("PROVIDES") + pkg_dict[pn] = data + if maintainer: + supported_pkg_dict[pn] = data + for pkg in packages.split(): + pkg_dict[pkg] = data + if maintainer: + supported_pkg_dict[pkg] = data + + return pkg_dict, supported_pkg_dict + +def resolve_dependencies(pkg_dict, supported_pkg_dict): + ''' Resolve dependencies and add them to supported packages ''' + sup_with_dep_dict = {} + for pkg in supported_pkg_dict: + depends = supported_pkg_dict[pkg].getVar("DEPENDS") or '' + rdepends = supported_pkg_dict[pkg].getVar("RDEPENDS") or '' + sup_with_dep_dict[pkg] = pkg_dict[pkg] + + for d_pkg in depends.split(): + if ("virtual/" in d_pkg) or ("native" in d_pkg): + continue + sup_with_dep_dict[d_pkg] = pkg_dict[d_pkg] + + for r_pkg in rdepends.split(): + if ("virtual/" in r_pkg) or ("native" in r_pkg): + continue + sup_with_dep_dict[r_pkg] = pkg_dict[r_pkg] + + return sup_with_dep_dict + + +def display(supported_pkg_dict): + ''' Display all pkgs and COREOS_RECIPE_MAINTAINER information ''' + print(f'{str("RECIPE NAMES:"):40} {str("META-LAYER:"):40} {str("COS-MAINTAINER:"):50}') + for pn in supported_pkg_dict: + recipe_name = supported_pkg_dict[pn].getVar("P") + recipe_path = supported_pkg_dict[pn].getVar("FILE") + meta_layer = re.search("(?<=/layers/)(.*)(?=/recipe)", recipe_path).group(0) + maintainer = supported_pkg_dict[pn].getVar("COREOS_RECIPE_MAINTAINER") or 'Supported by Dependency' + + print(f'{recipe_name:40} {meta_layer:40} {maintainer:50}') + + +def get_unique_list(supported_pkg_dict): + ''' Create a list that only contains one package based on PN ''' + unique_dict = {} + for pkg in supported_pkg_dict: + pn = supported_pkg_dict[pkg].getVar("P") + unique_dict[pn] = supported_pkg_dict[pkg] + + return unique_dict + +def print_to_file(supported_pkg_dict, file): + ''' print list to a file ''' + with open(file, "w") as file: + file.write(f'{str("RECIPE NAMES:"):40} {str("META-LAYER:"):40} {str("COS-MAINTAINER:"):50}\n') + for pn in supported_pkg_dict: + recipe_name = supported_pkg_dict[pn].getVar("P") + recipe_path = supported_pkg_dict[pn].getVar("FILE") + meta_layer = re.search("(?<=/layers/)(.*)(?=/recipe)", recipe_path).group(0) + maintainer = supported_pkg_dict[pn].getVar("COREOS_RECIPE_MAINTAINER") or 'Supported by Dependency' + + file.write(f'{recipe_name:40} {meta_layer:40} {maintainer:50}\n') + +def main(): + parser = optparse.OptionParser( + description = "Lists all recipes supported by CoreOS.", + usage = """ + %prog [options]""") + + parser.add_option("-p", "--print", + help = "print all recipes that are supported", + action="store_const", dest="print", default=True) + parser.add_option("-f", "--file", + help = "store in file", + action="store", dest="file", type="string") + + options, args = parser.parse_args(sys.argv) + + with bb.tinfoil.Tinfoil() as bbhandler: + bbhandler.prepare() + print("Gathering recipe data...") + pkg_dict, supported_pkg_dict = get_recipesdata(bbhandler) + new_len = len(supported_pkg_dict) + old_len = 0 + + while old_len != new_len: + supported_pkg_dict = resolve_dependencies(pkg_dict, supported_pkg_dict) + old_len = new_len + new_len = len(supported_pkg_dict) + + unique_dict = get_unique_list(supported_pkg_dict) + supported_pkg_dict = unique_dict + + if options.print: + display(supported_pkg_dict) + + if options.file: + print_to_file(supported_pkg_dict, options.file) + + +if __name__ == "__main__": + main()