Ok, so this is the first step before we can start to rewrite bits from
ipaserver/install to make them support other distros. There are no real
functional changes yet.

had some dependency issues installing the resulting rpm's, so didn't
test the install scripts but they should work :)
>From c28ad06c64c2f3a7040021cb4935696bad3996f2 Mon Sep 17 00:00:00 2001
From: Timo Aaltonen <tjaal...@ubuntu.com>
Date: Wed, 29 Aug 2012 13:52:59 +0300
Subject: [PATCH] convert the base platform modules into packages


Signed-off-by: Timo Aaltonen <tjaal...@ubuntu.com>
---
 freeipa.spec.in                         |    6 +
 ipapython/platform/base.py              |  175 -----------------------
 ipapython/platform/base/__init__.py     |  175 +++++++++++++++++++++++
 ipapython/platform/fedora16.py          |  159 ---------------------
 ipapython/platform/fedora16/__init__.py |   49 +++++++
 ipapython/platform/fedora16/service.py  |  132 ++++++++++++++++++
 ipapython/platform/redhat.py            |  230 -------------------------------
 ipapython/platform/redhat/__init__.py   |  120 ++++++++++++++++
 ipapython/platform/redhat/auth.py       |   49 +++++++
 ipapython/platform/redhat/service.py    |  106 ++++++++++++++
 ipapython/setup.py.in                   |    6 +-
 11 files changed, 642 insertions(+), 565 deletions(-)
 delete mode 100644 ipapython/platform/base.py
 create mode 100644 ipapython/platform/base/__init__.py
 delete mode 100644 ipapython/platform/fedora16.py
 create mode 100644 ipapython/platform/fedora16/__init__.py
 create mode 100644 ipapython/platform/fedora16/service.py
 delete mode 100644 ipapython/platform/redhat.py
 create mode 100644 ipapython/platform/redhat/__init__.py
 create mode 100644 ipapython/platform/redhat/auth.py
 create mode 100644 ipapython/platform/redhat/service.py

diff --git a/freeipa.spec.in b/freeipa.spec.in
index ef9678e..4ce88e5 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -734,8 +734,14 @@ 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/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/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 a1e6b4e..0000000
--- a/ipapython/platform/base.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Authors: Alexander Bokovoy <aboko...@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
-
-# 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']
-
-
-# The common ports for these services. This is used to wait for the
-# service to become available.
-wellknownports = {
-    'dirsrv@PKI-IPA.service': [7389],
-    'PKI-IPA': [7389],
-    'dirsrv': [389], # this is only used if the incoming instance name is blank
-    'pki-cad': [9180],
-    'pki-tomcatd@pki-tomcat.service': [8080],
-    'pki-tomcat': [8080],
-    'pki-tomcatd': [8080], # used if the incoming instance name is blank
-}
-
-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):
-        return
-
-    def stop(self, instance_name="", capture_output=True):
-        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..a1e6b4e
--- /dev/null
+++ b/ipapython/platform/base/__init__.py
@@ -0,0 +1,175 @@
+# Authors: Alexander Bokovoy <aboko...@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
+
+# 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']
+
+
+# The common ports for these services. This is used to wait for the
+# service to become available.
+wellknownports = {
+    'dirsrv@PKI-IPA.service': [7389],
+    'PKI-IPA': [7389],
+    'dirsrv': [389], # this is only used if the incoming instance name is blank
+    'pki-cad': [9180],
+    'pki-tomcatd@pki-tomcat.service': [8080],
+    'pki-tomcat': [8080],
+    'pki-tomcatd': [8080], # used if the incoming instance name is blank
+}
+
+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):
+        return
+
+    def stop(self, instance_name="", capture_output=True):
+        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/fedora16.py b/ipapython/platform/fedora16.py
deleted file mode 100644
index 794c39e..0000000
--- a/ipapython/platform/fedora16.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Author: Alexander Bokovoy <aboko...@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 ipapython import ipautil
-from ipapython.platform import base, redhat, systemd
-import os
-
-# 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_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']
-
-# For beginning just remap names to add .service
-# As more services will migrate to systemd, unit names will deviate and
-# mapping will be kept in this dictionary
-system_units = dict(map(lambda x: (x, "%s.service" % (x)), base.wellknownservices))
-
-system_units['rpcgssd'] = 'nfs-secure.service'
-system_units['rpcidmapd'] = 'nfs-idmap.service'
-
-# Rewrite dirsrv and pki-tomcatd services as they support instances via separate
-# service generator. To make this working, one needs to have both foo@.servic
-# and foo.target -- the latter is used when request should be coming for
-# all instances (like stop). systemd, unfortunately, does not allow one
-# to request action for all service instances at once if only foo@.service
-# unit is available. To add more, if any of those services need to be
-# started/stopped automagically, one needs to manually create symlinks in
-# /etc/systemd/system/foo.target.wants/ (look into systemd.py's enable()
-# code).
-system_units['dirsrv'] = 'dirsrv@.service'
-# Our directory server instance for PKI is dirsrv@PKI-IPA.service
-system_units['pkids'] = 'dirsrv@PKI-IPA.service'
-# Old style PKI instance
-system_units['pki-cad'] = 'pki-cad@pki-ca.service'
-system_units['pki_cad'] = system_units['pki-cad']
-# Our PKI instance is pki-tomcatd@pki-tomcat.service
-system_units['pki-tomcatd'] = 'pki-tomcatd@pki-tomcat.service'
-system_units['pki_tomcatd'] = system_units['pki-tomcatd']
-
-class Fedora16Service(systemd.SystemdService):
-    def __init__(self, service_name):
-        if service_name in system_units:
-            service_name = system_units[service_name]
-        else:
-            if len(service_name.split('.')) == 1:
-                # if service_name does not have a dot, it is not foo.service
-                # and not a foo.target. Thus, not correct service name for
-                # systemd, default to foo.service style then
-                service_name = "%s.service" % (service_name)
-        super(Fedora16Service, self).__init__(service_name)
-
-# Special handling of directory server service
-#
-# We need to explicitly enable instances to install proper symlinks as
-# dirsrv.target.wants/ dependencies. Standard systemd service class does it
-# on enable() method call. Unfortunately, ipa-server-install does not do
-# explicit dirsrv.enable() because the service startup is handled by ipactl.
-#
-# If we wouldn't do this, our instances will not be started as systemd would
-# not have any clue about instances (PKI-IPA and the domain we serve) at all.
-# Thus, hook into dirsrv.restart().
-class Fedora16DirectoryService(Fedora16Service):
-    def enable(self, instance_name=""):
-        super(Fedora16DirectoryService, self).enable(instance_name)
-        dirsrv_systemd = "/etc/sysconfig/dirsrv.systemd"
-        if os.path.exists(dirsrv_systemd):
-            # We need to enable LimitNOFILE=8192 in the dirsrv@.service
-            # Since 389-ds-base-1.2.10-0.8.a7 the configuration of the
-            # service parameters is performed via
-            # /etc/sysconfig/dirsrv.systemd file which is imported by systemd
-            # into dirsrv@.service unit
-            replacevars = {'LimitNOFILE':'8192'}
-            ipautil.inifile_replace_variables(dirsrv_systemd, 'service', replacevars=replacevars)
-            restore_context(dirsrv_systemd)
-            ipautil.run(["/bin/systemctl", "--system", "daemon-reload"],raiseonerr=False)
-
-    def restart(self, instance_name="", capture_output=True, wait=True):
-        if len(instance_name) > 0:
-            elements = self.service_name.split("@")
-            srv_etc = os.path.join(self.SYSTEMD_ETC_PATH, self.service_name)
-            srv_tgt = os.path.join(self.SYSTEMD_ETC_PATH, self.SYSTEMD_SRV_TARGET % (elements[0]))
-            srv_lnk = os.path.join(srv_tgt, self.service_instance(instance_name))
-            if not os.path.exists(srv_etc):
-                self.enable(instance_name)
-            elif not os.path.samefile(srv_etc, srv_lnk):
-                os.unlink(srv_lnk)
-                os.symlink(srv_etc, srv_lnk)
-        super(Fedora16DirectoryService, self).restart(instance_name, capture_output=capture_output, wait=wait)
-
-# Enforce restart of IPA services when we do enable it
-# This gets around the fact that after ipa-server-install systemd thinks
-# ipa.service is not yet started but all services were actually started
-# already.
-class Fedora16IPAService(Fedora16Service):
-    def enable(self, instance_name=""):
-        super(Fedora16IPAService, self).enable(instance_name)
-        self.restart(instance_name)
-
-class Fedora16SSHService(Fedora16Service):
-    def get_config_dir(self, instance_name=""):
-        return '/etc/ssh'
-
-# Redirect directory server service through special sub-class due to its
-# special handling of instances
-def f16_service(name):
-    if name == 'dirsrv':
-        return Fedora16DirectoryService(name)
-    if name == 'ipa':
-        return Fedora16IPAService(name)
-    if name == 'sshd':
-        return Fedora16SSHService(name)
-    return Fedora16Service(name)
-
-class Fedora16Services(base.KnownServices):
-    def __init__(self):
-        services = dict()
-        for s in base.wellknownservices:
-            services[s] = f16_service(s)
-        # Call base class constructor. This will lock services to read-only
-        super(Fedora16Services, self).__init__(services)
-
-def restore_context(filepath, restorecon='/usr/sbin/restorecon'):
-    return redhat.restore_context(filepath, restorecon)
-
-def check_selinux_status(restorecon='/usr/sbin/restorecon'):
-    return redhat.check_selinux_status(restorecon)
-
-authconfig = redhat.authconfig
-service = f16_service
-knownservices = Fedora16Services()
-backup_and_replace_hostname = redhat.backup_and_replace_hostname
diff --git a/ipapython/platform/fedora16/__init__.py b/ipapython/platform/fedora16/__init__.py
new file mode 100644
index 0000000..56b748a
--- /dev/null
+++ b/ipapython/platform/fedora16/__init__.py
@@ -0,0 +1,49 @@
+# Author: Alexander Bokovoy <aboko...@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 ipapython.platform import base, redhat
+from ipapython.platform.fedora16.service import *
+
+# 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_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']
+
+def restore_context(filepath, restorecon='/usr/sbin/restorecon'):
+    return redhat.restore_context(filepath, restorecon)
+
+def check_selinux_status(restorecon='/usr/sbin/restorecon'):
+    return redhat.check_selinux_status(restorecon)
+
+authconfig = redhat.authconfig
+service = f16_service
+knownservices = Fedora16Services()
+backup_and_replace_hostname = redhat.backup_and_replace_hostname
diff --git a/ipapython/platform/fedora16/service.py b/ipapython/platform/fedora16/service.py
new file mode 100644
index 0000000..75d38f5
--- /dev/null
+++ b/ipapython/platform/fedora16/service.py
@@ -0,0 +1,132 @@
+# Author: Alexander Bokovoy <aboko...@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
+
+from ipapython import ipautil
+from ipapython.platform import base, redhat, fedora16, systemd
+
+# For beginning just remap names to add .service
+# As more services will migrate to systemd, unit names will deviate and
+# mapping will be kept in this dictionary
+system_units = dict(map(lambda x: (x, "%s.service" % (x)), base.wellknownservices))
+
+system_units['rpcgssd'] = 'nfs-secure.service'
+system_units['rpcidmapd'] = 'nfs-idmap.service'
+
+# Rewrite dirsrv and pki-tomcatd services as they support instances via separate
+# service generator. To make this working, one needs to have both foo@.servic
+# and foo.target -- the latter is used when request should be coming for
+# all instances (like stop). systemd, unfortunately, does not allow one
+# to request action for all service instances at once if only foo@.service
+# unit is available. To add more, if any of those services need to be
+# started/stopped automagically, one needs to manually create symlinks in
+# /etc/systemd/system/foo.target.wants/ (look into systemd.py's enable()
+# code).
+system_units['dirsrv'] = 'dirsrv@.service'
+# Our directory server instance for PKI is dirsrv@PKI-IPA.service
+system_units['pkids'] = 'dirsrv@PKI-IPA.service'
+# Old style PKI instance
+system_units['pki-cad'] = 'pki-cad@pki-ca.service'
+system_units['pki_cad'] = system_units['pki-cad']
+# Our PKI instance is pki-tomcatd@pki-tomcat.service
+system_units['pki-tomcatd'] = 'pki-tomcatd@pki-tomcat.service'
+system_units['pki_tomcatd'] = system_units['pki-tomcatd']
+
+class Fedora16Service(systemd.SystemdService):
+    def __init__(self, service_name):
+        if service_name in system_units:
+            service_name = system_units[service_name]
+        else:
+            if len(service_name.split('.')) == 1:
+                # if service_name does not have a dot, it is not foo.service
+                # and not a foo.target. Thus, not correct service name for
+                # systemd, default to foo.service style then
+                service_name = "%s.service" % (service_name)
+        super(Fedora16Service, self).__init__(service_name)
+
+# Special handling of directory server service
+#
+# We need to explicitly enable instances to install proper symlinks as
+# dirsrv.target.wants/ dependencies. Standard systemd service class does it
+# on enable() method call. Unfortunately, ipa-server-install does not do
+# explicit dirsrv.enable() because the service startup is handled by ipactl.
+#
+# If we wouldn't do this, our instances will not be started as systemd would
+# not have any clue about instances (PKI-IPA and the domain we serve) at all.
+# Thus, hook into dirsrv.restart().
+class Fedora16DirectoryService(Fedora16Service):
+    def enable(self, instance_name=""):
+        super(Fedora16DirectoryService, self).enable(instance_name)
+        dirsrv_systemd = "/etc/sysconfig/dirsrv.systemd"
+        if os.path.exists(dirsrv_systemd):
+            # We need to enable LimitNOFILE=8192 in the dirsrv@.service
+            # Since 389-ds-base-1.2.10-0.8.a7 the configuration of the
+            # service parameters is performed via
+            # /etc/sysconfig/dirsrv.systemd file which is imported by systemd
+            # into dirsrv@.service unit
+            replacevars = {'LimitNOFILE':'8192'}
+            ipautil.inifile_replace_variables(dirsrv_systemd, 'service', replacevars=replacevars)
+            fedora16.restore_context(dirsrv_systemd)
+            ipautil.run(["/bin/systemctl", "--system", "daemon-reload"],raiseonerr=False)
+
+    def restart(self, instance_name="", capture_output=True, wait=True):
+        if len(instance_name) > 0:
+            elements = self.service_name.split("@")
+            srv_etc = os.path.join(self.SYSTEMD_ETC_PATH, self.service_name)
+            srv_tgt = os.path.join(self.SYSTEMD_ETC_PATH, self.SYSTEMD_SRV_TARGET % (elements[0]))
+            srv_lnk = os.path.join(srv_tgt, self.service_instance(instance_name))
+            if not os.path.exists(srv_etc):
+                self.enable(instance_name)
+            elif not os.path.samefile(srv_etc, srv_lnk):
+                os.unlink(srv_lnk)
+                os.symlink(srv_etc, srv_lnk)
+        super(Fedora16DirectoryService, self).restart(instance_name, capture_output=capture_output, wait=wait)
+
+# Enforce restart of IPA services when we do enable it
+# This gets around the fact that after ipa-server-install systemd thinks
+# ipa.service is not yet started but all services were actually started
+# already.
+class Fedora16IPAService(Fedora16Service):
+    def enable(self, instance_name=""):
+        super(Fedora16IPAService, self).enable(instance_name)
+        self.restart(instance_name)
+
+class Fedora16SSHService(Fedora16Service):
+    def get_config_dir(self, instance_name=""):
+        return '/etc/ssh'
+
+# Redirect directory server service through special sub-class due to its
+# special handling of instances
+def f16_service(name):
+    if name == 'dirsrv':
+        return Fedora16DirectoryService(name)
+    if name == 'ipa':
+        return Fedora16IPAService(name)
+    if name == 'sshd':
+        return Fedora16SSHService(name)
+    return Fedora16Service(name)
+
+class Fedora16Services(base.KnownServices):
+    def __init__(self):
+        services = dict()
+        for s in base.wellknownservices:
+            services[s] = f16_service(s)
+        # Call base class constructor. This will lock services to read-only
+        super(Fedora16Services, self).__init__(services)
diff --git a/ipapython/platform/redhat.py b/ipapython/platform/redhat.py
deleted file mode 100644
index 3f35cfc..0000000
--- a/ipapython/platform/redhat.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# Authors: Simo Sorce <sso...@redhat.com>
-#          Alexander Bokovoy <aboko...@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 tempfile
-import re
-import os
-import stat
-import sys
-import socket
-import stat
-
-from ipapython import ipautil
-from ipapython.platform import base
-from ipalib import api
-
-# 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_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']
-
-class RedHatService(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(["/sbin/service", self.service_name, "stop", instance_name], capture_output=capture_output)
-
-    def start(self, instance_name="", capture_output=True, wait=True):
-        ipautil.run(["/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)
-
-    def restart(self, instance_name="", capture_output=True, wait=True):
-        ipautil.run(["/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(["/sbin/service", self.service_name, "status", instance_name])
-            if sout.find("is stopped") >= 0:
-                ret = False
-        except ipautil.CalledProcessError:
-                ret = False
-        return ret
-
-    def is_installed(self):
-        installed = True
-        try:
-            ipautil.run(["/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=""):
-        (stdout, stderr, returncode) = ipautil.run(["/sbin/chkconfig", self.service_name],raiseonerr=False)
-        return (returncode == 0)
-
-    def enable(self, instance_name=""):
-        ipautil.run(["/sbin/chkconfig", self.service_name, "on"])
-
-    def disable(self, instance_name=""):
-        ipautil.run(["/sbin/chkconfig", self.service_name, "off"])
-
-    def install(self, instance_name=""):
-        ipautil.run(["/sbin/chkconfig", "--add", self.service_name])
-
-    def remove(self, instance_name=""):
-        ipautil.run(["/sbin/chkconfig", "--del", self.service_name])
-
-class RedHatSSHService(RedHatService):
-    def get_config_dir(self, instance_name=""):
-        return '/etc/ssh'
-
-class RedHatAuthConfig(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()
-        ipautil.run(["/usr/sbin/authconfig"]+args)
-
-def redhat_service(name):
-    if name == 'sshd':
-        return RedHatSSHService(name)
-    return RedHatService(name)
-
-class RedHatServices(base.KnownServices):
-    def __init__(self):
-        services = dict()
-        for s in base.wellknownservices:
-            services[s] = redhat_service(s)
-        # Call base class constructor. This will lock services to read-only
-        super(RedHatServices, self).__init__(services)
-
-authconfig = RedHatAuthConfig
-service = redhat_service
-knownservices = RedHatServices()
-
-def restore_context(filepath, restorecon='/sbin/restorecon'):
-    """
-    restore security context on the file path
-    SELinux equivalent is /path/to/restorecon <filepath>
-
-    restorecon's return values are not reliable so we have to
-    ignore them (BZ #739604).
-
-    ipautil.run() will do the logging.
-    """
-    try:
-        if (os.path.exists('/usr/sbin/selinuxenabled')):
-            ipautil.run(["/usr/sbin/selinuxenabled"])
-        else:
-            # No selinuxenabled, no SELinux
-            return
-    except ipautil.CalledProcessError:
-        # selinuxenabled returns 1 if not enabled
-        return
-
-    if (os.path.exists(restorecon)):
-        ipautil.run([restorecon, filepath], raiseonerr=False)
-
-def backup_and_replace_hostname(fstore, statestore, hostname):
-    old_hostname = socket.gethostname()
-    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))
-    replacevars = {'HOSTNAME':hostname}
-
-    filepath = '/etc/sysconfig/network'
-    if not os.path.exists(filepath):
-        # file doesn't exist; create it with correct ownership & mode
-        open(filepath, 'a').close()
-        os.chmod(filepath,
-            stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
-        os.chown(filepath, 0, 0)
-    old_values = ipautil.backup_config_and_replace_variables(
-        fstore, filepath, replacevars=replacevars)
-    restore_context("/etc/sysconfig/network")
-
-    if 'HOSTNAME' in old_values:
-        statestore.backup_state('network', 'hostname', old_values['HOSTNAME'])
-    else:
-        statestore.backup_state('network', 'hostname', old_hostname)
-
-def check_selinux_status(restorecon='/sbin/restorecon'):
-    """
-    We don't have a specific package requirement for policycoreutils
-    which provides restorecon. This is because we don't require
-    SELinux on client installs. However if SELinux is enabled then
-    this package is required.
-
-    This function returns nothing but may raise a Runtime exception
-    if SELinux is enabled but restorecon is not available.
-    """
-    try:
-        if (os.path.exists('/usr/sbin/selinuxenabled')):
-            ipautil.run(["/usr/sbin/selinuxenabled"])
-        else:
-            # No selinuxenabled, no SELinux
-            return
-    except ipautil.CalledProcessError:
-        # selinuxenabled returns 1 if not enabled
-        return
-
-    if not os.path.exists(restorecon):
-        raise RuntimeError('SELinux is enabled but %s does not exist.\nInstall the policycoreutils package and start the installation again.' % restorecon)
diff --git a/ipapython/platform/redhat/__init__.py b/ipapython/platform/redhat/__init__.py
new file mode 100644
index 0000000..8639621
--- /dev/null
+++ b/ipapython/platform/redhat/__init__.py
@@ -0,0 +1,120 @@
+# Authors: Simo Sorce <sso...@redhat.com>
+#          Alexander Bokovoy <aboko...@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 socket
+import stat
+import sys
+
+from ipapython.platform.redhat.auth import RedHatAuthConfig
+from ipapython.platform.redhat.service import redhat_service, RedHatServices
+from ipapython import ipautil
+
+# 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_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']
+
+authconfig = RedHatAuthConfig
+service = redhat_service
+knownservices = RedHatServices()
+
+def restore_context(filepath, restorecon='/sbin/restorecon'):
+    """
+    restore security context on the file path
+    SELinux equivalent is /path/to/restorecon <filepath>
+
+    restorecon's return values are not reliable so we have to
+    ignore them (BZ #739604).
+
+    ipautil.run() will do the logging.
+    """
+    try:
+        if (os.path.exists('/usr/sbin/selinuxenabled')):
+            ipautil.run(["/usr/sbin/selinuxenabled"])
+        else:
+            # No selinuxenabled, no SELinux
+            return
+    except ipautil.CalledProcessError:
+        # selinuxenabled returns 1 if not enabled
+        return
+
+    if (os.path.exists(restorecon)):
+        ipautil.run([restorecon, filepath], raiseonerr=False)
+
+def backup_and_replace_hostname(fstore, statestore, hostname):
+    old_hostname = socket.gethostname()
+    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))
+    replacevars = {'HOSTNAME':hostname}
+
+    filepath = '/etc/sysconfig/network'
+    if not os.path.exists(filepath):
+        # file doesn't exist; create it with correct ownership & mode
+        open(filepath, 'a').close()
+        os.chmod(filepath,
+            stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
+        os.chown(filepath, 0, 0)
+    old_values = ipautil.backup_config_and_replace_variables(
+        fstore, filepath, replacevars=replacevars)
+    restore_context("/etc/sysconfig/network")
+
+    if 'HOSTNAME' in old_values:
+        statestore.backup_state('network', 'hostname', old_values['HOSTNAME'])
+    else:
+        statestore.backup_state('network', 'hostname', old_hostname)
+
+def check_selinux_status(restorecon='/sbin/restorecon'):
+    """
+    We don't have a specific package requirement for policycoreutils
+    which provides restorecon. This is because we don't require
+    SELinux on client installs. However if SELinux is enabled then
+    this package is required.
+
+    This function returns nothing but may raise a Runtime exception
+    if SELinux is enabled but restorecon is not available.
+    """
+    try:
+        if (os.path.exists('/usr/sbin/selinuxenabled')):
+            ipautil.run(["/usr/sbin/selinuxenabled"])
+        else:
+            # No selinuxenabled, no SELinux
+            return
+    except ipautil.CalledProcessError:
+        # selinuxenabled returns 1 if not enabled
+        return
+
+    if not os.path.exists(restorecon):
+        raise RuntimeError('SELinux is enabled but %s does not exist.\nInstall the policycoreutils package and start the installation again.' % restorecon)
diff --git a/ipapython/platform/redhat/auth.py b/ipapython/platform/redhat/auth.py
new file mode 100644
index 0000000..9e10a5d
--- /dev/null
+++ b/ipapython/platform/redhat/auth.py
@@ -0,0 +1,49 @@
+# Authors: Simo Sorce <sso...@redhat.com>
+#          Alexander Bokovoy <aboko...@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/>.
+#
+
+from ipapython.platform.base import AuthConfig
+from ipapython import ipautil
+
+class RedHatAuthConfig(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()
+        ipautil.run(["/usr/sbin/authconfig"]+args)
diff --git a/ipapython/platform/redhat/service.py b/ipapython/platform/redhat/service.py
new file mode 100644
index 0000000..0f3bc23
--- /dev/null
+++ b/ipapython/platform/redhat/service.py
@@ -0,0 +1,106 @@
+# Authors: Simo Sorce <sso...@redhat.com>
+#          Alexander Bokovoy <aboko...@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/>.
+#
+
+from ipapython import ipautil
+from ipapython.platform import base
+from ipapython.platform.base import KnownServices
+from ipapython.platform.base import PlatformService
+from ipapython.platform.base import wellknownservices
+from ipalib import api
+
+class RedHatService(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(["/sbin/service", self.service_name, "stop", instance_name], capture_output=capture_output)
+
+    def start(self, instance_name="", capture_output=True, wait=True):
+        ipautil.run(["/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)
+
+    def restart(self, instance_name="", capture_output=True, wait=True):
+        ipautil.run(["/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(["/sbin/service", self.service_name, "status", instance_name])
+            if sout.find("is stopped") >= 0:
+                ret = False
+        except ipautil.CalledProcessError:
+                ret = False
+        return ret
+
+    def is_installed(self):
+        installed = True
+        try:
+            ipautil.run(["/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=""):
+        (stdout, stderr, returncode) = ipautil.run(["/sbin/chkconfig", self.service_name],raiseonerr=False)
+        return (returncode == 0)
+
+    def enable(self, instance_name=""):
+        ipautil.run(["/sbin/chkconfig", self.service_name, "on"])
+
+    def disable(self, instance_name=""):
+        ipautil.run(["/sbin/chkconfig", self.service_name, "off"])
+
+    def install(self, instance_name=""):
+        ipautil.run(["/sbin/chkconfig", "--add", self.service_name])
+
+    def remove(self, instance_name=""):
+        ipautil.run(["/sbin/chkconfig", "--del", self.service_name])
+
+class RedHatSSHService(RedHatService):
+    def get_config_dir(self, instance_name=""):
+        return '/etc/ssh'
+
+def redhat_service(name):
+    if name == 'sshd':
+        return RedHatSSHService(name)
+    return RedHatService(name)
+
+class RedHatServices(KnownServices):
+    def __init__(self):
+        services = dict()
+        for s in wellknownservices:
+            services[s] = redhat_service(s)
+        # Call base class constructor. This will lock services to read-only
+        super(RedHatServices, self).__init__(services)
diff --git a/ipapython/setup.py.in b/ipapython/setup.py.in
index df1cacf..b623c21 100644
--- a/ipapython/setup.py.in
+++ b/ipapython/setup.py.in
@@ -65,7 +65,11 @@ def setup_package():
             classifiers=filter(None, CLASSIFIERS.split('\n')),
             platforms = ["Linux", "Solaris", "Unix"],
             package_dir = {'ipapython': ''},
-            packages = [ "ipapython", "ipapython.platform" ],
+            packages = [ "ipapython",
+                         "ipapython.platform",
+                         "ipapython.platform.base",
+                         "ipapython.platform.fedora16",
+                         "ipapython.platform.redhat" ],
         )
     finally:
         del sys.path[0]
-- 
1.7.9.5

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to