ipa/freeipa-3.0.0.pre1-000-centralize-timeout-for-waiting-for-servers-to-start.patch
2012-08-06 18:17:49 +02:00

682 lines
30 KiB
Diff

From e5b6260008a3a7132fdaef99d800406eb8872316 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Thu, 24 May 2012 11:23:36 -0400
Subject: [PATCH 00/79] Centralize timeout for waiting for servers to start.
All service start/restart currently go through ipapython/platform so
move the "wait for service to start" code there as well.
A dictionary of known services and ports to wait on is defined in base.py
This is referenced by the platforms by instance name to determine what
to wait for. For the case of dirsrv if we get that as a plain name
(no specific instance) it is assumed to be the main IPA service.
https://fedorahosted.org/freeipa/ticket/2375
https://fedorahosted.org/freeipa/ticket/2610
---
install/tools/ipactl | 28 +++++++++-------
ipalib/constants.py | 2 ++
ipapython/ipautil.py | 54 +++++++++++++++++++++++++++++
ipapython/platform/base.py | 56 ++++++++++++++++++++-----------
ipapython/platform/fedora16.py | 4 +--
ipapython/platform/redhat.py | 22 ++++++++++--
ipapython/platform/systemd.py | 23 +++++++++++--
ipaserver/install/cainstance.py | 1 -
ipaserver/install/dsinstance.py | 3 +-
ipaserver/install/installutils.py | 52 ----------------------------
ipaserver/install/plugins/baseupdate.py | 8 +++++
ipaserver/install/plugins/updateclient.py | 4 +--
ipaserver/install/replication.py | 2 --
ipaserver/install/service.py | 10 +++---
ipaserver/install/upgradeinstance.py | 5 +++
ipaserver/ipaldap.py | 7 ++--
16 files changed, 176 insertions(+), 105 deletions(-)
diff --git a/install/tools/ipactl b/install/tools/ipactl
index c4d26b8df150119e0bc84abac020f8989a2a8ad2..22a4f6e03030e9874a533dd9978823dd3505658d 100755
--- a/install/tools/ipactl
+++ b/install/tools/ipactl
@@ -24,7 +24,8 @@ try:
from ipaserver.install import service, installutils
from ipapython import services as ipaservices
from ipaserver.install.dsinstance import config_dirname, realm_to_serverid
- from ipaserver.install.installutils import is_ipa_configured, wait_for_open_ports, wait_for_open_socket, ScriptError
+ from ipaserver.install.installutils import is_ipa_configured, ScriptError
+ from ipapython.ipautil import wait_for_open_ports, wait_for_open_socket
from ipapython import sysrestore
from ipapython import config
from ipalib import api, errors
@@ -105,22 +106,25 @@ def parse_options():
def emit_err(err):
sys.stderr.write(err + '\n')
-def get_config():
+def get_config(dirsrv):
base = "cn=%s,cn=masters,cn=ipa,cn=etc,%s" % (api.env.host,
api.env.basedn)
srcfilter = '(ipaConfigString=enabledService)'
attrs = ['cn', 'ipaConfigString']
+ if not dirsrv.is_running():
+ raise IpactlError("Failed to get list of services to probe status:\n" +
+ "Directory Server is stopped", 3)
try:
- # systemd services are so fast that we come here before
- # Directory Server actually starts listening. Wait for
- # the socket/port be really available.
+ # The start/restart functions already wait for the server to be
+ # started. What we are doing with this wait is really checking to see
+ # if the server is listening at all.
lurl = ldapurl.LDAPUrl(api.env.ldap_uri)
if lurl.urlscheme == 'ldapi':
- wait_for_open_socket(lurl.hostport, timeout=6)
+ wait_for_open_socket(lurl.hostport, timeout=api.env.startup_timeout)
else:
(host,port) = lurl.hostport.split(':')
- wait_for_open_ports(host, [int(port)], timeout=6)
+ wait_for_open_ports(host, [int(port)], timeout=api.env.startup_timeout)
con = ldap.initialize(api.env.ldap_uri)
con.sasl_interactive_bind_s('', SASL_EXTERNAL)
res = con.search_st(base,
@@ -175,7 +179,7 @@ def ipa_start(options):
svc_list = []
try:
- svc_list = get_config()
+ svc_list = get_config(dirsrv)
except Exception, e:
emit_err("Failed to read data from Directory Service: " + str(e))
emit_err("Shutting down")
@@ -219,14 +223,14 @@ def ipa_stop(options):
dirsrv = ipaservices.knownservices.dirsrv
svc_list = []
try:
- svc_list = get_config()
+ svc_list = get_config(dirsrv)
except Exception, e:
# ok if dirsrv died this may fail, so let's try to quickly restart it
# and see if we can get anything. If not throw our hands up and just
# exit
try:
dirsrv.start(capture_output=False)
- svc_list = get_config()
+ svc_list = get_config(dirsrv)
except Exception, e:
emit_err("Failed to read data from Directory Service: " + str(e))
emit_err("Shutting down")
@@ -266,7 +270,7 @@ def ipa_restart(options):
svc_list = []
try:
- svc_list = get_config()
+ svc_list = get_config(dirsrv)
except Exception, e:
emit_err("Failed to read data from Directory Service: " + str(e))
emit_err("Shutting down")
@@ -318,7 +322,7 @@ def ipa_status(options):
svc_list = []
try:
- svc_list = get_config()
+ svc_list = get_config(dirsrv)
except IpactlError, e:
raise e
except Exception, e:
diff --git a/ipalib/constants.py b/ipalib/constants.py
index f503472c9b493c6dc4e2ef22281899565d99044d..ad6d188692aa3de70cf29d5662d84672054ab4ef 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -111,6 +111,8 @@ DEFAULT_CONFIG = (
('xmlrpc_uri', 'http://localhost:8888/ipa/xml'),
('rpc_json_uri', 'http://localhost:8888/ipa/json'),
('ldap_uri', 'ldap://localhost:389'),
+ # Time to wait for a service to start, in seconds
+ ('startup_timeout', 120),
# Web Application mount points
('mount_ipa', '/ipa/'),
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 8884e7be92f800f02c4680fb62f5824c50eb0923..e80434cfd31ddb6112e83800aca9cf5440ffaff8 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -41,6 +41,7 @@ import re
import xmlrpclib
import datetime
import netaddr
+import time
from dns import resolver, rdatatype
from dns.exception import DNSException
@@ -1010,3 +1011,56 @@ def utf8_encode_values(values):
return map(utf8_encode_value, values)
else:
return utf8_encode_value(values)
+
+def wait_for_open_ports(host, ports, timeout=0):
+ """
+ Wait until the specified port(s) on the remote host are open. Timeout
+ in seconds may be specified to limit the wait.
+ """
+ if not isinstance(ports, (tuple, list)):
+ ports = [ports]
+
+ root_logger.debug('wait_for_open_ports: %s %s timeout %d' % (host, ports, timeout))
+ op_timeout = time.time() + timeout
+ ipv6_failover = False
+
+ for port in ports:
+ while True:
+ try:
+ if ipv6_failover:
+ s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
+ else:
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.connect((host, port))
+ s.close()
+ break
+ except socket.error, e:
+ if e.errno == 111: # 111: Connection refused
+ if timeout and time.time() > op_timeout: # timeout exceeded
+ raise e
+ time.sleep(1)
+ elif not ipv6_failover: # fallback to IPv6 connection
+ ipv6_failover = True
+ else:
+ raise e
+
+def wait_for_open_socket(socket_name, timeout=0):
+ """
+ Wait until the specified socket on the local host is open. Timeout
+ in seconds may be specified to limit the wait.
+ """
+ op_timeout = time.time() + timeout
+
+ while True:
+ try:
+ s = socket.socket(socket.AF_UNIX)
+ s.connect(socket_name)
+ s.close()
+ break
+ except socket.error, e:
+ if e.errno in (2,111): # 111: Connection refused, 2: File not found
+ if timeout and time.time() > op_timeout: # timeout exceeded
+ raise e
+ time.sleep(1)
+ else:
+ raise e
diff --git a/ipapython/platform/base.py b/ipapython/platform/base.py
index bf76b76303d221c07c93e7b41e586e06c622696f..6f9d3867ad48360727472f8c5231c030ce9d8bc2 100644
--- a/ipapython/platform/base.py
+++ b/ipapython/platform/base.py
@@ -18,29 +18,42 @@
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 remapping internally, if needed
+# 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']
+# 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],
+}
+
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.
+ 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!
+ 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.
+ 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):
@@ -53,9 +66,11 @@ class AuthConfig(object):
authconfig = PlatformAuthConfig
....
- See ipapython/platform/redhat.py for a sample implementation that uses authconfig(8) as its backend.
+ 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 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()
@@ -69,8 +84,8 @@ class AuthConfig(object):
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.
+ If you need to re-use existing AuthConfig instance for multiple runs,
+ make sure to call 'AuthConfig.reset()' between the runs.
"""
def __init__(self):
@@ -106,21 +121,21 @@ class AuthConfig(object):
class PlatformService(object):
"""
- PlatformService abstracts out external process running on the system which is possible
- to administer (start, stop, check status, etc).
+ 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):
+ 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):
+ def restart(self, instance_name="", capture_output=True, wait=True):
return
def is_running(self, instance_name=""):
@@ -149,8 +164,9 @@ class PlatformService(object):
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.
+ 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
index 985d368f966b0c42222d3af8474e99edbe3477f9..8b730e41cbdd63bbe9d0c9cb7809d0f6d4de8fbb 100644
--- a/ipapython/platform/fedora16.py
+++ b/ipapython/platform/fedora16.py
@@ -98,7 +98,7 @@ class Fedora16DirectoryService(Fedora16Service):
restore_context(dirsrv_systemd)
ipautil.run(["/bin/systemctl", "--system", "daemon-reload"],raiseonerr=False)
- def restart(self, instance_name="", capture_output=True):
+ 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)
@@ -109,7 +109,7 @@ class Fedora16DirectoryService(Fedora16Service):
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)
+ 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
diff --git a/ipapython/platform/redhat.py b/ipapython/platform/redhat.py
index 28a43e588952090007bea979a2cf72d386aa51f9..d3c23ab0debbcfa58eefa9607fe5cac8fcbf592b 100644
--- a/ipapython/platform/redhat.py
+++ b/ipapython/platform/redhat.py
@@ -26,6 +26,7 @@ import sys
import socket
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
@@ -46,14 +47,31 @@ from ipapython.platform import base
__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):
+ 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):
+ 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
diff --git a/ipapython/platform/systemd.py b/ipapython/platform/systemd.py
index ae06c0227aa59a46b2d4df024fc87577b8bbab29..a233e1045e225718353adbb9bf618a1d0b73c4ac 100644
--- a/ipapython/platform/systemd.py
+++ b/ipapython/platform/systemd.py
@@ -20,6 +20,7 @@
from ipapython import ipautil
from ipapython.platform import base
import sys, os, shutil
+from ipalib import api
class SystemdService(base.PlatformService):
SYSTEMD_ETC_PATH = "/etc/systemd/system/"
@@ -73,16 +74,34 @@ class SystemdService(base.PlatformService):
return (None,None)
return dict(map(lambda x: splitter(x, separator=separator), text.split("\n")))
+ 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:
+ elements = self.service_name.split("@")
+ if elements[0] in base.wellknownports:
+ ports = base.wellknownports[elements[0]]
+ if ports:
+ ipautil.wait_for_open_ports('localhost', ports, api.env.startup_timeout)
+
def stop(self, instance_name="", capture_output=True):
ipautil.run(["/bin/systemctl", "stop", self.service_instance(instance_name)], capture_output=capture_output)
- def start(self, instance_name="", capture_output=True):
+ def start(self, instance_name="", capture_output=True, wait=True):
ipautil.run(["/bin/systemctl", "start", self.service_instance(instance_name)], capture_output=capture_output)
+ if wait and self.is_running(instance_name):
+ self.__wait_for_open_ports(self.service_instance(instance_name))
- def restart(self, instance_name="", capture_output=True):
+ def restart(self, instance_name="", capture_output=True, wait=True):
# Restart command is broken before systemd-36-3.fc16
# If you have older systemd version, restart of dependent services will hang systemd indefinetly
ipautil.run(["/bin/systemctl", "restart", self.service_instance(instance_name)], capture_output=capture_output)
+ if wait and self.is_running(instance_name):
+ self.__wait_for_open_ports(self.service_instance(instance_name))
def is_running(self, instance_name=""):
ret = True
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index af8d39aa524ee801fb1ff5b2b83bee65b1eacb70..62c1dc4d082df740f675d8447a7dd13d69f2ec88 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -681,7 +681,6 @@ class CAInstance(service.Service):
def __restart_instance(self):
try:
self.restart(PKI_INSTANCE_NAME)
- installutils.wait_for_open_ports('localhost', 9180, 300)
except Exception:
# TODO: roll back here?
root_logger.critical("Failed to restart the certificate server. See the installation log for details.")
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index d74ee8987a3387b78ec7203c9b8c70059b35a812..9c137af030e2d86fa3df3e0e987e57d75d53c5d4 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -416,7 +416,6 @@ class DsInstance(service.Service):
if not is_ds_running(instance):
root_logger.critical("Failed to restart the directory server. See the installation log for details.")
sys.exit(1)
- installutils.wait_for_open_ports('localhost', self.open_ports, 300)
except SystemExit, e:
raise e
except Exception, e:
@@ -667,7 +666,7 @@ class DsInstance(service.Service):
# (re)start them.
for ds_instance in get_ds_instances():
try:
- ipaservices.knownservices.dirsrv.restart(ds_instance)
+ ipaservices.knownservices.dirsrv.restart(ds_instance, wait=False)
except Exception, e:
root_logger.error('Unable to restart ds instance %s: %s', ds_instance, e)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 313761777cddcbf5ad9dd134556d72931e51a2b3..b65958eda1b2b6da4db942d77bca63eee1c616f6 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -414,58 +414,6 @@ def create_keytab(path, principal):
kadmin("ktadd -k " + path + " " + principal)
-def wait_for_open_ports(host, ports, timeout=0):
- """
- Wait until the specified port(s) on the remote host are open. Timeout
- in seconds may be specified to limit the wait.
- """
- if not isinstance(ports, (tuple, list)):
- ports = [ports]
-
- op_timeout = time.time() + timeout
- ipv6_failover = False
-
- for port in ports:
- while True:
- try:
- if ipv6_failover:
- s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
- else:
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((host, port))
- s.close()
- break;
- except socket.error, e:
- if e.errno == 111: # 111: Connection refused
- if timeout and time.time() > op_timeout: # timeout exceeded
- raise e
- time.sleep(1)
- elif not ipv6_failover: # fallback to IPv6 connection
- ipv6_failover = True
- else:
- raise e
-
-def wait_for_open_socket(socket_name, timeout=0):
- """
- Wait until the specified socket on the local host is open. Timeout
- in seconds may be specified to limit the wait.
- """
- op_timeout = time.time() + timeout
-
- while True:
- try:
- s = socket.socket(socket.AF_UNIX)
- s.connect(socket_name)
- s.close()
- break;
- except socket.error, e:
- if e.errno in (2,111): # 111: Connection refused, 2: File not found
- if timeout and time.time() > op_timeout: # timeout exceeded
- raise e
- time.sleep(1)
- else:
- raise e
-
def resolve_host(host_name):
try:
addrinfos = socket.getaddrinfo(host_name, None,
diff --git a/ipaserver/install/plugins/baseupdate.py b/ipaserver/install/plugins/baseupdate.py
index 227dc917aa14ddea898015ef8c16d084860c94df..f91cf5dece314f28bcfb5f4fa8de8716400136ae 100644
--- a/ipaserver/install/plugins/baseupdate.py
+++ b/ipaserver/install/plugins/baseupdate.py
@@ -34,6 +34,14 @@ class DSRestart(service.Service):
"""
service.Service.__init__(self, "dirsrv")
+ def start(self, instance_name="", capture_output=True, wait=True):
+ """
+ During upgrades the server is listening only on the socket so
+ we don't want to wait on ports. The caller is responsible for
+ waiting for the socket to be ready.
+ """
+ super(DSRestart, self).start(wait=False)
+
def create_instance(self):
self.step("stopping directory server", self.stop)
self.step("starting directory server", self.start)
diff --git a/ipaserver/install/plugins/updateclient.py b/ipaserver/install/plugins/updateclient.py
index 10d899abcad091a3396d4315d877b5656068775e..e237694711ea5f22d29c0b5ac52f161231951c2d 100644
--- a/ipaserver/install/plugins/updateclient.py
+++ b/ipaserver/install/plugins/updateclient.py
@@ -18,11 +18,11 @@
#
import os
-from ipaserver.install import installutils
from ipaserver.install.plugins import FIRST, MIDDLE, LAST
from ipaserver.install.plugins import POST_UPDATE
from ipaserver.install.plugins.baseupdate import DSRestart
from ipaserver.install.ldapupdate import LDAPUpdate
+from ipapython.ipautil import wait_for_open_socket
from ipalib import api
from ipalib import backend
import ldap as _ldap
@@ -161,7 +161,7 @@ class updateclient(backend.Executioner):
if live_run:
self.destroy_context()
dsrestart.create_instance()
- installutils.wait_for_open_socket(socket_name)
+ wait_for_open_socket(socket_name)
self.create_context(dm_password)
else:
self.log.warn("Test mode, skipping restart")
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index 03758dfcbe302e1d437293f544677fca93e3b21f..417b7a0c5ee29615d2479842efc6862e39a7c3df 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -25,7 +25,6 @@ import sys
import ldap
from ipaserver import ipaldap
from ipapython import services as ipaservices
-import installutils
from ldap import modlist
from ipalib import api, util, errors
from ipapython import ipautil
@@ -92,7 +91,6 @@ def enable_replication_version_checking(hostname, realm, dirman_passwd):
conn.unbind()
serverid = "-".join(realm.split("."))
ipaservices.knownservices.dirsrv.restart(instance_name=serverid)
- installutils.wait_for_open_ports('localhost', [389, 636], 300)
else:
conn.unbind()
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
index 5cc7ae639db3fe2aa3805a90e0902f10f277064c..5c2699e3fa4c115c972528d4c2cc6aa170711837 100644
--- a/ipaserver/install/service.py
+++ b/ipaserver/install/service.py
@@ -35,6 +35,8 @@ from ipapython.ipa_log_manager import *
CACERT = "/etc/ipa/ca.crt"
+# The service name as stored in cn=masters,cn=ipa,cn=etc. In the tuple
+# the first value is the *nix service name, the second the start order.
SERVICE_LIST = {
'KDC':('krb5kdc', 10),
'KPASSWD':('kadmin', 20),
@@ -198,11 +200,11 @@ class Service(object):
def stop(self, instance_name="", capture_output=True):
self.service.stop(instance_name, capture_output=capture_output)
- def start(self, instance_name="", capture_output=True):
- self.service.start(instance_name, capture_output=capture_output)
+ def start(self, instance_name="", capture_output=True, wait=True):
+ self.service.start(instance_name, capture_output=capture_output, wait=wait)
- def restart(self, instance_name="", capture_output=True):
- self.service.restart(instance_name, capture_output=capture_output)
+ def restart(self, instance_name="", capture_output=True, wait=True):
+ self.service.restart(instance_name, capture_output=capture_output, wait=wait)
def is_running(self):
return self.service.is_running()
diff --git a/ipaserver/install/upgradeinstance.py b/ipaserver/install/upgradeinstance.py
index b04d92afcb31d66c3f4c98e80b1bc54d4887e518..f1f702b1c51eed0277fd4f02f5c1d4048292d894 100644
--- a/ipaserver/install/upgradeinstance.py
+++ b/ipaserver/install/upgradeinstance.py
@@ -60,6 +60,11 @@ class IPAUpgrade(service.Service):
self.badsyntax = False
self.upgradefailed = False
+ def start(self, instance_name="", capture_output=True, wait=True):
+ # Don't wait here because we've turned off port 389. The connection
+ # we make will wait for the socket.
+ super(IPAUpgrade, self).start(instance_name, capture_output, wait=False)
+
def create_instance(self):
self.step("stopping directory server", self.stop)
self.step("saving configuration", self.__save_config)
diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index 8b5451c730f0a4cc72a597f934a940dc2b143a05..e4fa2c644c660e34a1d675497a22837255a36b75 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -36,10 +36,9 @@ from ldap.controls import LDAPControl
from ldap.ldapobject import SimpleLDAPObject
from ipapython import ipautil
from ipalib import errors
-from ipapython.ipautil import format_netloc
+from ipapython.ipautil import format_netloc, wait_for_open_socket, wait_for_open_ports
from ipapython.entity import Entity
from ipaserver.plugins.ldap2 import IPASimpleLDAPObject
-from ipaserver.install import installutils
# Global variable to define SASL auth
SASL_AUTH = ldap.sasl.sasl({},'GSSAPI')
@@ -337,10 +336,10 @@ class IPAdmin(IPAEntryLDAPObject):
def __wait_for_connection(self, timeout):
lurl = ldapurl.LDAPUrl(self._uri)
if lurl.urlscheme == 'ldapi':
- installutils.wait_for_open_socket(lurl.hostport, timeout)
+ wait_for_open_socket(lurl.hostport, timeout)
else:
(host,port) = lurl.hostport.split(':')
- installutils.wait_for_open_ports(host, int(port), timeout)
+ wait_for_open_ports(host, int(port), timeout)
def __bind_with_wait(self, bind_func, timeout, *args, **kwargs):
try:
--
1.7.11.2