diff options
-rwxr-xr-x | install/tools/ipa-server-install | 4 | ||||
-rwxr-xr-x | install/tools/ipactl | 314 | ||||
-rwxr-xr-x | ipa.init | 45 | ||||
-rw-r--r-- | ipa.spec.in | 16 | ||||
-rw-r--r-- | ipaserver/install/bindinstance.py | 5 | ||||
-rw-r--r-- | ipaserver/install/cainstance.py | 14 | ||||
-rw-r--r-- | ipaserver/install/dsinstance.py | 5 | ||||
-rw-r--r-- | ipaserver/install/httpinstance.py | 5 | ||||
-rw-r--r-- | ipaserver/install/krbinstance.py | 10 | ||||
-rw-r--r-- | ipaserver/install/service.py | 51 |
10 files changed, 340 insertions, 129 deletions
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install index 32c9e8987..67c1a004e 100755 --- a/install/tools/ipa-server-install +++ b/install/tools/ipa-server-install @@ -842,6 +842,10 @@ def main(): except Exception, e: sys.exit("Configuration of client side components failed!\nipa-client-install returned: " + str(e)) + + #Everything installed properly, activate ipa service. + service.chkconfig_on('ipa') + print "==============================================================================" print "Setup complete" print "" diff --git a/install/tools/ipactl b/install/tools/ipactl index 596f07ff4..6c4db9bf4 100755 --- a/install/tools/ipactl +++ b/install/tools/ipactl @@ -1,6 +1,7 @@ -#!/bin/sh +#!/usr/bin/env python +# Authors: Simo Sorce <ssorce@redhat.com> # -# Copyright (C) 2008 Red Hat +# Copyright (C) 2008-2010 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or @@ -16,108 +17,207 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# -# IPA control to start/stop the various services required for IPA in the -# proper order -# - -# Set IFS so we can do space-embedded lists of services -IFS=";" - -# start and stop are basically a reverse of each other -services_stop="ipa_kpasswd;httpd;krb5kdc;dirsrv;ntpd;named;pki-cad pki-ca" -services_start="dirsrv;ntpd;krb5kdc;named;ipa_kpasswd;httpd;pki-cad pki-ca" - -function is_running() { - # $1 = service to check on - # $2 = optional instance to check on, for dirsrv and pki-cad - - # Returns - # 0 - running - # 1 - pid but dead service - # 2 - dead but locked subsys - # 3 - stopped - # 4 - no such service - if [ "$#" = 2 ] ; then - /sbin/service $1 status $2 > /dev/null 2>&1 - else - out=`/sbin/service $1 status 2>&1` - fi - case "$?" in - 0) - return 0;; - 1) - x=`echo $out | grep -c exists` - if [ $x -eq 1 ] ; then - return 1 - else - return 4 - fi - ;; - 2) - return 2;; - 3) - return 3;; - esac -} - -function start() { - for service in $services_start ; do - is_running $service - case "$?" in - 0) # running - ;; - 4) # no such service - ;; - *) # otherwise not running - /sbin/service $service start - ;; - esac - done -} - -function stop() { - for service in $services_stop ; do - is_running $service - case "$?" in - 0) # running - /sbin/service $service stop - ;; - *) # otherwise not running or doesn't exist - ;; - esac - done -} - -function status() { - for service in $services_start ; do - is_running $service - case "$?" in - 4) - ;; - *) - /sbin/service $service status - ;; - esac - done -} - -case "$1" in -restart) - stop - start - ;; -start) - start - ;; -stop) - stop - ;; -status) - status - ;; -*) - echo "Usage: ipactl {start|stop|restart|status}" - exit 1 - ;; -esac + +import sys +try: + from ipaserver.install import service + from ipapython import config + from ipalib import api, errors + import logging + import ldap + import socket + import syslog +except ImportError: + print >> sys.stderr, """\ +There was a problem importing one of the required Python modules. The +error was: + + %s +""" % sys.exc_value + sys.exit(1) + +def parse_options(): + usage = "%prog start|stop|restart|status\n" + parser = config.IPAOptionParser(usage=usage, + formatter=config.IPAFormatter()) + + parser.add_option("-d", "--debug", action="store_true", dest="debug", + help="Display debugging information") + + options, args = parser.parse_args() + safe_options = parser.get_safe_opts(options) + + return safe_options, options, args + +def emit_err(err): + syslog.syslog(syslog.LOG_ERR, err) + print err + +def get_config(): + base = "cn=%s,cn=masters,cn=ipa,cn=etc,%s" % (socket.gethostname(), + api.env.basedn) + srcfilter = '(ipaConfigString=enabledService)' + attrs = ['cn', 'ipaConfigString'] + + try: + con = ldap.initialize(api.env.ldap_uri) + con.simple_bind() + res = con.search_st(base, + ldap.SCOPE_SUBTREE, + filterstr=srcfilter, + attrlist=attrs, + timeout=10) + except e: + print "Error retrieving list of services %s" % e + print "Is IPA installed ?" + return + + svc_list = [] + + for entry in res: + name = entry[1]['cn'][0] + for p in entry[1]['ipaConfigString']: + if p.startswith('startOrder '): + order = p.split()[1] + svc_list.append((order, name)) + + return svc_list + +def ipa_start(): + + try: + print "Starting Directory Service" + service.start('dirsrv') + except: + emit_err("Failed to start Directory Service") + return + + svc_list = get_config() + + for (order, svc) in sorted(svc_list): + svc_name = service.SERVICE_LIST[svc][0] + try: + print "Starting %s Service" % svc + service.start(svc_name) + except: + emit_err("Failed to start %s Service" % svc) + emit_err("Shutting down") + for (order, svc) in sorted(svc_list): + svc_name = service.SERVICE_LIST[svc][0] + try: + service.stop(svc_name) + except: + pass + try: + service.stop('dirsrv') + except: + pass + return + +def ipa_stop(): + + svc_list = get_config() + + for (order, svc) in sorted(svc_list, reverse=True): + svc_name = service.SERVICE_LIST[svc][0] + try: + print "Stopping %s Service" % svc + service.stop(svc_name) + except: + emit_err("Failed to stop %s Service" % svc) + + try: + print "Stopping Directory Service" + service.stop('dirsrv') + except: + emit_err("Failed to stop Directory Service") + return + + +def ipa_restart(): + try: + print "Restarting Directory Service" + service.restart('dirsrv') + except: + emit_err("Failed to restart Directory Service") + return + + svc_list = get_config() + + for (order, svc) in sorted(svc_list): + svc_name = service.SERVICE_LIST[svc][0] + try: + print "Restarting %s Service" % svc + service.restart(svc_name) + except: + emit_err("Failed to restart %s Service" % svc) + emit_err("Shutting down") + for (order, svc) in sorted(svc_list): + svc_name = service.SERVICE_LIST[svc][0] + try: + service.stop(svc_name) + except: + pass + try: + service.stop('dirsrv') + except: + pass + return + +def ipa_status(): + try: + if service.is_running('dirsrv'): + print "Directory Service: RUNNING" + else: + print "Directory Service: STOPPED" + except: + print "Failed to get Directory Service status" + return + + svc_list = get_config() + + for (order, svc) in sorted(svc_list): + svc_name = service.SERVICE_LIST[svc][0] + try: + if service.is_running(svc_name): + print "%s Service: RUNNING" % svc + else: + print "%s Service: STOPPED" % svc + except: + print "Failed to get %s Service status" % svc + +def main(): + + safe_options, options, args = parse_options() + + if len(args) != 1: + sys.exit("You must specify one action") + elif args[0] != "start" and args[0] != "stop" and args[0] != "restart" and args[0] != "status": + sys.exit("Unrecognized action [" + args[0] + "]") + + api.bootstrap(context='cli', debug=options.debug) + api.finalize() + + syslog.openlog('ipa', syslog.LOG_NDELAY, syslog.LOG_DAEMON) + + if args[0].lower() == "start": + ipa_start() + elif args[0].lower() == "stop": + ipa_stop() + elif args[0].lower() == "restart": + ipa_restart() + elif args[0].lower() == "status": + ipa_status() + + syslog.closelog() + +try: + if __name__ == "__main__": + sys.exit(main()) +except RuntimeError, e: + print "%s" % e + sys.exit(1) +except SystemExit, e: + sys.exit(e) +except KeyboardInterrupt, e: + sys.exit(1) diff --git a/ipa.init b/ipa.init new file mode 100755 index 000000000..92c9f4918 --- /dev/null +++ b/ipa.init @@ -0,0 +1,45 @@ +#!/bin/sh +# +# ipa This starts and stops ipa +# +# chkconfig: - 21 79 +# description: IPA Server +# processname: /usr/sbin/ns-slapd +# configdir: /etc/ipa/ +# piddir: /var/run/dirsrv +# + +# Source function library. +if [ -f /etc/rc.d/init.d/functions ] ; then +. /etc/rc.d/init.d/functions +fi +# Source networking configuration. +if [ -f /etc/sysconfig/network ] ; then +. /etc/sysconfig/network +fi + +# Check that networking is up. +if [ "${NETWORKING}" = "no" ] +then + echo "Networking is down" + exit 0 +fi + +# Lockfile +if [ -d "/var/lock/subsys" ] ; then + lockfile="/var/lock/subsys/dirsrv" +else + lockfile="/var/lock/dirsrv/lock" +fi + +case "$1" in + start|stop|restart|status) + /usr/sbin/ipactl $1 + ;; + condrestart) + [ ! -f $lockfile ] || /usr/sbin/ipactl restart + ;; + *) + echo "Usage: $0 {start|stop|status|restart|condrestart}" + exit 2 +esac diff --git a/ipa.spec.in b/ipa.spec.in index 2597dad85..f808e4158 100644 --- a/ipa.spec.in +++ b/ipa.spec.in @@ -94,6 +94,8 @@ Requires(post): selinux-policy-base Requires: slapi-nis >= 0.15 Requires: pki-ca >= 1.3.6 Requires: pki-silent >= 1.3.4 +Requires(preun): python initscripts chkconfig +Requires(postun): python initscripts chkconfig %description server IPA is an integrated solution to provide centrally managed Identity (machine, @@ -280,7 +282,9 @@ ln -s ../../../..%{_sysconfdir}/ipa/html/unauthorized.html \ mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/ /bin/touch $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/ipa.conf /bin/touch $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/ipa-rewrite.conf +install -m755 ipa.init $RPM_BUILD_ROOT%{_initrddir}/ipa %endif + mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/ipa/ /bin/touch $RPM_BUILD_ROOT%{_sysconfdir}/ipa/default.conf mkdir -p %{buildroot}/%{_localstatedir}/lib/ipa-client/sysrestore @@ -296,6 +300,7 @@ rm -rf %{buildroot} %if ! %{ONLY_CLIENT} %post server if [ $1 = 1 ]; then + /sbin/chkconfig --add ipa /sbin/chkconfig --add ipa_kpasswd fi if [ -e /usr/share/ipa/serial ]; then @@ -305,15 +310,14 @@ fi %preun server if [ $1 = 0 ]; then + /sbin/chkconfig --del ipa /sbin/chkconfig --del ipa_kpasswd - /sbin/service ipa_kpasswd stop >/dev/null 2>&1 || : + /sbin/service ipa stop >/dev/null 2>&1 || : fi %postun server if [ "$1" -ge "1" ]; then - /sbin/service ipa_kpasswd condrestart >/dev/null 2>&1 || : - /sbin/service httpd condrestart >/dev/null 2>&1 || : - /sbin/service dirsrv condrestart >/dev/null 2>&1 || : + /sbin/service ipa condrestart >/dev/null 2>&1 || : fi %pre server-selinux @@ -373,6 +377,7 @@ fi %{_sbindir}/ipa_kpasswd %{_sbindir}/ipactl %{_sbindir}/ipa-upgradeconfig +%attr(755,root,root) %{_initrddir}/ipa %attr(755,root,root) %{_initrddir}/ipa_kpasswd %{python_sitelib}/ipaserver/* %dir %{_usr}/share/ipa @@ -503,6 +508,9 @@ fi %endif %changelog +* Tue Dec 7 2010 Simo Sorce <ssorce@redhat.com> - 1.99-33 +- Add ipa init script + * Fri Nov 19 2010 Rob Crittenden <rcritten@redhat.com> - 1.99-32 - Set minimum level of 389-ds-base to 1.2.7 for enhanced memberof plugin diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index a10b85464..30ce41138 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -275,7 +275,10 @@ class BindInstance(service.Service): def __enable(self): self.backup_state("enabled", self.is_running()) - self.chkconfig_on() + # We do not let the system start IPA components on its own, + # Instead we reply on the IPA init script to start only enabled + # components as found in our LDAP configuration tree + self.ldap_enable('DNS', self.fqdn, self.dm_password, self.suffix) def __setup_sub_dict(self): if self.forwarders: diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 5f13b721f..4a645bc84 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -242,7 +242,6 @@ class CADSInstance(service.Service): self.step("creating directory server user", self.__create_ds_user) self.step("creating directory server instance", self.__create_instance) - self.step("configuring directory to start on boot", self.__enable) self.step("restarting directory server", self.__restart_instance) self.start_creation("Configuring directory server for the CA", 30) @@ -255,13 +254,6 @@ class CADSInstance(service.Service): SERVER_ROOT=server_root, DOMAIN=self.domain, TIME=int(time.time()), DSPORT=self.ds_port) - def __enable(self): - name = self.service_name - self.service_name="dirsrv" - self.backup_state("enabled", self.is_enabled()) - self.chkconfig_on() - self.service_name = name - def __create_ds_user(self): user_exists = True try: @@ -483,7 +475,11 @@ class CAInstance(service.Service): def __enable(self): self.backup_state("enabled", self.is_enabled()) - self.chkconfig_on() + # We do not let the system start IPA components on its own, + # Instead we reply on the IPA init script to start only enabled + # components as found in our LDAP configuration tree + suffix = util.realm_to_suffix(self.realm) + self.ldap_enable('CA', self.fqdn, self.dm_password, suffix) def __create_ca_user(self): user_exists = True diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 03066984e..6fdc479ca 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -295,7 +295,10 @@ class DsInstance(service.Service): def __enable(self): self.backup_state("enabled", self.is_enabled()) - self.chkconfig_on() + # At the end of the installation ipa-server-install will enable the + # 'ipa' service wich takes care of starting/stopping dirsrv + # self.chkconfig_on() + self.chkconfig_off() def __setup_sub_dict(self): server_root = find_server_root() diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py index f55995b19..73930825f 100644 --- a/ipaserver/install/httpinstance.py +++ b/ipaserver/install/httpinstance.py @@ -91,7 +91,10 @@ class HTTPInstance(service.Service): def __enable(self): self.backup_state("enabled", self.is_running()) - self.chkconfig_on() + # We do not let the system start IPA components on its own, + # Instead we reply on the IPA init script to start only enabled + # components as found in our LDAP configuration tree + self.ldap_enable('HTTP', self.fqdn, self.dm_password, self.suffix) def __selinux_config(self): selinux=0 diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py index 8c22e6f41..516c7eac5 100644 --- a/ipaserver/install/krbinstance.py +++ b/ipaserver/install/krbinstance.py @@ -203,8 +203,7 @@ class KrbInstance(service.Service): self.start_creation("Configuring Kerberos KDC", 30) self.kpasswd = KpasswdInstance() - - self.kpasswd.create_instance() + self.kpasswd.create_instance('KPASSWD', self.fqdn, self.admin_password, self.suffix) def create_replica(self, ds_user, realm_name, host_name, domain_name, admin_password, @@ -233,7 +232,7 @@ class KrbInstance(service.Service): self.start_creation("Configuring Kerberos KDC", 30) self.kpasswd = KpasswdInstance() - self.kpasswd.create_instance() + self.kpasswd.create_instance('KPASSWD', self.fqdn, self.admin_password, self.suffix) def __copy_ldap_passwd(self, filename): self.fstore.backup_file("/var/kerberos/krb5kdc/ldappwd") @@ -258,7 +257,10 @@ class KrbInstance(service.Service): def __enable(self): self.backup_state("enabled", self.is_enabled()) - self.chkconfig_on() + # We do not let the system start IPA components on its own, + # Instead we reply on the IPA init script to start only enabled + # components as found in our LDAP configuration tree + self.ldap_enable('KDC', self.fqdn, self.admin_password, self.suffix) def __start_instance(self): try: diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py index 43437306e..41b5455d3 100644 --- a/ipaserver/install/service.py +++ b/ipaserver/install/service.py @@ -29,6 +29,13 @@ import base64 import time import datetime +SERVICE_LIST = { + 'KDC':('krb5kdc', 10), + 'KPASSWD':('ipa_kpasswd', 20), + 'DNS':('named', 30), + 'HTTP':('httpd', 40), + 'CA':('pki_cad', 50) +} def stop(service_name, instance_name=""): ipautil.run(["/sbin/service", service_name, "stop", instance_name]) @@ -263,8 +270,44 @@ class Service: self.steps = [] + def __get_conn(self, dm_password): + try: + conn = ipaldap.IPAdmin("127.0.0.1") + conn.simple_bind_s("cn=directory manager", dm_password) + except Exception, e: + logging.critical("Could not connect to the Directory Server on %s: %s" % (self.fqdn, str(e))) + raise e + + return conn + + def ldap_enable(self, name, fqdn, dm_password, ldap_suffix): + self.chkconfig_off() + conn = self.__get_conn(dm_password) + + entry_name = "cn=%s,cn=%s,%s,%s" % (name, fqdn, + "cn=masters,cn=ipa,cn=etc", + ldap_suffix) + order = SERVICE_LIST[name][1] + entry = ipaldap.Entry(entry_name) + entry.setValues("objectclass", + "nsContainer", "ipaConfigObject") + entry.setValues("cn", name) + entry.setValues("ipaconfigstring", + "enabledService", "startOrder " + str(order)) + + try: + conn.add_s(entry) + except ldap.ALREADY_EXISTS: + logging.critical("failed to add %s Service startup entry" % name) + raise e + class SimpleServiceInstance(Service): - def create_instance(self): + def create_instance(self, gensvc_name=None, fqdn=None, dm_password=None, ldap_suffix=None): + self.gensvc_name = gensvc_name + self.fqdn = fqdn + self.dm_password = dm_password + self.suffix = ldap_suffix + self.step("starting %s " % self.service_name, self.__start) self.step("configuring %s to start on boot" % self.service_name, self.__enable) self.start_creation("Configuring %s" % self.service_name) @@ -276,7 +319,11 @@ class SimpleServiceInstance(Service): def __enable(self): self.chkconfig_add() self.backup_state("enabled", self.is_enabled()) - self.chkconfig_on() + if self.gensvc_name == None: + self.chkconfig_on() + else: + self.ldap_enable(self.gensvc_name, self.fqdn, + self.dm_password, self.suffix) def uninstall(self): if self.is_configured(): |