Facts Timeout was not settable via ansible.cfg

The timeout for gathering facts needs to be settable from three places
(highest precedence to lowest):

* programmatically
* ansible.cfg (equivalent to the user specifying it explicitly when
  calling setup)
* from the default value

The code was changed in b4bd6c80de to
allow programmatically and the default value to work correctly but
setting via ansible.cfg/parameter was broken.

This change should fix setting via ansible.cfg and adds unittests for
all three cases

Fixes #23753
This commit is contained in:
Toshio Kuratomi 2017-04-20 10:51:36 -07:00
commit d088030fa6
3 changed files with 120 additions and 6 deletions

View file

@ -77,22 +77,24 @@ if platform.system() != 'SunOS':
# steps do not exceed a time limit
GATHER_TIMEOUT=None
DEFAULT_GATHER_TIMEOUT = 10
class TimeoutError(Exception):
pass
def timeout(seconds=None, error_message="Timer expired"):
if seconds is None:
seconds = globals().get('GATHER_TIMEOUT') or 10
def decorator(func):
def _handle_timeout(signum, frame):
raise TimeoutError(error_message)
def wrapper(*args, **kwargs):
local_seconds = seconds # Make local var as we modify this every time it's invoked
if local_seconds is None:
local_seconds = globals().get('GATHER_TIMEOUT') or DEFAULT_GATHER_TIMEOUT
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(seconds)
signal.alarm(local_seconds)
try:
result = func(*args, **kwargs)
finally:
@ -103,11 +105,11 @@ def timeout(seconds=None, error_message="Timer expired"):
# If we were called as @timeout, then the first parameter will be the
# function we are to wrap instead of the number of seconds. Detect this
# and correct it by setting seconds to our default value and return the
# and correct it by setting seconds to our sentinel value and return the
# inner decorator function manually wrapped around the function
if callable(seconds):
func = seconds
seconds = 10
seconds = None
return decorator(func)
# If we were called as @timeout([...]) then python itself will take