On 01/19/2016 04:52 PM, Jan Cholasta wrote:
> On 19.1.2016 13:45, Petr Viktorin wrote:
[...]
>>> Otherwise LGTM, including patch 758.
>>
>> Attaching updated patches, with py3k check as as default squashed in.
>> I also added a pylint exception for a new use of reload() in 0756.
>> One more thing I did was disable pylint's long and uninteresting report,
>> so now only the messages are shown.
> 
> Thanks, ACK.
> 
> Could you please rebase the patches on top of ipa-4-3 so I can push them?

Oh, they're going into an earlier release as well?

Here is a patchset for ipa-4-3.


-- 
Petr Viktorin
From d6c083bae2aeebeaddf30b998881dfa403a5cf47 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 5 Jan 2016 13:19:25 +0100
Subject: [PATCH] Use explicit truncating division

In Python 3, the truncating division operator, //, is needed to
get C-style "int division".
---
 ipalib/plugins/dns.py                    | 6 +++---
 ipalib/plugins/pwpolicy.py               | 4 ++--
 ipalib/plugins/trust.py                  | 2 +-
 ipaserver/install/ipa_otptoken_import.py | 4 ++--
 ipatests/test_integration/util.py        | 2 +-
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index 6272220aaf264dffaabaf48111c652544a08044a..e4a92e1d54afe68b2bb5fe2329b06d43e10bd706 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -350,9 +350,9 @@ def _reverse_zone_name(netstr):
     net = netaddr.IPNetwork(netstr)
     items = net.ip.reverse_dns.split('.')
     if net.version == 4:
-        return u'.'.join(items[4 - net.prefixlen / 8:])
+        return u'.'.join(items[4 - net.prefixlen // 8:])
     elif net.version == 6:
-        return u'.'.join(items[32 - net.prefixlen / 4:])
+        return u'.'.join(items[32 - net.prefixlen // 4:])
     else:
         return None
 
@@ -3417,7 +3417,7 @@ class dnsrecord(LDAPObject):
         resolver = dns.resolver.Resolver()
         resolver.set_flags(0)  # disable recursion (for NS RR checks)
         max_attempts = int(self.api.env['wait_for_dns'])
-        warn_attempts = max_attempts / 2
+        warn_attempts = max_attempts // 2
         period = 1  # second
         attempt = 0
         log_fn = self.log.debug
diff --git a/ipalib/plugins/pwpolicy.py b/ipalib/plugins/pwpolicy.py
index 7bd3c0984fde5c3182f229a545b487614106a128..dafa5be788128de7cfca1592be8d4a72cddaa930 100644
--- a/ipalib/plugins/pwpolicy.py
+++ b/ipalib/plugins/pwpolicy.py
@@ -373,11 +373,11 @@ class pwpolicy(LDAPObject):
         if not options.get('raw', False):
             if 'krbmaxpwdlife' in entry_attrs:
                 entry_attrs['krbmaxpwdlife'][0] = unicode(
-                    int(entry_attrs['krbmaxpwdlife'][0]) / 86400
+                    int(entry_attrs['krbmaxpwdlife'][0]) // 86400
                 )
             if 'krbminpwdlife' in entry_attrs:
                 entry_attrs['krbminpwdlife'][0] = unicode(
-                    int(entry_attrs['krbminpwdlife'][0]) / 3600
+                    int(entry_attrs['krbminpwdlife'][0]) // 3600
                 )
 
     def convert_time_on_input(self, entry_attrs):
diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
index 61846dc11e0decff2c45d599a803ca2e384364c9..7f925b734fe5583bec676f8270b860d446f0787a 100644
--- a/ipalib/plugins/trust.py
+++ b/ipalib/plugins/trust.py
@@ -385,7 +385,7 @@ def add_range(myapi, trustinstance, range_name, dom_sid, *keys, **options):
                 max_id = int(max(max_uid, max_gid)[0])
 
                 base_id = int(info.get('msSFU30OrderNumber')[0])
-                range_size = (1 + (max_id - base_id) / DEFAULT_RANGE_SIZE)\
+                range_size = (1 + (max_id - base_id) // DEFAULT_RANGE_SIZE)\
                              * DEFAULT_RANGE_SIZE
 
     # Second, options given via the CLI options take precedence to discovery
diff --git a/ipaserver/install/ipa_otptoken_import.py b/ipaserver/install/ipa_otptoken_import.py
index 10b8af6f158ee957036889b162dcccc21cb45e47..fe5588874fb14e8786c0a56cb2b0e7c7307ad69f 100644
--- a/ipaserver/install/ipa_otptoken_import.py
+++ b/ipaserver/install/ipa_otptoken_import.py
@@ -246,9 +246,9 @@ class XMLDecryptor(object):
         # Decrypt the data.
         slot = nss.get_best_slot(mech)
         key = nss.import_sym_key(slot, mech, nss.PK11_OriginUnwrap, nss.CKA_ENCRYPT, self.__key)
-        iv = nss.param_from_iv(mech, nss.SecItem(data[0:ivlen/8]))
+        iv = nss.param_from_iv(mech, nss.SecItem(data[0:ivlen//8]))
         ctx = nss.create_context_by_sym_key(mech, nss.CKA_DECRYPT, key, iv)
-        out = ctx.cipher_op(data[ivlen / 8:])
+        out = ctx.cipher_op(data[ivlen // 8:])
         out += ctx.digest_final()
         return out
 
diff --git a/ipatests/test_integration/util.py b/ipatests/test_integration/util.py
index 5cfbb2e948c04c70e77b29fd3813ae3fb8a1b84c..594737b6d753d476cd06aeb0d5cd376b7ca46467 100644
--- a/ipatests/test_integration/util.py
+++ b/ipatests/test_integration/util.py
@@ -57,7 +57,7 @@ def run_repeatedly(host, command, assert_zero_rc=True, test=None,
     raise AssertionError("Command: {cmd} repeatedly failed {times} times, "
                          "exceeding the timeout of {timeout} seconds."
                          .format(cmd=' '.join(command),
-                                 times=timeout / time_step,
+                                 times=timeout // time_step,
                                  timeout=timeout))
 
 
-- 
2.5.0

From f2da906974c71dc2316c3180a6dad9e08fd4583a Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 5 Jan 2016 13:36:15 +0100
Subject: [PATCH] Don't index exceptions directly

In Python 3, exceptions don't behave as tuples of their arguments;
instead of e[1] it's necessary to use e.args[1].
---
 ipalib/cli.py           | 4 ++--
 ipalib/plugins/vault.py | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/ipalib/cli.py b/ipalib/cli.py
index 3700572d9e9973b459abc9b42a3900d199ae6519..3a745a06c10de085e7c99b5a806c8e4ca4ea8575 100644
--- a/ipalib/cli.py
+++ b/ipalib/cli.py
@@ -1287,14 +1287,14 @@ class cli(backend.Executioner):
                     except IOError as e:
                         raise ValidationError(
                             name=to_cli(p.cli_name),
-                            error='%s: %s:' % (fname, e[1])
+                            error='%s: %s:' % (fname, e.args[1])
                         )
                 elif p.stdin_if_missing:
                     try:
                         raw = sys.stdin.read()
                     except IOError as e:
                         raise ValidationError(
-                            name=to_cli(p.cli_name), error=e[1]
+                            name=to_cli(p.cli_name), error=e.args[1]
                         )
 
                 if raw:
diff --git a/ipalib/plugins/vault.py b/ipalib/plugins/vault.py
index f94bf9d651a77ad6c49ec0df2b4bc3fcb7e0c70a..cbfa1e63028c41fce2f633e93815c5b588f5132c 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -223,7 +223,7 @@ def validated_read(argname, filename, mode='r', encoding=None):
         raise errors.ValidationError(
             name=argname,
             error=_("Cannot read file '%(filename)s': %(exc)s") % {
-                'filename': filename, 'exc': exc[1]
+                'filename': filename, 'exc': exc.args[1]
                 }
         )
     except UnicodeError as exc:
@@ -1549,7 +1549,7 @@ class vault_archive(PKQuery, Local):
             except OSError as exc:
                 raise errors.ValidationError(name="in", error=_(
                     "Cannot read file '%(filename)s': %(exc)s")
-                    % {'filename': input_file, 'exc': exc[1]})
+                    % {'filename': input_file, 'exc': exc.args[1]})
             if stat.st_size > MAX_VAULT_DATA_SIZE:
                 raise errors.ValidationError(name="in", error=_(
                     "Size of data exceeds the limit. Current vault data size "
-- 
2.5.0

From f1aa8d451887604a8cfe8dbc634851dafc51e8e2 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 5 Jan 2016 13:39:39 +0100
Subject: [PATCH] Use print_function future definition wherever print() is used

Pylint considers `print` a statement if the __future__ import is
not present, even if it's used like a function with one argument.

Add the __future__ import to files `pylint --py3k` complains about.
---
 doc/examples/python-api.py         | 1 +
 ipapython/dnssec/ldapkeydb.py      | 2 ++
 ipaserver/install/server/common.py | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/doc/examples/python-api.py b/doc/examples/python-api.py
index 8c79dc4cac0c170a577ed1b5f90fa5f268401559..0a6eb60efa84102ce0571277c1698664b1865619 100755
--- a/doc/examples/python-api.py
+++ b/doc/examples/python-api.py
@@ -19,6 +19,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 
+from __future__ import print_function
 from ipalib import api
 
 # 1. Initialize ipalib
diff --git a/ipapython/dnssec/ldapkeydb.py b/ipapython/dnssec/ldapkeydb.py
index 51819783f7d698b2eabba8cfaaf38ce5097afff2..c3f92c850992e04066de4002201815bb59b92c5a 100644
--- a/ipapython/dnssec/ldapkeydb.py
+++ b/ipapython/dnssec/ldapkeydb.py
@@ -2,6 +2,8 @@
 # Copyright (C) 2014  FreeIPA Contributors see COPYING for license
 #
 
+from __future__ import print_function
+
 from binascii import hexlify
 import collections
 import logging
diff --git a/ipaserver/install/server/common.py b/ipaserver/install/server/common.py
index a2c3e2d531ba775bf9f95d0d5219c5a17dbf37ef..c7d1d49c32e6a0e5c213d375dd4f97e81df2033d 100644
--- a/ipaserver/install/server/common.py
+++ b/ipaserver/install/server/common.py
@@ -2,6 +2,8 @@
 # Copyright (C) 2015  FreeIPA Contributors see COPYING for license
 #
 
+from __future__ import print_function
+
 import os
 import sys
 
-- 
2.5.0

From 4871fd9656aab83ac32044e768d53f5f78928b70 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 5 Jan 2016 13:54:43 +0100
Subject: [PATCH] Alias "unicode" to "str" under Python 3

Follow-up to commit 23507e6124041ed17f39db211e802495e37520e7

The six way of doing this is to replace all occurences of "unicode"
with "six.text_type". However, "unicode" is non-ambiguous and
(arguably) easier to read. Also, using it makes the patches smaller,
which should help with backporting.
---
 ipaserver/install/server/common.py                     | 5 +++++
 ipaserver/install/server/replicainstall.py             | 7 ++++++-
 ipatests/test_xmlrpc/test_caacl_profile_enforcement.py | 5 +++++
 ipatests/test_xmlrpc/test_certprofile_plugin.py        | 3 +++
 ipatests/test_xmlrpc/tracker/certprofile_plugin.py     | 4 ++++
 ipatests/test_xmlrpc/tracker/user_plugin.py            | 5 +++++
 6 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/ipaserver/install/server/common.py b/ipaserver/install/server/common.py
index c7d1d49c32e6a0e5c213d375dd4f97e81df2033d..2bf5a21ea67f7eff729118bb76ffe6147d137e3e 100644
--- a/ipaserver/install/server/common.py
+++ b/ipaserver/install/server/common.py
@@ -7,6 +7,8 @@ from __future__ import print_function
 import os
 import sys
 
+import six
+
 from ipapython.dn import DN
 from ipapython.install import common, core
 from ipapython.install.core import Knob
@@ -15,6 +17,9 @@ from ipaserver.install import bindinstance
 from ipapython.ipautil import check_zone_overlap
 from ipapython.dnsutil import DNSName
 
+if six.PY3:
+    unicode = str
+
 VALID_SUBJECT_ATTRS = ['st', 'o', 'ou', 'dnqualifier', 'c',
                        'serialnumber', 'l', 'title', 'sn', 'givenname',
                        'initials', 'generationqualifier', 'dc', 'mail',
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 854a90fadb5b3ab99f437a4bcde89a5557c61fef..09e7054553510417ae256a653efd12c1771da0a9 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -15,7 +15,9 @@ import socket
 import sys
 import tempfile
 
-from ipapython import certmonger, ipaldap, ipautil, sysrestore
+import six
+
+from ipapython import ipaldap, ipautil, sysrestore
 from ipapython.dn import DN
 from ipapython.install import common, core
 from ipapython.install.common import step
@@ -41,6 +43,9 @@ from binascii import hexlify
 
 from .common import BaseServer
 
+if six.PY3:
+    unicode = str
+
 DIRMAN_DN = DN(('cn', 'directory manager'))
 
 
diff --git a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
index 9de257a26f424ac00c24e06b15e604dedd5002bd..dca4151d614a4c2e2f5a09455426d117da4c1c80 100644
--- a/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
+++ b/ipatests/test_xmlrpc/test_caacl_profile_enforcement.py
@@ -7,6 +7,8 @@ import os
 import pytest
 import tempfile
 
+import six
+
 from ipalib import api, errors
 from ipatests.util import (
     prepare_config, unlock_principal_password, change_principal)
@@ -16,6 +18,9 @@ from ipatests.test_xmlrpc.tracker.caacl_plugin import CAACLTracker
 
 from ipapython.ipautil import run
 
+if six.PY3:
+    unicode = str
+
 BASE_DIR = os.path.dirname(__file__)
 
 SMIME_PROFILE_TEMPLATE = os.path.join(BASE_DIR, 'data/smime.cfg.tmpl')
diff --git a/ipatests/test_xmlrpc/test_certprofile_plugin.py b/ipatests/test_xmlrpc/test_certprofile_plugin.py
index 66a72de3e0da346289d9a8aa8eda039b6d6ddebc..e8459772d7a0b53b80b9cfa08a08dd57e4e12a47 100644
--- a/ipatests/test_xmlrpc/test_certprofile_plugin.py
+++ b/ipatests/test_xmlrpc/test_certprofile_plugin.py
@@ -10,12 +10,15 @@ Test the `ipalib.plugins.certprofile` module.
 import os
 
 import pytest
+import six
 
 from ipalib import api, errors
 from ipatests.util import prepare_config
 from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test, raises_exact
 from ipatests.test_xmlrpc.tracker.certprofile_plugin import CertprofileTracker
 
+if six.PY3:
+    unicode = str
 
 IPA_CERT_SUBJ_BASE = (
     api.Command.config_show()
diff --git a/ipatests/test_xmlrpc/tracker/certprofile_plugin.py b/ipatests/test_xmlrpc/tracker/certprofile_plugin.py
index eeb27eb14a5ab77695264afb5770fb9218e56bd4..21c96c5eb36bfeacdcae9f1df61d2f6f4aafa7e9 100644
--- a/ipatests/test_xmlrpc/tracker/certprofile_plugin.py
+++ b/ipatests/test_xmlrpc/tracker/certprofile_plugin.py
@@ -5,12 +5,16 @@
 
 import os
 
+import six
 
 from ipapython.dn import DN
 from ipatests.test_xmlrpc.tracker.base import Tracker
 from ipatests.test_xmlrpc import objectclasses
 from ipatests.util import assert_deepequal
 
+if six.PY3:
+    unicode = str
+
 
 class CertprofileTracker(Tracker):
     """Tracker class for certprofile plugin.
diff --git a/ipatests/test_xmlrpc/tracker/user_plugin.py b/ipatests/test_xmlrpc/tracker/user_plugin.py
index bcae2ec787b3d3a54e34917f125be006094e07b0..2e042c60eaea330819dd7747a696d2ece7c87449 100644
--- a/ipatests/test_xmlrpc/tracker/user_plugin.py
+++ b/ipatests/test_xmlrpc/tracker/user_plugin.py
@@ -5,12 +5,17 @@
 from ipalib import api, errors
 from ipapython.dn import DN
 
+import six
+
 from ipatests.util import assert_deepequal, get_group_dn, get_user_dn
 from ipatests.test_xmlrpc import objectclasses
 from ipatests.test_xmlrpc.xmlrpc_test import (
     fuzzy_digits, fuzzy_uuid, raises_exact)
 from ipatests.test_xmlrpc.tracker.base import Tracker
 
+if six.PY3:
+    unicode = str
+
 
 class UserTracker(Tracker):
     """ Class for host plugin like tests """
-- 
2.5.0

From 0fc8ea77f6b9b4a16484b57e7c2c91a6d97dc933 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 5 Jan 2016 13:57:51 +0100
Subject: [PATCH] Avoid builtins that were removed in Python 3

- `file` was removed in favor of `open`. Switch to the new spelling.
- `buffer` was removed in favor of a buffer protocol (and memoryview),
  and `reload` was moved to importlib.
  Both are used in py2-only blocks, so just placate PyLint.
---
 ipa-client/ipa-install/ipa-client-install | 2 +-
 ipalib/cli.py                             | 2 +-
 ipalib/x509.py                            | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index e9a7d45c3f82a58f6297db7354eb784f6416db4b..faa23b946d879ace160f7d83f368d9f7a3d836dc 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -1573,7 +1573,7 @@ def do_nsupdate(update_txt):
     root_logger.debug("Writing nsupdate commands to %s:", UPDATE_FILE)
     root_logger.debug("%s", update_txt)
 
-    update_fd = file(UPDATE_FILE, "w")
+    update_fd = open(UPDATE_FILE, "w")
     update_fd.write(update_txt)
     update_fd.flush()
     update_fd.close()
diff --git a/ipalib/cli.py b/ipalib/cli.py
index 3a745a06c10de085e7c99b5a806c8e4ca4ea8575..6116b2590d313c03aa8b375f06acde59581dbd41 100644
--- a/ipalib/cli.py
+++ b/ipalib/cli.py
@@ -40,7 +40,7 @@ if six.PY3:
     unicode = str
 
 if six.PY2:
-    reload(sys)
+    reload(sys)                         # pylint: disable=reload-builtin
     sys.setdefaultencoding('utf-8')     # pylint: disable=no-member
 
 from ipalib import frontend
diff --git a/ipalib/x509.py b/ipalib/x509.py
index 037d6785c85552a7335d848f7b21fb5eba26ceda..e7480fab9589131271e72244b307518cb76feb04 100644
--- a/ipalib/x509.py
+++ b/ipalib/x509.py
@@ -131,7 +131,7 @@ def load_certificate(data, datatype=PEM, dbdir=None):
     initialize_nss_database(dbdir=dbdir)
 
     if six.PY2:
-        return nss.Certificate(buffer(data))
+        return nss.Certificate(buffer(data))  # pylint: disable=buffer-builtin
     else:
         # In python 3 , `bytes` has the buffer interface
         return nss.Certificate(data)
-- 
2.5.0

From 251afa329358b3b718280d596176fc117592def3 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 5 Jan 2016 14:03:50 +0100
Subject: [PATCH] dnsutil: Rename __nonzero__ to __bool__

In Python 3, this special method got renamed. Set both to the same
function to keep compatibility.
---
 ipapython/dnsutil.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/ipapython/dnsutil.py b/ipapython/dnsutil.py
index a11d744d7131206cd0bb5d950c3725271b66410c..18141fa091b37c5e59a2efc1028812981bfd4884 100644
--- a/ipapython/dnsutil.py
+++ b/ipapython/dnsutil.py
@@ -49,11 +49,13 @@ class DNSName(dns.name.Name):
             # instead of a dns.exception
             raise dns.exception.SyntaxError(e)
 
-    def __nonzero__(self):
+    def __bool__(self):
         #dns.name.from_text('@') is represented like empty tuple
         #we need to acting '@' as nonzero value
         return True
 
+    __nonzero__ = __bool__  # for Python 2
+
     def __copy__(self):
         return DNSName(self.labels)
 
-- 
2.5.0

From 138f281dde06f77ef4cdc23da169c9c2230edcb4 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 5 Jan 2016 14:37:57 +0100
Subject: [PATCH] Remove deprecated contrib/RHEL4

This code is no longer maintained.
---
 contrib/RHEL4/Makefile.am      |  13 --
 contrib/RHEL4/configure.ac     |  55 -----
 contrib/RHEL4/ipa-client-setup | 356 --------------------------------
 contrib/RHEL4/ipa-client.spec  |  54 -----
 contrib/RHEL4/ipa.conf         |   3 -
 contrib/RHEL4/ipachangeconf.py | 458 -----------------------------------------
 contrib/RHEL4/setup.py         |  75 -------
 7 files changed, 1014 deletions(-)
 delete mode 100644 contrib/RHEL4/Makefile.am
 delete mode 100644 contrib/RHEL4/configure.ac
 delete mode 100644 contrib/RHEL4/ipa-client-setup
 delete mode 100644 contrib/RHEL4/ipa-client.spec
 delete mode 100644 contrib/RHEL4/ipa.conf
 delete mode 100644 contrib/RHEL4/ipachangeconf.py
 delete mode 100644 contrib/RHEL4/setup.py

diff --git a/contrib/RHEL4/Makefile.am b/contrib/RHEL4/Makefile.am
deleted file mode 100644
index f42303c477f2dcc8b9dd4fceddce45fb65786354..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-NULL =
-
-sbin_SCRIPTS =			\
-	ipa-client-setup	\
-	$(NULL)
-
-EXTRA_DIST =			\
-	$(sbin_SCRIPTS)		\
-	$(NULL)
-
-MAINTAINERCLEANFILES =		\
-	*~			\
-	Makefile.in
diff --git a/contrib/RHEL4/configure.ac b/contrib/RHEL4/configure.ac
deleted file mode 100644
index 1fd3fd23973d739bfa016cfd56af575c2e497010..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/configure.ac
+++ /dev/null
@@ -1,55 +0,0 @@
-AC_PREREQ(2.59)
-AC_INIT([ipa-client],
-        [0.99.0],
-        [http://www.freeipa.org/])
-
-AM_INIT_AUTOMAKE([foreign])
-
-AC_SUBST(VERSION)
-
-dnl ---------------------------------------------------------------------------
-dnl - Check for Python
-dnl ---------------------------------------------------------------------------
-
-AC_MSG_NOTICE([Checking for Python])
-have_python=no
-AM_PATH_PYTHON([2.3])
-
-if test "x$PYTHON" = "x" ; then
-  AC_MSG_ERROR([Python not found])
-fi
-
-dnl ---------------------------------------------------------------------------
-dnl - Set the data install directory since we don't use pkgdatadir
-dnl ---------------------------------------------------------------------------
-
-IPA_DATA_DIR="$datadir/ipa"
-AC_SUBST(IPA_DATA_DIR)
-
-dnl ---------------------------------------------------------------------------
-dnl Finish
-dnl ---------------------------------------------------------------------------
-
-# Files
-
-AC_CONFIG_FILES([
-    Makefile
-])
-
-AC_OUTPUT
-
-echo "
-                    IPA client $VERSION
-                    ========================
-
-	prefix:                   ${prefix}
-	exec_prefix:              ${exec_prefix}
-        libdir:                   ${libdir}
-        bindir:                   ${bindir}
-        sbindir:                  ${sbindir}
-        sysconfdir:               ${sysconfdir}
-        localstatedir:            ${localstatedir}
-        datadir:                  ${datadir}
-	source code location:	  ${srcdir}
-        Maintainer mode:          ${USE_MAINTAINER_MODE}
-"
diff --git a/contrib/RHEL4/ipa-client-setup b/contrib/RHEL4/ipa-client-setup
deleted file mode 100644
index 1096889ebf21e8634b59867e35a1035ebaa7efcd..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/ipa-client-setup
+++ /dev/null
@@ -1,356 +0,0 @@
-#! /usr/bin/python -E
-# Authors: Simo Sorce <sso...@redhat.com>
-#          Karl MacMillan <kmacmil...@mentalrootkit.com>
-#
-# Copyright (C) 2007  Red Hat
-# see file 'COPYING' for use and warranty information
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-VERSION = "%prog .1"
-
-import sys
-import os
-import string
-import shutil
-import socket
-from ipapython.ipa_log_manager import *
-from optparse import OptionParser
-import ipachangeconf
-import ldap
-from ldap import LDAPError
-from ipapython.dn import DN
-
-class ipaserver:
-
-    def __init__(self, server):
-        self.server = server
-        self.realm = None
-        self.domain = None
-        self.basedn = None
-
-    def getServerName(self):
-        return str(self.server)
-
-    def getDomainName(self):
-        return str(self.domain)
-
-    def getRealmName(self):
-        return str(self.realm)
-
-    def getBaseDN(self):
-        return str(self.basedn)
-
-    def check(self):
-
-        lret = []
-        lres = []
-        lattr = ""
-        linfo = ""
-        lrealms = []
-
-        i = 0
-
-        #now verify the server is really an IPA server
-        try:
-            root_logger.debug("Init ldap with: ldap://"+self.server+":389";)
-            lh = ldap.initialize("ldap://"+self.server+":389";)
-            lh.simple_bind_s("","")
-
-            root_logger.debug("Search rootdse")
-            lret = lh.search_s("", ldap.SCOPE_BASE, "(objectClass=*)")
-            for lattr in lret[0][1]:
-                if lattr.lower() == "namingcontexts":
-                    self.basedn = lret[0][1][lattr][0]
-
-            root_logger.debug("Search for (info=*) in "+self.basedn+"(base)")
-            lret = lh.search_s(self.basedn, ldap.SCOPE_BASE, "(info=IPA*)")
-            if not lret:
-                return False
-            root_logger.debug("Found: "+str(lret))
-
-            for lattr in lret[0][1]:
-                if lattr.lower() == "info":
-                    linfo = lret[0][1][lattr][0].lower()
-                    break
-
-            if not linfo:
-                return False
-
-            #search and return known realms
-            root_logger.debug("Search for (objectClass=krbRealmContainer) in "+self.basedn+"(sub)")
-            lret = lh.search_s(str(DN(('cn', 'kerberos'), self.basedn)),
-                               ldap.SCOPE_SUBTREE, "(objectClass=krbRealmContainer)")
-            if not lret:
-                #something very wrong
-                return False
-            root_logger.debug("Found: "+str(lret))
-
-            for lres in lret:
-                for lattr in lres[1]:
-                    if lattr.lower() == "cn":
-                        lrealms.append(lres[1][lattr][0])
-
-
-            if len(lrealms) != 1:
-                #which one? we can't attach to a multi-realm server without DNS working
-                return False
-            else:
-                self.realm = lrealms[0]
-                self.domain = lrealms[0].lower()
-                return True
-
-        except LDAPError as err:
-            #no good
-            root_logger.error("Ldap Error: "+str(err))
-            return False
-
-ntp_conf = """# Permit time synchronization with our time source, but do not
-# permit the source to query or modify the service on this system.
-restrict default kod nomodify notrap nopeer noquery
-restrict -6 default kod nomodify notrap nopeer noquery
-
-# Permit all access over the loopback interface.  This could
-# be tightened as well, but to do so would effect some of
-# the administrative functions.
-restrict 127.0.0.1
-restrict -6 ::1
-
-# Hosts on local network are less restricted.
-#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
-
-# Use public servers from the pool.ntp.org project.
-# Please consider joining the pool (http://www.pool.ntp.org/join.html).
-server $SERVER
-
-#broadcast 192.168.1.255 key 42		# broadcast server
-#broadcastclient			# broadcast client
-#broadcast 224.0.1.1 key 42		# multicast server
-#multicastclient 224.0.1.1		# multicast client
-#manycastserver 239.255.254.254		# manycast server
-#manycastclient 239.255.254.254 key 42	# manycast client
-
-# Undisciplined Local Clock. This is a fake driver intended for backup
-# and when no outside source of synchronized time is available.
-server	127.127.1.0	# local clock
-#fudge	127.127.1.0 stratum 10
-
-# Drift file.  Put this in a directory which the daemon can write to.
-# No symbolic links allowed, either, since the daemon updates the file
-# by creating a temporary in the same directory and then rename()'ing
-# it to the file.
-driftfile /var/lib/ntp/drift
-
-# Key file containing the keys and key identifiers used when operating
-# with symmetric key cryptography.
-keys /etc/ntp/keys
-
-# Specify the key identifiers which are trusted.
-#trustedkey 4 8 42
-
-# Specify the key identifier to use with the ntpdc utility.
-#requestkey 8
-
-# Specify the key identifier to use with the ntpq utility.
-#controlkey 8
-"""
-
-ntp_sysconfig = """# Drop root to id 'ntp:ntp' by default.
-OPTIONS="-x -u ntp:ntp -p /var/run/ntpd.pid"
-
-# Set to 'yes' to sync hw clock after successful ntpdate
-SYNC_HWCLOCK=yes
-
-# Additional options for ntpdate
-NTPDATE_OPTIONS=""
-"""
-
-def config_ntp(server_fqdn):
-
-    nc = string.replace(ntp_conf, "$SERVER", server_fqdn)
-
-    shutil.copy("/etc/ntp.conf", "/etc/ntp.conf.ipasave")
-
-    fd = open("/etc/ntp.conf", "w")
-    fd.write(nc)
-    fd.close()
-
-    shutil.copy("/etc/sysconfig/ntpd", "/etc/sysconfig/ntpd.ipasave")
-
-    fd = open("/etc/sysconfig/ntpd", "w")
-    fd.write(ntp_sysconfig)
-    fd.close()
-
-    # Set the ntpd to start on boot
-    os.system("/sbin/chkconfig ntpd on")
-
-    # Restart ntpd
-    os.system("/sbin/service ntpd restart")
-
-def parse_options():
-    parser = OptionParser(version=VERSION)
-    parser.add_option("--server", dest="server", help="IPA server")
-    parser.add_option("-d", "--debug", dest="debug", action="store_true",
-                      default=False, help="print debugging information")
-    parser.add_option("-U", "--unattended", dest="unattended",
-                      action="store_true",
-                      help="unattended installation never prompts the user")
-    parser.add_option("-N", "--no-ntp", action="store_false",
-                      help="do not configure ntp", default=True, dest="conf_ntp")
-
-    options, args = parser.parse_args()
-    if not options.server:
-        parser.error("must provide an IPA server name with --server")
-
-    return options
-
-def ask_for_confirmation(message):
-    yesno = raw_input(message + " [y/N]: ")
-    if not yesno or yesno.lower()[0] != "y":
-        return False
-    print "\n"
-    return True
-
-def logging_setup(options):
-    standard_logging_setup('ipaclient-install.log', debug=options.debug)
-
-def main():
-    options = parse_options()
-    logging_setup(options)
-    dnsok = True
-
-    ipasrv = ipaserver(options.server)
-
-    ret = ipasrv.check()
-    if ret == False:
-        print "Failed to verify that ["+options.server+"] is an IPA Server, aborting!"
-        return -1
-
-    print "IPA Server verified."
-    print "Realm: "+ipasrv.getRealmName()
-    print "DNS Domain: "+ipasrv.getDomainName()
-    print "IPA Server: "+ipasrv.getServerName()
-    print "BaseDN: "+ipasrv.getBaseDN()
-
-    print "\n"
-    if not options.unattended and not ask_for_confirmation("Continue to configure the system with these values?"):
-        return 1
-
-    # Configure ipa.conf
-    ipaconf = ipachangeconf.IPAChangeConf("IPA Installer")
-    ipaconf.setOptionAssignment(" = ")
-    ipaconf.setSectionNameDelimiters(("[","]"))
-
-    opts = [{'name':'comment', 'type':'comment', 'value':'File modified by ipa-client-install'},
-            {'name':'empty', 'type':'empty'}]
-
-    #[global]
-    defopts = [{'name':'xmlrpc_uri', 'type':'option', 'value':'https://%s/ipa/xml' % ipasrv.getServerName()},
-             {'name':'realm', 'type':'option', 'value':ipasrv.getRealmName()}]
-
-    opts.append({'name':'global', 'type':'section', 'value':defopts})
-    opts.append({'name':'empty', 'type':'empty'})
-
-    ipaconf.newConf("/etc/ipa/default.conf", opts)
-
-    # Configure ldap.conf
-    ldapconf = ipachangeconf.IPAChangeConf("IPA Installer")
-    ldapconf.setOptionAssignment(" ")
-
-    opts = [{'name':'comment', 'type':'comment', 'value':'File modified by ipa-client-install'},
-            {'name':'empty', 'type':'empty'},
-            {'name':'ldap_version', 'type':'option', 'value':'3'},
-            {'name':'base', 'type':'option', 'value':ipasrv.getBaseDN()},
-            {'name':'empty', 'type':'empty'},
-            {'name':'nss_base_passwd', 'type':'option', 'value':str(DN(('cn', 'users'), ('cn', 'accounts'), ipasrv.getBaseDN()))+'?sub'},
-            {'name':'nss_base_group', 'type':'option', 'value':str(DN(('cn', 'users'), ('cn', 'accounts'), ipasrv.getBaseDN()))+'?sub'},
-            {'name':'nss_schema', 'type':'option', 'value':'rfc2307bis'},
-            {'name':'nss_map_attribute', 'type':'option', 'value':'uniqueMember member'},
-            {'name':'nss_initgroups_ignoreusers', 'type':'option', 'value':'root,dirsrv'},
-            {'name':'empty', 'type':'empty'},
-            {'name':'nss_reconnect_maxsleeptime', 'type':'option', 'value':'8'},
-            {'name':'nss_reconnect_sleeptime', 'type':'option', 'value':'1'},
-            {'name':'bind_timelimit', 'type':'option', 'value':'5'},
-            {'name':'timelimit', 'type':'option', 'value':'15'},
-            {'name':'empty', 'type':'empty'},
-            {'name':'uri', 'type':'option', 'value':'ldap://'+ipasrv.getServerName()},
-            {'name':'empty', 'type':'empty'}]
-    try:
-        ldapconf.newConf("/etc/ldap.conf", opts)
-    except Exception as e:
-        print "Configuration failed: " + str(e)
-        return 1
-
-    if not "" == ipasrv.getRealmName():
-        #Configure krb5.conf
-        krbconf = ipachangeconf.IPAChangeConf("IPA Installer")
-        krbconf.setOptionAssignment(" = ")
-        krbconf.setSectionNameDelimiters(("[","]"))
-        krbconf.setSubSectionDelimiters(("{","}"))
-        krbconf.setIndent(("","  ","    "))
-
-        opts = [{'name':'comment', 'type':'comment', 'value':'File modified by ipa-client-install'},
-                {'name':'empty', 'type':'empty'}]
-
-        #[libdefaults]
-        libopts = [{'name':'default_realm', 'type':'option', 'value':ipasrv.getRealmName()}]
-        libopts.append({'name':'dns_lookup_realm', 'type':'option', 'value':'false'})
-        libopts.append({'name':'dns_lookup_kdc', 'type':'option', 'value':'true'})
-        libopts.append({'name':'ticket_lifetime', 'type':'option', 'value':'24h'})
-        libopts.append({'name':'forwardable', 'type':'option', 'value':'yes'})
-
-        opts.append({'name':'libdefaults', 'type':'section', 'value':libopts})
-        opts.append({'name':'empty', 'type':'empty'})
-
-        #[realms]
-        kropts =[{'name':'kdc', 'type':'option', 'value':ipasrv.getServerName()+':88'},
-                 {'name':'master_kdc', 'type':'option', 'value':ipasrv.getServerName()+':88'},
-                 {'name':'admin_server', 'type':'option', 'value':ipasrv.getServerName()+':749'},
-                 {'name':'default_domain', 'type':'option', 'value':ipasrv.getDomainName()}]
-        ropts = [{'name':ipasrv.getRealmName(), 'type':'subsection', 'value':kropts}]
-        opts.append({'name':'realms', 'type':'section', 'value':ropts})
-        opts.append({'name':'empty', 'type':'empty'})
-
-        #[domain_realm]
-        dropts = [{'name':'.'+ipasrv.getDomainName(), 'type':'option', 'value':ipasrv.getRealmName()},
-                  {'name':ipasrv.getDomainName(), 'type':'option', 'value':ipasrv.getRealmName()}]
-        opts.append({'name':'domain_realm', 'type':'section', 'value':dropts})
-        opts.append({'name':'empty', 'type':'empty'})
-
-        #[appdefaults]
-        pamopts = [{'name':'debug', 'type':'option', 'value':'false'},
-                   {'name':'ticket_lifetime', 'type':'option', 'value':'36000'},
-                   {'name':'renew_lifetime', 'type':'option', 'value':'36000'},
-                   {'name':'forwardable', 'type':'option', 'value':'true'},
-                   {'name':'krb4_convert', 'type':'option', 'value':'false'}]
-        appopts = [{'name':'pam', 'type':'subsection', 'value':pamopts}]
-        opts.append({'name':'appdefaults', 'type':'section', 'value':appopts})
-
-        krbconf.newConf("/etc/krb5.conf", opts);
-
-    #Modify nsswitch to add nss_ldap
-    os.system("/usr/sbin/authconfig --enableldap --kickstart")
-
-    #Modify pam to add pam_krb5
-    os.system("/usr/sbin/authconfig --enablekrb5 --kickstart")
-
-    if options.conf_ntp:
-        config_ntp(ipasrv.getServerName())
-
-    print "Client configuration complete."
-
-    return 0
-
-sys.exit(main())
diff --git a/contrib/RHEL4/ipa-client.spec b/contrib/RHEL4/ipa-client.spec
deleted file mode 100644
index d2173c73d89784339e1e97184aaabdb66e27bfd5..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/ipa-client.spec
+++ /dev/null
@@ -1,54 +0,0 @@
-Name:           ipa-client
-Version:        1.0.0
-Release:        1%{?dist}
-Summary:        IPA client Setup script for RHEL-4
-
-Group:          System Environment/Base
-License:        GPLv2
-URL:            http://www.freeipa.org
-Source0:        %{name}-%{version}.tgz
-BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-BuildArch:      noarch
-#BuildRequires:  python-devel
-
-Requires: python
-Requires: python-ldap
-
-%{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
-
-%description
-IPA is a server for identity, policy, and audit.
-The client package provide install and configuration scripts for RHEL-4 clients.
-
-%prep
-%setup -q
-%configure --prefix=/usr
-
-%build
-
-make
-
-%install
-rm -rf %{buildroot}
-%{__python} setup.py install --no-compile --root=%{buildroot}
-%makeinstall \
-	SBINDIR=$RPM_BUILD_ROOT%{_sbindir}
-mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/ipa
-install -m644 ipa.conf $RPM_BUILD_ROOT%{_sysconfdir}/ipa/ipa.conf
-
-%clean
-rm -rf %{buildroot}
-
-%files
-%defattr(-,root,root,-)
-%{_sbindir}/ipa-client-setup
-%{python_sitelib}/ipachangeconf.py*
-%config(noreplace) %{_sysconfdir}/ipa/ipa.conf
-
-%changelog
-* Thu Apr  3 2008 Rob Crittenden <rcrit...@redhat.com> - 1.0.0-1
-- Version bump for release
-
-* Mon Mar 25 2008 Simo Sorce <sso...@redhat.com> - 0.99.0-1
-- First RHEL-4 release
-
diff --git a/contrib/RHEL4/ipa.conf b/contrib/RHEL4/ipa.conf
deleted file mode 100644
index 516f764d5aaa5b83c4c1d834311f45922816e273..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/ipa.conf
+++ /dev/null
@@ -1,3 +0,0 @@
-[defaults]
-# realm = EXAMPLE.COM
-# server = ipa.example.com
diff --git a/contrib/RHEL4/ipachangeconf.py b/contrib/RHEL4/ipachangeconf.py
deleted file mode 100644
index de1a215b71597d0976168980c6fb25bd8f98aa31..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/ipachangeconf.py
+++ /dev/null
@@ -1,458 +0,0 @@
-#
-# ipachangeconf - configuration file manipulation classes and functions
-# partially based on authconfig code
-# Copyright (c) 1999-2007 Red Hat, Inc.
-# Author: Simo Sorce <sso...@redhat.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-import fcntl
-import os
-import string
-import time
-import shutil
-
-def openLocked(filename, perms):
-    fd = -1
-    try:
-        fd = os.open(filename, os.O_RDWR | os.O_CREAT, perms)
-        
-        fcntl.lockf(fd, fcntl.LOCK_EX)
-    except OSError as e:
-        if fd != -1:
-            try:
-                os.close(fd)
-            except OSError:
-                pass
-        raise IOError(e.errno, e.strerror)
-    return os.fdopen(fd, "r+")
-
-
-    #TODO: add subsection as a concept
-    #      (ex. REALM.NAME = { foo = x bar = y } )
-    #TODO: put section delimiters as separating element of the list
-    #      so that we can process multiple sections in one go
-    #TODO: add a comment all but provided options as a section option
-class IPAChangeConf:
-
-    def __init__(self, name):
-        self.progname = name
-        self.indent = ("","","")
-        self.assign = (" = ","=")
-        self.dassign = self.assign[0]
-        self.comment = ("#",)
-        self.dcomment = self.comment[0]
-        self.eol = ("\n",)
-        self.deol = self.eol[0]
-        self.sectnamdel = ("[","]")
-        self.subsectdel = ("{","}")
-
-    def setProgName(self, name):
-        self.progname = name
-
-    def setIndent(self, indent):
-        if type(indent) is tuple:
-            self.indent = indent
-        elif type(indent) is str:
-            self.indent = (indent, )
-        else:
-           raise ValueError, 'Indent must be a list of strings'
-
-    def setOptionAssignment(self, assign):
-        if type(assign) is tuple:
-            self.assign = assign
-        else:
-            self.assign = (assign, )
-        self.dassign = self.assign[0]
-
-    def setCommentPrefix(self, comment):
-        if type(comment) is tuple:
-            self.comment = comment
-        else:
-            self.comment = (comment, )
-        self.dcomment = self.comment[0]
-
-    def setEndLine(self, eol):
-        if type(eol) is tuple:
-            self.eol = eol
-        else:
-            self.eol = (eol, )
-        self.deol = self.eol[0]
-
-    def setSectionNameDelimiters(self, delims):
-        self.sectnamdel = delims
-
-    def setSubSectionDelimiters(self, delims):
-        self.subsectdel = delims
-
-    def matchComment(self, line):
-        for v in self.comment:
-            if line.lstrip().startswith(v):
-                return line.lstrip()[len(v):]
-        return False
-
-    def matchEmpty(self, line):
-        if line.strip() == "":
-            return True
-        return False
-
-    def matchSection(self, line):
-        cl = "".join(line.strip().split()).lower()
-        if len(self.sectnamdel) != 2:
-            return False
-        if not cl.startswith(self.sectnamdel[0]):
-            return False
-        if not cl.endswith(self.sectnamdel[1]):
-            return False
-        return cl[len(self.sectnamdel[0]):-len(self.sectnamdel[1])]            
-
-    def matchSubSection(self, line):
-        if self.matchComment(line):
-            return False
-
-        parts = line.split(self.dassign, 1)
-        if len(parts) < 2:
-            return False
-
-        if parts[1].strip() == self.subsectdel[0]:
-            return parts[0].strip()
-
-        return False
-
-    def matchSubSectionEnd(self, line):
-        if self.matchComment(line):
-            return False
-
-        if line.strip() == self.subsectdel[1]:
-            return True
-
-        return False
-
-    def getSectionLine(self, section):
-        if len(self.sectnamdel) != 2:
-            return section
-        return self.sectnamdel[0]+section+self.sectnamdel[1]+self.deol
-
-    def dump(self, options, level=0):
-        output = ""
-        if level >= len(self.indent):
-            level = len(self.indent)-1
-
-        for o in options:
-            if o['type'] == "section":
-                output += self.sectnamdel[0]+o['name']+self.sectnamdel[1]+self.deol
-                output += self.dump(o['value'], level+1)
-                continue
-            if o['type'] == "subsection":
-                output += self.indent[level]+o['name']+self.dassign+self.subsectdel[0]+self.deol
-                output += self.dump(o['value'], level+1)
-                output += self.indent[level]+self.subsectdel[1]+self.deol
-                continue
-            if o['type'] == "option":
-                output += self.indent[level]+o['name']+self.dassign+o['value']+self.deol
-                continue
-            if o['type'] == "comment":
-                output += self.dcomment+o['value']+self.deol
-                continue
-            if o['type'] == "empty":
-                output += self.deol
-                continue
-            raise SyntaxError, 'Unknown type: ['+o['type']+']'
-
-        return output
-
-    def parseLine(self, line):
-
-        if self.matchEmpty(line):
-            return {'name':'empty', 'type':'empty'}
-
-        value = self.matchComment(line)
-        if value:
-            return {'name':'comment', 'type':'comment', 'value':value.rstrip()} #pylint: disable=E1103
-
-        parts = line.split(self.dassign, 1)
-        if len(parts) < 2:
-            raise SyntaxError, 'Syntax Error: Unknown line format'
-
-        return {'name':parts[0].strip(), 'type':'option', 'value':parts[1].rstrip()}
-
-    def findOpts(self, opts, type, name, exclude_sections=False):
-
-        num = 0
-        for o in opts:
-            if o['type'] == type and o['name'] == name:
-                return (num, o)
-            if exclude_sections and (o['type'] == "section" or o['type'] == "subsection"):
-                return (num, None)
-            num += 1
-        return (num, None)
-
-    def commentOpts(self, inopts, level = 0):
-
-        opts = []
-
-        if level >= len(self.indent):
-            level = len(self.indent)-1
-
-        for o in inopts:
-            if o['type'] == 'section':
-                no = self.commentOpts(o['value'], level+1)
-                val = self.dcomment+self.sectnamdel[0]+o['name']+self.sectnamdel[1]
-                opts.append({'name':'comment', 'type':'comment', 'value':val})
-                for n in no:
-                    opts.append(n)
-                continue
-            if o['type'] == 'subsection':
-                no = self.commentOpts(o['value'], level+1)
-                val = self.indent[level]+o['name']+self.dassign+self.subsectdel[0]
-                opts.append({'name':'comment', 'type':'comment', 'value':val})
-                for n in no:
-                    opts.append(n)
-                val = self.indent[level]+self.subsectdel[1]
-                opts.append({'name':'comment', 'type':'comment', 'value':val})
-                continue
-            if o['type'] == 'option':
-                val = self.indent[level]+o['name']+self.dassign+o['value']
-                opts.append({'name':'comment', 'type':'comment', 'value':val})
-                continue
-            if o['type'] == 'comment':
-                opts.append(o)
-                continue
-            if o['type'] == 'empty':
-                opts.append({'name':'comment', 'type':'comment', 'value':''})
-                continue
-            raise SyntaxError, 'Unknown type: ['+o['type']+']'
-
-        return opts
-
-    def mergeOld(self, oldopts, newopts):
-
-        opts = []
-
-        for o in oldopts:
-            if o['type'] == "section" or o['type'] == "subsection":
-                (num, no) = self.findOpts(newopts, o['type'], o['name'])
-                if not no:
-                    opts.append(o)
-                    continue
-                if no['action'] == "set":
-                    mo = self.mergeOld(o['value'], no['value'])
-                    opts.append({'name':o['name'], 'type':o['type'], 'value':mo})
-                    continue
-                if no['action'] == "comment":
-                    co = self.commentOpts(o['value'])
-                    for c in co:
-                        opts.append(c)
-                    continue
-                if no['action'] == "remove":
-                    continue
-                raise SyntaxError, 'Unknown action: ['+no['action']+']'
-
-            if o['type'] == "comment" or o['type'] == "empty":
-                 opts.append(o)
-                 continue
-
-            if o['type'] == "option":
-                (num, no) = self.findOpts(newopts, 'option', o['name'], True)
-                if not no:
-                    opts.append(o)
-                    continue
-                if no['action'] == 'comment' or no['action'] == 'remove':
-                    if no['value'] != None and o['value'] != no['value']:
-                        opts.append(o)
-                        continue
-                    if no['action'] == 'comment':
-                       opts.append({'name':'comment', 'type':'comment',
-                                    'value':self.dcomment+o['name']+self.dassign+o['value']})
-                    continue
-                if no['action'] == 'set':
-                    opts.append(no)
-                    continue
-                raise SyntaxError, 'Unknown action: ['+o['action']+']'
-
-            raise SyntaxError, 'Unknown type: ['+o['type']+']'
-
-        return opts
-
-    def mergeNew(self, opts, newopts):
-
-        cline = 0
-
-        for no in newopts:
-
-            if no['type'] == "section" or no['type'] == "subsection":
-                (num, o) = self.findOpts(opts, no['type'], no['name'])
-                if not o:
-                    if no['action'] == 'set':
-                        opts.append(no)
-                    continue
-                if no['action'] == "set":
-                    self.mergeNew(o['value'], no['value'])
-                    continue
-                cline = num+1
-                continue
-
-            if no['type'] == "option":
-                (num, o) = self.findOpts(opts, no['type'], no['name'], True)
-                if not o:
-                    if no['action'] == 'set':
-                        opts.append(no)
-                    continue
-                cline = num+1
-                continue
-
-            if no['type'] == "comment" or no['type'] == "empty":
-                opts.insert(cline, no)
-                cline += 1
-                continue
-
-            raise SyntaxError, 'Unknown type: ['+no['type']+']'
-
-
-    def merge(self, oldopts, newopts):
-
-        #Use a two pass strategy
-        #First we create a new opts tree from oldopts removing/commenting
-        #  the options as indicated by the contents of newopts
-        #Second we fill in the new opts tree with options as indicated
-        #  in the newopts tree (this is becaus eentire (sub)sections may
-        #  exist in the newopts that do not exist in oldopts)
-
-        opts = self.mergeOld(oldopts, newopts)
-        self.mergeNew(opts, newopts)
-        return opts
-
-    #TODO: Make parse() recursive?
-    def parse(self, f):
-
-        opts = []
-        sectopts = []
-        section = None
-        subsectopts = []
-        subsection = None
-        curopts = opts
-        fatheropts = opts
-
-        # Read in the old file.
-        for line in f:
-
-            # It's a section start.
-            value = self.matchSection(line)
-            if value:
-                if section is not None:
-                    opts.append({'name':section, 'type':'section', 'value':sectopts})
-                sectopts = []
-                curopts = sectopts
-                fatheropts = sectopts
-                section = value
-                continue
-
-            # It's a subsection start.
-            value = self.matchSubSection(line)
-            if value:
-                if subsection is not None:
-                    raise SyntaxError, 'nested subsections are not supported yet'
-                subsectopts = []
-                curopts = subsectopts
-                subsection = value
-                continue
-
-            value = self.matchSubSectionEnd(line)
-            if value:
-                if subsection is None:
-                    raise SyntaxError, 'Unmatched end subsection terminator found'
-                fatheropts.append({'name':subsection, 'type':'subsection', 'value':subsectopts})
-                subsection = None
-                curopts = fatheropts
-                continue
-
-            # Copy anything else as is.
-            curopts.append(self.parseLine(line))
-
-        #Add last section if any
-        if len(sectopts) is not 0:
-            opts.append({'name':section, 'type':'section', 'value':sectopts})
-
-        return opts
-
-    # Write settings to configuration file
-    # file is a path
-    # options is a set of dictionaries in the form:
-    #     [{'name': 'foo', 'value': 'bar', 'action': 'set/comment'}]
-    # section is a section name like 'global'
-    def changeConf(self, file, newopts):
-        autosection = False
-        savedsection = None
-        done = False
-        output = ""
-        f = None
-        try:
-            #Do not catch an unexisting file error, we want to fail in that case
-            shutil.copy2(file, file+".ipabkp")
-
-            f = openLocked(file, 0o644)
-
-            oldopts = self.parse(f)
-
-            options = self.merge(oldopts, newopts)
-
-            output = self.dump(options)
-
-            # Write it out and close it.
-            f.seek(0)
-            f.truncate(0)
-            f.write(output)
-        finally:
-            try:
-                if f:
-                    f.close()
-            except IOError:
-                pass
-        return True
-
-    # Write settings to new file, backup old
-    # file is a path
-    # options is a set of dictionaries in the form:
-    #     [{'name': 'foo', 'value': 'bar', 'action': 'set/comment'}]
-    # section is a section name like 'global'
-    def newConf(self, file, options):
-        autosection = False
-        savedsection = None
-        done = False
-        output = ""
-        f = None
-        try:
-            try:
-                shutil.copy2(file, file+".ipabkp")
-            except IOError as err:
-                if err.errno == 2:
-                    # The orign file did not exist
-                    pass
-
-            f = openLocked(file, 0o644)
-
-            # Trunkate
-            f.seek(0)
-            f.truncate(0)
-
-            output = self.dump(options)
-
-            f.write(output)
-        finally:
-            try:
-                if f:
-                    f.close()
-            except IOError:
-                pass
-        return True
diff --git a/contrib/RHEL4/setup.py b/contrib/RHEL4/setup.py
deleted file mode 100644
index f535875b4aaaa6dfb790dd5e95d7d4b717bb9eaa..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/setup.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2007  Red Hat
-# see file 'COPYING' for use and warranty information
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-"""FreeIPA python support library
-
-FreeIPA is a server for identity, policy, and audit.
-"""
-
-DOCLINES = __doc__.split("\n")
-
-import os
-import sys
-import distutils.sysconfig
-
-CLASSIFIERS = """\
-Development Status :: 4 - Beta
-Intended Audience :: System Environment/Base
-License :: GPL
-Programming Language :: Python
-Operating System :: POSIX
-Operating System :: Unix
-"""
-
-# BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
-# update it when the contents of directories change.
-if os.path.exists('MANIFEST'): os.remove('MANIFEST')
-
-def setup_package():
-
-    from distutils.core import setup
-
-    old_path = os.getcwd()
-    local_path = os.path.dirname(os.path.abspath(sys.argv[0]))
-    os.chdir(local_path)
-    sys.path.insert(0,local_path)
-
-    try:
-        setup(
-            name = "ipa-client",
-            version = "0.99.0",
-            license = "GPL",
-            author = "Simo Sorce",
-            author_email = "sso...@redhat.com",
-            maintainer = "freeIPA Developers",
-            maintainer_email = "freeipa-devel@redhat.com",
-            url = "http://www.freeipa.org/";,
-            description = DOCLINES[0],
-            long_description = "\n".join(DOCLINES[2:]),
-            download_url = "http://www.freeipa.org/page/Downloads";,
-            classifiers=filter(None, CLASSIFIERS.split('\n')),
-            platforms = ["Linux"],
-            py_modules=['ipachangeconf']
-        )
-    finally:
-        del sys.path[0]
-        os.chdir(old_path)
-    return
-
-if __name__ == '__main__':
-    setup_package()
-- 
2.5.0

From 89806d61f8a8d61cbc02a27a858392f1bb07fae3 Mon Sep 17 00:00:00 2001
From: Petr Viktorin <pvikt...@redhat.com>
Date: Tue, 5 Jan 2016 14:31:39 +0100
Subject: [PATCH] make-lint: Allow running pylint --py3k to detect Python3
 issues

Pylint can be run with the --py3k switch to detect porting issues.
This is not compatible with regular checking (i.e. to do all checks,
pylint must be run twice, with and without --py3k).
So, do an additional run of pylint in a subprocess for the py3k checks.

Add a --no-py3k switch to skip the additional py3k run.
Also add a --no-lint switch to allow only running the py3 checks.
---
 make-lint | 45 +++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/make-lint b/make-lint
index 1af5336de3127aa2a6cb69bb908dd0bd0becb2da..7e85a5acb871149437602d0db65bf5a2cecf4d57 100755
--- a/make-lint
+++ b/make-lint
@@ -28,6 +28,7 @@ import os
 import sys
 from optparse import OptionParser
 from fnmatch import fnmatch, fnmatchcase
+import subprocess
 
 try:
     from pylint import checkers
@@ -222,6 +223,10 @@ def main():
         dest='fail', default=True, action='store_false')
     optparser.add_option('--enable-noerror', help='enable warnings and other non-error messages',
         dest='errors_only', default=True, action='store_false')
+    optparser.add_option('--no-py3k', help='Do not check for Python 3 porting issues',
+        dest='py3k', default=True, action='store_false')
+    optparser.add_option('--no-lint', help='Skip the main lint check',
+        dest='do_lint', default=True, action='store_false')
 
     options, args = optparser.parse_args()
     cwd = os.getcwd()
@@ -250,33 +255,41 @@ def main():
     linter.set_option('persistent', False)
     linter.set_option('disable', 'python3')
 
-    linter.check(files)
+    if options.do_lint:
+        linter.check(files)
 
-    if linter.msg_status != 0:
-        print("""
-===============================================================================
-Errors were found during the static code check.
-""", file=sys.stderr)
-
-        if len(linter.missing) > 0:
-            print("There are some missing imports:", file=sys.stderr)
-            for mod in sorted(linter.missing):
-                print("    " + mod, file=sys.stderr)
+        if linter.msg_status != 0:
             print("""
+===============================================================================
+Errors were found during the static code check.
+""", file=sys.stderr)
+
+            if len(linter.missing) > 0:
+                print("There are some missing imports:", file=sys.stderr)
+                for mod in sorted(linter.missing):
+                    print("    " + mod, file=sys.stderr)
+                print("""
 Please make sure all of the required and optional (python-gssapi, python-rhsm)
 python packages are installed.
 """, file=sys.stderr)
 
-        print("""\
+                print("""\
 If you are certain that any of the reported errors are false positives, please
 mark them in the source code according to the pylint documentation.
 ===============================================================================
 """, file=sys.stderr)
 
-    if options.fail:
-        return linter.msg_status
-    else:
-        return 0
+        if options.fail and linter.msg_status != 0:
+            return linter.msg_status
+
+    if options.py3k:
+        args = ['pylint', '--py3k', '-d', 'no-absolute-import', '--reports=n']
+        args.extend(files)
+        returncode = subprocess.call(args)
+        if options.fail and returncode != 0:
+            return returncode
+
+    return 0
 
 if __name__ == "__main__":
     sys.exit(main())
-- 
2.5.0

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to