4646import mitogen .fork
4747import mitogen .utils
4848
49+ import ansible_mitogen .mixins
4950import ansible_mitogen .parsing
5051import ansible_mitogen .process
5152import ansible_mitogen .services
@@ -533,6 +534,47 @@ def on_action_run(self, task_vars, delegate_to_hostname, loader_basedir):
533534 self .loader_basedir = loader_basedir
534535 self ._mitogen_reset (mode = 'put' )
535536
537+ def _get_task_vars (self ):
538+ """
539+ More information is needed than normally provided to an Ansible
540+ connection. For proxied connections, intermediary configuration must
541+ be inferred, and for any connection the configured Python interpreter
542+ must be known.
543+
544+ There is no clean way to access this information that would not deviate
545+ from the running Ansible version. The least invasive method known is to
546+ reuse the running task's task_vars dict.
547+
548+ This method walks the stack to find task_vars of the Action plugin's
549+ run(), or if no Action is present, from Strategy's _execute_meta(), as
550+ in the case of 'meta: reset_connection'. The stack is walked in
551+ addition to subclassing Action.run()/on_action_run(), as it is possible
552+ for new connections to be constructed in addition to the preconstructed
553+ connection passed into any running action.
554+ """
555+ f = sys ._getframe ()
556+
557+ while f :
558+ if f .f_code .co_name == 'run' :
559+ f_locals = f .f_locals
560+ f_self = f_locals .get ('self' )
561+ if isinstance (f_self , ansible_mitogen .mixins .ActionModuleMixin ):
562+ task_vars = f_locals .get ('task_vars' )
563+ if task_vars :
564+ LOG .debug ('recovered task_vars from Action' )
565+ return task_vars
566+ elif f .f_code .co_name == '_execute_meta' :
567+ f_all_vars = f .f_locals .get ('all_vars' )
568+ if isinstance (f_all_vars , dict ):
569+ LOG .debug ('recovered task_vars from meta:' )
570+ return f_all_vars
571+
572+ f = f .f_back
573+
574+ LOG .warning ('could not recover task_vars. This means some connection '
575+ 'settings may erroneously be reset to their defaults. '
576+ 'Please report a bug if you encounter this message.' )
577+
536578 def get_task_var (self , key , default = None ):
537579 """
538580 Fetch the value of a task variable related to connection configuration,
@@ -544,12 +586,13 @@ def get_task_var(self, key, default=None):
544586 does not make sense to extract connection-related configuration for the
545587 delegated-to machine from them.
546588 """
547- if self ._task_vars :
589+ task_vars = self ._task_vars or self ._get_task_vars ()
590+ if task_vars is not None :
548591 if self .delegate_to_hostname is None :
549- if key in self . _task_vars :
550- return self . _task_vars [key ]
592+ if key in task_vars :
593+ return task_vars [key ]
551594 else :
552- delegated_vars = self . _task_vars ['ansible_delegated_vars' ]
595+ delegated_vars = task_vars ['ansible_delegated_vars' ]
553596 if self .delegate_to_hostname in delegated_vars :
554597 task_vars = delegated_vars [self .delegate_to_hostname ]
555598 if key in task_vars :
0 commit comments