[Pkg-freeipa-devel] freeipa: Changes to 'ubuntu'

Timo Aaltonen tjaalton-guest at alioth.debian.org
Fri Mar 1 12:27:02 UTC 2013


 debian/changelog                               |   15 
 debian/control                                 |    5 
 debian/patches/add-debian-platform.diff        |  185 ++
 debian/patches/add_debian.py.patch             |  182 -
 debian/patches/check-dbus-before-starting.diff |   36 
 debian/patches/convert-base-platform.diff      | 2307 +++++++++++++++++++++++++
 debian/patches/fix-ldap-conf-path.diff         |   13 
 debian/patches/fix-ntpdate-opts.diff           |   13 
 debian/patches/fix-symlink-exclusion.diff      |   22 
 debian/patches/series                          |    7 
 debian/python-freeipa.install                  |    1 
 debian/rules                                   |    3 
 12 files changed, 2599 insertions(+), 190 deletions(-)

New commits:
commit 9ac656f5c39c90125d8596bf7b5263de6044632e
Author: Timo Aaltonen <tjaalton at ubuntu.com>
Date:   Fri Mar 1 14:26:33 2013 +0200

    add changelog entries for patches by Nick

diff --git a/debian/changelog b/debian/changelog
index 66b558a..c82b3bc 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -38,4 +38,13 @@ freeipa (3.1.2-1) UNRELEASED; urgency=low
     that.
   * Add support for Debian platform.
 
+  [ Nick Hatch ]
+  * Added three patches
+    - fix-symlink-exclusion.diff: Don't exclude symlinks when loading
+      plugins
+    - fix-ldap-conf-path.diff: Patch client installer to use correct LDAP
+      conf path.
+    - check-dbus-before-starting.diff: Check to see if dbus is running
+      before attempting to start it
+
  -- Timo Aaltonen <tjaalton at ubuntu.com>  Tue, 01 Nov 2011 10:52:25 -0400

commit 0ce99f5ed5b8b71e8661a533bab03af8669bd269
Author: Timo Aaltonen <tjaalton at ubuntu.com>
Date:   Fri Mar 1 14:14:41 2013 +0200

    Add support for Debian platform.

diff --git a/debian/changelog b/debian/changelog
index 58c1876..66b558a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -11,7 +11,6 @@ freeipa (3.1.2-1) UNRELEASED; urgency=low
   * Migrate to source format 3.0 (quilt).
   * Migrate to dh.
   * Fix dependencies.
-  * Add add_debian.py.patch, platform support code.
   * Add no-testcert.patch to not fail make-testcert.
   * Bump compat and debhelper build-depends to 9.
   * Add missing files to freeipa.install.
@@ -37,5 +36,6 @@ freeipa (3.1.2-1) UNRELEASED; urgency=low
     install the python bits to the correct path.
   * fix-ntpdate-opts.diff: Drop -U from nptdate opts, we don't have
     that.
+  * Add support for Debian platform.
 
  -- Timo Aaltonen <tjaalton at ubuntu.com>  Tue, 01 Nov 2011 10:52:25 -0400
diff --git a/debian/patches/add-debian-platform.diff b/debian/patches/add-debian-platform.diff
new file mode 100644
index 0000000..0075e2c
--- /dev/null
+++ b/debian/patches/add-debian-platform.diff
@@ -0,0 +1,185 @@
+commit b076743f2cdd3a3cb9e8d0e8be7be8c90160fc21
+Author: Timo Aaltonen <tjaalton at ubuntu.com>
+Date:   Fri Mar 1 12:21:00 2013 +0200
+
+    add debian platform support
+
+--- /dev/null
++++ b/ipapython/platform/debian/__init__.py
+@@ -0,0 +1,43 @@
++import os
++
++from ipapython.platform import base, redhat, fedora18
++from ipapython.platform.debian.auth import DebianAuthConfig
++from ipapython.platform.debian.service import debian_service, DebianServices
++
++# All what we allow exporting directly from this module
++# Everything else is made available through these symbols when they are
++# directly imported into ipapython.services:
++#
++# authconfig -- class reference for platform-specific implementation of
++#               authconfig(8)
++# service    -- class reference for platform-specific implementation of a
++#               PlatformService class
++# knownservices -- factory instance to access named services IPA cares about,
++#                  names are ipapython.services.wellknownservices
++# backup_and_replace_hostname -- platform-specific way to set hostname and
++#                                make it persistent over reboots
++# restore_network_configuration -- platform-specific way of restoring network
++#                                  configuration (e.g. static hostname)
++# restore_context -- platform-sepcific way to restore security context, if
++#                    applicable
++# check_selinux_status -- platform-specific way to see if SELinux is enabled
++#                         and restorecon is installed.
++__all__ = ['authconfig', 'service', 'knownservices',
++    'backup_and_replace_hostname', 'restore_context', 'check_selinux_status',
++    'restore_network_configuration', 'timedate_services']
++
++# Just copy a referential list of timedate services
++timedate_services = list(base.timedate_services)
++
++def restore_network_configuration(fstore, statestore):
++    filepath = '/etc/hostname'
++    if fstore.has_file(filepath):
++        fstore.restore_file(filepath)
++        hostname_was_configured = True
++
++authconfig = DebianAuthConfig
++service = debian_service
++knownservices = DebianServices()
++backup_and_replace_hostname = fedora18.backup_and_replace_hostname
++restore_context = redhat.restore_context
++check_selinux_status = redhat.check_selinux_status
+--- /dev/null
++++ b/ipapython/platform/debian/auth.py
+@@ -0,0 +1,18 @@
++from ipapython.platform import base
++
++class DebianAuthConfig(base.AuthConfig):
++    """
++    Debian implementation of the AuthConfig class.
++
++    Debian doesn't provide a single application for changing both
++    nss and pam configuration. PAM can be configured using debconf but there
++    is currently no such solution for updating NSS database and every package
++    does it by itself.
++
++    We'll have to play a catch-up game with the rest of the FreeIPA project
++    filtering out .enable() and .disable() calls that are useless for us,
++    and making the best out of the rest of them.
++    """
++
++    def execute(self):
++        raise NotImplementedError
+--- /dev/null
++++ b/ipapython/platform/debian/service.py
+@@ -0,0 +1,99 @@
++import time
++
++from ipapython import ipautil
++from ipapython.ipa_log_manager import root_logger
++from ipapython.platform import base
++from ipalib import api
++
++class DebianService(base.PlatformService):
++    def __wait_for_open_ports(self, instance_name=""):
++        """
++        If this is a service we need to wait for do so.
++        """
++        ports = None
++        if instance_name in base.wellknownports:
++            ports = base.wellknownports[instance_name]
++        else:
++            if self.service_name in base.wellknownports:
++                ports = base.wellknownports[self.service_name]
++        if ports:
++            ipautil.wait_for_open_ports('localhost', ports, api.env.startup_timeout)
++    def stop(self, instance_name='', capture_output=True):
++        ipautil.run(["/usr/sbin/service", self.service_name, "stop",
++                     instance_name], capture_output=capture_output)
++        super(DebianService, self).stop(instance_name)
++
++    def start(self, instance_name='', capture_output=True, wait=True):
++        ipautil.run(["/usr/sbin/service", self.service_name, "start",
++                     instance_name], capture_output=capture_output)
++        if wait and self.is_running(instance_name):
++            self.__wait_for_open_ports(instance_name)
++        super(DebianService, self).start(instance_name)
++
++    def restart(self, instance_name='', capture_output=True, wait=True):
++        ipautil.run(["/usr/sbin/service", self.service_name, "restart",
++                     instance_name], capture_output=capture_output)
++        if wait and self.is_running(instance_name):
++            self.__wait_for_open_ports(instance_name)
++
++    def is_running(self, instance_name=""):
++        ret = True
++        try:
++            (sout, serr, rcode) = ipautil.run(["/usr/sbin/service",
++                                              self.service_name, "status",
++                                              instance_name])
++            if sout.find("NOT running") >= 0:
++                ret = False
++            if sout.find("stop") >= 0:
++                ret = False
++        except ipautil.CalledProcessError:
++                ret = False
++        return ret
++
++    def is_installed(self):
++        installed = True
++        try:
++            ipautil.run(["/usr/sbin/service", self.service_name, "status"])
++        except ipautil.CalledProcessError, e:
++            if e.returncode == 1:
++                # service is not installed or there is other serious issue
++                installed = False
++        return installed
++
++    def is_enabled(self, instance_name=""):
++        # Services are always assumed to be enabled when installed
++        return True
++
++    def enable(self):
++        return True
++
++    def disable(self):
++        return True
++
++    def install(self):
++        return True
++
++    def remove(self):
++        return True
++
++class DebianSSHService(DebianService):
++    def get_config_dir(self, instance_name=""):
++        return '/etc/ssh'
++
++def debian_service(name):
++    if name == 'sshd':
++        return DebianSSHService(name)
++    return DebianService(name)
++
++class DebianServices(base.KnownServices):
++    def __init__(self):
++        services = dict()
++        for s in base.wellknownservices:
++            if s == "messagebus":
++                services[s] = debian_service("dbus")
++            elif s == "ntpd":
++                services[s] = debian_service("ntp")
++            else:
++                services[s] = debian_service(s)
++        # Call base class constructor. This will lock services to read-only
++        super(DebianServices, self).__init__(services)
+--- a/ipapython/setup.py.in
++++ b/ipapython/setup.py.in
+@@ -68,6 +68,7 @@ def setup_package():
+             packages = [ "ipapython",
+                          "ipapython.platform",
+                          "ipapython.platform.base",
++                         "ipapython.platform.debian",
+                          "ipapython.platform.fedora16",
+                          "ipapython.platform.fedora18",
+                          "ipapython.platform.redhat" ],
diff --git a/debian/patches/add_debian.py.patch b/debian/patches/add_debian.py.patch
deleted file mode 100644
index a866db2..0000000
--- a/debian/patches/add_debian.py.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-Author: Timo Aaltonen <tjaalton at ubuntu.com>
-Date:   Fri Oct 28 15:57:04 2011 +0300
-
-    Add add_debian.py.patch, platform support code.
-
---- /dev/null
-+++ b/ipapython/platform/debian.py
-@@ -0,0 +1,174 @@
-+# Authors: Simo Sorce <ssorce redhat com>
-+#          Alexander Bokovoy <abokovoy redhat com>
-+#          Marko Myllynen <myllynen redhat com>
-+#
-+# Copyright (C) 2007-2011   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/>.
-+#
-+
-+import os
-+import sys
-+from ipapython import ipautil
-+from ipapython.platform import base
-+
-+# All what we allow exporting directly from this module
-+# Everything else is made available through these symbols when they directly imported into ipapython.services:
-+# authconfig -- class reference for platform-specific implementation of authconfig(8)
-+# service    -- class reference for platform-specific implementation of a PlatformService class
-+# knownservices -- factory instance to access named services IPA cares about, names are ipapython.services.wellknownservices
-+# backup_and_replace_hostname -- platform-specific way to set hostname and make it persistent over reboots
-+# restore_context -- platform-sepcific way to restore security context, if applicable
-+__all__ = ['authconfig', 'service', 'knownservices', 'backup_and_replace_hostname', 'restore_context']
-+
-+class DebianService(base.PlatformService):
-+    def stop(self, instance_name="", capture_output=True):
-+        ipautil.run(["/usr/sbin/service", self.service_name, "stop", instance_name], capture_output=capture_output)
-+
-+    def start(self, instance_name="", capture_output=True):
-+        ipautil.run(["/usr/sbin/service", self.service_name, "start", instance_name], capture_output=capture_output)
-+
-+    def restart(self, instance_name="", capture_output=True):
-+        ipautil.run(["/usr/sbin/service", self.service_name, "restart", instance_name], capture_output=capture_output)
-+
-+    def is_running(self, instance_name=""):
-+        ret = True
-+        try:
-+            (sout,serr,rcode) = ipautil.run(["/usr/sbin/service", self.service_name, "status", instance_name])
-+            if sout.find("NOT running") >= 0:
-+                ret = False
-+            if sout.find("stop") >= 0:
-+                ret = False
-+        except ipautil.CalledProcessError:
-+                ret = False
-+        return ret
-+
-+    def is_installed(self):
-+        installed = True
-+        try:
-+            ipautil.run(["/usr/sbin/service", self.service_name, "status"])
-+        except ipautil.CalledProcessError, e:
-+            if e.returncode == 1:
-+                # service is not installed or there is other serious issue
-+                installed = False
-+        return installed
-+
-+    def is_enabled(self):
-+        ret = True
-+        try:
-+            (sout,serr,rcode) = ipautil.run(["/usr/sbin/service", self.service_name, "status"])
-+            if sout.find("off") >= 0:
-+                ret = False
-+            if sout.find("unknown service") >= 0:
-+                ret = False
-+        except ipautil.CalledProcessError:
-+                ret = False
-+        return ret
-+
-+    def enable(self):
-+        return True
-+
-+    def disable(self):
-+        return True
-+
-+    def install(self):
-+        return True
-+
-+    def remove(self):
-+        return True
-+
-+class DebianAuthConfig(base.AuthConfig):
-+    """
-+    AuthConfig class implements system-independent interface to configure
-+    system authentication resources. In Red Hat-produced systems this is done with
-+    authconfig(8) utility.
-+    """
-+    def __build_args(self):
-+        args = []
-+        for (option, value) in self.parameters.items():
-+            if type(value) is bool:
-+                if value:
-+                    args.append("--enable%s" % (option))
-+                else:
-+                    args.append("--disable%s" % (option))
-+            elif type(value) in (tuple, list):
-+                args.append("--%s" % (option))
-+                args.append("%s" % (value[0]))
-+            elif value is None:
-+                args.append("--%s" % (option))
-+            else:
-+                args.append("--%s%s" % (option,value))
-+        return args
-+
-+    def execute(self):
-+        args = self.__build_args()
-+        print "Would run on a Red Hat platform: /usr/sbin/authconfig " + " ".join(args)
-+        ipautil.user_input("Please do the corresponding changes manually and press Enter")
-+        #ipautil.run(["/usr/sbin/authconfig"]+args)
-+
-+class DebianServices(base.KnownServices):
-+    def __init__(self):
-+        services = dict()
-+        for s in base.wellknownservices:
-+            if s == "certmonger":
-+                services[s] = DebianService("certmonger")
-+            elif s == "messagebus":
-+                services[s] = DebianService("dbus")
-+            elif s == "ntpd":
-+                services[s] = DebianService("ntp")
-+            else:
-+                services[s] = DebianService(s)
-+        # Call base class constructor. This will lock services to read-only
-+        super(DebianServices, self).__init__(services)
-+
-+authconfig = DebianAuthConfig
-+service = DebianService
-+knownservices = DebianServices()
-+
-+def restore_context(filepath):
-+    """
-+    restore security context on the file path
-+    SELinux equivalent is /sbin/restorecon <filepath>
-+
-+    restorecon's return values are not reliable so we have to
-+    ignore them (BZ #739604).
-+
-+    ipautil.run() will do the logging.
-+    """
-+    if os.path.exists("/sbin/restorecon"):
-+        ipautil.run(["/sbin/restorecon", filepath], raiseonerr=False)
-+
-+def backup_and_replace_hostname(fstore, statestore, hostname):
-+    network_filename = "/etc/hostname"
-+    # Backup original /etc/hostname
-+    fstore.backup_file(network_filename)
-+
-+    # Write new configuration
-+    f = open(network_filename, 'w')
-+    f.write(hostname + "\n")
-+    f.close()
-+
-+    try:
-+        ipautil.run(['/bin/hostname', hostname])
-+    except ipautil.CalledProcessError, e:
-+        print >>sys.stderr, "Failed to set this machine hostname to %s (%s)." % (hostname, str(e))
-+
-+    # For SE Linux environments it is important to reset SE labels to the expected ones
-+    try:
-+        restore_context(network_filename)
-+    except ipautil.CalledProcessError, e:
-+        print >>sys.stderr, "Failed to set permissions for %s (%s)." % (network_filename, str(e))
-+
-+
diff --git a/debian/patches/convert-base-platform.diff b/debian/patches/convert-base-platform.diff
new file mode 100644
index 0000000..7df4d5e
--- /dev/null
+++ b/debian/patches/convert-base-platform.diff
@@ -0,0 +1,2307 @@
+commit 874d03b7c8edbb81d4f73de52fb1fb11505abecb
+Author: Timo Aaltonen <tjaalton at ubuntu.com>
+Date:   Wed Dec 5 14:58:06 2012 +0200
+
+    convert the base platform modules into packages
+
+diff --git a/freeipa.spec.in b/freeipa.spec.in
+index f1c45b6..0ce06cc 100644
+--- a/freeipa.spec.in
++++ b/freeipa.spec.in
+@@ -740,8 +740,16 @@ fi
+ %doc COPYING README Contributors.txt
+ %dir %{python_sitelib}/ipapython
+ %dir %{python_sitelib}/ipapython/platform
++%dir %{python_sitelib}/ipapython/platform/base
++%dir %{python_sitelib}/ipapython/platform/fedora16
++%dir %{python_sitelib}/ipapython/platform/fedora18
++%dir %{python_sitelib}/ipapython/platform/redhat
+ %{python_sitelib}/ipapython/*.py*
+ %{python_sitelib}/ipapython/platform/*.py*
++%{python_sitelib}/ipapython/platform/base/*.py*
++%{python_sitelib}/ipapython/platform/fedora16/*.py*
++%{python_sitelib}/ipapython/platform/fedora18/*.py*
++%{python_sitelib}/ipapython/platform/redhat/*.py*
+ %dir %{python_sitelib}/ipalib
+ %{python_sitelib}/ipalib/*
+ %{python_sitearch}/default_encoding_utf8.so
+diff --git a/ipapython/platform/base.py b/ipapython/platform/base.py
+deleted file mode 100644
+index e2aa33f..0000000
+--- a/ipapython/platform/base.py
++++ /dev/null
+@@ -1,226 +0,0 @@
+-# Authors: Alexander Bokovoy <abokovoy at redhat.com>
+-#
+-# Copyright (C) 2011  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/>.
+-
+-from ipalib.plugable import MagicDict
+-import json
+-import os
+-
+-# Canonical names of services as IPA wants to see them. As we need to have
+-# *some* naming, set them as in Red Hat distributions. Actual implementation
+-# should make them available through knownservices.<name> and take care of
+-# re-mapping internally, if needed
+-wellknownservices = ['certmonger', 'dirsrv', 'httpd', 'ipa', 'krb5kdc',
+-                     'messagebus', 'nslcd', 'nscd', 'ntpd', 'portmap',
+-                     'rpcbind', 'kadmin', 'sshd', 'autofs', 'rpcgssd',
+-                     'rpcidmapd', 'pki_tomcatd', 'pki-cad', 'chronyd']
+-
+-# System may support more time&date services. FreeIPA supports ntpd only, other
+-# services will be disabled during IPA installation
+-timedate_services = ['ntpd', 'chronyd']
+-
+-
+-# The common ports for these services. This is used to wait for the
+-# service to become available.
+-wellknownports = {
+-    'dirsrv at PKI-IPA.service': [7389],
+-    'PKI-IPA': [7389],
+-    'dirsrv': [389], # this is only used if the incoming instance name is blank
+-    'pki-cad': [9180, 9443, 9444],
+-    'pki-tomcatd at pki-tomcat.service': [8080, 8443],
+-    'pki-tomcat': [8080, 8443],
+-    'pki-tomcatd': [8080, 8443],  # used if the incoming instance name is blank
+-}
+-
+-SVC_LIST_FILE = "/var/run/ipa/services.list"
+-
+-class AuthConfig(object):
+-    """
+-    AuthConfig class implements system-independent interface to configure
+-    system authentication resources. In Red Hat systems this is done with
+-    authconfig(8) utility.
+-
+-    AuthConfig class is nothing more than a tool to gather configuration
+-    options and execute their processing. These options then converted by
+-    an actual implementation to series of a system calls to appropriate
+-    utilities performing real configuration.
+-
+-    IPA *expects* names of AuthConfig's options to follow authconfig(8)
+-    naming scheme!
+-
+-    Actual implementation should be done in ipapython/platform/<platform>.py
+-    by inheriting from platform.AuthConfig and redefining __build_args()
+-    and execute() methods.
+-
+-    from ipapython.platform import platform
+-    class PlatformAuthConfig(platform.AuthConfig):
+-        def __build_args():
+-        ...
+-
+-        def execute():
+-        ...
+-
+-    authconfig = PlatformAuthConfig
+-    ....
+-
+-    See ipapython/platform/redhat.py for a sample implementation that uses
+-    authconfig(8) as its backend.
+-
+-    From IPA code perspective, the authentication configuration should be
+-    done with use of ipapython.services.authconfig:
+-
+-    from ipapython import services as ipaservices
+-    auth_config = ipaservices.authconfig()
+-    auth_config.disable("ldap").\
+-                disable("krb5").\
+-                disable("sssd").\
+-                disable("sssdauth").\
+-                disable("mkhomedir").\
+-                add_option("update").\
+-                enable("nis").\
+-                add_parameter("nisdomain","foobar")
+-    auth_config.execute()
+-
+-    If you need to re-use existing AuthConfig instance for multiple runs,
+-    make sure to call 'AuthConfig.reset()' between the runs.
+-    """
+-
+-    def __init__(self):
+-        self.parameters = {}
+-
+-    def enable(self, option):
+-        self.parameters[option] = True
+-        return self
+-
+-    def disable(self, option):
+-        self.parameters[option] = False
+-        return self
+-
+-    def add_option(self, option):
+-        self.parameters[option] = None
+-        return self
+-
+-    def add_parameter(self, option, value):
+-        self.parameters[option] = [value]
+-        return self
+-
+-    def __build_args(self):
+-        # do nothing
+-        return None
+-
+-    def execute(self):
+-        # do nothing
+-        return None
+-
+-    def reset(self):
+-        self.parameters = {}
+-        return self
+-
+-class PlatformService(object):
+-    """
+-    PlatformService abstracts out external process running on the system
+-    which is possible to administer (start, stop, check status, etc).
+-
+-    """
+-
+-    def __init__(self, service_name):
+-        self.service_name = service_name
+-
+-    def start(self, instance_name="", capture_output=True, wait=True,
+-        update_service_list=True):
+-        """
+-        When a service is started record the fact in a special file.
+-        This allows ipactl stop to always stop all services that have
+-        been started via ipa tools
+-        """
+-        if not update_service_list:
+-            return
+-        svc_list = []
+-        try:
+-            f = open(SVC_LIST_FILE, 'r')
+-            svc_list = json.load(f)
+-        except Exception:
+-            # not fatal, may be the first service
+-            pass
+-
+-        if self.service_name not in svc_list:
+-            svc_list.append(self.service_name)
+-
+-        f = open(SVC_LIST_FILE, 'w')
+-        json.dump(svc_list, f)
+-        f.flush()
+-        f.close()
+-        return
+-
+-    def stop(self, instance_name="", capture_output=True, update_service_list=True):
+-        """
+-        When a service is stopped remove it from the service list file.
+-        """
+-        if not update_service_list:
+-            return
+-        svc_list = []
+-        try:
+-            f = open(SVC_LIST_FILE, 'r')
+-            svc_list = json.load(f)
+-        except Exception:
+-            # not fatal, may be the first service
+-            pass
+-
+-        while self.service_name in svc_list:
+-            svc_list.remove(self.service_name)
+-
+-        f = open(SVC_LIST_FILE, 'w')
+-        json.dump(svc_list, f)
+-        f.flush()
+-        f.close()
+-        return
+-
+-    def restart(self, instance_name="", capture_output=True, wait=True):
+-        return
+-
+-    def is_running(self, instance_name=""):
+-        return False
+-
+-    def is_installed(self):
+-        return False
+-
+-    def is_enabled(self, instance_name=""):
+-        return False
+-
+-    def enable(self, instance_name=""):
+-        return
+-
+-    def disable(self, instance_name=""):
+-        return
+-
+-    def install(self, instance_name=""):
+-        return
+-
+-    def remove(self, instance_name=""):
+-        return
+-
+-    def get_config_dir(self, instance_name=""):
+-        return
+-
+-class KnownServices(MagicDict):
+-    """
+-    KnownServices is an abstract class factory that should give out instances
+-    of well-known platform services. Actual implementation must create these
+-    instances as its own attributes on first access (or instance creation)
+-    and cache them.
+-    """
+-
+diff --git a/ipapython/platform/base/__init__.py b/ipapython/platform/base/__init__.py
+new file mode 100644
+index 0000000..e2aa33f
+--- /dev/null
++++ b/ipapython/platform/base/__init__.py
+@@ -0,0 +1,226 @@
++# Authors: Alexander Bokovoy <abokovoy at redhat.com>
++#
++# Copyright (C) 2011  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/>.
++
++from ipalib.plugable import MagicDict
++import json
++import os
++
++# Canonical names of services as IPA wants to see them. As we need to have
++# *some* naming, set them as in Red Hat distributions. Actual implementation
++# should make them available through knownservices.<name> and take care of
++# re-mapping internally, if needed
++wellknownservices = ['certmonger', 'dirsrv', 'httpd', 'ipa', 'krb5kdc',
++                     'messagebus', 'nslcd', 'nscd', 'ntpd', 'portmap',
++                     'rpcbind', 'kadmin', 'sshd', 'autofs', 'rpcgssd',
++                     'rpcidmapd', 'pki_tomcatd', 'pki-cad', 'chronyd']
++
++# System may support more time&date services. FreeIPA supports ntpd only, other
++# services will be disabled during IPA installation
++timedate_services = ['ntpd', 'chronyd']
++
++
++# The common ports for these services. This is used to wait for the
++# service to become available.
++wellknownports = {
++    'dirsrv at PKI-IPA.service': [7389],
++    'PKI-IPA': [7389],
++    'dirsrv': [389], # this is only used if the incoming instance name is blank
++    'pki-cad': [9180, 9443, 9444],
++    'pki-tomcatd at pki-tomcat.service': [8080, 8443],
++    'pki-tomcat': [8080, 8443],
++    'pki-tomcatd': [8080, 8443],  # used if the incoming instance name is blank
++}
++
++SVC_LIST_FILE = "/var/run/ipa/services.list"
++
++class AuthConfig(object):
++    """
++    AuthConfig class implements system-independent interface to configure
++    system authentication resources. In Red Hat systems this is done with
++    authconfig(8) utility.
++
++    AuthConfig class is nothing more than a tool to gather configuration
++    options and execute their processing. These options then converted by
++    an actual implementation to series of a system calls to appropriate
++    utilities performing real configuration.
++
++    IPA *expects* names of AuthConfig's options to follow authconfig(8)
++    naming scheme!
++
++    Actual implementation should be done in ipapython/platform/<platform>.py
++    by inheriting from platform.AuthConfig and redefining __build_args()
++    and execute() methods.
++
++    from ipapython.platform import platform
++    class PlatformAuthConfig(platform.AuthConfig):
++        def __build_args():
++        ...
++
++        def execute():
++        ...
++
++    authconfig = PlatformAuthConfig
++    ....
++
++    See ipapython/platform/redhat.py for a sample implementation that uses
++    authconfig(8) as its backend.
++
++    From IPA code perspective, the authentication configuration should be
++    done with use of ipapython.services.authconfig:
++
++    from ipapython import services as ipaservices
++    auth_config = ipaservices.authconfig()
++    auth_config.disable("ldap").\
++                disable("krb5").\
++                disable("sssd").\
++                disable("sssdauth").\
++                disable("mkhomedir").\
++                add_option("update").\
++                enable("nis").\
++                add_parameter("nisdomain","foobar")
++    auth_config.execute()
++
++    If you need to re-use existing AuthConfig instance for multiple runs,
++    make sure to call 'AuthConfig.reset()' between the runs.
++    """
++
++    def __init__(self):
++        self.parameters = {}
++
++    def enable(self, option):
++        self.parameters[option] = True
++        return self
++
++    def disable(self, option):
++        self.parameters[option] = False
++        return self
++
++    def add_option(self, option):
++        self.parameters[option] = None
++        return self
++
++    def add_parameter(self, option, value):
++        self.parameters[option] = [value]
++        return self
++
++    def __build_args(self):
++        # do nothing
++        return None
++
++    def execute(self):
++        # do nothing
++        return None
++
++    def reset(self):
++        self.parameters = {}
++        return self
++
++class PlatformService(object):
++    """
++    PlatformService abstracts out external process running on the system
++    which is possible to administer (start, stop, check status, etc).
++
++    """
++
++    def __init__(self, service_name):
++        self.service_name = service_name
++
++    def start(self, instance_name="", capture_output=True, wait=True,
++        update_service_list=True):
++        """
++        When a service is started record the fact in a special file.
++        This allows ipactl stop to always stop all services that have
++        been started via ipa tools
++        """
++        if not update_service_list:
++            return
++        svc_list = []
++        try:
++            f = open(SVC_LIST_FILE, 'r')
++            svc_list = json.load(f)
++        except Exception:
++            # not fatal, may be the first service
++            pass
++
++        if self.service_name not in svc_list:
++            svc_list.append(self.service_name)
++
++        f = open(SVC_LIST_FILE, 'w')
++        json.dump(svc_list, f)
++        f.flush()
++        f.close()
++        return
++
++    def stop(self, instance_name="", capture_output=True, update_service_list=True):
++        """
++        When a service is stopped remove it from the service list file.
++        """
++        if not update_service_list:
++            return
++        svc_list = []
++        try:
++            f = open(SVC_LIST_FILE, 'r')
++            svc_list = json.load(f)
++        except Exception:
++            # not fatal, may be the first service
++            pass
++
++        while self.service_name in svc_list:
++            svc_list.remove(self.service_name)
++
++        f = open(SVC_LIST_FILE, 'w')
++        json.dump(svc_list, f)
++        f.flush()
++        f.close()
++        return
++
++    def restart(self, instance_name="", capture_output=True, wait=True):
++        return
++
++    def is_running(self, instance_name=""):
++        return False
++
++    def is_installed(self):
++        return False
++
++    def is_enabled(self, instance_name=""):
++        return False
++
++    def enable(self, instance_name=""):
++        return
++
++    def disable(self, instance_name=""):
++        return
++
++    def install(self, instance_name=""):
++        return
++
++    def remove(self, instance_name=""):
++        return
++
++    def get_config_dir(self, instance_name=""):
++        return
++
++class KnownServices(MagicDict):
++    """
++    KnownServices is an abstract class factory that should give out instances
++    of well-known platform services. Actual implementation must create these
++    instances as its own attributes on first access (or instance creation)
++    and cache them.
++    """
++
+diff --git a/ipapython/platform/base/systemd.py b/ipapython/platform/base/systemd.py
+new file mode 100644
+index 0000000..a9c1ec0
+--- /dev/null
++++ b/ipapython/platform/base/systemd.py
+@@ -0,0 +1,233 @@
++# Author: Alexander Bokovoy <abokovoy at redhat.com>
++#
++# Copyright (C) 2011   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/>.
++#
++
++import os
++import shutil
++import sys
++
++from ipapython import ipautil
++from ipapython.platform import base
++from ipalib import api
++
++class SystemdService(base.PlatformService):
++    SYSTEMD_ETC_PATH = "/etc/systemd/system/"
++    SYSTEMD_LIB_PATH = "/lib/systemd/system/"
++    SYSTEMD_SRV_TARGET = "%s.target.wants"
++
++    def __init__(self, service_name, systemd_name):
++        super(SystemdService, self).__init__(service_name)
++        self.systemd_name = systemd_name
++        self.lib_path = os.path.join(self.SYSTEMD_LIB_PATH, self.systemd_name)
++        self.lib_path_exists = None
++
++    def service_instance(self, instance_name):
++        if self.lib_path_exists is None:
++            self.lib_path_exists = os.path.exists(self.lib_path)
++
++        elements = self.systemd_name.split("@")
++
++        # Short-cut: if there is already exact service name, return it
++        if self.lib_path_exists and len(instance_name) == 0:
++            if len(elements) == 1:
++                # service name is like pki-tomcatd.target or krb5kdc.service
++                return self.systemd_name
++            if len(elements) > 1 and elements[1][0] != '.':
++                # Service name is like pki-tomcatd at pki-tomcat.service and that file exists
++                return self.systemd_name
++



More information about the Pkg-freeipa-devel mailing list