Skip to content

Commit be3d496

Browse files
authored
Merge pull request #1382 from moreati/issue1225-interpreter-python-fallback
ansible_mitogen: Use INTERPRETER_PYTHON_FALLBACK as python candidates
2 parents abb77e7 + 699a8eb commit be3d496

File tree

3 files changed

+34
-25
lines changed

3 files changed

+34
-25
lines changed

ansible_mitogen/mixins.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -470,18 +470,7 @@ def _low_level_execute_command(self, cmd, sudoable=True, in_data=None,
470470
# chicken-and-egg issue, mitogen needs a python to run low_level_execute_command
471471
# which is required by Ansible's discover_interpreter function
472472
if self._mitogen_discovering_interpreter:
473-
possible_pythons = [
474-
'/usr/bin/python',
475-
'python3',
476-
'python3.7',
477-
'python3.6',
478-
'python3.5',
479-
'python2.7',
480-
'python2.6',
481-
'/usr/libexec/platform-python',
482-
'/usr/bin/python3',
483-
'python'
484-
]
473+
possible_pythons = self._mitogen_interpreter_candidates
485474
else:
486475
# not used, just adding a filler value
487476
possible_pythons = ['python']
@@ -492,12 +481,15 @@ def _low_level_execute_command(self, cmd, sudoable=True, in_data=None,
492481
rc, stdout, stderr = self._connection.exec_command(
493482
cmd, in_data, sudoable, mitogen_chdir=chdir,
494483
)
495-
# TODO: what exception is thrown?
496-
except:
484+
except BaseException as exc:
497485
# we've reached the last python attempted and failed
498486
if possible_python == possible_pythons[-1]:
499487
raise
500488
else:
489+
LOG.debug(
490+
'%r._low_level_execute_command: candidate=%r ignored: %s, %r',
491+
self, possible_python, type(exc), exc,
492+
)
501493
continue
502494

503495
stdout_text = to_text(stdout, errors=encoding_errors)

ansible_mitogen/transport_config.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,21 @@
7373
from ansible.module_utils.six import with_metaclass
7474
from ansible.module_utils.parsing.convert_bool import boolean
7575

76+
import ansible_mitogen.utils
7677
import mitogen.core
7778

7879

7980
LOG = logging.getLogger(__name__)
8081

82+
if ansible_mitogen.utils.ansible_version[:2] >= (2, 19):
83+
_FALLBACK_INTERPRETER = ansible.executor.interpreter_discovery._FALLBACK_INTERPRETER
84+
elif ansible_mitogen.utils.ansible_version[:2] >= (2, 17):
85+
_FALLBACK_INTERPRETER = u'/usr/bin/python3'
86+
else:
87+
_FALLBACK_INTERPRETER = u'/usr/bin/python'
8188

82-
def run_interpreter_discovery_if_necessary(s, task_vars, action, rediscover_python):
89+
90+
def run_interpreter_discovery_if_necessary(s, candidates, task_vars, action, rediscover_python):
8391
"""
8492
Triggers ansible python interpreter discovery if requested.
8593
Caches this value the same way Ansible does it.
@@ -107,8 +115,11 @@ def run_interpreter_discovery_if_necessary(s, task_vars, action, rediscover_pyth
107115
# blow away the discovered_interpreter_config cache and rediscover
108116
del task_vars['ansible_facts'][discovered_interpreter_config]
109117

110-
if discovered_interpreter_config not in task_vars['ansible_facts']:
118+
try:
119+
s = task_vars[u'ansible_facts'][discovered_interpreter_config]
120+
except KeyError:
111121
action._mitogen_discovering_interpreter = True
122+
action._mitogen_interpreter_candidates = candidates
112123
# fake pipelining so discover_interpreter can be happy
113124
action._connection.has_pipelining = True
114125
s = ansible.executor.interpreter_discovery.discover_interpreter(
@@ -121,18 +132,17 @@ def run_interpreter_discovery_if_necessary(s, task_vars, action, rediscover_pyth
121132
# cache discovered interpreter
122133
task_vars['ansible_facts'][discovered_interpreter_config] = s
123134
action._connection.has_pipelining = False
124-
else:
125-
s = task_vars['ansible_facts'][discovered_interpreter_config]
126135

127136
# propagate discovered interpreter as fact
128137
action._discovered_interpreter_key = discovered_interpreter_config
129138
action._discovered_interpreter = s
130139

131140
action._mitogen_discovering_interpreter = False
141+
action._mitogen_interpreter_candidates = None
132142
return s
133143

134144

135-
def parse_python_path(s, task_vars, action, rediscover_python):
145+
def parse_python_path(s, candidates, task_vars, action, rediscover_python):
136146
"""
137147
Given the string set for ansible_python_interpeter, parse it using shell
138148
syntax and return an appropriate argument vector. If the value detected is
@@ -143,10 +153,9 @@ def parse_python_path(s, task_vars, action, rediscover_python):
143153
# if python_path doesn't exist, default to `auto` and attempt to discover it
144154
s = 'auto'
145155

146-
s = run_interpreter_discovery_if_necessary(s, task_vars, action, rediscover_python)
147-
# if unable to determine python_path, fallback to '/usr/bin/python'
156+
s = run_interpreter_discovery_if_necessary(s, candidates, task_vars, action, rediscover_python)
148157
if not s:
149-
s = '/usr/bin/python'
158+
s = _FALLBACK_INTERPRETER
150159

151160
return ansible.utils.shlex.shlex_split(s)
152161

@@ -510,13 +519,17 @@ def python_path(self, rediscover_python=False):
510519
interpreter_python = C.config.get_config_value(
511520
'INTERPRETER_PYTHON', variables=variables,
512521
)
522+
interpreter_python_fallback = C.config.get_config_value(
523+
'INTERPRETER_PYTHON_FALLBACK', variables=variables,
524+
)
513525

514526
if '{{' in interpreter_python or '{%' in interpreter_python:
515527
templar = self._connection.templar
516528
interpreter_python = templar.template(interpreter_python)
517529

518530
return parse_python_path(
519531
interpreter_python,
532+
candidates=interpreter_python_fallback,
520533
task_vars=self._task_vars,
521534
action=self._action,
522535
rediscover_python=rediscover_python)
@@ -732,11 +745,12 @@ def port(self):
732745

733746
def python_path(self, rediscover_python=False):
734747
s = self._host_vars.get('ansible_python_interpreter')
735-
# #511, #536: executor/module_common.py::_get_shebang() hard-wires
736-
# "/usr/bin/python" as the default interpreter path if no other
737-
# interpreter is specified.
748+
interpreter_python_fallback = self._host_vars.get(
749+
'ansible_interpreter_python_fallback', [],
750+
)
738751
return parse_python_path(
739752
s,
753+
candidates=interpreter_python_fallback,
740754
task_vars=self._task_vars,
741755
action=self._action,
742756
rediscover_python=rediscover_python)

docs/changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ To avail of fixes in an unreleased version, please download a ZIP file
2121
In progress (unreleased)
2222
------------------------
2323

24+
* :gh:issue:`1132` :mod:`ansible_mitogen` During intrepreter discovery use
25+
Ansible ``INTERPRETER_PYTHON_FALLBACK`` config as list of candidates
26+
2427

2528
v0.3.34 (2025-11-27)
2629
--------------------

0 commit comments

Comments
 (0)