diff --git a/Makefile.am b/Makefile.am
index 7fb6e41ff0..79ad83b0bf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -58,6 +58,7 @@ EXTRA_DIST = \
scripts/check-symsorting.py \
scripts/dtrace2systemtap.py \
scripts/esx_vi_generator.py \
+ scripts/genaclperms.py \
scripts/genpolkit.py \
scripts/gensystemtap.py \
scripts/group-qemu-caps.py \
diff --git a/docs/Makefile.am b/docs/Makefile.am
index bf479c6b38..4dae290940 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -344,7 +344,6 @@ schemadir = $(pkgdatadir)/schemas
schema_DATA = $(wildcard $(srcdir)/schemas/*.rng)
EXTRA_DIST= \
- genaclperms.pl \
site.xsl subsite.xsl newapi.xsl page.xsl \
wrapstring.xsl \
$(dot_html_in) $(dot_rst) $(gif) $(apipng) \
@@ -359,8 +358,8 @@ EXTRA_DIST= \
acl_generated = aclperms.htmlinc
aclperms.htmlinc: $(top_srcdir)/src/access/viraccessperm.h \
- $(srcdir)/genaclperms.pl Makefile.am
- $(AM_V_GEN)$(PERL) $(srcdir)/genaclperms.pl $< > $@
+ $(top_srcdir)/scripts/genaclperms.py Makefile.am
+ $(AM_V_GEN)$(RUNUTF8) $(PYTHON) $(top_srcdir)/scripts/genaclperms.py $< > $@
CLEANFILES = \
$(dot_html) \
diff --git a/docs/genaclperms.pl b/docs/genaclperms.pl
deleted file mode 100755
index 0de2cfad4d..0000000000
--- a/docs/genaclperms.pl
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright (C) 2013 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
-# .
-#
-
-use strict;
-use warnings;
-
-my @objects = (
- "CONNECT", "DOMAIN", "INTERFACE",
- "NETWORK_PORT", "NETWORK", "NODE_DEVICE",
- "NWFILTER_BINDING", "NWFILTER",
- "SECRET", "STORAGE_POOL", "STORAGE_VOL",
- );
-
-my %class;
-
-foreach my $object (@objects) {
- my $class = lc $object;
-
- $class =~ s/(^\w|_\w)/uc $1/eg;
- $class =~ s/_//g;
- $class =~ s/Nwfilter/NWFilter/;
- $class = "vir" . $class . "Ptr";
-
- $class{$object} = $class;
-}
-
-my $objects = join ("|", @objects);
-
-my %opts;
-my $in_opts = 0;
-
-my %perms;
-
-while (<>) {
- if ($in_opts) {
- if (m,\*/,) {
- $in_opts = 0;
- } elsif (/\*\s*\@(\w+):\s*(.*?)\s*$/) {
- $opts{$1} = $2;
- }
- } elsif (m,/\*\*,) {
- $in_opts = 1;
- } elsif (/VIR_ACCESS_PERM_($objects)_((?:\w|_)+),/) {
- my $object = $1;
- my $perm = lc $2;
- next if $perm eq "last";
-
- $perm =~ s/_/-/g;
-
- $perms{$object} = {} unless exists $perms{$object};
- $perms{$object}->{$perm} = {
- desc => $opts{desc},
- message => $opts{message},
- anonymous => $opts{anonymous}
- };
- %opts = ();
- }
-}
-
-print <
-
-
-
-EOF
-
-foreach my $object (sort { $a cmp $b } keys %perms) {
- my $class = $class{$object};
- my $olink = lc "object_" . $object;
- print <$class
-
-
-
- Permission |
- Description |
-
-
-
-EOF
-
- foreach my $perm (sort { $a cmp $b } keys %{$perms{$object}}) {
- my $description = $perms{$object}->{$perm}->{desc};
-
- die "missing description for $object.$perm" unless
- defined $description;
-
- my $plink = lc "perm_" . $object . "_" . $perm;
- $plink =~ s/-/_/g;
-
- print <
- $perm |
- $description |
-
-EOF
-
- }
-
- print <
-
-EOF
-}
-
-print <
-
-EOF
diff --git a/scripts/genaclperms.py b/scripts/genaclperms.py
new file mode 100755
index 0000000000..e228b3ef60
--- /dev/null
+++ b/scripts/genaclperms.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2013-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
+# .
+#
+
+import re
+import sys
+
+objects = [
+ "CONNECT", "DOMAIN", "INTERFACE",
+ "NETWORK_PORT", "NETWORK", "NODE_DEVICE",
+ "NWFILTER_BINDING", "NWFILTER",
+ "SECRET", "STORAGE_POOL", "STORAGE_VOL",
+]
+
+
+classes = {}
+
+for obj in objects:
+ klass = obj.lower()
+
+ klass = re.sub(r'''(^\w|_\w)''', lambda a: a.group(1).upper(), klass)
+ klass = klass.replace("_", "")
+ klass = klass.replace("Nwfilter", "NWFilter")
+ klass = "vir" + klass + "Ptr"
+
+ classes[obj] = klass
+
+
+objectstr = "|".join(objects)
+
+opts = {}
+in_opts = {}
+
+perms = {}
+
+aclfile = sys.argv[1]
+with open(aclfile, "r") as fh:
+ for line in fh:
+ if in_opts:
+ if line.find("*/") != -1:
+ in_opts = False
+ else:
+ m = re.search(r'''\*\s*\@(\w+):\s*(.*?)\s*$''', line)
+ if m is not None:
+ opts[m.group(1)] = m.group(2)
+ elif line.find("**") != -1:
+ in_opts = True
+ else:
+ m = re.search(r'''VIR_ACCESS_PERM_(%s)_((?:\w|_)+),''' %
+ objectstr, line)
+ if m is not None:
+ obj = m.group(1)
+ perm = m.group(2).lower()
+ if perm == "last":
+ continue
+
+ perm = perm.replace("_", "-")
+
+ if obj not in perms:
+ perms[obj] = {}
+ perms[obj][perm] = {
+ "desc": opts.get("desc", None),
+ "message": opts.get("message", None),
+ "anonymous": opts.get("anonymous", None),
+ }
+ opts = {}
+
+print('')
+print('')
+print('')
+print(' ')
+
+for obj in sorted(perms.keys()):
+ klass = classes[obj]
+
+ olink = "object_" + obj.lower()
+
+ print(' ' % (olink, klass))
+ print(' ')
+ print(' ')
+ print(' ')
+ print(' Permission | ')
+ print(' Description | ')
+ print('
')
+ print(' ')
+ print(' ')
+
+ for perm in sorted(perms[obj].keys()):
+ description = perms[obj][perm]["desc"]
+
+ if description is None:
+ raise Exception("missing description for %s.%s" % (obj, perm))
+
+ plink = "perm_" + obj.lower() + "_" + perm.lower()
+ plink = plink.replace("-", "_")
+
+ print(' ')
+ print(' %s | ' % (plink, perm))
+ print(' %s | ' % description)
+ print('
')
+
+ print(' ')
+ print('
')
+
+print(' ')
+print('')