make timeout decorator for facts have a configurable duration (#16551)

* Add a gather_timeout parameter
* update example ansible.cfg
* fix play level fact gathering too
pull/16407/merge
jctanner 8 years ago committed by GitHub
parent ebd3eeec8c
commit fe8258a378

@ -45,6 +45,13 @@
# A minimal set of facts is always gathered.
#gather_subset = all
# some hardware related facts are collected
# with a maximum timeout of 10 seconds. This
# option lets you increase or decrease that
# timeout to something more suitable for the
# environment.
# gather_timeout = 10
# additional paths to search for roles in, colon separated
#roles_path = /etc/ansible/roles

@ -177,6 +177,7 @@ DEFAULT_JINJA2_EXTENSIONS = get_config(p, DEFAULTS, 'jinja2_extensions', 'ANSIBL
DEFAULT_EXECUTABLE = get_config(p, DEFAULTS, 'executable', 'ANSIBLE_EXECUTABLE', '/bin/sh')
DEFAULT_GATHERING = get_config(p, DEFAULTS, 'gathering', 'ANSIBLE_GATHERING', 'implicit').lower()
DEFAULT_GATHER_SUBSET = get_config(p, DEFAULTS, 'gather_subset', 'ANSIBLE_GATHER_SUBSET', 'all').lower()
DEFAULT_GATHER_TIMEOUT = get_config(p, DEFAULTS, 'gather_timeout', 'ANSIBLE_GATHER_TIMEOUT', 10, integer=True)
DEFAULT_LOG_PATH = get_config(p, DEFAULTS, 'log_path', 'ANSIBLE_LOG_PATH', '', ispath=True)
DEFAULT_FORCE_HANDLERS = get_config(p, DEFAULTS, 'force_handlers', 'ANSIBLE_FORCE_HANDLERS', False, boolean=True)
DEFAULT_INVENTORY_IGNORE = get_config(p, DEFAULTS, 'inventory_ignore_extensions', 'ANSIBLE_INVENTORY_IGNORE', ["~", ".orig", ".bak", ".ini", ".cfg", ".retry", ".pyc", ".pyo"], islist=True)

@ -156,10 +156,14 @@ class PlayIterator:
# Default options to gather
gather_subset = C.DEFAULT_GATHER_SUBSET
gather_timeout = C.DEFAULT_GATHER_TIMEOUT
# Retrieve subset to gather
if self._play.gather_subset is not None:
gather_subset = self._play.gather_subset
# Retrieve timeout for gather
if self._play.gather_timeout is not None:
gather_timeout = self._play.gather_timeout
setup_block = Block(play=self._play)
setup_task = Task(block=setup_block)
@ -168,6 +172,8 @@ class PlayIterator:
setup_task.args = {
'gather_subset': gather_subset,
}
if gather_timeout:
setup_task.args['gather_timeout'] = gather_timeout
setup_task.set_loader(self._play._loader)
setup_block.block = [setup_task]

@ -113,15 +113,21 @@ if platform.system() != 'SunOS':
# timeout function to make sure some fact gathering
# steps do not exceed a time limit
GATHER_TIMEOUT=None
class TimeoutError(Exception):
pass
def timeout(seconds=10, error_message="Timer expired"):
def decorator(func):
def _handle_timeout(signum, frame):
raise TimeoutError(error_message)
def wrapper(*args, **kwargs):
if 'GATHER_TIMEOUT' in globals():
if GATHER_TIMEOUT:
seconds = GATHER_TIMEOUT
signal.signal(signal.SIGALRM, _handle_timeout)
signal.alarm(seconds)
try:
@ -3225,6 +3231,9 @@ def get_all_facts(module):
# Retrieve module parameters
gather_subset = module.params['gather_subset']
global GATHER_TIMEOUT
GATHER_TIMEOUT = module.params['gather_timeout']
# Retrieve all facts elements
additional_subsets = set()
exclude_subsets = set()

@ -65,6 +65,7 @@ class Play(Base, Taggable, Become):
# Connection
_gather_facts = FieldAttribute(isa='bool', default=None, always_post_validate=True)
_gather_subset = FieldAttribute(isa='barelist', default=None, always_post_validate=True)
_gather_timeout = FieldAttribute(isa='int', default=None, always_post_validate=True)
_hosts = FieldAttribute(isa='list', required=True, listof=string_types, always_post_validate=True)
_name = FieldAttribute(isa='string', default='', always_post_validate=True)

Loading…
Cancel
Save