[libvirt] [PATCH v3 16/22] src: rewrite polkit ACL generator in Python

Daniel P. Berrangé berrange at redhat.com
Tue Sep 24 14:58:57 UTC 2019


As part of an goal to eliminate Perl from libvirt build tools,
rewrite the genpolkit.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 at redhat.com>
---
 src/access/Makefile.inc.am |   7 ++-
 src/access/genpolkit.pl    | 119 ------------------------------------
 src/access/genpolkit.py    | 122 +++++++++++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+), 122 deletions(-)
 delete mode 100755 src/access/genpolkit.pl
 create mode 100755 src/access/genpolkit.py

diff --git a/src/access/Makefile.inc.am b/src/access/Makefile.inc.am
index 4dc742f4e5..1550cce720 100644
--- a/src/access/Makefile.inc.am
+++ b/src/access/Makefile.inc.am
@@ -44,7 +44,7 @@ GENERATED_SYM_FILES += $(ACCESS_DRIVER_SYM_FILES)
 
 EXTRA_DIST += \
 	$(ACCESS_DRIVER_POLKIT_POLICY) \
-	access/genpolkit.pl \
+	access/genpolkit.py \
 	$(NULL)
 
 
@@ -63,8 +63,9 @@ libvirt_driver_access_la_LIBADD =
 
 
 $(ACCESS_DRIVER_POLKIT_POLICY): $(srcdir)/access/viraccessperm.h \
-    $(srcdir)/access/genpolkit.pl Makefile.am
-	$(AM_V_GEN)$(PERL) $(srcdir)/access/genpolkit.pl < $< > $@ || rm -f $@
+    $(srcdir)/access/genpolkit.py Makefile.am
+	$(AM_V_GEN)$(RUNUTF8) $(PYTHON) \
+	$(srcdir)/access/genpolkit.py $< > $@ || rm -f $@
 
 if WITH_POLKIT
 libvirt_driver_access_la_SOURCES += $(ACCESS_DRIVER_POLKIT_SOURCES)
diff --git a/src/access/genpolkit.pl b/src/access/genpolkit.pl
deleted file mode 100755
index f8f20caf65..0000000000
--- a/src/access/genpolkit.pl
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/env perl
-#
-# Copyright (C) 2012-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
-# <http://www.gnu.org/licenses/>.
-#
-
-use strict;
-use warnings;
-
-my @objects = (
-    "CONNECT", "DOMAIN", "INTERFACE", "NETWORK_PORT",
-    "NETWORK","NODE_DEVICE", "NWFILTER_BINDING", "NWFILTER",
-    "SECRET", "STORAGE_POOL", "STORAGE_VOL",
-    );
-
-my $objects = join ("|", @objects);
-
-# Data we're going to be generating looks like this
-#
-# <policyconfig>
-#   <action id="org.libvirt.unix.monitor">
-#     <description>Monitor local virtualized systems</description>
-#     <message>System policy prevents monitoring of local virtualized systems</message>
-#     <defaults>
-#       <allow_any>yes</allow_any>
-#       <allow_inactive>yes</allow_inactive>
-#       <allow_active>yes</allow_active>
-#     </defaults>
-#   </action>
-#   ...more <action> rules...
-# </policyconfig>
-
-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 = lc $1;
-        my $perm = lc $2;
-        next if $perm eq "last";
-
-        $object =~ s/_/-/g;
-        $perm =~ s/_/-/g;
-
-        $perms{$object} = {} unless exists $perms{$object};
-        $perms{$object}->{$perm} = {
-            desc => $opts{desc},
-            message => $opts{message},
-            anonymous => $opts{anonymous}
-        };
-        %opts = ();
-    }
-}
-
-print <<EOF;
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE policyconfig PUBLIC "-//freedesktop//DTD polkit Policy Configuration 1.0//EN"
-    "http://www.freedesktop.org/software/polkit/policyconfig-1.dtd">
-<policyconfig>
-  <vendor>Libvirt Project</vendor>
-  <vendor_url>https://libvirt.org</vendor_url>
-EOF
-
-foreach my $object (sort { $a cmp $b } keys %perms) {
-    foreach my $perm (sort { $a cmp $b } keys %{$perms{$object}}) {
-        my $description = $perms{$object}->{$perm}->{desc};
-        my $message = $perms{$object}->{$perm}->{message};
-        my $anonymous = $perms{$object}->{$perm}->{anonymous};
-
-        die "missing description for $object.$perm" unless
-            defined $description;
-        die "missing message for $object.$perm" unless
-            defined $message;
-
-        my $allow_any = $anonymous ? "yes" : "no";
-        my $allow_inactive = $allow_any;
-        my $allow_active = $allow_any;
-
-        print <<EOF;
-  <action id="org.libvirt.api.$object.$perm">
-    <description>$description</description>
-    <message>$message</message>
-    <defaults>
-      <allow_any>$allow_any</allow_any>
-      <allow_inactive>$allow_inactive</allow_inactive>
-      <allow_active>$allow_active</allow_active>
-    </defaults>
-  </action>
-EOF
-
-    }
-}
-
-print <<EOF;
-</policyconfig>
-EOF
diff --git a/src/access/genpolkit.py b/src/access/genpolkit.py
new file mode 100755
index 0000000000..04628d2d6a
--- /dev/null
+++ b/src/access/genpolkit.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2012-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/>.
+#
+
+from __future__ import print_function
+
+import re
+import sys
+
+objects = [
+    "CONNECT", "DOMAIN", "INTERFACE", "NETWORK_PORT",
+    "NETWORK", "NODE_DEVICE", "NWFILTER_BINDING",
+    "NWFILTER", "SECRET", "STORAGE_POOL", "STORAGE_VOL",
+]
+
+objectstr = "|".join(objects)
+
+# Data we're going to be generating looks like this
+#
+# <policyconfig>
+#   <action id="org.libvirt.unix.monitor">
+#     <description>Monitor local virtualized systems</description>
+#     <message>System policy prevents monitoring of
+#              local virtualized systems</message>
+#     <defaults>
+#       <allow_any>yes</allow_any>
+#       <allow_inactive>yes</allow_inactive>
+#       <allow_active>yes</allow_active>
+#     </defaults>
+#   </action>
+#   ...more <action> rules...
+# </policyconfig>
+
+opts = {}
+in_opts = False
+
+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.match(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.match(r'''.*VIR_ACCESS_PERM_(%s)_((?:\w|_)+),''' %
+                         objectstr, line)
+            if m is not None:
+                obj = m.group(1).lower()
+                perm = m.group(2).lower()
+                if perm == "last":
+                    continue
+
+                obj = obj.replace("_", "-")
+                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('<?xml version="1.0" encoding="UTF-8"?>')
+print('<!DOCTYPE policyconfig PUBLIC ' +
+      '"-//freedesktop//DTD polkit Policy Configuration 1.0//EN"')
+print('    "http://www.freedesktop.org/software/polkit/policyconfig-1.dtd">')
+print('<policyconfig>')
+print('  <vendor>Libvirt Project</vendor>')
+print('  <vendor_url>https://libvirt.org</vendor_url>')
+
+for obj in sorted(perms.keys()):
+    for perm in sorted(perms[obj].keys()):
+        description = perms[obj][perm]["desc"]
+        message = perms[obj][perm]["message"]
+        anonymous = perms[obj][perm]["anonymous"]
+
+        if description is None:
+            raise Exception("missing description for %s.%s" % (obj, perm))
+        if message is None:
+            raise Exception("missing message for %s.%s" % (obj, perm))
+
+        allow_any = "no"
+        if anonymous:
+            allow_any = "yes"
+        allow_inactive = allow_any
+        allow_active = allow_any
+
+        print('  <action id="org.libvirt.api.%s.%s">' % (obj, perm))
+        print('    <description>%s</description>' % description)
+        print('    <message>%s</message>' % message)
+        print('    <defaults>')
+        print('      <allow_any>%s</allow_any>' % allow_any)
+        print('      <allow_inactive>%s</allow_inactive>' % allow_inactive)
+        print('      <allow_active>%s</allow_active>' % allow_active)
+        print('    </defaults>')
+        print('  </action>')
+
+print('</policyconfig>')
-- 
2.21.0




More information about the libvir-list mailing list