diff options
author | Armin Kuster <akuster808@gmail.com> | 2022-05-03 14:31:21 -0700 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2022-05-14 10:51:32 -0700 |
commit | a764533c20c9cedf0834138076d38d329982e1af (patch) | |
tree | 4cedb5cc647faeef6636ad0319b495cf89d8a2ea /dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py | |
parent | 20c13f6335165d693f7f3270c829b3069dbbad66 (diff) | |
download | meta-security-a764533c20c9cedf0834138076d38d329982e1af.tar.gz |
meta-security: move perl and python recipes to dynamic layers structure
Signed-off-by: Armin Kuster <akuster808@gmail.com>
Diffstat (limited to 'dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py')
-rwxr-xr-x | dynamic-layers/meta-perl/recipes-security/bastille/files/set_required_questions.py | 157 |
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 @@ | |||
1 | #!/usr/bin/env python3 | ||
2 | |||
3 | #Signed-off-by: Anne Mulhern <mulhern@yoctoproject.org> | ||
4 | |||
5 | import argparse, os, shutil, sys, tempfile, traceback | ||
6 | from os import path | ||
7 | |||
8 | |||
9 | |||
10 | def get_config(lines): | ||
11 | """ | ||
12 | From a sequence of lines retrieve the question file name, question identifier | ||
13 | pairs. | ||
14 | """ | ||
15 | for l in lines: | ||
16 | if not l.startswith("#"): | ||
17 | try: | ||
18 | (coord, value) = l.split("=") | ||
19 | try: | ||
20 | (fname, ident) = coord.split(".") | ||
21 | yield fname, ident | ||
22 | except ValueError as e: | ||
23 | raise ValueError("Badly formatted coordinates %s in line %s." % (coord, l.strip())) | ||
24 | except ValueError as e: | ||
25 | raise ValueError("Skipping badly formatted line %s, %s" % (l.strip(), e)) | ||
26 | |||
27 | |||
28 | |||
29 | def check_contains(line, name): | ||
30 | """ | ||
31 | Check if the value field for REQUIRE_DISTRO contains the given name. | ||
32 | @param name line The REQUIRE_DISTRO line | ||
33 | @param name name The name to look for in the value field of the line. | ||
34 | """ | ||
35 | try: | ||
36 | (label, distros) = line.split(":") | ||
37 | return name in distros.split() | ||
38 | except ValueError as e: | ||
39 | raise ValueError("Error splitting REQUIRE_DISTRO line: %s" % e) | ||
40 | |||
41 | |||
42 | |||
43 | def add_requires(the_ident, distro, lines): | ||
44 | |||
45 | """ | ||
46 | Yield a sequence of lines the same as lines except that where | ||
47 | the_ident matches a question identifier change the REQUIRE_DISTRO so that | ||
48 | it includes the specified distro. | ||
49 | |||
50 | @param name the_ident The question identifier to be matched. | ||
51 | @param name distro The distribution to added to the questions REQUIRE_DISTRO | ||
52 | field. | ||
53 | @param lines The sequence to be processed. | ||
54 | """ | ||
55 | for l in lines: | ||
56 | yield l | ||
57 | if l.startswith("LABEL:"): | ||
58 | try: | ||
59 | (label, ident) = l.split(":") | ||
60 | if ident.strip() == the_ident: | ||
61 | break | ||
62 | except ValueError as e: | ||
63 | raise ValueError("Unexpected line %s in questions file." % l.strip()) | ||
64 | for l in lines: | ||
65 | if l.startswith("REQUIRE_DISTRO"): | ||
66 | if not check_contains(l, distro): | ||
67 | yield l.rstrip() + " " + distro + "\n" | ||
68 | else: | ||
69 | yield l | ||
70 | break; | ||
71 | else: | ||
72 | yield l | ||
73 | for l in lines: | ||
74 | yield l | ||
75 | |||
76 | |||
77 | |||
78 | def xform_file(qfile, distro, qlabel): | ||
79 | """ | ||
80 | Transform a Questions file. | ||
81 | @param name qfile The designated questions file. | ||
82 | @param name distro The distribution to add to the required distributions. | ||
83 | @param name qlabel The question label for which the distro is to be added. | ||
84 | """ | ||
85 | questions_in = open(qfile) | ||
86 | questions_out = tempfile.NamedTemporaryFile(mode="w+", delete=False) | ||
87 | for l in add_requires(qlabel, distro, questions_in): | ||
88 | questions_out.write(l) | ||
89 | questions_out.close() | ||
90 | questions_in.close() | ||
91 | shutil.copystat(qfile, questions_out.name) | ||
92 | os.remove(qfile) | ||
93 | shutil.move(questions_out.name, qfile) | ||
94 | |||
95 | |||
96 | |||
97 | def handle_args(parser): | ||
98 | parser.add_argument('config_file', | ||
99 | help = "Configuration file path.") | ||
100 | parser.add_argument('questions_dir', | ||
101 | help = "Directory containing Questions files.") | ||
102 | parser.add_argument('--distro', '-d', | ||
103 | help = "The distribution, the default is Yocto.", | ||
104 | default = "Yocto") | ||
105 | parser.add_argument('--debug', '-b', | ||
106 | help = "Print debug information.", | ||
107 | action = 'store_true') | ||
108 | return parser.parse_args() | ||
109 | |||
110 | |||
111 | |||
112 | def check_args(args): | ||
113 | args.config_file = os.path.abspath(args.config_file) | ||
114 | args.questions_dir = os.path.abspath(args.questions_dir) | ||
115 | |||
116 | if not os.path.isdir(args.questions_dir): | ||
117 | raise ValueError("Specified Questions directory %s does not exist or is not a directory." % args.questions_dir) | ||
118 | |||
119 | if not os.path.isfile(args.config_file): | ||
120 | raise ValueError("Specified configuration file %s not found." % args.config_file) | ||
121 | |||
122 | |||
123 | |||
124 | def main(): | ||
125 | opts = handle_args(argparse.ArgumentParser(description="A simple script that sets required questions based on the question/answer pairs in a configuration file.")) | ||
126 | |||
127 | try: | ||
128 | check_args(opts) | ||
129 | except ValueError as e: | ||
130 | if opts.debug: | ||
131 | traceback.print_exc() | ||
132 | else: | ||
133 | sys.exit("Fatal error:\n%s" % e) | ||
134 | |||
135 | |||
136 | try: | ||
137 | config_in = open(opts.config_file) | ||
138 | for qfile, qlabel in get_config(config_in): | ||
139 | questions_file = os.path.join(opts.questions_dir, qfile + ".txt") | ||
140 | xform_file(questions_file, opts.distro, qlabel) | ||
141 | config_in.close() | ||
142 | |||
143 | except IOError as e: | ||
144 | if opts.debug: | ||
145 | traceback.print_exc() | ||
146 | else: | ||
147 | sys.exit("Fatal error reading or writing file:\n%s" % e) | ||
148 | except ValueError as e: | ||
149 | if opts.debug: | ||
150 | traceback.print_exc() | ||
151 | else: | ||
152 | sys.exit("Fatal error:\n%s" % e) | ||
153 | |||
154 | |||
155 | |||
156 | if __name__ == "__main__": | ||
157 | main() | ||