Hello,

Patches 0753-0757 fix remaining warnings from `pylint --py3k`, except
"no-absolute-import" (which seems redundant to me) and the ones in
contrib/RHEL4.

As for contrib/RHEL4, I found a mail [0] from 2013 saying it hasn't been
used for a long time and probably doesn't work. Since then it's for
example been changed to use ipapython.dn, which I'd bet no one checks
for Python 2.5 compatibility. Since this seems to be untested and
non-working code, so I'm sending a patch to remove it. But if that's not
wanted tell me, and I'll skip pylint --py3k checks there instead.

The last patch adds py3k lint check  to make-lint. It's a bit
cumbersome, since pylint doesn't allow running regular checkers and the
py3k ones at the same time, but it allows you to run the check. As for
whether to enable --py3k by default, or run it on every package build,
I'd like to defer the decision to core devs. (Is CI good enough nowadays
to only run it there?)


[0] https://www.redhat.com/archives/freeipa-users/2013-July/msg00055.html

-- 
Petr Viktorin
From 576d4ac726659f9c3bf1440d1d9ea3b002f749c4 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 3b1b5a39371845d59bab07ac2fc32de598a469be..5398b7e7a8d5e0bfd72ef0638994968f8ae35c7c 100644
--- a/ipalib/cli.py
+++ b/ipalib/cli.py
@@ -1291,14 +1291,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 0cf6f1d2447716a469c9c5626fffba97419d8fdb..4d8419e75770dc4c8b856560cf6c1613a132f8c0 100644
--- a/ipalib/plugins/vault.py
+++ b/ipalib/plugins/vault.py
@@ -221,7 +221,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:
@@ -1547,7 +1547,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 b76b2e9fac3c44cdf41f071f647ed9c520e6a0f5 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 +
 ipaserver/install/server/common.py | 2 ++
 2 files changed, 3 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/ipaserver/install/server/common.py b/ipaserver/install/server/common.py
index 637e5664348bf3b7f2e4f2a867b8ecb224ccf388..277e839c3691a5ec8865684eedbfadf1984d7526 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 b1cb55fef50cc86d91f2f3dfd82feb30e48419f6 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             | 5 +++++
 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, 27 insertions(+)

diff --git a/ipaserver/install/server/common.py b/ipaserver/install/server/common.py
index 277e839c3691a5ec8865684eedbfadf1984d7526..8a9be92ee28d7b8e655198df309daab9c020e167 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
@@ -14,6 +16,9 @@ from ipalib.util import validate_domain_name
 from ipaserver.install import bindinstance
 from ipapython.ipautil import check_zone_overlap
 
+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 78e32ae9b6ee5aacef9a1db055f576a996fd03f0..4a8f1e476592cbc72161311dd31aecb90d93d0c2 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -15,6 +15,8 @@ import socket
 import sys
 import tempfile
 
+import six
+
 from ipapython import ipaldap, ipautil, sysrestore
 from ipapython.dn import DN
 from ipapython.install.common import step
@@ -40,6 +42,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 0dcf69ebbb17297a7c16b5f2bd6814a8e185a89f 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).
  It is used in a py2-only block so just placate PyLint.
- `long` and `int` were unified, but str(int(x)) does the same thing
  as str(long(x)) even on py2. Use the former.
---
 ipa-client/ipa-install/ipa-client-install | 2 +-
 ipalib/x509.py                            | 2 +-
 ipaplatform/redhat/tasks.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 af8d27bd0da9b847fef917d3bcc2ebd1837c5fb0..81443fd23964cf71f5e2e30eb0ce41c1eee65a0d 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/x509.py b/ipalib/x509.py
index 886bf6af61c10b298e71ba1c605e8a3e7897611f..2d28876de6ba7963417ef1505558a1d7b52a429f 100644
--- a/ipalib/x509.py
+++ b/ipalib/x509.py
@@ -130,7 +130,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)
diff --git a/ipaplatform/redhat/tasks.py b/ipaplatform/redhat/tasks.py
index a0b4060cb26bab66248c4397c24b4d58bf1bf8d6..dd7a7d6578ae0b895f2ed6f0c9e5668dd92e6339 100644
--- a/ipaplatform/redhat/tasks.py
+++ b/ipaplatform/redhat/tasks.py
@@ -56,7 +56,7 @@ def stringToVersion(verstring):
     i = verstring.find(':')
     if i != -1:
         try:
-            epoch = str(long(verstring[:i]))
+            epoch = str(int(verstring[:i]))
         except ValueError:
             # look, garbage in the epoch field, how fun, kill it
             epoch = '0' # this is our fallback, deal
-- 
2.5.0

From 62b3dbae803286e153eeb3bad0d119ed02215a93 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 0bbb76b6c9df509b8d2977a6f532d447379774ec 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 contrib/RHEL4

This code was never tested against an IPA v2 server.
---
 contrib/RHEL4/Makefile.am      |  13 --
 contrib/RHEL4/configure.ac     |  55 -----
 contrib/RHEL4/ipa-client-setup | 355 --------------------------------
 contrib/RHEL4/ipa-client.spec  |  54 -----
 contrib/RHEL4/ipa.conf         |   3 -
 contrib/RHEL4/ipachangeconf.py | 456 -----------------------------------------
 contrib/RHEL4/setup.py         |  74 -------
 7 files changed, 1010 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 2a6fc67761f41519fe2f575ed4d3b16ee02e5195..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/ipa-client-setup
+++ /dev/null
@@ -1,355 +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
-from ipapython.ipa_log_manager import root_logger, standard_logging_setup
-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 e3432a0fc0adde8c54fa799afa5a62cfc7c595d4..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/ipachangeconf.py
+++ /dev/null
@@ -1,456 +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 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 1fa23a8bd3b6710bdf13abc8679ee1b70aa4b173..0000000000000000000000000000000000000000
--- a/contrib/RHEL4/setup.py
+++ /dev/null
@@ -1,74 +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
-
-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 77117508620d9f7fda8af77c75bfc71ecb72bb5f 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).

Add a --py3k switch to make-lint to do a py3 run.
Also add a --no-lint switch to allow only running the py3 checks.
---
 make-lint | 63 ++++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 38 insertions(+), 25 deletions(-)

diff --git a/make-lint b/make-lint
index 97b5cd0f92e19911dd59d7e6122be54c01ae2997..e78127c1d324585ecfce472630a8bf3ba0ca2e24 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('--py3k', help='Also check for Python 3 porting issues',
+        dest='py3k', default=False, action='store_true')
+    optparser.add_option('--no-lint', help='Skil the main lint check',
+        dest='do_lint', default=True, action='store_false')
 
     options, args = optparser.parse_args()
     cwd = os.getcwd()
@@ -310,33 +315,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("""
-Please make sure all of the required and optional (python-gssapi, python-rhsm)
-python packages are installed.
-""", file=sys.stderr)
-
-        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
+    ===============================================================================
+    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("""\
+    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 and linter.msg_status != 0:
+            return linter.msg_status
+
+    if options.py3k:
+        args = ['pylint', '--py3k', '-d', 'no-absolute-import']
+        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