able to pass tests running interpreter detection in rhel8 container

pull/658/head
Steven Robertson 5 years ago
parent 7d6d76e444
commit 89d87445c8

@ -122,6 +122,7 @@ class ActionModuleMixin(ansible.plugins.action.ActionBase):
# required for python interpreter discovery # required for python interpreter discovery
connection.templar = self._templar connection.templar = self._templar
self._finding_python_interpreter = False self._finding_python_interpreter = False
self._rediscovered_python = False
# redeclaring interpreter discovery vars here in case running ansible < 2.8.0 # redeclaring interpreter discovery vars here in case running ansible < 2.8.0
self._discovered_interpreter_key = None self._discovered_interpreter_key = None
self._discovered_interpreter = False self._discovered_interpreter = False
@ -402,7 +403,11 @@ class ActionModuleMixin(ansible.plugins.action.ActionBase):
if result.get('ansible_facts') is None: if result.get('ansible_facts') is None:
result['ansible_facts'] = {} result['ansible_facts'] = {}
result['ansible_facts'][self._discovered_interpreter_key] = self._discovered_interpreter # only cache discovered_interpreter if we're not running a rediscovery
# rediscovery happens in places like docker connections that could have different
# python interpreters than the main host
if not self._rediscovered_python:
result['ansible_facts'][self._discovered_interpreter_key] = self._discovered_interpreter
if self._discovery_warnings: if self._discovery_warnings:
if result.get('warnings') is None: if result.get('warnings') is None:
@ -457,12 +462,47 @@ class ActionModuleMixin(ansible.plugins.action.ActionBase):
if executable: if executable:
cmd = executable + ' -c ' + shlex_quote(cmd) cmd = executable + ' -c ' + shlex_quote(cmd)
rc, stdout, stderr = self._connection.exec_command( # TODO: HACK: if finding python interpreter then we need to keep
cmd=cmd, # calling exec_command until we run into the right python we'll use
in_data=in_data, # chicken-and-egg issue, mitogen needs a python to run low_level_execute_command
sudoable=sudoable, # which is required by Ansible's discover_interpreter function
mitogen_chdir=chdir, if self._finding_python_interpreter:
) possible_pythons = [
'/usr/bin/python',
'python3.7',
'python3.6',
'python3.5',
'python2.7',
'python2.6',
'usr/libexec/platform-python',
'usr/bin/python3',
'python'
]
else:
# not used, just adding a filler value
possible_pythons = ['python']
def _run_cmd():
return self._connection.exec_command(
cmd=cmd,
in_data=in_data,
sudoable=sudoable,
mitogen_chdir=chdir,
)
for possible_python in possible_pythons:
try:
self._possible_python_interpreter = possible_python
rc, stdout, stderr = _run_cmd()
# TODO: what exception is thrown?
except:
# we've reached the last python attempted and failed
# TODO: could use enumerate(), need to check which version of python first had it though
if possible_python == 'python':
raise
else:
continue
stdout_text = to_text(stdout, errors=encoding_errors) stdout_text = to_text(stdout, errors=encoding_errors)
return { return {

@ -88,7 +88,10 @@ def run_interpreter_discovery_if_necessary(s, task_vars, action, rediscover_pyth
For connections like `docker`, we want to rediscover the python interpreter because For connections like `docker`, we want to rediscover the python interpreter because
it could be different than what's ran on the host it could be different than what's ran on the host
""" """
# TODO: avoid infinite recursion via _finding_python_interpreter + low_level_execute_command called from discover_interpreter # keep trying different interpreters until we don't error
if action._finding_python_interpreter:
return action._possible_python_interpreter
if s in ['auto', 'auto_legacy', 'auto_silent', 'auto_legacy_silent']: if s in ['auto', 'auto_legacy', 'auto_silent', 'auto_legacy_silent']:
# python is the only supported interpreter_name as of Ansible 2.8.8 # python is the only supported interpreter_name as of Ansible 2.8.8
interpreter_name = 'python' interpreter_name = 'python'
@ -98,6 +101,11 @@ def run_interpreter_discovery_if_necessary(s, task_vars, action, rediscover_pyth
task_vars['ansible_facts'] = {} task_vars['ansible_facts'] = {}
if rediscover_python and task_vars.get('ansible_facts', {}).get(discovered_interpreter_config): if rediscover_python and task_vars.get('ansible_facts', {}).get(discovered_interpreter_config):
# if we're rediscovering python then chances are we're running something like a docker connection
# this will handle scenarios like running a playbook that does stuff + then dynamically creates a docker container,
# then runs the rest of the playbook inside that container, and then rerunning the playbook again
action._rediscovered_python = True
# blow away the discovered_interpreter_config cache and rediscover # blow away the discovered_interpreter_config cache and rediscover
del task_vars['ansible_facts'][discovered_interpreter_config] del task_vars['ansible_facts'][discovered_interpreter_config]
@ -110,6 +118,7 @@ def run_interpreter_discovery_if_necessary(s, task_vars, action, rediscover_pyth
interpreter_name=interpreter_name, interpreter_name=interpreter_name,
discovery_mode=s, discovery_mode=s,
task_vars=task_vars)) task_vars=task_vars))
# cache discovered interpreter # cache discovered interpreter
task_vars['ansible_facts'][discovered_interpreter_config] = s task_vars['ansible_facts'][discovered_interpreter_config] = s
action._connection.has_pipelining = False action._connection.has_pipelining = False

Loading…
Cancel
Save