commit b076743f2cdd3a3cb9e8d0e8be7be8c90160fc21 Author: Timo Aaltonen 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,42 @@ +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 __build_args(self): + args = ['--force'] + for (option, value) in self.parameters.items(): + if option == "sssdauth": + option = "sss" + # only sssd supported, filter the dupe + elif option in ["sssd", "krb5", "ldap", "update"]: + option = "" + if type(value) is bool: + if value: + if not "package" in args: + args.append("--package %s" % (option)) + else: + args.append("%s" % (option)) + else: + if not any("remove" in s for s in args): + args.append("--remove %s" % (option)) + else: + args.append("%s" % (option)) + + + def execute(self): + env = "DEBCONF_FRONTEND=noninteractive" + args = self.__build_args() + ipautil.run(["/usr/sbin/pam-auth-update"]+args,env) + --- /dev/null +++ b/ipapython/platform/debian/service.py @@ -0,0 +1,107 @@ +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) + if 'context' in api.env and api.env.context in ['ipactl', 'installer']: + update_service_list = True + else: + update_service_list = False + 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 '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(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" ],