issue #633: various task_vars fixes

- take host_vars from task_vars too
- make missing task_vars a hard error
- update tests to provide stub task_vars
pull/653/head
David Wilson 5 years ago
parent fc09b81949
commit efd82dd35a

@ -56,6 +56,12 @@ import ansible_mitogen.transport_config
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
task_vars_msg = (
'could not recover task_vars. This means some connection '
'settings may erroneously be reset to their defaults. '
'Please report a bug if you encounter this message.'
)
def get_remote_name(spec): def get_remote_name(spec):
""" """
@ -489,9 +495,6 @@ class Connection(ansible.plugins.connection.ConnectionBase):
#: Set to task_vars by on_action_run(). #: Set to task_vars by on_action_run().
_task_vars = None _task_vars = None
#: Set to 'hostvars' by on_action_run()
host_vars = None
#: Set by on_action_run() #: Set by on_action_run()
delegate_to_hostname = None delegate_to_hostname = None
@ -525,7 +528,6 @@ class Connection(ansible.plugins.connection.ConnectionBase):
Loader base directory; see :attr:`loader_basedir`. Loader base directory; see :attr:`loader_basedir`.
""" """
self._task_vars = task_vars self._task_vars = task_vars
self.host_vars = task_vars['hostvars']
self.delegate_to_hostname = delegate_to_hostname self.delegate_to_hostname = delegate_to_hostname
self.loader_basedir = loader_basedir self.loader_basedir = loader_basedir
self._put_connection() self._put_connection()
@ -548,8 +550,10 @@ class Connection(ansible.plugins.connection.ConnectionBase):
for new connections to be constructed in addition to the preconstructed for new connections to be constructed in addition to the preconstructed
connection passed into any running action. connection passed into any running action.
""" """
f = sys._getframe() if self._task_vars is not None:
return self._task_vars
f = sys._getframe()
while f: while f:
if f.f_code.co_name == 'run': if f.f_code.co_name == 'run':
f_locals = f.f_locals f_locals = f.f_locals
@ -567,9 +571,23 @@ class Connection(ansible.plugins.connection.ConnectionBase):
f = f.f_back f = f.f_back
LOG.warning('could not recover task_vars. This means some connection ' raise ansible.errors.AnsibleConnectionFailure(task_vars_msg)
'settings may erroneously be reset to their defaults. '
'Please report a bug if you encounter this message.') def get_host_vars(self, inventory_hostname):
"""
Fetch the HostVars for a host.
:returns:
Variables dictionary or :data:`None`.
:raises ansible.errors.AnsibleConnectionFailure:
Task vars unavailable.
"""
task_vars = self._get_task_vars()
hostvars = task_vars.get('hostvars')
if hostvars:
return hostvars.get(inventory_hostname)
raise ansible.errors.AnsibleConnectionFailure(task_vars_msg)
def get_task_var(self, key, default=None): def get_task_var(self, key, default=None):
""" """
@ -582,17 +600,16 @@ class Connection(ansible.plugins.connection.ConnectionBase):
does not make sense to extract connection-related configuration for the does not make sense to extract connection-related configuration for the
delegated-to machine from them. delegated-to machine from them.
""" """
task_vars = self._task_vars or self._get_task_vars() task_vars = self._get_task_vars()
if task_vars is not None: if self.delegate_to_hostname is None:
if self.delegate_to_hostname is None: if key in task_vars:
return task_vars[key]
else:
delegated_vars = task_vars['ansible_delegated_vars']
if self.delegate_to_hostname in delegated_vars:
task_vars = delegated_vars[self.delegate_to_hostname]
if key in task_vars: if key in task_vars:
return task_vars[key] return task_vars[key]
else:
delegated_vars = task_vars['ansible_delegated_vars']
if self.delegate_to_hostname in delegated_vars:
task_vars = delegated_vars[self.delegate_to_hostname]
if key in task_vars:
return task_vars[key]
return default return default
@ -624,7 +641,8 @@ class Connection(ansible.plugins.connection.ConnectionBase):
# must use __contains__ to avoid a TypeError for a missing host on # must use __contains__ to avoid a TypeError for a missing host on
# Ansible 2.3. # Ansible 2.3.
if self.host_vars is None or inventory_name not in self.host_vars: via_vars = self.get_host_vars(inventory_name)
if via_vars is None:
raise ansible.errors.AnsibleConnectionFailure( raise ansible.errors.AnsibleConnectionFailure(
self.unknown_via_msg % ( self.unknown_via_msg % (
via_spec, via_spec,
@ -632,7 +650,6 @@ class Connection(ansible.plugins.connection.ConnectionBase):
) )
) )
via_vars = self.host_vars[inventory_name]
return ansible_mitogen.transport_config.MitogenViaSpec( return ansible_mitogen.transport_config.MitogenViaSpec(
inventory_name=inventory_name, inventory_name=inventory_name,
play_context=self._play_context, play_context=self._play_context,

@ -173,12 +173,12 @@ class ContextService(mitogen.service.Service):
l = mitogen.core.Latch() l = mitogen.core.Latch()
context = None context = None
with self._lock: with self._lock:
for spec in stack: for i, spec in enumerate(stack):
key = key_from_dict(via=context, **spec) key = key_from_dict(via=context, **spec)
response = self._response_by_key.get(key) response = self._response_by_key.get(key)
if response is None: if response is None:
LOG.debug('%r: could not find connection to shut down', LOG.debug('%r: could not find connection to shut down; '
self) 'failed at hop %d', self, i)
return False return False
context = response['context'] context = response['context']

@ -46,7 +46,13 @@ class ConnectionMixin(MuxProcessMixin):
def make_connection(self): def make_connection(self):
play_context = ansible.playbook.play_context.PlayContext() play_context = ansible.playbook.play_context.PlayContext()
return self.klass(play_context, new_stdin=False) conn = self.klass(play_context, new_stdin=False)
conn.on_action_run(
task_vars={},
delegate_to_hostname=None,
loader_basedir=None,
)
return conn
def wait_for_completion(self): def wait_for_completion(self):
# put_data() is asynchronous, must wait for operation to happen. Do # put_data() is asynchronous, must wait for operation to happen. Do

Loading…
Cancel
Save