URL: https://github.com/freeipa/freeipa/pull/373
Author: tjaalton
 Title: #373: ipaplatform: Add Debian platform module.
Action: opened

PR body:
"""
Hi, this just adds the Debian platform module. There are still other changes 
needed before vanilla master can be used on Debian or it's derivatives, but 
they need bigger changes while this is mostly standalone.
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/373/head:pr373
git checkout pr373
From 593a3e7bd5d00f72bf048e64434f2f2189ac528b Mon Sep 17 00:00:00 2001
From: Timo Aaltonen <tjaal...@debian.org>
Date: Thu, 5 Jan 2017 12:41:08 +0200
Subject: [PATCH] ipaplatform: Add Debian platform module.

---
 ipaplatform/debian/__init__.py  |   7 ++
 ipaplatform/debian/constants.py |  25 ++++++
 ipaplatform/debian/paths.py     |  98 +++++++++++++++++++++
 ipaplatform/debian/services.py  | 183 ++++++++++++++++++++++++++++++++++++++++
 ipaplatform/debian/tasks.py     |  46 ++++++++++
 ipaplatform/setup.py            |   1 +
 6 files changed, 360 insertions(+)
 create mode 100644 ipaplatform/debian/__init__.py
 create mode 100644 ipaplatform/debian/constants.py
 create mode 100644 ipaplatform/debian/paths.py
 create mode 100644 ipaplatform/debian/services.py
 create mode 100644 ipaplatform/debian/tasks.py

diff --git a/ipaplatform/debian/__init__.py b/ipaplatform/debian/__init__.py
new file mode 100644
index 0000000..6305270
--- /dev/null
+++ b/ipaplatform/debian/__init__.py
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2017  FreeIPA Contributors see COPYING for license
+#
+
+"""
+This module contains Debian specific platform files.
+"""
diff --git a/ipaplatform/debian/constants.py b/ipaplatform/debian/constants.py
new file mode 100644
index 0000000..1edcb5a
--- /dev/null
+++ b/ipaplatform/debian/constants.py
@@ -0,0 +1,25 @@
+#
+# Copyright (C) 2017  FreeIPA Contributors see COPYING for license
+#
+
+'''
+This Debian family platform module exports platform dependant constants.
+'''
+
+# Fallback to default path definitions
+from ipaplatform.base.constants import BaseConstantsNamespace
+
+
+class DebianConstantsNamespace(BaseConstantsNamespace):
+    HTTPD_USER = "www-data"
+    NAMED_USER = "bind"
+    NAMED_GROUP = "bind"
+    # ntpd init variable used for daemon options
+    NTPD_OPTS_VAR = "NTPD_OPTS"
+    # quote used for daemon options
+    NTPD_OPTS_QUOTE = "\'"
+    ODS_USER = "opendnssec"
+    ODS_GROUP = "opendnssec"
+    SECURE_NFS_VAR = "NEED_GSSD"
+
+constants = DebianConstantsNamespace()
diff --git a/ipaplatform/debian/paths.py b/ipaplatform/debian/paths.py
new file mode 100644
index 0000000..a3fa02f
--- /dev/null
+++ b/ipaplatform/debian/paths.py
@@ -0,0 +1,98 @@
+#
+# Copyright (C) 2017  FreeIPA Contributors see COPYING for license
+#
+
+"""
+This Debian base platform module exports default filesystem paths as common
+in Debian-based systems.
+"""
+
+# Fallback to default path definitions
+from ipaplatform.base.paths import BasePathNamespace
+import sysconfig
+
+MULTIARCH = sysconfig.get_config_var('MULTIARCH')
+
+class DebianPathNamespace(BasePathNamespace):
+    BIN_HOSTNAMECTL = "/usr/bin/hostnamectl"
+    AUTOFS_LDAP_AUTH_CONF = "/etc/autofs_ldap_auth.conf"
+    ETC_HTTPD_DIR = "/etc/apache2"
+    HTTPD_ALIAS_DIR = "/etc/apache2/nssdb"
+    ALIAS_CACERT_ASC = "/etc/apache2/nssdb/cacert.asc"
+    ALIAS_PWDFILE_TXT = "/etc/apache2/nssdb/pwdfile.txt"
+    HTTPD_CONF_D_DIR = "/etc/apache2/conf-enabled/"
+    HTTPD_IPA_KDCPROXY_CONF_SYMLINK = "/etc/apache2/conf-enabled/ipa-kdc-proxy.conf"
+    HTTPD_IPA_PKI_PROXY_CONF = "/etc/apache2/conf-enabled/ipa-pki-proxy.conf"
+    HTTPD_IPA_REWRITE_CONF = "/etc/apache2/conf-available/ipa-rewrite.conf"
+    HTTPD_IPA_CONF = "/etc/apache2/conf-enabled/ipa.conf"
+    HTTPD_NSS_CONF = "/etc/apache2/mods-available/nss.conf"
+    IPA_KEYTAB = "/etc/apache2/ipa.keytab"
+    HTTPD_PASSWORD_CONF = "/etc/apache2/password.conf"
+    NAMED_CONF = "/etc/bind/named.conf"
+    NAMED_VAR_DIR = "/var/cache/bind"
+    NAMED_KEYTAB = "/etc/bind/named.keytab"
+    NAMED_RFC1912_ZONES = "/etc/bind/named.conf.default-zones"
+    NAMED_ROOT_KEY = "/etc/bind/bind.keys"
+    NAMED_BINDKEYS_FILE = "/etc/bind/bind.keys"
+    NAMED_MANAGED_KEYS_DIR = "/var/cache/bind/dynamic"
+    OPENLDAP_LDAP_CONF = "/etc/ldap/ldap.conf"
+    ETC_DEBIAN_VERSION = "/etc/debian_version"
+    IPA_P11_KIT = "/usr/local/share/ca-certificates/ipa-ca.crt"
+    ETC_SYSCONFIG_DIR = "/etc/default"
+    SYSCONFIG_AUTOFS = "/etc/default/autofs"
+    SYSCONFIG_DIRSRV = "/etc/default/dirsrv"
+    SYSCONFIG_DIRSRV_INSTANCE = "/etc/default/dirsrv-%s"
+    SYSCONFIG_DIRSRV_SYSTEMD = "/etc/default/dirsrv.systemd"
+    SYSCONFIG_IPA_DNSKEYSYNCD = "/etc/default/ipa-dnskeysyncd"
+    SYSCONFIG_IPA_ODS_EXPORTER = "/etc/default/ipa-ods-exporter"
+    SYSCONFIG_KRB5KDC_DIR = "/etc/default/krb5-kdc"
+    SYSCONFIG_NAMED = "/etc/default/bind9"
+    SYSCONFIG_NFS = "/etc/default/nfs-common"
+    SYSCONFIG_NTPD = "/etc/default/ntp"
+    SYSCONFIG_ODS = "/etc/default/opendnssec"
+    SYSCONFIG_PKI = "/etc/dogtag/"
+    SYSCONFIG_PKI_TOMCAT = "/etc/default/pki-tomcat"
+    SYSCONFIG_PKI_TOMCAT_PKI_TOMCAT_DIR = "/etc/dogtag/tomcat/pki-tomcat"
+    SYSTEMD_SYSTEM_HTTPD_D_DIR = "/etc/systemd/system/apache2.service.d/"
+    SYSTEMD_SYSTEM_HTTPD_IPA_CONF = "/etc/systemd/system/apache2.service.d/ipa.conf"
+    DNSSEC_TRUSTED_KEY = "/etc/bind/trusted-key.key"
+    KRA_AGENT_PEM = "/etc/apache2/nssdb/kra-agent.pem"
+    SBIN_SERVICE = "/usr/sbin/service"
+    CERTMONGER_COMMAND_TEMPLATE = "/usr/lib/ipa/certmonger/%s"
+    UPDATE_CA_TRUST = "/usr/sbin/update-ca-certificates"
+    BIND_LDAP_SO = "/usr/share/doc/bind9-dyndb-ldap/copyright"
+    BIND_LDAP_DNS_IPA_WORKDIR = "/var/cache/bind/dyndb-ldap/ipa/"
+    BIND_LDAP_DNS_ZONE_WORKDIR = "/var/cache/bind/dyndb-ldap/ipa/master/"
+    LIBSOFTHSM2_SO = "/usr/lib/softhsm/libsofthsm2.so"
+    PAM_KRB5_SO = "/usr/lib/%s/security/pam_krb5.so" % MULTIARCH
+    LIB_SYSTEMD_SYSTEMD_DIR = "/lib/systemd/system/"
+    DOGTAG_IPA_CA_RENEW_AGENT_SUBMIT = "/usr/lib/certmonger/dogtag-ipa-ca-renew-agent-submit"
+    DOGTAG_IPA_RENEW_AGENT_SUBMIT = "/usr/lib/certmonger/dogtag-ipa-renew-agent-submit"
+    IPA_SERVER_GUARD = "/usr/lib/certmonger/ipa-server-guard"
+    GENERATE_RNDC_KEY = "/bin/true"
+    IPA_DNSKEYSYNCD_REPLICA = "/usr/lib/ipa/ipa-dnskeysync-replica"
+    IPA_DNSKEYSYNCD = "/usr/lib/ipa/ipa-dnskeysyncd"
+    IPA_ODS_EXPORTER = "/usr/lib/ipa/ipa-ods-exporter"
+    HTTPD = "/usr/sbin/apache2ctl"
+    REMOVE_DS_PL = "/usr/sbin/remove-ds"
+    SETUP_DS_PL = "/usr/sbin/setup-ds"
+    VAR_KERBEROS_KRB5KDC_DIR = "/var/lib/krb5kdc/"
+    VAR_KRB5KDC_K5_REALM = "/var/lib/krb5kdc/.k5."
+    CACERT_PEM = "/var/lib/krb5kdc/cacert.pem"
+    KRB5KDC_KADM5_ACL = "/etc/krb5kdc/kadm5.acl"
+    KRB5KDC_KADM5_KEYTAB = "/etc/krb5kdc/kadm5.keytab"
+    KRB5KDC_KDC_CONF = "/etc/krb5kdc/kdc.conf"
+    KDC_CERT = "/var/lib/krb5kdc/kdc.crt"
+    KDC_KEY = "/var/lib/krb5kdc/kdc.key"
+    VAR_LOG_HTTPD_DIR = "/var/log/apache2"
+    VAR_LOG_HTTPD_ERROR = "/var/log/apache2/error.log"
+    NAMED_RUN = "/var/cache/bind/named.run"
+    VAR_OPENDNSSEC_DIR = "/var/lib/opendnssec"
+    OPENDNSSEC_KASP_DB = "/var/lib/opendnssec/db/kasp.db"
+    IPA_ODS_EXPORTER_CCACHE = "/var/lib/opendnssec/tmp/ipa-ods-exporter.ccache"
+    KRB5CC_HTTPD = "/var/run/apache2/ipa/krbcache/krb5ccache"
+    IPA_CUSTODIA_SOCKET = "/run/apache2/ipa-custodia.sock"
+    IPA_CUSTODIA_AUDIT_LOG = '/var/log/ipa-custodia.audit.log'
+    IPA_GETKEYTAB = '/usr/sbin/ipa-getkeytab'
+
+paths = DebianPathNamespace()
diff --git a/ipaplatform/debian/services.py b/ipaplatform/debian/services.py
new file mode 100644
index 0000000..be8cf6b
--- /dev/null
+++ b/ipaplatform/debian/services.py
@@ -0,0 +1,183 @@
+#
+# Copyright (C) 2017  FreeIPA Contributors see COPYING for license
+#
+
+"""
+Contains Debian-specific service class implementations.
+"""
+
+import time
+
+from ipaplatform.tasks import tasks
+from ipaplatform.base import services as base_services
+from ipaplatform.redhat import services as redhat_services
+from ipapython import ipautil
+from ipapython.ipa_log_manager import root_logger
+from ipalib import api
+from ipaplatform.paths import paths
+
+# Mappings from service names as FreeIPA code references to these services
+# to their actual systemd service names
+debian_system_units = redhat_services.redhat_system_units
+
+debian_system_units['httpd'] = 'apache2.service'
+debian_system_units['kadmin'] = 'krb5-admin-server.service'
+debian_system_units['krb5kdc'] = 'krb5-kdc.service'
+debian_system_units['named-regular'] = 'bind9.service'
+debian_system_units['named-pkcs11'] = 'bind9-pkcs11.service'
+debian_system_units['named'] = debian_system_units['named-pkcs11']
+debian_system_units['pki-tomcatd'] = 'pki-tomcatd.service'
+debian_system_units['pki_tomcatd'] = debian_system_units['pki-tomcatd']
+debian_system_units['ods-enforcerd'] = 'opendnssec-enforcer.service'
+debian_system_units['ods_enforcerd'] = debian_system_units['ods-enforcerd']
+debian_system_units['ods-signerd'] = 'opendnssec-signer.service'
+debian_system_units['ods_signerd'] = debian_system_units['ods-signerd']
+debian_system_units['rpcgssd'] = 'rpc-gssd.service'
+debian_system_units['rpcidmapd'] = 'nfs-idmapd.service'
+debian_system_units['smb'] = 'smbd.service'
+
+# Service classes that implement Debian-specific behaviour
+
+class DebianService(redhat_services.RedHatService):
+    system_units = debian_system_units
+
+
+class DebianSysvService(base_services.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_services.wellknownports:
+            ports = base_services.wellknownports[instance_name]
+        else:
+            if self.service_name in base_services.wellknownports:
+                ports = base_services.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([paths.SBIN_SERVICE, self.service_name, "stop",
+                     instance_name], capture_output=capture_output)
+        if 'context' in api.env and api.env.context in ['ipactl', 'installer']:
+            update_service_list = True
+        else:
+            update_service_list = False
+        super(DebianSysvService, self).stop(instance_name)
+
+    def start(self, instance_name='', capture_output=True, wait=True):
+        ipautil.run([paths.SBIN_SERVICE, self.service_name, "start",
+                     instance_name], capture_output=capture_output)
+        if 'context' in api.env and api.env.context in ['ipactl', 'installer']:
+            update_service_list = True
+        else:
+            update_service_list = False
+        if wait and self.is_running(instance_name):
+            self.__wait_for_open_ports(instance_name)
+        super(DebianSysvService, self).start(instance_name)
+
+    def restart(self, instance_name='', capture_output=True, wait=True):
+        ipautil.run([paths.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:
+            result = ipautil.run([paths.SBIN_SERVICE,
+                                  self.service_name, "status",
+                                  instance_name],
+                                  capture_output=True)
+            sout = result.output
+            if sout.find("NOT running") >= 0:
+                ret = False
+            if sout.find("stop") >= 0:
+                ret = False
+            if sout.find("inactive") >= 0:
+                ret = False
+        except ipautil.CalledProcessError:
+                ret = False
+        return ret
+
+    def is_installed(self):
+        installed = True
+        try:
+            ipautil.run([paths.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
+
+    def tune_nofile_platform(self):
+        return True
+
+# For services which have no Debian counterpart
+class DebianNoService(base_services.PlatformService):
+    def start(self):
+        return True
+
+    def stop(self):
+        return True
+
+    def restart(self):
+        return True
+
+    def disable(self):
+        return True
+
+class DebianSSHService(DebianSysvService):
+    def get_config_dir(self, instance_name=""):
+        return '/etc/ssh'
+
+# Function that constructs proper Debian-specific server classes for services
+# of specified name
+
+def debian_service_class_factory(name):
+    if name == 'dirsrv':
+        return redhat_services.RedHatDirectoryService(name)
+    if name == 'domainname':
+        return DebianNoService(name)
+    if name == 'ipa':
+        return redhat_services.RedHatIPAService(name)
+    if name == 'messagebus':
+        return DebianNoService(name)
+    if name == 'ntpd':
+        return DebianSysvService("ntp")
+    if name == 'sshd':
+        return DebianSSHService(name)
+    return DebianService(name)
+
+
+# Magicdict containing DebianService instances.
+
+class DebianServices(base_services.KnownServices):
+    def __init__(self):
+        services = dict()
+        for s in base_services.wellknownservices:
+            services[s] = debian_service_class_factory(s)
+        # Call base class constructor. This will lock services to read-only
+        super(DebianServices, self).__init__(services)
+
+
+# Objects below are expected to be exported by platform module
+
+from ipaplatform.base.services import timedate_services
+service = debian_service_class_factory
+knownservices = DebianServices()
diff --git a/ipaplatform/debian/tasks.py b/ipaplatform/debian/tasks.py
new file mode 100644
index 0000000..2310fa7
--- /dev/null
+++ b/ipaplatform/debian/tasks.py
@@ -0,0 +1,46 @@
+#
+# Copyright (C) 2017  FreeIPA Contributors see COPYING for license
+#
+
+"""
+This module contains default Debian-specific implementations of system tasks.
+"""
+
+from ipaplatform.paths import paths
+from ipaplatform.base.tasks import *
+from ipaplatform.redhat.tasks import RedHatTaskNamespace
+
+BaseTask = BaseTaskNamespace()
+
+class DebianTaskNamespace(RedHatTaskNamespace):
+
+    def restore_pre_ipa_client_configuration(self, fstore, statestore,
+                                             was_sssd_installed,
+                                             was_sssd_configured):
+        # Debian doesn't use authconfig, nothing to restore
+        return True
+
+    def set_nisdomain(self, nisdomain):
+        # Debian doesn't use authconfig, nothing to set
+        return True
+
+    def modify_nsswitch_pam_stack(self, sssd, mkhomedir, statestore):
+        # Debian doesn't use authconfig, this is handled by pam-auth-update
+        return True
+
+    def modify_pam_to_use_krb5(self, statestore):
+        # Debian doesn't use authconfig, this is handled by pam-auth-update
+        return True
+
+    def backup_auth_configuration(self, path):
+        # Debian doesn't use authconfig, nothing to backup
+        return True
+
+    def restore_auth_configuration(self, path):
+        # Debian doesn't use authconfig, nothing to restore
+        return True
+
+    def parse_ipa_version(self, version):
+        return BaseTask.parse_ipa_version(version)
+
+tasks = DebianTaskNamespace()
diff --git a/ipaplatform/setup.py b/ipaplatform/setup.py
index 9c47da7..6637830 100644
--- a/ipaplatform/setup.py
+++ b/ipaplatform/setup.py
@@ -35,6 +35,7 @@
         packages=[
             "ipaplatform",
             "ipaplatform.base",
+            "ipaplatform.debian",
             "ipaplatform.fedora",
             "ipaplatform.redhat",
             "ipaplatform.rhel"
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to