diff options
-rw-r--r-- | ipa-client/ipaclient/ntpconf.py | 8 | ||||
-rw-r--r-- | ipaplatform/base/paths.py | 1 | ||||
-rw-r--r-- | ipapython/ipautil.py | 12 |
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 |