Skip to content

Commit 7edb4fa

Browse files
committed
WIP
1 parent 67c7bd0 commit 7edb4fa

File tree

3 files changed

+24
-16
lines changed

3 files changed

+24
-16
lines changed

ansible_mitogen/mixins.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -460,23 +460,27 @@ def _low_level_execute_command(self, cmd, sudoable=True, in_data=None,
460460
# chicken-and-egg issue, mitogen needs a python to run low_level_execute_command
461461
# which is required by Ansible's discover_interpreter function
462462
if self._mitogen_discovering_interpreter:
463-
possible_pythons = [
464-
'python3',
465-
'python2',
466-
'python'
467-
]
463+
if self._connection.transport in {'ssh'}:
464+
possible_pythons = [
465+
'$(for p in python3 python2 python; do command -v "$p" 2>/dev/null && break; done;)',
466+
]
467+
else:
468+
possible_pythons = ['python3' 'python2', 'python']
468469
else:
469470
# not used, just adding a filler value
470471
possible_pythons = ['python']
471472

472473
for possible_python in possible_pythons:
473474
try:
475+
LOG.debug('_low_level_execute_command(): trying possible_python=%r', possible_python)
474476
self._mitogen_interpreter_candidate = possible_python
475477
rc, stdout, stderr = self._connection.exec_command(
476478
cmd, in_data, sudoable, mitogen_chdir=chdir,
477479
)
480+
LOG.debug('_low_level_execute_command(): got rc=%d, stdout=%r, stderr=%r', rc, stdout, stderr)
478481
# TODO: what exception is thrown?
479-
except:
482+
except BaseException as exc:
483+
LOG.debug('%r._low_level_execute_command for possible_python=%r: %s, %r', self, possible_python, type(exc), exc)
480484
# we've reached the last python attempted and failed
481485
if possible_python == possible_pythons[-1]:
482486
raise

mitogen/parent.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,7 @@ def get_python_argv(self):
14541454
return self.options.python_path
14551455
return [self.options.python_path]
14561456

1457-
def get_boot_command(self):
1457+
def _first_stage_base64(self):
14581458
source = inspect.getsource(self._first_stage)
14591459
source = textwrap.dedent('\n'.join(source.strip().split('\n')[2:]))
14601460
source = source.replace(' ', ' ')
@@ -1464,17 +1464,23 @@ def get_boot_command(self):
14641464
str(len(preamble_compressed)))
14651465
compressed = zlib.compress(source.encode(), 9)
14661466
encoded = binascii.b2a_base64(compressed).replace(b('\n'), b(''))
1467+
return encoded.decode('ascii')
14671468

1469+
def _bootstrap_argv(self):
14681470
# Just enough to decode, decompress, and exec the first stage.
14691471
# Priorities: wider compatibility, faster startup, shorter length.
14701472
# `import os` here, instead of stage 1, to save a few bytes.
14711473
# `sys.path=...` for https://github.com/python/cpython/issues/115911.
1472-
return self.get_python_argv() + [
1474+
return [
14731475
'-c',
14741476
'import sys;sys.path=[p for p in sys.path if p];import binascii,os,zlib;'
1475-
'exec(zlib.decompress(binascii.a2b_base64("%s")))' % (encoded.decode(),),
1477+
'exec(zlib.decompress(binascii.a2b_base64(sys.argv[1])))',
1478+
self._first_stage_base64(),
14761479
]
14771480

1481+
def get_boot_command(self):
1482+
return self.get_python_argv() + self._bootstrap_argv()
1483+
14781484
def get_econtext_config(self):
14791485
assert self.options.max_message_size is not None
14801486
parent_ids = mitogen.parent_ids[:]
@@ -1510,7 +1516,7 @@ def _get_name(self):
15101516

15111517
def start_child(self):
15121518
args = self.get_boot_command()
1513-
LOG.debug('command line for %r: %s', self, Argv(args))
1519+
LOG.debug('command line for %r: %s', self, args)
15141520
try:
15151521
return self.create_child(args=args, **self.create_child_args)
15161522
except OSError:

mitogen/ssh.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,8 @@ def get_boot_command(self):
296296
if self.options.ssh_args:
297297
bits += self.options.ssh_args
298298
bits.append(self.options.hostname)
299-
base = super(Connection, self).get_boot_command()
300299

301-
base_parts = []
302-
for s in base:
303-
val = s if s in self.SHLEX_IGNORE else shlex_quote(s).strip()
304-
base_parts.append(val)
305-
return bits + base_parts
300+
# https://datatracker.ietf.org/doc/html/rfc4254#section-6.5
301+
python_argv = self.get_python_argv()
302+
bootstrap_argv = self._bootstrap_argv()
303+
return bits + python_argv + [shlex_quote(s) for s in bootstrap_argv]

0 commit comments

Comments
 (0)