As part of an goal to eliminate Perl from libvirt build tools,
rewrite the check-file-access.pl tool in Python.
This was a straight conversion, manually going line-by-line to
change the syntax from Perl to Python. Thus the overall structure
of the file and approach is the same.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
tests/Makefile.am | 4 +-
tests/check-file-access.pl | 126 --------------------------------
tests/check-file-access.py | 121 ++++++++++++++++++++++++++++++
tests/file_access_whitelist.txt | 2 +-
4 files changed, 124 insertions(+), 129 deletions(-)
delete mode 100755 tests/check-file-access.pl
create mode 100755 tests/check-file-access.py
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f92710db43..48d1924707 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -450,14 +450,14 @@ EXTRA_DIST += $(test_scripts)
if WITH_LINUX
check-access: file-access-clean
VIR_TEST_FILE_ACCESS=1 $(MAKE) $(AM_MAKEFLAGS) check
- $(PERL) check-file-access.pl | sort -u
+ $(RUNUTF8) $(PYTHON) check-file-access.py | sort -u
file-access-clean:
test_file_access.txt
endif WITH_LINUX
EXTRA_DIST += \
- check-file-access.pl \
+ check-file-access.py \
file_access_whitelist.txt
if WITH_TESTS
diff --git a/tests/check-file-access.pl b/tests/check-file-access.pl
deleted file mode 100755
index ea0b7a18a2..0000000000
--- a/tests/check-file-access.pl
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright (C) 2016 Red Hat, Inc.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library. If not, see
-# <
http://www.gnu.org/licenses/>.
-#
-# This script is supposed to check test_file_access.txt file and
-# warn about file accesses outside our working tree.
-#
-#
-
-use strict;
-use warnings;
-
-my $access_file = "test_file_access.txt";
-my $whitelist_file = "file_access_whitelist.txt";
-
-my @known_actions = ("open", "fopen", "access",
"stat", "lstat", "connect");
-
-my @files;
-my @whitelist;
-
-open FILE, "<", $access_file or die "Unable to open $access_file:
$!";
-while (<FILE>) {
- chomp;
- if (/^(\S*):\s*(\S*):\s*(\S*)(\s*:\s*(.*))?$/) {
- my %rec;
- ${rec}{path} = $1;
- ${rec}{action} = $2;
- ${rec}{progname} = $3;
- if (defined $5) {
- ${rec}{testname} = $5;
- }
- push (@files, \%rec);
- } else {
- die "Malformed line $_";
- }
-}
-close FILE;
-
-open FILE, "<", $whitelist_file or die "Unable to open $whitelist_file:
$!";
-while (<FILE>) {
- chomp;
- if (/^\s*#.*$/) {
- # comment
- } elsif (/^(\S*):\s*(\S*)(:\s*(\S*)(\s*:\s*(.*))?)?$/ and
- grep /^$2$/, @known_actions) {
- # $path: $action: $progname: $testname
- my %rec;
- ${rec}{path} = $1;
- ${rec}{action} = $3;
- if (defined $4) {
- ${rec}{progname} = $4;
- }
- if (defined $6) {
- ${rec}{testname} = $6;
- }
- push (@whitelist, \%rec);
- } elsif (/^(\S*)(:\s*(\S*)(\s*:\s*(.*))?)?$/) {
- # $path: $progname: $testname
- my %rec;
- ${rec}{path} = $1;
- if (defined $3) {
- ${rec}{progname} = $3;
- }
- if (defined $5) {
- ${rec}{testname} = $5;
- }
- push (@whitelist, \%rec);
- } else {
- die "Malformed line $_";
- }
-}
-close FILE;
-
-# Now we should check if %traces is included in $whitelist. For
-# now checking just keys is sufficient
-my $error = 0;
-for my $file (@files) {
- my $match = 0;
-
- for my $rule (@whitelist) {
- if (not %${file}{path} =~ m/^$rule->{path}$/) {
- next;
- }
-
- if (defined %${rule}{action} and
- not %${file}{action} =~ m/^$rule->{action}$/) {
- next;
- }
-
- if (defined %${rule}{progname} and
- not %${file}{progname} =~ m/^$rule->{progname}$/) {
- next;
- }
-
- if (defined %${rule}{testname} and
- defined %${file}{testname} and
- not %${file}{testname} =~ m/^$rule->{testname}$/) {
- next;
- }
-
- $match = 1;
- }
-
- if (not $match) {
- $error = 1;
- print "$file->{path}: $file->{action}: $file->{progname}";
- print ": $file->{testname}" if defined %${file}{testname};
- print "\n";
- }
-}
-
-exit $error;
diff --git a/tests/check-file-access.py b/tests/check-file-access.py
new file mode 100755
index 0000000000..33583a5b52
--- /dev/null
+++ b/tests/check-file-access.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016-2019 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see
+# <
http://www.gnu.org/licenses/>.
+#
+# This script is supposed to check test_file_access.txt file and
+# warn about file accesses outside our working tree.
+#
+#
+
+from __future__ import print_function
+
+import re
+import sys
+
+access_file = "test_file_access.txt"
+whitelist_file = "file_access_whitelist.txt"
+
+known_actions = ["open", "fopen", "access",
"stat", "lstat", "connect"]
+
+files = []
+whitelist = []
+
+with open(access_file, "r") as fh:
+ for line in fh:
+ line = line.rstrip("\n")
+
+ m =
re.match(r'''^(\S*):\s*(\S*):\s*(\S*)(\s*:\s*(.*))?$''', line)
+ if m is not None:
+ rec = {
+ "path": m.group(1),
+ "action": m.group(2),
+ "progname": m.group(3),
+ "testname": m.group(5),
+ }
+ files.append(rec)
+ else:
+ raise Exception("Malformed line %s" % line)
+
+with open(whitelist_file, "r") as fh:
+ for line in fh:
+ line = line.rstrip("\n")
+
+ if re.match(r'''^\s*#.*$''', line):
+ continue # comment
+ if line == "":
+ continue
+
+ m =
re.match(r'''^(\S*):\s*(\S*)(:\s*(\S*)(\s*:\s*(.*))?)?$''', line)
+ if m is not None and m.group(2) in known_actions:
+ # $path: $action: $progname: $testname
+ rec = {
+ "path": m.group(1),
+ "action": m.group(3),
+ "progname": m.group(4),
+ "testname": m.group(6),
+ }
+ whitelist.append(rec)
+ else:
+ m =
re.match(r'''^(\S*)(:\s*(\S*)(\s*:\s*(.*))?)?$''', line)
+ if m is not None:
+ # $path: $progname: $testname
+ rec = {
+ "path": m.group(1),
+ "action": None,
+ "progname": m.group(3),
+ "testname": m.group(5),
+ }
+ whitelist.append(rec)
+ else:
+ raise Exception("Malformed line %s" % line)
+
+
+# Now we should check if %traces is included in $whitelist. For
+# now checking just keys is sufficient
+err = False
+for file in files:
+ match = False
+
+ for rule in whitelist:
+ if not re.match("^" + rule["path"], file["path"]):
+ continue
+
+ if (rule["action"] is not None and
+ not re.match("^" + rule["action"],
file["action"])):
+ continue
+
+ if (rule["progname"] is not None and
+ not re.match("^" + rule["progname"],
file["progname"])):
+ continue
+
+ if (rule["testname"] is not None and
+ file["testname"] is not None and
+ not re.match("^" + rule["testname"],
file["testname"])):
+ continue
+
+ match = True
+
+ if not match:
+ err = True
+ print("%s: %s: %s" % (file["path"], file["action"],
file["progname"]), file=sys.stderr, end="")
+ if file["testname"] is not None:
+ print(": %s" % file["testname"], file=sys.stderr,
end="")
+ print("", file=sys.stderr)
+
+if err:
+ sys.exit(1)
+sys.exit(0)
diff --git a/tests/file_access_whitelist.txt b/tests/file_access_whitelist.txt
index 3fb318cbab..5ec7ee63bb 100644
--- a/tests/file_access_whitelist.txt
+++ b/tests/file_access_whitelist.txt
@@ -5,7 +5,7 @@
# $path: $progname: $testname
# $path: $action: $progname: $testname
#
-# All these variables are evaluated as perl RE. So to allow
+# All these variables are evaluated as python RE. So to allow
# /dev/sda and /dev/sdb, you can just '/dev/sd[a-b]', or to allow
# /proc/$pid/status you can '/proc/\d+/status' and so on.
# Moreover, $action, $progname and $testname can be empty, in which
--
2.21.0