diff --git a/ansible_mitogen/connection.py b/ansible_mitogen/connection.py index 1231acb5..a043ef1d 100644 --- a/ansible_mitogen/connection.py +++ b/ansible_mitogen/connection.py @@ -933,31 +933,39 @@ class Connection(ansible.plugins.connection.ConnectionBase): self.reset_compat_msg ) - # Strategy's _execute_meta doesn't have an action obj but we'll need one for - # running interpreter_discovery - # will create a new temporary action obj for this purpose - self._action = ansible_mitogen.mixins.ActionModuleMixin( - task=0, - connection=self, - play_context=self._play_context, - loader=0, - templar=0, - shared_loader_obj=0 - ) - - # Workaround for https://github.com/ansible/ansible/issues/84238 + # Handle templated connection variables during `meta: reset_connection`. + # Many bugs/implementation details of Mitogen & Ansible collide here. + # See #1079, #1096, #1132, ansible/ansible#84238, ... try: task, templar = self._play_context.vars.pop( '_mitogen.smuggled.reset_connection', ) except KeyError: - pass + self._action_monkey_patched_by_mitogen = False else: + # LOG.info('%r.reset(): remote_addr=%r', self, self._play_context.remote_addr) + # ansible.plugins.strategy.StrategyBase._execute_meta() doesn't + # have an action object, which we need for interpreter_discovery. + # Create a temporary action object for this purpose. + self._action = ansible_mitogen.mixins.ActionModuleMixin( + task=task, + connection=self, + play_context=self._play_context, + loader=templar._loader, + templar=templar, + shared_loader_obj=0, + ) + self._action_monkey_patched_by_mitogen = True + + # Workaround for https://github.com/ansible/ansible/issues/84238 self.set_options( task_keys=task.dump_attrs(), var_options=self._mitogen_var_options(templar), ) + del task + del templar + # Clear out state in case we were ever connected. self.close() @@ -977,6 +985,11 @@ class Connection(ansible.plugins.connection.ConnectionBase): finally: binding.close() + # Cleanup any monkey patching we did for `meta: reset_connection` + if self._action_monkey_patched_by_mitogen: + del self._action + del self._action_monkey_patched_by_mitogen + # Compatibility with Ansible 2.4 wait_for_connection plug-in. _reset = reset diff --git a/docs/changelog.rst b/docs/changelog.rst index d15a7b5c..0b83a04c 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -21,6 +21,8 @@ To avail of fixes in an unreleased version, please download a ZIP file In progress (unreleased) ------------------------ +* :gh:issue:`1079` :mod:`ansible_mitogen`: Fix :ans:mod:`wait_for_connection` + timeout with templated ``ansible_python_interpreter`` v0.3.19 (2024-12-02) diff --git a/tests/ansible/hosts/default.hosts b/tests/ansible/hosts/default.hosts index 17d1fd6d..a232c6ab 100644 --- a/tests/ansible/hosts/default.hosts +++ b/tests/ansible/hosts/default.hosts @@ -19,6 +19,9 @@ ssh-common-args ansible_host=localhost ansible_user="{{ lookup('pipe', 'whoami') ansible_ssh_common_args=-o PermitLocalCommand=yes -o LocalCommand="touch {{ ssh_args_canary_file }}" ssh_args_canary_file=/tmp/ssh_args_by_inv_{{ inventory_hostname }} +[issue1079] +wait-for-connection ansible_host=localhost ansible_user="{{ lookup('pipe', 'whoami') }}" + [tt_targets_bare] tt-bare diff --git a/tests/ansible/regression/all.yml b/tests/ansible/regression/all.yml index a4272805..a7c8033e 100644 --- a/tests/ansible/regression/all.yml +++ b/tests/ansible/regression/all.yml @@ -16,4 +16,5 @@ - import_playbook: issue_776__load_plugins_called_twice.yml - import_playbook: issue_952__ask_become_pass.yml - import_playbook: issue_1066__add_host__host_key_checking.yml +- import_playbook: issue_1079__wait_for_connection_timeout.yml - import_playbook: issue_1087__template_streamerror.yml diff --git a/tests/ansible/regression/issue_1079__wait_for_connection_timeout.yml b/tests/ansible/regression/issue_1079__wait_for_connection_timeout.yml new file mode 100644 index 00000000..2ff1899b --- /dev/null +++ b/tests/ansible/regression/issue_1079__wait_for_connection_timeout.yml @@ -0,0 +1,10 @@ +- name: regression/issue_1079__wait_for_connection_timeout.yml + hosts: issue1079 + gather_facts: false + tasks: + - name: Wait for connection at start of play + wait_for_connection: + timeout: 5 + tags: + - issue_1079 + - wait_for_connection diff --git a/tests/ansible/templates/test-targets.j2 b/tests/ansible/templates/test-targets.j2 index bb0d85ec..87b0e7c9 100644 --- a/tests/ansible/templates/test-targets.j2 +++ b/tests/ansible/templates/test-targets.j2 @@ -40,6 +40,13 @@ ssh_args_canary_file=/tmp/ssh_args_by_inv_{{ '{{' }} inventory_hostname {{ '}}' {% set tt = containers[0] %} +[issue1079] +wait-for-connection ansible_host={{ tt.hostname }} ansible_port={{ tt.port }} ansible_python_interpreter="{{ '{{' }} '{{ tt.python_path }}' | trim {{ '}}' }}" + +[issue1079:vars] +ansible_user=mitogen__has_sudo_nopw +ansible_password=has_sudo_nopw_password + [tt_targets_bare] tt-bare