From a764533c20c9cedf0834138076d38d329982e1af Mon Sep 17 00:00:00 2001 From: Armin Kuster Date: Tue, 3 May 2022 14:31:21 -0700 Subject: meta-security: move perl and python recipes to dynamic layers structure Signed-off-by: Armin Kuster --- .../bastille/files/set_required_questions.py | 157 +++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100755 dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py (limited to 'dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py') diff --git a/dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py b/dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py new file mode 100755 index 0000000..f306109 --- /dev/null +++ b/dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 + +#Signed-off-by: Anne Mulhern + +import argparse, os, shutil, sys, tempfile, traceback +from os import path + + + +def get_config(lines): + """ + From a sequence of lines retrieve the question file name, question identifier + pairs. + """ + for l in lines: + if not l.startswith("#"): + try: + (coord, value) = l.split("=") + try: + (fname, ident) = coord.split(".") + yield fname, ident + except ValueError as e: + raise ValueError("Badly formatted coordinates %s in line %s." % (coord, l.strip())) + except ValueError as e: + raise ValueError("Skipping badly formatted line %s, %s" % (l.strip(), e)) + + + +def check_contains(line, name): + """ + Check if the value field for REQUIRE_DISTRO contains the given name. + @param name line The REQUIRE_DISTRO line + @param name name The name to look for in the value field of the line. + """ + try: + (label, distros) = line.split(":") + return name in distros.split() + except ValueError as e: + raise ValueError("Error splitting REQUIRE_DISTRO line: %s" % e) + + + +def add_requires(the_ident, distro, lines): + + """ + Yield a sequence of lines the same as lines except that where + the_ident matches a question identifier change the REQUIRE_DISTRO so that + it includes the specified distro. + + @param name the_ident The question identifier to be matched. + @param name distro The distribution to added to the questions REQUIRE_DISTRO + field. + @param lines The sequence to be processed. + """ + for l in lines: + yield l + if l.startswith("LABEL:"): + try: + (label, ident) = l.split(":") + if ident.strip() == the_ident: + break + except ValueError as e: + raise ValueError("Unexpected line %s in questions file." % l.strip()) + for l in lines: + if l.startswith("REQUIRE_DISTRO"): + if not check_contains(l, distro): + yield l.rstrip() + " " + distro + "\n" + else: + yield l + break; + else: + yield l + for l in lines: + yield l + + + +def xform_file(qfile, distro, qlabel): + """ + Transform a Questions file. + @param name qfile The designated questions file. + @param name distro The distribution to add to the required distributions. + @param name qlabel The question label for which the distro is to be added. + """ + questions_in = open(qfile) + questions_out = tempfile.NamedTemporaryFile(mode="w+", delete=False) + for l in add_requires(qlabel, distro, questions_in): + questions_out.write(l) + questions_out.close() + questions_in.close() + shutil.copystat(qfile, questions_out.name) + os.remove(qfile) + shutil.move(questions_out.name, qfile) + + + +def handle_args(parser): + parser.add_argument('config_file', + help = "Configuration file path.") + parser.add_argument('questions_dir', + help = "Directory containing Questions files.") + parser.add_argument('--distro', '-d', + help = "The distribution, the default is Yocto.", + default = "Yocto") + parser.add_argument('--debug', '-b', + help = "Print debug information.", + action = 'store_true') + return parser.parse_args() + + + +def check_args(args): + args.config_file = os.path.abspath(args.config_file) + args.questions_dir = os.path.abspath(args.questions_dir) + + if not os.path.isdir(args.questions_dir): + raise ValueError("Specified Questions directory %s does not exist or is not a directory." % args.questions_dir) + + if not os.path.isfile(args.config_file): + raise ValueError("Specified configuration file %s not found." % args.config_file) + + + +def main(): + opts = handle_args(argparse.ArgumentParser(description="A simple script that sets required questions based on the question/answer pairs in a configuration file.")) + + try: + check_args(opts) + except ValueError as e: + if opts.debug: + traceback.print_exc() + else: + sys.exit("Fatal error:\n%s" % e) + + + try: + config_in = open(opts.config_file) + for qfile, qlabel in get_config(config_in): + questions_file = os.path.join(opts.questions_dir, qfile + ".txt") + xform_file(questions_file, opts.distro, qlabel) + config_in.close() + + except IOError as e: + if opts.debug: + traceback.print_exc() + else: + sys.exit("Fatal error reading or writing file:\n%s" % e) + except ValueError as e: + if opts.debug: + traceback.print_exc() + else: + sys.exit("Fatal error:\n%s" % e) + + + +if __name__ == "__main__": + main() -- cgit v1.2.3-54-g00ecf