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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> -# Karl MacMillan <[email protected]> -# -# 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 <[email protected]> - 1.0.0-1 -- Version bump for release - -* Mon Mar 25 2008 Simo Sorce <[email protected]> - 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 <[email protected]> -# -# 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 = "[email protected]", - maintainer = "freeIPA Developers", - maintainer_email = "[email protected]", - 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 <[email protected]> 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
