Skip to content

Commit d3f6ad7

Browse files
committed
Merge remote-tracking branch 'origin/stable-029' into stable
2 parents 706a94b + 153d79b commit d3f6ad7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+498
-616
lines changed

.ci/ci_lib.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ def start_containers(containers):
264264
"docker rm -f %(name)s || true" % container,
265265
"docker run "
266266
"--rm "
267-
"--cpuset-cpus 0,1 "
267+
# "--cpuset-cpus 0,1 "
268268
"--detach "
269269
"--privileged "
270270
"--cap-add=SYS_PTRACE "

.ci/mitogen_py24_install.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
'docker pull %s' % (ci_lib.image_for_distro(ci_lib.DISTRO),),
88
],
99
[
10-
'sudo tar -C / -jxvf tests/data/ubuntu-python-2.4.6.tar.bz2',
10+
'curl https://dw.github.io/mitogen/binaries/ubuntu-python-2.4.6.tar.bz2 | sudo tar -C / -jxv',
1111
]
1212
]
1313

ansible_mitogen/affinity.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,19 @@ def _mask_to_bytes(self, mask):
265265
mask >>= 64
266266
return mitogen.core.b('').join(chunks)
267267

268+
def _get_thread_ids(self):
269+
try:
270+
ents = os.listdir('/proc/self/task')
271+
except OSError:
272+
LOG.debug('cannot fetch thread IDs for current process')
273+
return [os.getpid()]
274+
275+
return [int(s) for s in ents if s.isdigit()]
276+
268277
def _set_cpu_mask(self, mask):
269278
s = self._mask_to_bytes(mask)
270-
_sched_setaffinity(os.getpid(), len(s), s)
279+
for tid in self._get_thread_ids():
280+
_sched_setaffinity(tid, len(s), s)
271281

272282

273283
if _sched_setaffinity is not None:

ansible_mitogen/connection.py

Lines changed: 62 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@
5656

5757
LOG = logging.getLogger(__name__)
5858

59+
task_vars_msg = (
60+
'could not recover task_vars. This means some connection '
61+
'settings may erroneously be reset to their defaults. '
62+
'Please report a bug if you encounter this message.'
63+
)
64+
5965

6066
def get_remote_name(spec):
6167
"""
@@ -486,15 +492,9 @@ class Connection(ansible.plugins.connection.ConnectionBase):
486492
# the case of the synchronize module.
487493
#
488494

489-
#: Set to the host name as it appears in inventory by on_action_run().
490-
inventory_hostname = None
491-
492495
#: Set to task_vars by on_action_run().
493496
_task_vars = None
494497

495-
#: Set to 'hostvars' by on_action_run()
496-
host_vars = None
497-
498498
#: Set by on_action_run()
499499
delegate_to_hostname = None
500500

@@ -527,12 +527,10 @@ def on_action_run(self, task_vars, delegate_to_hostname, loader_basedir):
527527
:param str loader_basedir:
528528
Loader base directory; see :attr:`loader_basedir`.
529529
"""
530-
self.inventory_hostname = task_vars['inventory_hostname']
531530
self._task_vars = task_vars
532-
self.host_vars = task_vars['hostvars']
533531
self.delegate_to_hostname = delegate_to_hostname
534532
self.loader_basedir = loader_basedir
535-
self._mitogen_reset(mode='put')
533+
self._put_connection()
536534

537535
def _get_task_vars(self):
538536
"""
@@ -552,8 +550,10 @@ def _get_task_vars(self):
552550
for new connections to be constructed in addition to the preconstructed
553551
connection passed into any running action.
554552
"""
555-
f = sys._getframe()
553+
if self._task_vars is not None:
554+
return self._task_vars
556555

556+
f = sys._getframe()
557557
while f:
558558
if f.f_code.co_name == 'run':
559559
f_locals = f.f_locals
@@ -571,9 +571,23 @@ def _get_task_vars(self):
571571

572572
f = f.f_back
573573

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.')
574+
raise ansible.errors.AnsibleConnectionFailure(task_vars_msg)
575+
576+
def get_host_vars(self, inventory_hostname):
577+
"""
578+
Fetch the HostVars for a host.
579+
580+
:returns:
581+
Variables dictionary or :data:`None`.
582+
:raises ansible.errors.AnsibleConnectionFailure:
583+
Task vars unavailable.
584+
"""
585+
task_vars = self._get_task_vars()
586+
hostvars = task_vars.get('hostvars')
587+
if hostvars:
588+
return hostvars.get(inventory_hostname)
589+
590+
raise ansible.errors.AnsibleConnectionFailure(task_vars_msg)
577591

578592
def get_task_var(self, key, default=None):
579593
"""
@@ -586,17 +600,16 @@ def get_task_var(self, key, default=None):
586600
does not make sense to extract connection-related configuration for the
587601
delegated-to machine from them.
588602
"""
589-
task_vars = self._task_vars or self._get_task_vars()
590-
if task_vars is not None:
591-
if self.delegate_to_hostname is None:
603+
task_vars = self._get_task_vars()
604+
if self.delegate_to_hostname is None:
605+
if key in task_vars:
606+
return task_vars[key]
607+
else:
608+
delegated_vars = task_vars['ansible_delegated_vars']
609+
if self.delegate_to_hostname in delegated_vars:
610+
task_vars = delegated_vars[self.delegate_to_hostname]
592611
if key in task_vars:
593612
return task_vars[key]
594-
else:
595-
delegated_vars = task_vars['ansible_delegated_vars']
596-
if self.delegate_to_hostname in delegated_vars:
597-
task_vars = delegated_vars[self.delegate_to_hostname]
598-
if key in task_vars:
599-
return task_vars[key]
600613

601614
return default
602615

@@ -628,15 +641,15 @@ def _spec_from_via(self, proxied_inventory_name, via_spec):
628641

629642
# must use __contains__ to avoid a TypeError for a missing host on
630643
# Ansible 2.3.
631-
if self.host_vars is None or inventory_name not in self.host_vars:
644+
via_vars = self.get_host_vars(inventory_name)
645+
if via_vars is None:
632646
raise ansible.errors.AnsibleConnectionFailure(
633647
self.unknown_via_msg % (
634648
via_spec,
635649
proxied_inventory_name,
636650
)
637651
)
638652

639-
via_vars = self.host_vars[inventory_name]
640653
return ansible_mitogen.transport_config.MitogenViaSpec(
641654
inventory_name=inventory_name,
642655
play_context=self._play_context,
@@ -712,7 +725,7 @@ def _build_stack(self):
712725
connection=self,
713726
play_context=self._play_context,
714727
transport=self.transport,
715-
inventory_name=self.inventory_hostname,
728+
inventory_name=self.get_task_var('inventory_hostname'),
716729
)
717730
stack = self._stack_from_spec(spec)
718731
return spec.inventory_name(), stack
@@ -778,18 +791,16 @@ def _connect(self):
778791

779792
inventory_name, stack = self._build_stack()
780793
worker_model = ansible_mitogen.process.get_worker_model()
781-
self.binding = worker_model.get_binding(inventory_name)
794+
self.binding = worker_model.get_binding(
795+
mitogen.utils.cast(inventory_name)
796+
)
782797
self._connect_stack(stack)
783798

784-
def _mitogen_reset(self, mode):
799+
def _put_connection(self):
785800
"""
786801
Forget everything we know about the connected context. This function
787802
cannot be called _reset() since that name is used as a public API by
788803
Ansible 2.4 wait_for_connection plug-in.
789-
790-
:param str mode:
791-
Name of ContextService method to use to discard the context, either
792-
'put' or 'reset'.
793804
"""
794805
if not self.context:
795806
return
@@ -798,7 +809,7 @@ def _mitogen_reset(self, mode):
798809
mitogen.service.call(
799810
call_context=self.binding.get_service_context(),
800811
service_name='ansible_mitogen.services.ContextService',
801-
method_name=mode,
812+
method_name='put',
802813
context=self.context
803814
)
804815

@@ -813,24 +824,11 @@ def close(self):
813824
gracefully shut down, and wait for shutdown to complete. Safe to call
814825
multiple times.
815826
"""
816-
self._mitogen_reset(mode='put')
827+
self._put_connection()
817828
if self.binding:
818829
self.binding.close()
819830
self.binding = None
820831

821-
def _reset_find_task_vars(self):
822-
"""
823-
Monsterous hack: since "meta: reset_connection" does not run from an
824-
action, we cannot capture task variables via :meth:`on_action_run`.
825-
Instead walk the parent frames searching for the `all_vars` local from
826-
StrategyBase._execute_meta(). If this fails, just leave task_vars
827-
unset, likely causing a subtly wrong configuration to be selected.
828-
"""
829-
frame = sys._getframe()
830-
while frame and not self._task_vars:
831-
self._task_vars = frame.f_locals.get('all_vars')
832-
frame = frame.f_back
833-
834832
reset_compat_msg = (
835833
'Mitogen only supports "reset_connection" on Ansible 2.5.6 or later'
836834
)
@@ -842,20 +840,31 @@ def reset(self):
842840
the 'disconnected' state, and informs ContextService the connection is
843841
bad somehow, and should be shut down and discarded.
844842
"""
845-
if self._task_vars is None:
846-
self._reset_find_task_vars()
847-
848843
if self._play_context.remote_addr is None:
849844
# <2.5.6 incorrectly populate PlayContext for reset_connection
850845
# https://github.com/ansible/ansible/issues/27520
851846
raise ansible.errors.AnsibleConnectionFailure(
852847
self.reset_compat_msg
853848
)
854849

855-
self._connect()
856-
self._mitogen_reset(mode='reset')
857-
self.binding.close()
858-
self.binding = None
850+
# Clear out state in case we were ever connected.
851+
self.close()
852+
853+
inventory_name, stack = self._build_stack()
854+
if self._play_context.become:
855+
stack = stack[:-1]
856+
857+
worker_model = ansible_mitogen.process.get_worker_model()
858+
binding = worker_model.get_binding(inventory_name)
859+
try:
860+
mitogen.service.call(
861+
call_context=binding.get_service_context(),
862+
service_name='ansible_mitogen.services.ContextService',
863+
method_name='reset',
864+
stack=mitogen.utils.cast(list(stack)),
865+
)
866+
finally:
867+
binding.close()
859868

860869
# Compatibility with Ansible 2.4 wait_for_connection plug-in.
861870
_reset = reset

ansible_mitogen/loaders.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,8 @@
5555
from ansible.plugins import module_utils_loader
5656
from ansible.plugins import shell_loader
5757
from ansible.plugins import strategy_loader
58+
59+
60+
# These are original, unwrapped implementations
61+
action_loader__get = action_loader.get
62+
connection_loader__get = connection_loader.get

ansible_mitogen/logging.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ def setup():
107107
l_mitogen = logging.getLogger('mitogen')
108108
l_mitogen_io = logging.getLogger('mitogen.io')
109109
l_ansible_mitogen = logging.getLogger('ansible_mitogen')
110+
l_operon = logging.getLogger('operon')
110111

111-
for logger in l_mitogen, l_mitogen_io, l_ansible_mitogen:
112+
for logger in l_mitogen, l_mitogen_io, l_ansible_mitogen, l_operon:
112113
logger.handlers = [Handler(display.vvv)]
113114
logger.propagate = False
114115

ansible_mitogen/mixins.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@
5555
import ansible_mitogen.target
5656
from ansible.module_utils._text import to_text
5757

58+
try:
59+
from ansible.utils.unsafe_proxy import wrap_var
60+
except ImportError:
61+
from ansible.vars.unsafe_proxy import wrap_var
62+
5863

5964
LOG = logging.getLogger(__name__)
6065

@@ -306,7 +311,7 @@ def get_task_timeout_secs(self):
306311
except AttributeError:
307312
return getattr(self._task, 'async')
308313

309-
def _temp_file_gibberish(self, module_args, wrap_async):
314+
def _set_temp_file_args(self, module_args, wrap_async):
310315
# Ansible>2.5 module_utils reuses the action's temporary directory if
311316
# one exists. Older versions error if this key is present.
312317
if ansible.__version__ > '2.5':
@@ -343,7 +348,7 @@ def _execute_module(self, module_name=None, module_args=None, tmp=None,
343348
self._update_module_args(module_name, module_args, task_vars)
344349
env = {}
345350
self._compute_environment_string(env)
346-
self._temp_file_gibberish(module_args, wrap_async)
351+
self._set_temp_file_args(module_args, wrap_async)
347352

348353
self._connection._connect()
349354
result = ansible_mitogen.planner.invoke(
@@ -365,7 +370,7 @@ def _execute_module(self, module_name=None, module_args=None, tmp=None,
365370
# on _execute_module().
366371
self._remove_tmp_path(tmp)
367372

368-
return result
373+
return wrap_var(result)
369374

370375
def _postprocess_response(self, result):
371376
"""

0 commit comments

Comments
 (0)