diff mbox

[v2,2/2] policycoreutils: Make sepolicy work with python3

Message ID 20161107095108.22306-1-bigon@debian.org (mailing list archive)
State Not Applicable
Headers show

Commit Message

Laurent Bigonville Nov. 7, 2016, 9:51 a.m. UTC
From: Laurent Bigonville <bigon@bigon.be>

Add python3 support for sepolicy

Signed-off-by: Laurent Bigonville <bigon@bigon.be>
---
 policycoreutils/sepolicy/selinux_client.py       |  6 ++--
 policycoreutils/sepolicy/sepolicy.py             | 38 ++++++++++++------------
 policycoreutils/sepolicy/sepolicy/__init__.py    | 16 ++++++----
 policycoreutils/sepolicy/sepolicy/communicate.py |  4 +--
 policycoreutils/sepolicy/sepolicy/generate.py    | 30 +++++++++----------
 policycoreutils/sepolicy/sepolicy/interface.py   | 14 ++++++---
 policycoreutils/sepolicy/sepolicy/manpage.py     |  7 +++--
 7 files changed, 65 insertions(+), 50 deletions(-)

Comments

Stephen Smalley Nov. 8, 2016, 3:21 p.m. UTC | #1
On 11/07/2016 04:51 AM, Laurent Bigonville wrote:
> From: Laurent Bigonville <bigon@bigon.be>
> 
> Add python3 support for sepolicy
> 
> Signed-off-by: Laurent Bigonville <bigon@bigon.be>
> ---
>  policycoreutils/sepolicy/selinux_client.py       |  6 ++--
>  policycoreutils/sepolicy/sepolicy.py             | 38 ++++++++++++------------
>  policycoreutils/sepolicy/sepolicy/__init__.py    | 16 ++++++----
>  policycoreutils/sepolicy/sepolicy/communicate.py |  4 +--
>  policycoreutils/sepolicy/sepolicy/generate.py    | 30 +++++++++----------
>  policycoreutils/sepolicy/sepolicy/interface.py   | 14 ++++++---
>  policycoreutils/sepolicy/sepolicy/manpage.py     |  7 +++--
>  7 files changed, 65 insertions(+), 50 deletions(-)

make test doesn't pass in policycoreutils/sepolicy, although I'm not
sure that's new to this patch.  I think the manpage ones were already
failing; I don't recall the network one hanging before though.  But
maybe that is because I wasn't testing with setools3 fully removed before?

> 
> diff --git a/policycoreutils/sepolicy/selinux_client.py b/policycoreutils/sepolicy/selinux_client.py
> index 7f4a91c..dc29f28 100644
> --- a/policycoreutils/sepolicy/selinux_client.py
> +++ b/policycoreutils/sepolicy/selinux_client.py
> @@ -39,6 +39,6 @@ if __name__ == "__main__":
>      try:
>          dbus_proxy = SELinuxDBus()
>          resp = dbus_proxy.customized()
> -        print convert_customization(resp)
> -    except dbus.DBusException, e:
> -        print e
> +        print(convert_customization(resp))
> +    except dbus.DBusException as e:
> +        print(e)
> diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py
> index 3e502a7..5bf9b52 100755
> --- a/policycoreutils/sepolicy/sepolicy.py
> +++ b/policycoreutils/sepolicy/sepolicy.py
> @@ -262,7 +262,7 @@ def _print_net(src, protocol, perm):
>      if len(portdict) > 0:
>          bold_start = "\033[1m"
>          bold_end = "\033[0;0m"
> -        print "\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end
> +        print("\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end)
>          port_strings = []
>          boolean_text = ""
>          for p in portdict:
> @@ -275,7 +275,7 @@ def _print_net(src, protocol, perm):
>                      port_strings.append("%s (%s)" % (", ".join(recs), t))
>          port_strings.sort(numcmp)
>          for p in port_strings:
> -            print "\t" + p
> +            print("\t" + p)
>  
>  
>  def network(args):
> @@ -286,7 +286,7 @@ def network(args):
>              if i[0] not in all_ports:
>                  all_ports.append(i[0])
>          all_ports.sort()
> -        print "\n".join(all_ports)
> +        print("\n".join(all_ports))
>  
>      for port in args.port:
>          found = False
> @@ -297,18 +297,18 @@ def network(args):
>                  else:
>                      range = "%s-%s" % (i[0], i[1])
>                  found = True
> -                print "%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range)
> +                print("%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range))
>          if not found:
>              if port < 500:
> -                print "Undefined reserved port type"
> +                print("Undefined reserved port type")
>              else:
> -                print "Undefined port type"
> +                print("Undefined port type")
>  
>      for t in args.type:
>          if (t, 'tcp') in portrecs.keys():
> -            print "%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp']))
> +            print("%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp'])))
>          if (t, 'udp') in portrecs.keys():
> -            print "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp']))
> +            print( "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp'])))
>  
>      for a in args.applications:
>          d = sepolicy.get_init_transtype(a)
> @@ -357,7 +357,7 @@ def manpage(args):
>  
>      for domain in test_domains:
>          m = ManPage(domain, path, args.root, args.source_files, args.web)
> -        print m.get_man_page_path()
> +        print(m.get_man_page_path())
>  
>      if args.web:
>          HTMLManPages(manpage_roles, manpage_domains, path, args.os)
> @@ -418,7 +418,7 @@ def communicate(args):
>      out = list(set(writable) & set(readable))
>  
>      for t in out:
> -        print t
> +        print(t)
>  
>  
>  def gen_communicate_args(parser):
> @@ -445,7 +445,7 @@ def booleans(args):
>      args.booleans.sort()
>  
>      for b in args.booleans:
> -        print "%s=_(\"%s\")" % (b, boolean_desc(b))
> +        print("%s=_(\"%s\")" % (b, boolean_desc(b)))
>  
>  
>  def gen_booleans_args(parser):
> @@ -484,16 +484,16 @@ def print_interfaces(interfaces, args, append=""):
>      for i in interfaces:
>          if args.verbose:
>              try:
> -                print get_interface_format_text(i + append)
> +                print(get_interface_format_text(i + append))
>              except KeyError:
> -                print i
> +                print(i)
>          if args.compile:
>              try:
>                  interface_compile_test(i)
>              except KeyError:
> -                print i
> +                print(i)
>          else:
> -            print i
> +            print(i)
>  
>  
>  def interface(args):
> @@ -565,7 +565,7 @@ def generate(args):
>      if args.policytype in APPLICATIONS:
>          mypolicy.gen_writeable()
>          mypolicy.gen_symbols()
> -    print mypolicy.generate(args.path)
> +    print(mypolicy.generate(args.path))
>  
>  
>  def gen_interface_args(parser):
> @@ -698,12 +698,12 @@ if __name__ == '__main__':
>          args = parser.parse_args(args=parser_args)
>          args.func(args)
>          sys.exit(0)
> -    except ValueError, e:
> +    except ValueError as e:
>          sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
>          sys.exit(1)
> -    except IOError, e:
> +    except IOError as e:
>          sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
>          sys.exit(1)
>      except KeyboardInterrupt:
> -        print "Out"
> +        print("Out")
>          sys.exit(0)
> diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py
> index 8fbd5b4..fee6438 100644
> --- a/policycoreutils/sepolicy/sepolicy/__init__.py
> +++ b/policycoreutils/sepolicy/sepolicy/__init__.py
> @@ -695,7 +695,7 @@ def get_methods():
>      # List of per_role_template interfaces
>          ifs = interfaces.InterfaceSet()
>          ifs.from_file(fd)
> -        methods = ifs.interfaces.keys()
> +        methods = list(ifs.interfaces.keys())
>          fd.close()
>      except:
>          sys.stderr.write("could not open interface info [%s]\n" % fn)
> @@ -752,7 +752,10 @@ def get_all_entrypoint_domains():
>  
>  
>  def gen_interfaces():
> -    import commands
> +    try:
> +        from commands import getstatusoutput
> +    except ImportError:
> +        from subprocess import getstatusoutput
>      ifile = defaults.interface_info()
>      headers = defaults.headers()
>      try:
> @@ -763,7 +766,7 @@ def gen_interfaces():
>  
>      if os.getuid() != 0:
>          raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen"))
> -    print(commands.getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
> +    print(getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
>  
>  
>  def gen_port_dict():
> @@ -1085,8 +1088,11 @@ def get_os_version():
>      os_version = ""
>      pkg_name = "selinux-policy"
>      try:
> -        import commands
> -        rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name)
> +        try:
> +            from commands import getstatusoutput
> +        except ImportError:
> +            from subprocess import getstatusoutput
> +        rc, output = getstatusoutput("rpm -q '%s'" % pkg_name)
>          if rc == 0:
>              os_version = output.split(".")[-2]
>      except:
> diff --git a/policycoreutils/sepolicy/sepolicy/communicate.py b/policycoreutils/sepolicy/sepolicy/communicate.py
> index b96c4b9..299316e 100755
> --- a/policycoreutils/sepolicy/sepolicy/communicate.py
> +++ b/policycoreutils/sepolicy/sepolicy/communicate.py
> @@ -34,8 +34,8 @@ def usage(parser, msg):
>  
>  def expand_attribute(attribute):
>      try:
> -        return sepolicy.info(sepolicy.ATTRIBUTE, attribute)[0]["types"]
> -    except RuntimeError:
> +        return list(next(sepolicy.info(sepolicy.ATTRIBUTE, attribute))["types"])
> +    except StopIteration:
>          return [attribute]
>  
>  
> diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py
> index 65b33b6..5696110 100644
> --- a/policycoreutils/sepolicy/sepolicy/generate.py
> +++ b/policycoreutils/sepolicy/sepolicy/generate.py
> @@ -31,21 +31,21 @@ import time
>  import types
>  import platform
>  
> -from templates import executable
> -from templates import boolean
> -from templates import etc_rw
> -from templates import unit_file
> -from templates import var_cache
> -from templates import var_spool
> -from templates import var_lib
> -from templates import var_log
> -from templates import var_run
> -from templates import tmp
> -from templates import rw
> -from templates import network
> -from templates import script
> -from templates import spec
> -from templates import user
> +from .templates import executable
> +from .templates import boolean
> +from .templates import etc_rw
> +from .templates import unit_file
> +from .templates import var_cache
> +from .templates import var_spool
> +from .templates import var_lib
> +from .templates import var_log
> +from .templates import var_run
> +from .templates import tmp
> +from .templates import rw
> +from .templates import network
> +from .templates import script
> +from .templates import spec
> +from .templates import user
>  import sepolgen.interfaces as interfaces
>  import sepolgen.defaults as defaults
>  
> diff --git a/policycoreutils/sepolicy/sepolicy/interface.py b/policycoreutils/sepolicy/sepolicy/interface.py
> index c2cb971..8956f39 100644
> --- a/policycoreutils/sepolicy/sepolicy/interface.py
> +++ b/policycoreutils/sepolicy/sepolicy/interface.py
> @@ -192,10 +192,13 @@ def generate_compile_te(interface, idict, name="compiletest"):
>  def get_xml_file(if_file):
>      """ Returns xml format of interfaces for given .if policy file"""
>      import os
> -    import commands
> +    try:
> +            from commands import getstatusoutput
> +    except ImportError:
> +            from subprocess import getstatusoutput
>      basedir = os.path.dirname(if_file) + "/"
>      filename = os.path.basename(if_file).split(".")[0]
> -    rc, output = commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
> +    rc, output = getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
>      if rc != 0:
>          sys.stderr.write("\n Could not proceed selected interface file.\n")
>          sys.stderr.write("\n%s" % output)
> @@ -208,7 +211,10 @@ def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
>      exclude_interfaces = ["userdom", "kernel", "corenet", "files", "dev"]
>      exclude_interface_type = ["template"]
>  
> -    import commands
> +    try:
> +            from commands import getstatusoutput
> +    except ImportError:
> +            from subprocess import getstatusoutput
>      import os
>      policy_files = {'pp': "compiletest.pp", 'te': "compiletest.te", 'fc': "compiletest.fc", 'if': "compiletest.if"}
>      idict = get_interface_dict(path)
> @@ -219,7 +225,7 @@ def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
>              fd = open(policy_files['te'], "w")
>              fd.write(generate_compile_te(interface, idict))
>              fd.close()
> -            rc, output = commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
> +            rc, output = getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
>              if rc != 0:
>                  sys.stderr.write(output)
>                  sys.stderr.write(_("\nCompile test for %s failed.\n") % interface)
> diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py
> index 7365f93..773a9ab 100755
> --- a/policycoreutils/sepolicy/sepolicy/manpage.py
> +++ b/policycoreutils/sepolicy/sepolicy/manpage.py
> @@ -27,7 +27,6 @@ __all__ = ['ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_d
>  import string
>  import selinux
>  import sepolicy
> -import commands
>  import os
>  import time
>  
> @@ -162,7 +161,11 @@ def get_alphabet_manpages(manpage_list):
>  
>  
>  def convert_manpage_to_html(html_manpage, manpage):
> -    rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
> +    try:
> +            from commands import getstatusoutput
> +    except ImportError:
> +            from subprocess import getstatusoutput
> +    rc, output = getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
>      if rc == 0:
>          print(html_manpage, "has been created")
>          fd = open(html_manpage, 'w')
>
Stephen Smalley Nov. 8, 2016, 3:29 p.m. UTC | #2
On 11/08/2016 10:21 AM, Stephen Smalley wrote:
> On 11/07/2016 04:51 AM, Laurent Bigonville wrote:
>> From: Laurent Bigonville <bigon@bigon.be>
>>
>> Add python3 support for sepolicy
>>
>> Signed-off-by: Laurent Bigonville <bigon@bigon.be>
>> ---
>>  policycoreutils/sepolicy/selinux_client.py       |  6 ++--
>>  policycoreutils/sepolicy/sepolicy.py             | 38 ++++++++++++------------
>>  policycoreutils/sepolicy/sepolicy/__init__.py    | 16 ++++++----
>>  policycoreutils/sepolicy/sepolicy/communicate.py |  4 +--
>>  policycoreutils/sepolicy/sepolicy/generate.py    | 30 +++++++++----------
>>  policycoreutils/sepolicy/sepolicy/interface.py   | 14 ++++++---
>>  policycoreutils/sepolicy/sepolicy/manpage.py     |  7 +++--
>>  7 files changed, 65 insertions(+), 50 deletions(-)
> 
> make test doesn't pass in policycoreutils/sepolicy, although I'm not
> sure that's new to this patch.  I think the manpage ones were already
> failing; I don't recall the network one hanging before though.  But
> maybe that is because I wasn't testing with setools3 fully removed before?

Oh, I guess it is just very slow with setools4.  It did finally complete
sepolicy network -d and has moved on (next slow/hanging one is
transition -t).

>>
>> diff --git a/policycoreutils/sepolicy/selinux_client.py b/policycoreutils/sepolicy/selinux_client.py
>> index 7f4a91c..dc29f28 100644
>> --- a/policycoreutils/sepolicy/selinux_client.py
>> +++ b/policycoreutils/sepolicy/selinux_client.py
>> @@ -39,6 +39,6 @@ if __name__ == "__main__":
>>      try:
>>          dbus_proxy = SELinuxDBus()
>>          resp = dbus_proxy.customized()
>> -        print convert_customization(resp)
>> -    except dbus.DBusException, e:
>> -        print e
>> +        print(convert_customization(resp))
>> +    except dbus.DBusException as e:
>> +        print(e)
>> diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py
>> index 3e502a7..5bf9b52 100755
>> --- a/policycoreutils/sepolicy/sepolicy.py
>> +++ b/policycoreutils/sepolicy/sepolicy.py
>> @@ -262,7 +262,7 @@ def _print_net(src, protocol, perm):
>>      if len(portdict) > 0:
>>          bold_start = "\033[1m"
>>          bold_end = "\033[0;0m"
>> -        print "\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end
>> +        print("\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end)
>>          port_strings = []
>>          boolean_text = ""
>>          for p in portdict:
>> @@ -275,7 +275,7 @@ def _print_net(src, protocol, perm):
>>                      port_strings.append("%s (%s)" % (", ".join(recs), t))
>>          port_strings.sort(numcmp)
>>          for p in port_strings:
>> -            print "\t" + p
>> +            print("\t" + p)
>>  
>>  
>>  def network(args):
>> @@ -286,7 +286,7 @@ def network(args):
>>              if i[0] not in all_ports:
>>                  all_ports.append(i[0])
>>          all_ports.sort()
>> -        print "\n".join(all_ports)
>> +        print("\n".join(all_ports))
>>  
>>      for port in args.port:
>>          found = False
>> @@ -297,18 +297,18 @@ def network(args):
>>                  else:
>>                      range = "%s-%s" % (i[0], i[1])
>>                  found = True
>> -                print "%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range)
>> +                print("%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range))
>>          if not found:
>>              if port < 500:
>> -                print "Undefined reserved port type"
>> +                print("Undefined reserved port type")
>>              else:
>> -                print "Undefined port type"
>> +                print("Undefined port type")
>>  
>>      for t in args.type:
>>          if (t, 'tcp') in portrecs.keys():
>> -            print "%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp']))
>> +            print("%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp'])))
>>          if (t, 'udp') in portrecs.keys():
>> -            print "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp']))
>> +            print( "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp'])))
>>  
>>      for a in args.applications:
>>          d = sepolicy.get_init_transtype(a)
>> @@ -357,7 +357,7 @@ def manpage(args):
>>  
>>      for domain in test_domains:
>>          m = ManPage(domain, path, args.root, args.source_files, args.web)
>> -        print m.get_man_page_path()
>> +        print(m.get_man_page_path())
>>  
>>      if args.web:
>>          HTMLManPages(manpage_roles, manpage_domains, path, args.os)
>> @@ -418,7 +418,7 @@ def communicate(args):
>>      out = list(set(writable) & set(readable))
>>  
>>      for t in out:
>> -        print t
>> +        print(t)
>>  
>>  
>>  def gen_communicate_args(parser):
>> @@ -445,7 +445,7 @@ def booleans(args):
>>      args.booleans.sort()
>>  
>>      for b in args.booleans:
>> -        print "%s=_(\"%s\")" % (b, boolean_desc(b))
>> +        print("%s=_(\"%s\")" % (b, boolean_desc(b)))
>>  
>>  
>>  def gen_booleans_args(parser):
>> @@ -484,16 +484,16 @@ def print_interfaces(interfaces, args, append=""):
>>      for i in interfaces:
>>          if args.verbose:
>>              try:
>> -                print get_interface_format_text(i + append)
>> +                print(get_interface_format_text(i + append))
>>              except KeyError:
>> -                print i
>> +                print(i)
>>          if args.compile:
>>              try:
>>                  interface_compile_test(i)
>>              except KeyError:
>> -                print i
>> +                print(i)
>>          else:
>> -            print i
>> +            print(i)
>>  
>>  
>>  def interface(args):
>> @@ -565,7 +565,7 @@ def generate(args):
>>      if args.policytype in APPLICATIONS:
>>          mypolicy.gen_writeable()
>>          mypolicy.gen_symbols()
>> -    print mypolicy.generate(args.path)
>> +    print(mypolicy.generate(args.path))
>>  
>>  
>>  def gen_interface_args(parser):
>> @@ -698,12 +698,12 @@ if __name__ == '__main__':
>>          args = parser.parse_args(args=parser_args)
>>          args.func(args)
>>          sys.exit(0)
>> -    except ValueError, e:
>> +    except ValueError as e:
>>          sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
>>          sys.exit(1)
>> -    except IOError, e:
>> +    except IOError as e:
>>          sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
>>          sys.exit(1)
>>      except KeyboardInterrupt:
>> -        print "Out"
>> +        print("Out")
>>          sys.exit(0)
>> diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py
>> index 8fbd5b4..fee6438 100644
>> --- a/policycoreutils/sepolicy/sepolicy/__init__.py
>> +++ b/policycoreutils/sepolicy/sepolicy/__init__.py
>> @@ -695,7 +695,7 @@ def get_methods():
>>      # List of per_role_template interfaces
>>          ifs = interfaces.InterfaceSet()
>>          ifs.from_file(fd)
>> -        methods = ifs.interfaces.keys()
>> +        methods = list(ifs.interfaces.keys())
>>          fd.close()
>>      except:
>>          sys.stderr.write("could not open interface info [%s]\n" % fn)
>> @@ -752,7 +752,10 @@ def get_all_entrypoint_domains():
>>  
>>  
>>  def gen_interfaces():
>> -    import commands
>> +    try:
>> +        from commands import getstatusoutput
>> +    except ImportError:
>> +        from subprocess import getstatusoutput
>>      ifile = defaults.interface_info()
>>      headers = defaults.headers()
>>      try:
>> @@ -763,7 +766,7 @@ def gen_interfaces():
>>  
>>      if os.getuid() != 0:
>>          raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen"))
>> -    print(commands.getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
>> +    print(getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
>>  
>>  
>>  def gen_port_dict():
>> @@ -1085,8 +1088,11 @@ def get_os_version():
>>      os_version = ""
>>      pkg_name = "selinux-policy"
>>      try:
>> -        import commands
>> -        rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name)
>> +        try:
>> +            from commands import getstatusoutput
>> +        except ImportError:
>> +            from subprocess import getstatusoutput
>> +        rc, output = getstatusoutput("rpm -q '%s'" % pkg_name)
>>          if rc == 0:
>>              os_version = output.split(".")[-2]
>>      except:
>> diff --git a/policycoreutils/sepolicy/sepolicy/communicate.py b/policycoreutils/sepolicy/sepolicy/communicate.py
>> index b96c4b9..299316e 100755
>> --- a/policycoreutils/sepolicy/sepolicy/communicate.py
>> +++ b/policycoreutils/sepolicy/sepolicy/communicate.py
>> @@ -34,8 +34,8 @@ def usage(parser, msg):
>>  
>>  def expand_attribute(attribute):
>>      try:
>> -        return sepolicy.info(sepolicy.ATTRIBUTE, attribute)[0]["types"]
>> -    except RuntimeError:
>> +        return list(next(sepolicy.info(sepolicy.ATTRIBUTE, attribute))["types"])
>> +    except StopIteration:
>>          return [attribute]
>>  
>>  
>> diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py
>> index 65b33b6..5696110 100644
>> --- a/policycoreutils/sepolicy/sepolicy/generate.py
>> +++ b/policycoreutils/sepolicy/sepolicy/generate.py
>> @@ -31,21 +31,21 @@ import time
>>  import types
>>  import platform
>>  
>> -from templates import executable
>> -from templates import boolean
>> -from templates import etc_rw
>> -from templates import unit_file
>> -from templates import var_cache
>> -from templates import var_spool
>> -from templates import var_lib
>> -from templates import var_log
>> -from templates import var_run
>> -from templates import tmp
>> -from templates import rw
>> -from templates import network
>> -from templates import script
>> -from templates import spec
>> -from templates import user
>> +from .templates import executable
>> +from .templates import boolean
>> +from .templates import etc_rw
>> +from .templates import unit_file
>> +from .templates import var_cache
>> +from .templates import var_spool
>> +from .templates import var_lib
>> +from .templates import var_log
>> +from .templates import var_run
>> +from .templates import tmp
>> +from .templates import rw
>> +from .templates import network
>> +from .templates import script
>> +from .templates import spec
>> +from .templates import user
>>  import sepolgen.interfaces as interfaces
>>  import sepolgen.defaults as defaults
>>  
>> diff --git a/policycoreutils/sepolicy/sepolicy/interface.py b/policycoreutils/sepolicy/sepolicy/interface.py
>> index c2cb971..8956f39 100644
>> --- a/policycoreutils/sepolicy/sepolicy/interface.py
>> +++ b/policycoreutils/sepolicy/sepolicy/interface.py
>> @@ -192,10 +192,13 @@ def generate_compile_te(interface, idict, name="compiletest"):
>>  def get_xml_file(if_file):
>>      """ Returns xml format of interfaces for given .if policy file"""
>>      import os
>> -    import commands
>> +    try:
>> +            from commands import getstatusoutput
>> +    except ImportError:
>> +            from subprocess import getstatusoutput
>>      basedir = os.path.dirname(if_file) + "/"
>>      filename = os.path.basename(if_file).split(".")[0]
>> -    rc, output = commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
>> +    rc, output = getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
>>      if rc != 0:
>>          sys.stderr.write("\n Could not proceed selected interface file.\n")
>>          sys.stderr.write("\n%s" % output)
>> @@ -208,7 +211,10 @@ def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
>>      exclude_interfaces = ["userdom", "kernel", "corenet", "files", "dev"]
>>      exclude_interface_type = ["template"]
>>  
>> -    import commands
>> +    try:
>> +            from commands import getstatusoutput
>> +    except ImportError:
>> +            from subprocess import getstatusoutput
>>      import os
>>      policy_files = {'pp': "compiletest.pp", 'te': "compiletest.te", 'fc': "compiletest.fc", 'if': "compiletest.if"}
>>      idict = get_interface_dict(path)
>> @@ -219,7 +225,7 @@ def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
>>              fd = open(policy_files['te'], "w")
>>              fd.write(generate_compile_te(interface, idict))
>>              fd.close()
>> -            rc, output = commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
>> +            rc, output = getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
>>              if rc != 0:
>>                  sys.stderr.write(output)
>>                  sys.stderr.write(_("\nCompile test for %s failed.\n") % interface)
>> diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py
>> index 7365f93..773a9ab 100755
>> --- a/policycoreutils/sepolicy/sepolicy/manpage.py
>> +++ b/policycoreutils/sepolicy/sepolicy/manpage.py
>> @@ -27,7 +27,6 @@ __all__ = ['ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_d
>>  import string
>>  import selinux
>>  import sepolicy
>> -import commands
>>  import os
>>  import time
>>  
>> @@ -162,7 +161,11 @@ def get_alphabet_manpages(manpage_list):
>>  
>>  
>>  def convert_manpage_to_html(html_manpage, manpage):
>> -    rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
>> +    try:
>> +            from commands import getstatusoutput
>> +    except ImportError:
>> +            from subprocess import getstatusoutput
>> +    rc, output = getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
>>      if rc == 0:
>>          print(html_manpage, "has been created")
>>          fd = open(html_manpage, 'w')
>>
>
Stephen Smalley Nov. 8, 2016, 3:35 p.m. UTC | #3
On 11/07/2016 04:51 AM, Laurent Bigonville wrote:
> From: Laurent Bigonville <bigon@bigon.be>
> 
> Add python3 support for sepolicy

Thanks, applied.

> 
> Signed-off-by: Laurent Bigonville <bigon@bigon.be>
> ---
>  policycoreutils/sepolicy/selinux_client.py       |  6 ++--
>  policycoreutils/sepolicy/sepolicy.py             | 38 ++++++++++++------------
>  policycoreutils/sepolicy/sepolicy/__init__.py    | 16 ++++++----
>  policycoreutils/sepolicy/sepolicy/communicate.py |  4 +--
>  policycoreutils/sepolicy/sepolicy/generate.py    | 30 +++++++++----------
>  policycoreutils/sepolicy/sepolicy/interface.py   | 14 ++++++---
>  policycoreutils/sepolicy/sepolicy/manpage.py     |  7 +++--
>  7 files changed, 65 insertions(+), 50 deletions(-)
> 
> diff --git a/policycoreutils/sepolicy/selinux_client.py b/policycoreutils/sepolicy/selinux_client.py
> index 7f4a91c..dc29f28 100644
> --- a/policycoreutils/sepolicy/selinux_client.py
> +++ b/policycoreutils/sepolicy/selinux_client.py
> @@ -39,6 +39,6 @@ if __name__ == "__main__":
>      try:
>          dbus_proxy = SELinuxDBus()
>          resp = dbus_proxy.customized()
> -        print convert_customization(resp)
> -    except dbus.DBusException, e:
> -        print e
> +        print(convert_customization(resp))
> +    except dbus.DBusException as e:
> +        print(e)
> diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py
> index 3e502a7..5bf9b52 100755
> --- a/policycoreutils/sepolicy/sepolicy.py
> +++ b/policycoreutils/sepolicy/sepolicy.py
> @@ -262,7 +262,7 @@ def _print_net(src, protocol, perm):
>      if len(portdict) > 0:
>          bold_start = "\033[1m"
>          bold_end = "\033[0;0m"
> -        print "\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end
> +        print("\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end)
>          port_strings = []
>          boolean_text = ""
>          for p in portdict:
> @@ -275,7 +275,7 @@ def _print_net(src, protocol, perm):
>                      port_strings.append("%s (%s)" % (", ".join(recs), t))
>          port_strings.sort(numcmp)
>          for p in port_strings:
> -            print "\t" + p
> +            print("\t" + p)
>  
>  
>  def network(args):
> @@ -286,7 +286,7 @@ def network(args):
>              if i[0] not in all_ports:
>                  all_ports.append(i[0])
>          all_ports.sort()
> -        print "\n".join(all_ports)
> +        print("\n".join(all_ports))
>  
>      for port in args.port:
>          found = False
> @@ -297,18 +297,18 @@ def network(args):
>                  else:
>                      range = "%s-%s" % (i[0], i[1])
>                  found = True
> -                print "%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range)
> +                print("%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range))
>          if not found:
>              if port < 500:
> -                print "Undefined reserved port type"
> +                print("Undefined reserved port type")
>              else:
> -                print "Undefined port type"
> +                print("Undefined port type")
>  
>      for t in args.type:
>          if (t, 'tcp') in portrecs.keys():
> -            print "%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp']))
> +            print("%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp'])))
>          if (t, 'udp') in portrecs.keys():
> -            print "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp']))
> +            print( "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp'])))
>  
>      for a in args.applications:
>          d = sepolicy.get_init_transtype(a)
> @@ -357,7 +357,7 @@ def manpage(args):
>  
>      for domain in test_domains:
>          m = ManPage(domain, path, args.root, args.source_files, args.web)
> -        print m.get_man_page_path()
> +        print(m.get_man_page_path())
>  
>      if args.web:
>          HTMLManPages(manpage_roles, manpage_domains, path, args.os)
> @@ -418,7 +418,7 @@ def communicate(args):
>      out = list(set(writable) & set(readable))
>  
>      for t in out:
> -        print t
> +        print(t)
>  
>  
>  def gen_communicate_args(parser):
> @@ -445,7 +445,7 @@ def booleans(args):
>      args.booleans.sort()
>  
>      for b in args.booleans:
> -        print "%s=_(\"%s\")" % (b, boolean_desc(b))
> +        print("%s=_(\"%s\")" % (b, boolean_desc(b)))
>  
>  
>  def gen_booleans_args(parser):
> @@ -484,16 +484,16 @@ def print_interfaces(interfaces, args, append=""):
>      for i in interfaces:
>          if args.verbose:
>              try:
> -                print get_interface_format_text(i + append)
> +                print(get_interface_format_text(i + append))
>              except KeyError:
> -                print i
> +                print(i)
>          if args.compile:
>              try:
>                  interface_compile_test(i)
>              except KeyError:
> -                print i
> +                print(i)
>          else:
> -            print i
> +            print(i)
>  
>  
>  def interface(args):
> @@ -565,7 +565,7 @@ def generate(args):
>      if args.policytype in APPLICATIONS:
>          mypolicy.gen_writeable()
>          mypolicy.gen_symbols()
> -    print mypolicy.generate(args.path)
> +    print(mypolicy.generate(args.path))
>  
>  
>  def gen_interface_args(parser):
> @@ -698,12 +698,12 @@ if __name__ == '__main__':
>          args = parser.parse_args(args=parser_args)
>          args.func(args)
>          sys.exit(0)
> -    except ValueError, e:
> +    except ValueError as e:
>          sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
>          sys.exit(1)
> -    except IOError, e:
> +    except IOError as e:
>          sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
>          sys.exit(1)
>      except KeyboardInterrupt:
> -        print "Out"
> +        print("Out")
>          sys.exit(0)
> diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py
> index 8fbd5b4..fee6438 100644
> --- a/policycoreutils/sepolicy/sepolicy/__init__.py
> +++ b/policycoreutils/sepolicy/sepolicy/__init__.py
> @@ -695,7 +695,7 @@ def get_methods():
>      # List of per_role_template interfaces
>          ifs = interfaces.InterfaceSet()
>          ifs.from_file(fd)
> -        methods = ifs.interfaces.keys()
> +        methods = list(ifs.interfaces.keys())
>          fd.close()
>      except:
>          sys.stderr.write("could not open interface info [%s]\n" % fn)
> @@ -752,7 +752,10 @@ def get_all_entrypoint_domains():
>  
>  
>  def gen_interfaces():
> -    import commands
> +    try:
> +        from commands import getstatusoutput
> +    except ImportError:
> +        from subprocess import getstatusoutput
>      ifile = defaults.interface_info()
>      headers = defaults.headers()
>      try:
> @@ -763,7 +766,7 @@ def gen_interfaces():
>  
>      if os.getuid() != 0:
>          raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen"))
> -    print(commands.getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
> +    print(getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
>  
>  
>  def gen_port_dict():
> @@ -1085,8 +1088,11 @@ def get_os_version():
>      os_version = ""
>      pkg_name = "selinux-policy"
>      try:
> -        import commands
> -        rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name)
> +        try:
> +            from commands import getstatusoutput
> +        except ImportError:
> +            from subprocess import getstatusoutput
> +        rc, output = getstatusoutput("rpm -q '%s'" % pkg_name)
>          if rc == 0:
>              os_version = output.split(".")[-2]
>      except:
> diff --git a/policycoreutils/sepolicy/sepolicy/communicate.py b/policycoreutils/sepolicy/sepolicy/communicate.py
> index b96c4b9..299316e 100755
> --- a/policycoreutils/sepolicy/sepolicy/communicate.py
> +++ b/policycoreutils/sepolicy/sepolicy/communicate.py
> @@ -34,8 +34,8 @@ def usage(parser, msg):
>  
>  def expand_attribute(attribute):
>      try:
> -        return sepolicy.info(sepolicy.ATTRIBUTE, attribute)[0]["types"]
> -    except RuntimeError:
> +        return list(next(sepolicy.info(sepolicy.ATTRIBUTE, attribute))["types"])
> +    except StopIteration:
>          return [attribute]
>  
>  
> diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py
> index 65b33b6..5696110 100644
> --- a/policycoreutils/sepolicy/sepolicy/generate.py
> +++ b/policycoreutils/sepolicy/sepolicy/generate.py
> @@ -31,21 +31,21 @@ import time
>  import types
>  import platform
>  
> -from templates import executable
> -from templates import boolean
> -from templates import etc_rw
> -from templates import unit_file
> -from templates import var_cache
> -from templates import var_spool
> -from templates import var_lib
> -from templates import var_log
> -from templates import var_run
> -from templates import tmp
> -from templates import rw
> -from templates import network
> -from templates import script
> -from templates import spec
> -from templates import user
> +from .templates import executable
> +from .templates import boolean
> +from .templates import etc_rw
> +from .templates import unit_file
> +from .templates import var_cache
> +from .templates import var_spool
> +from .templates import var_lib
> +from .templates import var_log
> +from .templates import var_run
> +from .templates import tmp
> +from .templates import rw
> +from .templates import network
> +from .templates import script
> +from .templates import spec
> +from .templates import user
>  import sepolgen.interfaces as interfaces
>  import sepolgen.defaults as defaults
>  
> diff --git a/policycoreutils/sepolicy/sepolicy/interface.py b/policycoreutils/sepolicy/sepolicy/interface.py
> index c2cb971..8956f39 100644
> --- a/policycoreutils/sepolicy/sepolicy/interface.py
> +++ b/policycoreutils/sepolicy/sepolicy/interface.py
> @@ -192,10 +192,13 @@ def generate_compile_te(interface, idict, name="compiletest"):
>  def get_xml_file(if_file):
>      """ Returns xml format of interfaces for given .if policy file"""
>      import os
> -    import commands
> +    try:
> +            from commands import getstatusoutput
> +    except ImportError:
> +            from subprocess import getstatusoutput
>      basedir = os.path.dirname(if_file) + "/"
>      filename = os.path.basename(if_file).split(".")[0]
> -    rc, output = commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
> +    rc, output = getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
>      if rc != 0:
>          sys.stderr.write("\n Could not proceed selected interface file.\n")
>          sys.stderr.write("\n%s" % output)
> @@ -208,7 +211,10 @@ def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
>      exclude_interfaces = ["userdom", "kernel", "corenet", "files", "dev"]
>      exclude_interface_type = ["template"]
>  
> -    import commands
> +    try:
> +            from commands import getstatusoutput
> +    except ImportError:
> +            from subprocess import getstatusoutput
>      import os
>      policy_files = {'pp': "compiletest.pp", 'te': "compiletest.te", 'fc': "compiletest.fc", 'if': "compiletest.if"}
>      idict = get_interface_dict(path)
> @@ -219,7 +225,7 @@ def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
>              fd = open(policy_files['te'], "w")
>              fd.write(generate_compile_te(interface, idict))
>              fd.close()
> -            rc, output = commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
> +            rc, output = getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
>              if rc != 0:
>                  sys.stderr.write(output)
>                  sys.stderr.write(_("\nCompile test for %s failed.\n") % interface)
> diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py
> index 7365f93..773a9ab 100755
> --- a/policycoreutils/sepolicy/sepolicy/manpage.py
> +++ b/policycoreutils/sepolicy/sepolicy/manpage.py
> @@ -27,7 +27,6 @@ __all__ = ['ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_d
>  import string
>  import selinux
>  import sepolicy
> -import commands
>  import os
>  import time
>  
> @@ -162,7 +161,11 @@ def get_alphabet_manpages(manpage_list):
>  
>  
>  def convert_manpage_to_html(html_manpage, manpage):
> -    rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
> +    try:
> +            from commands import getstatusoutput
> +    except ImportError:
> +            from subprocess import getstatusoutput
> +    rc, output = getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
>      if rc == 0:
>          print(html_manpage, "has been created")
>          fd = open(html_manpage, 'w')
>
Chris PeBenito Nov. 11, 2016, 12:58 a.m. UTC | #4
On 11/08/16 10:29, Stephen Smalley wrote:
> On 11/08/2016 10:21 AM, Stephen Smalley wrote:
>> On 11/07/2016 04:51 AM, Laurent Bigonville wrote:
>>> From: Laurent Bigonville <bigon@bigon.be>
>>>
>>> Add python3 support for sepolicy
>>>
>>> Signed-off-by: Laurent Bigonville <bigon@bigon.be>
>>> ---
>>>  policycoreutils/sepolicy/selinux_client.py       |  6 ++--
>>>  policycoreutils/sepolicy/sepolicy.py             | 38 ++++++++++++------------
>>>  policycoreutils/sepolicy/sepolicy/__init__.py    | 16 ++++++----
>>>  policycoreutils/sepolicy/sepolicy/communicate.py |  4 +--
>>>  policycoreutils/sepolicy/sepolicy/generate.py    | 30 +++++++++----------
>>>  policycoreutils/sepolicy/sepolicy/interface.py   | 14 ++++++---
>>>  policycoreutils/sepolicy/sepolicy/manpage.py     |  7 +++--
>>>  7 files changed, 65 insertions(+), 50 deletions(-)
>>
>> make test doesn't pass in policycoreutils/sepolicy, although I'm not
>> sure that's new to this patch.  I think the manpage ones were already
>> failing; I don't recall the network one hanging before though.  But
>> maybe that is because I wasn't testing with setools3 fully removed before?
>
> Oh, I guess it is just very slow with setools4.  It did finally complete
> sepolicy network -d and has moved on (next slow/hanging one is
> transition -t).

Yes, sadly setools4 is slower.  I haven't spent much time on trying to 
improve the performance yet (preliminary profiling seems to indicate 
that swig is the problem).  However, looking through the sepolicy code, 
I found that it could use the setools code more efficiently (I realize 
the first matter of business was just to get it over to setools4).

The biggest win will be to minimize how many times the code iterates 
over all TE rules.  For example, in the search function, it runs the 
TERuleQuery twice, when it could be done in one query.  Also, for the 
transition command, it seems to manually implement a domain transition 
analysis.  When I compared the sepolicy transition run time to sedta, 
sedta was a minute faster for the same analysis.
Nicolas Iooss Nov. 13, 2016, 4:20 p.m. UTC | #5
On Fri, Nov 11, 2016 at 1:58 AM, Chris PeBenito <pebenito@ieee.org> wrote:

> On 11/08/16 10:29, Stephen Smalley wrote:
>
>> On 11/08/2016 10:21 AM, Stephen Smalley wrote:
>>
>>> On 11/07/2016 04:51 AM, Laurent Bigonville wrote:
>>>
>>>> From: Laurent Bigonville <bigon@bigon.be>
>>>>
>>>> Add python3 support for sepolicy
>>>>
>>>> Signed-off-by: Laurent Bigonville <bigon@bigon.be>
>>>> ---
>>>>  policycoreutils/sepolicy/selinux_client.py       |  6 ++--
>>>>  policycoreutils/sepolicy/sepolicy.py             | 38
>>>> ++++++++++++------------
>>>>  policycoreutils/sepolicy/sepolicy/__init__.py    | 16 ++++++----
>>>>  policycoreutils/sepolicy/sepolicy/communicate.py |  4 +--
>>>>  policycoreutils/sepolicy/sepolicy/generate.py    | 30
>>>> +++++++++----------
>>>>  policycoreutils/sepolicy/sepolicy/interface.py   | 14 ++++++---
>>>>  policycoreutils/sepolicy/sepolicy/manpage.py     |  7 +++--
>>>>  7 files changed, 65 insertions(+), 50 deletions(-)
>>>>
>>>
>>> make test doesn't pass in policycoreutils/sepolicy, although I'm not
>>> sure that's new to this patch.  I think the manpage ones were already
>>> failing; I don't recall the network one hanging before though.  But
>>> maybe that is because I wasn't testing with setools3 fully removed
>>> before?
>>>
>>
>> Oh, I guess it is just very slow with setools4.  It did finally complete
>> sepolicy network -d and has moved on (next slow/hanging one is
>> transition -t).
>>
>
> Yes, sadly setools4 is slower.  I haven't spent much time on trying to
> improve the performance yet (preliminary profiling seems to indicate that
> swig is the problem).  However, looking through the sepolicy code, I found
> that it could use the setools code more efficiently (I realize the first
> matter of business was just to get it over to setools4).
>
> The biggest win will be to minimize how many times the code iterates over
> all TE rules.  For example, in the search function, it runs the TERuleQuery
> twice, when it could be done in one query.  Also, for the transition
> command, it seems to manually implement a domain transition analysis.  When
> I compared the sepolicy transition run time to sedta, sedta was a minute
> faster for the same analysis.


A few months ago (in August) I did some profiling on sesearch (from SETools
4) and found that a lot of time was spent in SWIG casting operations (like
qpol_avrule_from_void). A quick patch to remove a cast (
https://github.com/fishilico/setools/commit/461bf0297b950ae40ba5bcb17db0f2a19f14d560)
made sesearch quite faster (I don't have the precise numbers here).
In short I believe the way the SWIG wrappers use objects (and create
objects from pointers) causes a noticeable performance impact, and I have
no opinion on what would be the best approach to improve the code.

Nicolas
Chris PeBenito Nov. 13, 2016, 6:56 p.m. UTC | #6
On 11/13/16 11:20, Nicolas Iooss wrote:
> On Fri, Nov 11, 2016 at 1:58 AM, Chris PeBenito <pebenito@ieee.org
> <mailto:pebenito@ieee.org>> wrote:
>     On 11/08/16 10:29, Stephen Smalley wrote:
>         Oh, I guess it is just very slow with setools4.  It did finally
>         complete
>         sepolicy network -d and has moved on (next slow/hanging one is
>         transition -t).
>     Yes, sadly setools4 is slower.  I haven't spent much time on trying
>     to improve the performance yet (preliminary profiling seems to
>     indicate that swig is the problem).  However, looking through the
>     sepolicy code, I found that it could use the setools code more
>     efficiently (I realize the first matter of business was just to get
>     it over to setools4).
>
>     The biggest win will be to minimize how many times the code iterates
>     over all TE rules.  For example, in the search function, it runs the
>     TERuleQuery twice, when it could be done in one query.  Also, for
>     the transition command, it seems to manually implement a domain
>     transition analysis.  When I compared the sepolicy transition run
>     time to sedta, sedta was a minute faster for the same analysis.
>
>
> A few months ago (in August) I did some profiling on sesearch (from
> SETools 4) and found that a lot of time was spent in SWIG casting
> operations (like qpol_avrule_from_void). A quick patch to remove a cast
> (https://github.com/fishilico/setools/commit/461bf0297b950ae40ba5bcb17db0f2a19f14d560)
> made sesearch quite faster (I don't have the precise numbers here).
> In short I believe the way the SWIG wrappers use objects (and create
> objects from pointers) causes a noticeable performance impact, and I
> have no opinion on what would be the best approach to improve the code.

I've also been considering transitioning out of SWIG into cython. 
There's no need to support anything other than Python, it's much less 
magical than SWIG and easier to understand.  Unfortunately that will 
take some effort.
diff mbox

Patch

diff --git a/policycoreutils/sepolicy/selinux_client.py b/policycoreutils/sepolicy/selinux_client.py
index 7f4a91c..dc29f28 100644
--- a/policycoreutils/sepolicy/selinux_client.py
+++ b/policycoreutils/sepolicy/selinux_client.py
@@ -39,6 +39,6 @@  if __name__ == "__main__":
     try:
         dbus_proxy = SELinuxDBus()
         resp = dbus_proxy.customized()
-        print convert_customization(resp)
-    except dbus.DBusException, e:
-        print e
+        print(convert_customization(resp))
+    except dbus.DBusException as e:
+        print(e)
diff --git a/policycoreutils/sepolicy/sepolicy.py b/policycoreutils/sepolicy/sepolicy.py
index 3e502a7..5bf9b52 100755
--- a/policycoreutils/sepolicy/sepolicy.py
+++ b/policycoreutils/sepolicy/sepolicy.py
@@ -262,7 +262,7 @@  def _print_net(src, protocol, perm):
     if len(portdict) > 0:
         bold_start = "\033[1m"
         bold_end = "\033[0;0m"
-        print "\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end
+        print("\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end)
         port_strings = []
         boolean_text = ""
         for p in portdict:
@@ -275,7 +275,7 @@  def _print_net(src, protocol, perm):
                     port_strings.append("%s (%s)" % (", ".join(recs), t))
         port_strings.sort(numcmp)
         for p in port_strings:
-            print "\t" + p
+            print("\t" + p)
 
 
 def network(args):
@@ -286,7 +286,7 @@  def network(args):
             if i[0] not in all_ports:
                 all_ports.append(i[0])
         all_ports.sort()
-        print "\n".join(all_ports)
+        print("\n".join(all_ports))
 
     for port in args.port:
         found = False
@@ -297,18 +297,18 @@  def network(args):
                 else:
                     range = "%s-%s" % (i[0], i[1])
                 found = True
-                print "%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range)
+                print("%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range))
         if not found:
             if port < 500:
-                print "Undefined reserved port type"
+                print("Undefined reserved port type")
             else:
-                print "Undefined port type"
+                print("Undefined port type")
 
     for t in args.type:
         if (t, 'tcp') in portrecs.keys():
-            print "%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp']))
+            print("%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp'])))
         if (t, 'udp') in portrecs.keys():
-            print "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp']))
+            print( "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp'])))
 
     for a in args.applications:
         d = sepolicy.get_init_transtype(a)
@@ -357,7 +357,7 @@  def manpage(args):
 
     for domain in test_domains:
         m = ManPage(domain, path, args.root, args.source_files, args.web)
-        print m.get_man_page_path()
+        print(m.get_man_page_path())
 
     if args.web:
         HTMLManPages(manpage_roles, manpage_domains, path, args.os)
@@ -418,7 +418,7 @@  def communicate(args):
     out = list(set(writable) & set(readable))
 
     for t in out:
-        print t
+        print(t)
 
 
 def gen_communicate_args(parser):
@@ -445,7 +445,7 @@  def booleans(args):
     args.booleans.sort()
 
     for b in args.booleans:
-        print "%s=_(\"%s\")" % (b, boolean_desc(b))
+        print("%s=_(\"%s\")" % (b, boolean_desc(b)))
 
 
 def gen_booleans_args(parser):
@@ -484,16 +484,16 @@  def print_interfaces(interfaces, args, append=""):
     for i in interfaces:
         if args.verbose:
             try:
-                print get_interface_format_text(i + append)
+                print(get_interface_format_text(i + append))
             except KeyError:
-                print i
+                print(i)
         if args.compile:
             try:
                 interface_compile_test(i)
             except KeyError:
-                print i
+                print(i)
         else:
-            print i
+            print(i)
 
 
 def interface(args):
@@ -565,7 +565,7 @@  def generate(args):
     if args.policytype in APPLICATIONS:
         mypolicy.gen_writeable()
         mypolicy.gen_symbols()
-    print mypolicy.generate(args.path)
+    print(mypolicy.generate(args.path))
 
 
 def gen_interface_args(parser):
@@ -698,12 +698,12 @@  if __name__ == '__main__':
         args = parser.parse_args(args=parser_args)
         args.func(args)
         sys.exit(0)
-    except ValueError, e:
+    except ValueError as e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
         sys.exit(1)
-    except IOError, e:
+    except IOError as e:
         sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e)))
         sys.exit(1)
     except KeyboardInterrupt:
-        print "Out"
+        print("Out")
         sys.exit(0)
diff --git a/policycoreutils/sepolicy/sepolicy/__init__.py b/policycoreutils/sepolicy/sepolicy/__init__.py
index 8fbd5b4..fee6438 100644
--- a/policycoreutils/sepolicy/sepolicy/__init__.py
+++ b/policycoreutils/sepolicy/sepolicy/__init__.py
@@ -695,7 +695,7 @@  def get_methods():
     # List of per_role_template interfaces
         ifs = interfaces.InterfaceSet()
         ifs.from_file(fd)
-        methods = ifs.interfaces.keys()
+        methods = list(ifs.interfaces.keys())
         fd.close()
     except:
         sys.stderr.write("could not open interface info [%s]\n" % fn)
@@ -752,7 +752,10 @@  def get_all_entrypoint_domains():
 
 
 def gen_interfaces():
-    import commands
+    try:
+        from commands import getstatusoutput
+    except ImportError:
+        from subprocess import getstatusoutput
     ifile = defaults.interface_info()
     headers = defaults.headers()
     try:
@@ -763,7 +766,7 @@  def gen_interfaces():
 
     if os.getuid() != 0:
         raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen"))
-    print(commands.getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
+    print(getstatusoutput("/usr/bin/sepolgen-ifgen")[1])
 
 
 def gen_port_dict():
@@ -1085,8 +1088,11 @@  def get_os_version():
     os_version = ""
     pkg_name = "selinux-policy"
     try:
-        import commands
-        rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name)
+        try:
+            from commands import getstatusoutput
+        except ImportError:
+            from subprocess import getstatusoutput
+        rc, output = getstatusoutput("rpm -q '%s'" % pkg_name)
         if rc == 0:
             os_version = output.split(".")[-2]
     except:
diff --git a/policycoreutils/sepolicy/sepolicy/communicate.py b/policycoreutils/sepolicy/sepolicy/communicate.py
index b96c4b9..299316e 100755
--- a/policycoreutils/sepolicy/sepolicy/communicate.py
+++ b/policycoreutils/sepolicy/sepolicy/communicate.py
@@ -34,8 +34,8 @@  def usage(parser, msg):
 
 def expand_attribute(attribute):
     try:
-        return sepolicy.info(sepolicy.ATTRIBUTE, attribute)[0]["types"]
-    except RuntimeError:
+        return list(next(sepolicy.info(sepolicy.ATTRIBUTE, attribute))["types"])
+    except StopIteration:
         return [attribute]
 
 
diff --git a/policycoreutils/sepolicy/sepolicy/generate.py b/policycoreutils/sepolicy/sepolicy/generate.py
index 65b33b6..5696110 100644
--- a/policycoreutils/sepolicy/sepolicy/generate.py
+++ b/policycoreutils/sepolicy/sepolicy/generate.py
@@ -31,21 +31,21 @@  import time
 import types
 import platform
 
-from templates import executable
-from templates import boolean
-from templates import etc_rw
-from templates import unit_file
-from templates import var_cache
-from templates import var_spool
-from templates import var_lib
-from templates import var_log
-from templates import var_run
-from templates import tmp
-from templates import rw
-from templates import network
-from templates import script
-from templates import spec
-from templates import user
+from .templates import executable
+from .templates import boolean
+from .templates import etc_rw
+from .templates import unit_file
+from .templates import var_cache
+from .templates import var_spool
+from .templates import var_lib
+from .templates import var_log
+from .templates import var_run
+from .templates import tmp
+from .templates import rw
+from .templates import network
+from .templates import script
+from .templates import spec
+from .templates import user
 import sepolgen.interfaces as interfaces
 import sepolgen.defaults as defaults
 
diff --git a/policycoreutils/sepolicy/sepolicy/interface.py b/policycoreutils/sepolicy/sepolicy/interface.py
index c2cb971..8956f39 100644
--- a/policycoreutils/sepolicy/sepolicy/interface.py
+++ b/policycoreutils/sepolicy/sepolicy/interface.py
@@ -192,10 +192,13 @@  def generate_compile_te(interface, idict, name="compiletest"):
 def get_xml_file(if_file):
     """ Returns xml format of interfaces for given .if policy file"""
     import os
-    import commands
+    try:
+            from commands import getstatusoutput
+    except ImportError:
+            from subprocess import getstatusoutput
     basedir = os.path.dirname(if_file) + "/"
     filename = os.path.basename(if_file).split(".")[0]
-    rc, output = commands.getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
+    rc, output = getstatusoutput("python /usr/share/selinux/devel/include/support/segenxml.py -w -m %s" % basedir + filename)
     if rc != 0:
         sys.stderr.write("\n Could not proceed selected interface file.\n")
         sys.stderr.write("\n%s" % output)
@@ -208,7 +211,10 @@  def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
     exclude_interfaces = ["userdom", "kernel", "corenet", "files", "dev"]
     exclude_interface_type = ["template"]
 
-    import commands
+    try:
+            from commands import getstatusoutput
+    except ImportError:
+            from subprocess import getstatusoutput
     import os
     policy_files = {'pp': "compiletest.pp", 'te': "compiletest.te", 'fc': "compiletest.fc", 'if': "compiletest.if"}
     idict = get_interface_dict(path)
@@ -219,7 +225,7 @@  def interface_compile_test(interface, path="/usr/share/selinux/devel/policy.xml"
             fd = open(policy_files['te'], "w")
             fd.write(generate_compile_te(interface, idict))
             fd.close()
-            rc, output = commands.getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
+            rc, output = getstatusoutput("make -f /usr/share/selinux/devel/Makefile %s" % policy_files['pp'])
             if rc != 0:
                 sys.stderr.write(output)
                 sys.stderr.write(_("\nCompile test for %s failed.\n") % interface)
diff --git a/policycoreutils/sepolicy/sepolicy/manpage.py b/policycoreutils/sepolicy/sepolicy/manpage.py
index 7365f93..773a9ab 100755
--- a/policycoreutils/sepolicy/sepolicy/manpage.py
+++ b/policycoreutils/sepolicy/sepolicy/manpage.py
@@ -27,7 +27,6 @@  __all__ = ['ManPage', 'HTMLManPages', 'manpage_domains', 'manpage_roles', 'gen_d
 import string
 import selinux
 import sepolicy
-import commands
 import os
 import time
 
@@ -162,7 +161,11 @@  def get_alphabet_manpages(manpage_list):
 
 
 def convert_manpage_to_html(html_manpage, manpage):
-    rc, output = commands.getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
+    try:
+            from commands import getstatusoutput
+    except ImportError:
+            from subprocess import getstatusoutput
+    rc, output = getstatusoutput("/usr/bin/groff -man -Thtml %s 2>/dev/null" % manpage)
     if rc == 0:
         print(html_manpage, "has been created")
         fd = open(html_manpage, 'w')