3 # check-config -- check the current config for issues
7 my $P = 'check-config';
10 if ($ARGV[0] eq '--test') {
12 } elsif ($#ARGV != 4) {
13 die "Usage: $P <config> <arch> <flavour> <commonconfig> <warn-only>\n";
16 my ($config, $arch, $flavour, $commonconfig, $warn_only) = @ARGV;
18 my $checks = "$commonconfig/enforce";
21 # If we are in overridden then still perform the checks and emit the messages
22 # but do not return failure. Those items marked FATAL will alway trigger
25 $fail_exit = 0 if ($warn_only eq 'true' || $warn_only eq '1');
28 # Predicate execution engine.
36 for ($off = 0; $off <= length($rest); $off++) {
37 $char = substr($rest, $off, 1);
40 } elsif ($char eq ')') {
42 } elsif ($depth == 0 && $char eq '&') {
44 } elsif ($depth == 0 && $char eq '|') {
49 die "$P: $rest: missing close parenthesis ')'\n";
50 } elsif ($depth < 0) {
51 die "$P: $rest: missing open parenthesis '('\n";
54 ($pred, $rest) = (substr($rest, 0, $off), substr($rest, $off + 1));
59 #print "pred<$pred> rest<$rest> char<$char>\n";
60 ($pred, $rest, $char);
65 my (@a) = split(' ', $pred);
67 if ($a[0] eq 'arch') {
68 die "$P: $pred: malformed -- $pred <arch>\n" if ($#a != 1);
69 #print " *** ARCH<$arch ?? $a[1]>\n";
70 return ($arch eq $a[1])
71 } elsif ($a[0] eq 'flavour') {
72 die "$P: $pred: malformed -- $pred <flavour>\n" if ($#a != 1);
73 #print " *** FLAVOUR<$flavour ?? $a[1]>\n";
74 return ($flavour eq $a[1])
75 } elsif ($a[0] eq 'value') {
76 die "$P: $pred: malformed -- $pred <name> <val>\n" if ($#a != 2);
77 #print " *** CHECK<$a[1] $a[2] ?? " . $values{$a[1]} . ">\n";
78 return ($values{$a[1]} eq $a[2]);
79 } elsif ($a[0] eq 'exists') {
80 die "$P: $pred: malformed -- $pred <name>\n" if ($#a != 1);
81 return (defined $values{$a[1]});
83 die "$P: $pred: unknown predicate\n";
93 #print "pred_exec<$rest>\n";
95 ($pred, $rest, $sep) = pred_first($rest);
97 # Leading ! implies inversion.
98 if ($pred =~ /^\s*!\s*(.*)$/) {
99 #print " invert<$1>\n";
100 $res = !pred_exec($1);
102 # Recurse left for complex expressions.
103 } elsif ($pred =~ /^\s*\((.*)\)\s*$/) {
104 #print " left<$1>\n";
105 $res = pred_exec($1);
107 # Check for common syntax issues.
108 } elsif ($pred eq '') {
109 if ($sep eq '&' || $sep eq '|') {
110 die "$P: $pred$rest: malformed binary operator\n";
112 die "$P: $pred$rest: syntax error\n";
115 # A predicate, execute it.
117 #print " DO<$pred> sep<$sep>\n";
118 $res = pred_do($pred);
121 #print " pre-return res<$res> sep<$sep>\n";
125 # Recurse right for binary operators -- note these are lazy.
126 } elsif ($sep eq '&' || $sep eq '|') {
127 #print " right<$rest> ? sep<$sep> res<$res>\n";
128 if ($rest =~ /^\s*($|\||\&)/) {
129 die "$P: $pred$rest: malformed binary operator\n";
131 if (($res && $sep eq '&') || (!$res && $sep eq '|')) {
132 #print " right<$rest>\n";
133 $res = pred_exec($rest);
137 die "$P: $pred$rest: malformed predicate\n";
139 #print " return res<$res> sep<$sep>\n";
149 my ($pred, $eres, $eerr) = @_;
150 my ($res, $err, $fail);
153 if ($test != 0 && $test != $test_total - 1) {
158 $res = pred_exec($pred);
167 if (defined $eres && $res != $eres) {
168 $fail = "result missmatch, expected $eres returned $res";
170 if (defined $eerr && $err eq '') {
171 $fail = "error missmatch, expected '$eerr' returned success";
172 } elsif (defined $eerr && $err !~ /$eerr/) {
173 $fail = "error missmatch, expected '$eerr' returned '$err'";
174 } elsif (!defined $eerr && $err ne '') {
175 $fail = "error missmatch, expected success returned '$err'";
181 print "$pred: $test_total: FAIL: $fail\n";
183 #print "TEST<$pred> eres<$eres> eerr<$eerr> res<$res> err<$err>\n";
187 $flavour = 'MYFLAVOUR';
188 %values = ( 'ENABLED' => 'y', 'DISABLED' => 'n' );
191 my $eunkn = 'unknown predicate';
192 my $epred = 'malformed';
193 my $eclose = 'missing close parenthesis';
194 my $eopen = 'missing open parenthesis';
195 my $ebinary = 'malformed binary operator';
197 # Basic predicate tests.
198 print "TEST: $test_total: basic predicate tests ...\n";
200 pred_test('nosuchcommand', undef, $eunkn);
201 pred_test('arch', undef, $epred);
202 pred_test('arch MYARCH MYARCH', undef, $epred);
203 pred_test('arch MYARCH', 1, undef);
204 pred_test('arch NOTMYARCH', 0, undef);
206 pred_test('flavour', undef, $epred);
207 pred_test('flavour MYFLAVOUR myflavour', undef, $epred);
208 pred_test('flavour MYFLAVOUR', 1, undef);
209 pred_test('flavour NOTMYFLAVOUR', 0, undef);
211 pred_test('value', undef, $epred);
212 pred_test('value ENABLED', undef, $epred);
213 pred_test('value ENABLED ENABLED ENABLED', undef, $epred);
214 pred_test('value ENABLED y', 1, undef);
215 pred_test('value ENABLED n', 0, undef);
216 pred_test('value DISABLED n', 1, undef);
217 pred_test('value DISABLED y', 0, undef);
219 pred_test('exists', undef, $epred);
220 pred_test('exists ENABLED ENABLED', undef, $epred);
221 pred_test('exists ENABLED', 1, undef);
222 pred_test('exists DISABLED', 1, undef);
223 pred_test('exists MISSING', 0, undef);
225 print "TEST: $test_total: inversion tests ...\n";
226 pred_test('!exists ENABLED', 0, undef);
227 pred_test('!exists MISSING', 1, undef);
228 pred_test('!!exists ENABLED', 1, undef);
229 pred_test('!!exists MISSING', 0, undef);
230 pred_test('!!!exists ENABLED', 0, undef);
231 pred_test('!!!exists MISSING', 1, undef);
233 print "TEST: $test_total: parentheses tests ...\n";
234 pred_test('(exists ENABLED)', 1, undef);
235 pred_test('((exists ENABLED))', 1, undef);
236 pred_test('(((exists ENABLED)))', 1, undef);
237 pred_test('(exists MISSING)', 0, undef);
238 pred_test('((exists MISSING))', 0, undef);
239 pred_test('(((exists MISSING)))', 0, undef);
241 pred_test('(!exists ENABLED)', 0, undef);
242 pred_test('((!exists ENABLED))', 0, undef);
243 pred_test('(((!exists ENABLED)))', 0, undef);
244 pred_test('(!exists MISSING)', 1, undef);
245 pred_test('((!exists MISSING))', 1, undef);
246 pred_test('(((!exists MISSING)))', 1, undef);
248 pred_test('((!(exists ENABLED)))', 0, undef);
249 pred_test('((!(exists MISSING)))', 1, undef);
250 pred_test('(!((exists ENABLED)))', 0, undef);
251 pred_test('(!((exists MISSING)))', 1, undef);
252 pred_test('!(((exists ENABLED)))', 0, undef);
253 pred_test('!(((exists MISSING)))', 1, undef);
254 pred_test('!((!(exists ENABLED)))', 1, undef);
255 pred_test('!((!(exists MISSING)))', 0, undef);
256 pred_test('!(!(!(exists ENABLED)))', 0, undef);
257 pred_test('!(!(!(exists MISSING)))', 1, undef);
259 pred_test('(', undef, $eclose);
260 pred_test('()(', undef, $eclose);
261 pred_test('(())(', undef, $eclose);
262 pred_test('((()))(', undef, $eclose);
263 pred_test('(()', undef, $eclose);
264 pred_test('((())', undef, $eclose);
265 pred_test('(((()))', undef, $eclose);
266 pred_test('(()()', undef, $eclose);
267 pred_test('((())()', undef, $eclose);
269 pred_test(')', undef, $eopen);
270 pred_test('())', undef, $eopen);
271 pred_test('(()))', undef, $eopen);
272 pred_test('((())))', undef, $eopen);
274 print "TEST: $test_total: binary and tests ...\n";
276 pred_test('exists ENABLED &', undef, $ebinary);
277 pred_test('& exists ENABLED', undef, $ebinary);
278 pred_test('exists ENABLED & & exists ENABLED', undef, $ebinary);
280 pred_test('exists MISSING & exists MISSING', 0, undef);
281 pred_test('exists MISSING & exists ENABLED', 0, undef);
282 pred_test('exists ENABLED & exists MISSING', 0, undef);
283 pred_test('exists ENABLED & exists ENABLED', 1, undef);
285 pred_test('exists MISSING & exists MISSING & exists MISSING', 0, undef);
286 pred_test('exists MISSING & exists MISSING & exists ENABLED', 0, undef);
287 pred_test('exists MISSING & exists ENABLED & exists MISSING', 0, undef);
288 pred_test('exists MISSING & exists ENABLED & exists ENABLED', 0, undef);
289 pred_test('exists ENABLED & exists MISSING & exists MISSING', 0, undef);
290 pred_test('exists ENABLED & exists MISSING & exists ENABLED', 0, undef);
291 pred_test('exists ENABLED & exists ENABLED & exists MISSING', 0, undef);
292 pred_test('exists ENABLED & exists ENABLED & exists ENABLED', 1, undef);
294 print "TEST: $test_total: binary or tests ...\n";
296 pred_test('exists ENABLED |', undef, $ebinary);
297 pred_test('| exists ENABLED', undef, $ebinary);
298 pred_test('exists ENABLED | | exists ENABLED', undef, $ebinary);
300 pred_test('exists MISSING | exists MISSING', 0, undef);
301 pred_test('exists MISSING | exists ENABLED', 1, undef);
302 pred_test('exists ENABLED | exists MISSING', 1, undef);
303 pred_test('exists ENABLED | exists ENABLED', 1, undef);
305 pred_test('exists MISSING | exists MISSING | exists MISSING', 0, undef);
306 pred_test('exists MISSING | exists MISSING | exists ENABLED', 1, undef);
307 pred_test('exists MISSING | exists ENABLED | exists MISSING', 1, undef);
308 pred_test('exists MISSING | exists ENABLED | exists ENABLED', 1, undef);
309 pred_test('exists ENABLED | exists MISSING | exists MISSING', 1, undef);
310 pred_test('exists ENABLED | exists MISSING | exists ENABLED', 1, undef);
311 pred_test('exists ENABLED | exists ENABLED | exists MISSING', 1, undef);
312 pred_test('exists ENABLED | exists ENABLED | exists ENABLED', 1, undef);
314 print "TEST: $test_total: binary or/and combination tests ...\n";
316 pred_test('exists MISSING | exists MISSING & exists MISSING', 0, undef);
317 pred_test('exists MISSING | exists MISSING & exists ENABLED', 0, undef);
318 pred_test('exists MISSING | exists ENABLED & exists MISSING', 0, undef);
319 pred_test('exists MISSING | exists ENABLED & exists ENABLED', 1, undef);
320 pred_test('exists ENABLED | exists MISSING & exists MISSING', 1, undef);
321 pred_test('exists ENABLED | exists MISSING & exists ENABLED', 1, undef);
322 pred_test('exists ENABLED | exists ENABLED & exists MISSING', 1, undef);
323 pred_test('exists ENABLED | exists ENABLED & exists ENABLED', 1, undef);
325 print "TEST: $test_total: binary and/or combination tests ...\n";
327 pred_test('exists MISSING & exists MISSING | exists MISSING', 0, undef);
328 pred_test('exists MISSING & exists MISSING | exists ENABLED', 0, undef);
329 pred_test('exists MISSING & exists ENABLED | exists MISSING', 0, undef);
330 pred_test('exists MISSING & exists ENABLED | exists ENABLED', 0, undef);
331 pred_test('exists ENABLED & exists MISSING | exists MISSING', 0, undef);
332 pred_test('exists ENABLED & exists MISSING | exists ENABLED', 1, undef);
333 pred_test('exists ENABLED & exists ENABLED | exists MISSING', 1, undef);
334 pred_test('exists ENABLED & exists ENABLED | exists ENABLED', 1, undef);
337 print "TEST: $test_good/$test_total succeeded\n";
342 # Load up the current configuration values -- FATAL if this fails
343 print "$P: $config: loading config\n";
344 open(CONFIG, "<$config") || die "$P: $config: open failed -- $! -- aborting\n";
347 /^#*\s*(CONFIG_\w+)[\s=](.*)$/ or next;
348 if ($2 eq 'is not set') {
356 # FATAL: Check if we have an enforcement list.
360 print "$P: $checks: loading checks\n";
361 open(CHECKS, "<$checks") || die "$P: $checks: open failed -- $! -- aborting\n";
367 if ($line =~ /\\$/) {
372 $line =~ /^\s*$/ && next;
374 #print "CHECK: <$line>\n";
376 my $result = pred_exec($line);
378 print "$P: FAIL: $line\n";
379 $exit_val = $fail_exit;
388 print "$P: $pass/$total checks passed -- exit $exit_val\n";