summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipa-client/ipaclient/ntpconf.py8
-rw-r--r--ipaplatform/base/paths.py1
-rw-r--r--ipapython/ipautil.py12
3 files changed, 19 insertions, 2 deletions
diff --git a/ipa-client/ipaclient/ntpconf.py b/ipa-client/ipaclient/ntpconf.py
index e1ac55a1d..7d5c82a89 100644
--- a/ipa-client/ipaclient/ntpconf.py
+++ b/ipa-client/ipaclient/ntpconf.py
@@ -18,6 +18,7 @@
#
from ipapython import ipautil
+from ipapython.ipa_log_manager import root_logger
import shutil
import os
from ipaplatform.tasks import tasks
@@ -149,7 +150,12 @@ def synconce_ntp(server_fqdn):
tmp_ntp_conf = ipautil.write_tmp_file('server %s' % server_fqdn)
try:
- ipautil.run([ntpd, '-qgc', tmp_ntp_conf.name])
+ # The ntpd command will never exit if it is unable to reach the
+ # server, so timeout after 15 seconds.
+ timeout = 15
+ root_logger.info('Attempting to sync time using ntpd. '
+ 'Will timeout after %d seconds' % timeout)
+ ipautil.run([ntpd, '-qgc', tmp_ntp_conf.name], timeout=timeout)
return True
except ipautil.CalledProcessError:
return False
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index 7922e3bbc..11c7e9212 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -186,6 +186,7 @@ class BasePathNamespace(object):
SSLGET = "/usr/bin/sslget"
SSS_SSH_AUTHORIZEDKEYS = "/usr/bin/sss_ssh_authorizedkeys"
SSS_SSH_KNOWNHOSTSPROXY = "/usr/bin/sss_ssh_knownhostsproxy"
+ BIN_TIMEOUT = "/usr/bin/timeout"
UPDATE_CA_TRUST = "/usr/bin/update-ca-trust"
BIN_WGET = "/usr/bin/wget"
ZIP = "/usr/bin/zip"
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 4116d974e..6a06a8e95 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -249,7 +249,7 @@ def shell_quote(string):
def run(args, stdin=None, raiseonerr=True,
nolog=(), env=None, capture_output=True, skip_output=False, cwd=None,
- runas=None):
+ runas=None, timeout=None):
"""
Execute a command and return stdin, stdout and the process return code.
@@ -277,6 +277,8 @@ def run(args, stdin=None, raiseonerr=True,
:param cwd: Current working directory
:param runas: Name of a user that the command shold be run as. The spawned
process will have both real and effective UID and GID set.
+ :param timeout: Timeout if the command hasn't returned within the specified
+ number of seconds.
"""
p_in = None
p_out = None
@@ -302,6 +304,11 @@ def run(args, stdin=None, raiseonerr=True,
p_out = subprocess.PIPE
p_err = subprocess.PIPE
+ if timeout:
+ # If a timeout was provided, use the timeout command
+ # to execute the requested command.
+ args[0:0] = [paths.BIN_TIMEOUT, str(timeout)]
+
arg_string = nolog_replace(' '.join(shell_quote(a) for a in args), nolog)
root_logger.debug('Starting external process')
root_logger.debug('args=%s' % arg_string)
@@ -332,6 +339,9 @@ def run(args, stdin=None, raiseonerr=True,
if skip_output:
p_out.close() # pylint: disable=E1103
+ if timeout and p.returncode == 124:
+ root_logger.debug('Process did not complete before timeout')
+
root_logger.debug('Process finished, return code=%s', p.returncode)
# The command and its output may include passwords that we don't want