aboutsummaryrefslogtreecommitdiffstats
path: root/dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py
diff options
context:
space:
mode:
Diffstat (limited to 'dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py')
-rwxr-xr-xdynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py157
1 files changed, 157 insertions, 0 deletions
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 <mulhern@yoctoproject.org>
+
+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()