working on ansible discovery; need to fix passing ActionModuleMixin reference still

pull/658/head
Steven Robertson 5 years ago
parent e728cee7cb
commit 806651e112

@ -559,12 +559,20 @@ class Connection(ansible.plugins.connection.ConnectionBase):
f_locals = f.f_locals f_locals = f.f_locals
f_self = f_locals.get('self') f_self = f_locals.get('self')
if isinstance(f_self, ansible_mitogen.mixins.ActionModuleMixin): if isinstance(f_self, ansible_mitogen.mixins.ActionModuleMixin):
# backref for python interpreter discovery, should be safe because _get_task_vars
# is always called before running interpreter discovery
self._action = f_self
task_vars = f_locals.get('task_vars') task_vars = f_locals.get('task_vars')
if task_vars: if task_vars:
LOG.debug('recovered task_vars from Action') LOG.debug('recovered task_vars from Action')
return task_vars return task_vars
elif f.f_code.co_name == '_execute_meta': elif f.f_code.co_name == '_execute_meta':
f_all_vars = f.f_locals.get('all_vars') f_all_vars = f.f_locals.get('all_vars')
f_self = f_locals.get('self')
if isinstance(f_self, ansible_mitogen.mixins.ActionModuleMixin):
# backref for python interpreter discovery, should be safe because _get_task_vars
# is always called before running interpreter discovery
self._action = f_self
if isinstance(f_all_vars, dict): if isinstance(f_all_vars, dict):
LOG.debug('recovered task_vars from meta:') LOG.debug('recovered task_vars from meta:')
return f_all_vars return f_all_vars
@ -671,6 +679,8 @@ class Connection(ansible.plugins.connection.ConnectionBase):
inventory_name=inventory_name, inventory_name=inventory_name,
play_context=self._play_context, play_context=self._play_context,
host_vars=dict(via_vars), # TODO: make it lazy host_vars=dict(via_vars), # TODO: make it lazy
task_vars=self._get_task_vars(), # needed for interpreter discovery in parse_python_path
action=self._action,
become_method=become_method or None, become_method=become_method or None,
become_user=become_user or None, become_user=become_user or None,
) )
@ -743,6 +753,7 @@ class Connection(ansible.plugins.connection.ConnectionBase):
play_context=self._play_context, play_context=self._play_context,
transport=self.transport, transport=self.transport,
inventory_name=self.get_task_var('inventory_hostname'), inventory_name=self.get_task_var('inventory_hostname'),
action=self._action
) )
stack = self._stack_from_spec(spec) stack = self._stack_from_spec(spec)
return spec.inventory_name(), stack return spec.inventory_name(), stack

@ -353,6 +353,7 @@ class StrategyMixin(object):
are configured for the duration of the call. are configured for the duration of the call.
""" """
_assert_supported_release() _assert_supported_release()
wrappers = AnsibleWrappers() wrappers = AnsibleWrappers()
self._worker_model = self._get_worker_model() self._worker_model = self._get_worker_model()
ansible_mitogen.process.set_worker_model(self._worker_model) ansible_mitogen.process.set_worker_model(self._worker_model)

@ -65,18 +65,47 @@ import os
import ansible.utils.shlex import ansible.utils.shlex
import ansible.constants as C import ansible.constants as C
from ansible.executor.interpreter_discovery import discover_interpreter
from ansible.module_utils.six import with_metaclass from ansible.module_utils.six import with_metaclass
from ansible.utils.unsafe_proxy import AnsibleUnsafeText
import mitogen.core import mitogen.core
def parse_python_path(s): def run_interpreter_discovery_if_necessary(s, task_vars, action):
"""
Triggers ansible python interpreter discovery if requested.
Caches this value the same way Ansible does it.
"""
if s in ['auto', 'auto_legacy', 'auto_silent', 'auto_legacy_silent']:
# python is the only supported interpreter_name as of Ansible 2.8.6
interpreter_name = 'python'
discovered_interpreter_config = u'discovered_interpreter_%s' % interpreter_name
facts_from_task_vars = task_vars.get('ansible_facts', {})
if discovered_interpreter_config not in facts_from_task_vars:
s = AnsibleUnsafeText(discover_interpreter(
action=action,
interpreter_name=interpreter_name,
discovery_mode=s,
task_vars=task_vars))
# cache discovered interpreter
facts_from_task_vars['ansible_facts'][interpreter_name] = s
else:
s = facts_from_task_vars[discovered_interpreter_config]
return s
def parse_python_path(s, task_vars, action):
""" """
Given the string set for ansible_python_interpeter, parse it using shell Given the string set for ansible_python_interpeter, parse it using shell
syntax and return an appropriate argument vector. syntax and return an appropriate argument vector. If the value detected is
one of interpreter discovery then run that first. Caches python interpreter
discovery value in `facts_from_task_vars` like how Ansible handles this.
""" """
if s: if s:
s = run_interpreter_discovery_if_necessary(s, task_vars, action)
return ansible.utils.shlex.shlex_split(s) return ansible.utils.shlex.shlex_split(s)
@ -325,11 +354,14 @@ class PlayContextSpec(Spec):
PlayContext. It is used for normal connections and delegate_to connections, PlayContext. It is used for normal connections and delegate_to connections,
and should always be accurate. and should always be accurate.
""" """
def __init__(self, connection, play_context, transport, inventory_name): def __init__(self, connection, play_context, transport, inventory_name, action):
self._connection = connection self._connection = connection
self._play_context = play_context self._play_context = play_context
self._transport = transport self._transport = transport
self._inventory_name = inventory_name self._inventory_name = inventory_name
self._task_vars = self._connection._get_task_vars()
# used to run interpreter discovery
self._action = action
def transport(self): def transport(self):
return self._transport return self._transport
@ -366,7 +398,10 @@ class PlayContextSpec(Spec):
# #511, #536: executor/module_common.py::_get_shebang() hard-wires # #511, #536: executor/module_common.py::_get_shebang() hard-wires
# "/usr/bin/python" as the default interpreter path if no other # "/usr/bin/python" as the default interpreter path if no other
# interpreter is specified. # interpreter is specified.
return parse_python_path(s or '/usr/bin/python') return parse_python_path(
s or '/usr/bin/python',
task_vars=self._task_vars,
action=self._action)
def private_key_file(self): def private_key_file(self):
return self._play_context.private_key_file return self._play_context.private_key_file
@ -490,14 +525,16 @@ class MitogenViaSpec(Spec):
having a configruation problem with connection delegation, the answer to having a configruation problem with connection delegation, the answer to
your problem lies in the method implementations below! your problem lies in the method implementations below!
""" """
def __init__(self, inventory_name, host_vars, become_method, become_user, def __init__(self, inventory_name, host_vars, task_vars, become_method, become_user,
play_context): play_context, action):
""" """
:param str inventory_name: :param str inventory_name:
The inventory name of the intermediary machine, i.e. not the target The inventory name of the intermediary machine, i.e. not the target
machine. machine.
:param dict host_vars: :param dict host_vars:
The HostVars magic dictionary provided by Ansible in task_vars. The HostVars magic dictionary provided by Ansible in task_vars.
:param dict host_vars:
The HostVars magic dictionary provided by Ansible in task_vars.
:param str become_method: :param str become_method:
If the mitogen_via= spec included a become method, the method it If the mitogen_via= spec included a become method, the method it
specifies. specifies.
@ -509,14 +546,18 @@ class MitogenViaSpec(Spec):
the real target machine. Values from this object are **strictly the real target machine. Values from this object are **strictly
restricted** to values that are Ansible-global, e.g. the passwords restricted** to values that are Ansible-global, e.g. the passwords
specified interactively. specified interactively.
:param ActionModuleMixin action:
Backref to the ActionModuleMixin required for ansible interpreter discovery
""" """
self._inventory_name = inventory_name self._inventory_name = inventory_name
self._host_vars = host_vars self._host_vars = host_vars
self._task_vars = task_vars
self._become_method = become_method self._become_method = become_method
self._become_user = become_user self._become_user = become_user
# Dangerous! You may find a variable you want in this object, but it's # Dangerous! You may find a variable you want in this object, but it's
# almost certainly for the wrong machine! # almost certainly for the wrong machine!
self._dangerous_play_context = play_context self._dangerous_play_context = play_context
self._action = action
def transport(self): def transport(self):
return ( return (
@ -579,7 +620,10 @@ class MitogenViaSpec(Spec):
# #511, #536: executor/module_common.py::_get_shebang() hard-wires # #511, #536: executor/module_common.py::_get_shebang() hard-wires
# "/usr/bin/python" as the default interpreter path if no other # "/usr/bin/python" as the default interpreter path if no other
# interpreter is specified. # interpreter is specified.
return parse_python_path(s or '/usr/bin/python') return parse_python_path(
s or '/usr/bin/python',
task_vars=self._task_vars,
action=self._action)
def private_key_file(self): def private_key_file(self):
# TODO: must come from PlayContext too. # TODO: must come from PlayContext too.

Loading…
Cancel
Save