diff options
author | Timo Aaltonen <tjaalton@ubuntu.com> | 2012-12-05 14:58:06 +0200 |
---|---|---|
committer | Martin Kosek <mkosek@redhat.com> | 2013-01-14 14:39:54 +0100 |
commit | ed849639272acf0aed44935591ba525ec1348d59 (patch) | |
tree | dce45b15575c4c9561a260a898d358575b45c610 /ipapython/platform/redhat | |
parent | 38dded7db6529be096b92c9d63182a980e0b3a93 (diff) | |
download | freeipa-ed849639272acf0aed44935591ba525ec1348d59.tar.gz freeipa-ed849639272acf0aed44935591ba525ec1348d59.tar.xz freeipa-ed849639272acf0aed44935591ba525ec1348d59.zip |
convert the base platform modules into packages
Diffstat (limited to 'ipapython/platform/redhat')
-rw-r--r-- | ipapython/platform/redhat/__init__.py | 133 | ||||
-rw-r--r-- | ipapython/platform/redhat/auth.py | 49 | ||||
-rw-r--r-- | ipapython/platform/redhat/service.py | 123 |
3 files changed, 305 insertions, 0 deletions
diff --git a/ipapython/platform/redhat/__init__.py b/ipapython/platform/redhat/__init__.py new file mode 100644 index 00000000..f7680e7e --- /dev/null +++ b/ipapython/platform/redhat/__init__.py @@ -0,0 +1,133 @@ +# Authors: Simo Sorce <ssorce@redhat.com> +# Alexander Bokovoy <abokovoy@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 import ipautil +from ipapython.platform import base +from ipapython.platform.redhat.auth import RedHatAuthConfig +from ipapython.platform.redhat.service import redhat_service, RedHatServices + +# 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) + +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) + +def restore_network_configuration(fstore, statestore): + filepath = '/etc/sysconfig/network' + if fstore.has_file(filepath): + fstore.restore_file(filepath) diff --git a/ipapython/platform/redhat/auth.py b/ipapython/platform/redhat/auth.py new file mode 100644 index 00000000..93c3c5e9 --- /dev/null +++ b/ipapython/platform/redhat/auth.py @@ -0,0 +1,49 @@ +# Authors: Simo Sorce <ssorce@redhat.com> +# Alexander Bokovoy <abokovoy@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 + +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) diff --git a/ipapython/platform/redhat/service.py b/ipapython/platform/redhat/service.py new file mode 100644 index 00000000..61511b48 --- /dev/null +++ b/ipapython/platform/redhat/service.py @@ -0,0 +1,123 @@ +# Authors: Simo Sorce <ssorce@redhat.com> +# Alexander Bokovoy <abokovoy@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 time + +from ipapython import ipautil +from ipapython.ipa_log_manager import root_logger +from ipapython.platform import base +from ipalib import api + +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) + super(RedHatService, self).stop(instance_name) + + 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) + super(RedHatService, self).start(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 RedHatHTTPDService(RedHatService): + def restart(self, instance_name="", capture_output=True, wait=True): + try: + super(RedHatHTTPDService, self).restart(instance_name, capture_output, wait) + except ipautil.CalledProcessError: + # http may have issues with binding to ports, try to fallback + # https://bugzilla.redhat.com/show_bug.cgi?id=845405 + root_logger.debug("%s restart failed, try to stop&start again", self.service_name) + time.sleep(5) + self.stop(instance_name, capture_output) + time.sleep(5) + self.start(instance_name, capture_output, wait) + +def redhat_service(name): + if name == 'sshd': + return RedHatSSHService(name) + elif name == 'httpd': + return RedHatHTTPDService(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) |