From c1296b5d75db3fb4654062518d12151af20c17ac Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Wed, 2 Jul 2025 11:29:37 +0100 Subject: [PATCH] ansible_mitogen: Support ANSIBLE_SSH_VERBOSITY with Ansible >= 12 In vanilla Ansible >= 12 (ansible-core 2.19) - ssh connection plugin `verbosity` controls `ssh [-v[v[v]]]` - config option `DEFAULT_VERBOSITY` controls whether that output is displayed In vanilla Ansible <= 11 (ansible-core <= 2.18) - `DEFAULT_VERBOSITY` controls both `ssh` verbosity & display verbositty As of this change - Mitogen + Ansible >= 12 behaviour matches vanilla Ansible >= 12. - Mitogen + Ansible <= 11 behaviour remains unchanged - `DEFAULT_VERBOSITY` only controls display verbosity. - Mitogen + Ansible respect the Ansible variable `mitogen_ssh_debug_level` I've chosen not to retroactively replicate the old vanilla Ansible behaviour in Mitogen + Ansible <= 11 cases. I'm pretty sure it was an oversight, rather than a design choice, but Ansible+Mitogen with `ANSIBLE_VERBOSITY=3` is already very verbose. fixes #1282 See - https://docs.ansible.com/ansible/latest/reference_appendices/config.html#default-verbosity - https://docs.ansible.com/ansible/devel/collections/ansible/builtin/ssh_connection.html#parameter-verbosity --- ansible_mitogen/connection.py | 2 +- ansible_mitogen/transport_config.py | 27 ++++++++++++ docs/changelog.rst | 2 + .../delegate_to_template.yml | 4 +- .../stack_construction.yml | 14 +++---- tests/ansible/integration/ssh/all.yml | 1 + tests/ansible/integration/ssh/verbosity.yml | 41 +++++++++++++++++++ 7 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 tests/ansible/integration/ssh/verbosity.yml diff --git a/ansible_mitogen/connection.py b/ansible_mitogen/connection.py index 3e02b971..03856f4d 100644 --- a/ansible_mitogen/connection.py +++ b/ansible_mitogen/connection.py @@ -147,7 +147,7 @@ def _connect_ssh(spec): 'ssh_path': spec.ssh_executable(), 'connect_timeout': spec.timeout(), 'ssh_args': spec.ssh_args(), - 'ssh_debug_level': spec.mitogen_ssh_debug_level(), + 'ssh_debug_level': spec.verbosity(), 'remote_name': get_remote_name(spec), 'keepalive_count': ( spec.mitogen_ssh_keepalive_count() or 10 diff --git a/ansible_mitogen/transport_config.py b/ansible_mitogen/transport_config.py index 22afd197..3d5fac3c 100644 --- a/ansible_mitogen/transport_config.py +++ b/ansible_mitogen/transport_config.py @@ -406,6 +406,12 @@ class Spec(with_metaclass(abc.ABCMeta, object)): Value of "ansible_doas_exe" variable. """ + @abc.abstractmethod + def verbosity(self): + """ + How verbose to make logging or diagnostics output. + """ + class PlayContextSpec(Spec): """ @@ -601,6 +607,17 @@ class PlayContextSpec(Spec): os.environ.get('ANSIBLE_DOAS_EXE') ) + def verbosity(self): + try: + verbosity = self._connection.get_option('verbosity', hostvars=self._task_vars) + except KeyError: + verbosity = self.mitogen_ssh_debug_level() + + if verbosity: + return int(verbosity) + + return 0 + class MitogenViaSpec(Spec): """ @@ -836,3 +853,13 @@ class MitogenViaSpec(Spec): self._host_vars.get('ansible_doas_exe') or os.environ.get('ANSIBLE_DOAS_EXE') ) + + def verbosity(self): + verbosity = self._host_vars.get('ansible_ssh_verbosity') + if verbosity is None: + verbosity = self.mitogen_ssh_debug_level() + + if verbosity: + return int(verbosity) + + return 0 diff --git a/docs/changelog.rst b/docs/changelog.rst index c7b7ae49..f2de5561 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -38,6 +38,8 @@ to strategy plugins under :gh:issue:`1278`. release candidate is under test * :gh:issue:`1275` CI: Test ``ansible_ssh_password`` behaviour without ``sshpass`` installed +* :gh:issue:`1282` :mod:`ansible_mitogen`: Support ``ANSIBLE_SSH_VERBOSITY`` + with Ansible 12 v0.3.25a2 (2025-06-21) diff --git a/tests/ansible/integration/connection_delegation/delegate_to_template.yml b/tests/ansible/integration/connection_delegation/delegate_to_template.yml index 4cff57e1..8cd50f98 100644 --- a/tests/ansible/integration/connection_delegation/delegate_to_template.yml +++ b/tests/ansible/integration/connection_delegation/delegate_to_template.yml @@ -50,7 +50,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, @@ -78,7 +78,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'ansible-cfg-remote-user', }, diff --git a/tests/ansible/integration/connection_delegation/stack_construction.yml b/tests/ansible/integration/connection_delegation/stack_construction.yml index 1cfd34ef..58abac7b 100644 --- a/tests/ansible/integration/connection_delegation/stack_construction.yml +++ b/tests/ansible/integration/connection_delegation/stack_construction.yml @@ -87,7 +87,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, @@ -131,7 +131,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, @@ -186,7 +186,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'ansible-cfg-remote-user', }, @@ -230,7 +230,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, @@ -258,7 +258,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'ansible-cfg-remote-user', }, @@ -312,7 +312,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'newuser-normal-normal-user', }, @@ -357,7 +357,7 @@ -o, PubkeyAcceptedKeyTypes=+ssh-rsa, -o, UserKnownHostsFile=/dev/null, ], - 'ssh_debug_level': null, + 'ssh_debug_level': 0, 'ssh_path': 'ssh', 'username': 'alias-user', }, diff --git a/tests/ansible/integration/ssh/all.yml b/tests/ansible/integration/ssh/all.yml index 20031704..6dbf945f 100644 --- a/tests/ansible/integration/ssh/all.yml +++ b/tests/ansible/integration/ssh/all.yml @@ -8,3 +8,4 @@ - import_playbook: templated_by_play_taskvar.yml - import_playbook: templated_by_task_keyword.yml - import_playbook: variables.yml +- import_playbook: verbosity.yml diff --git a/tests/ansible/integration/ssh/verbosity.yml b/tests/ansible/integration/ssh/verbosity.yml new file mode 100644 index 00000000..2bf1ed10 --- /dev/null +++ b/tests/ansible/integration/ssh/verbosity.yml @@ -0,0 +1,41 @@ +# Ansible >= 12 (ansible-core >= 2.19) adds SSH connection `verbosity` property. +# Ansible <= 11 (ansible-core <= 2.18) applies ANSIBLE_VERBOSITY -> ssh. + +- name: integration/ssh/verbosity.yml + hosts: test-targets + gather_facts: false + tasks: + - meta: end_play + when: + - ansible_version_major_minor is version('2.19', '<', strict=True) + + - name: Exercise ssh verbosity + connection: local + environment: + ANSIBLE_CALLBACK_RESULT_FORMAT: json + ANSIBLE_LOAD_CALLBACK_PLUGINS: "false" + ANSIBLE_SSH_VERBOSITY: 3 + ANSIBLE_STRATEGY: "{{ lookup('env', 'ANSIBLE_STRATEGY') | mandatory }}" + ANSIBLE_VERBOSITY: 3 + vars: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + command: + cmd: + ansible + {% for inv in ansible_inventory_sources %} + -i "{{ inv }}" + {% endfor %} + "{{ inventory_hostname }}" + -m ping + chdir: ../.. + register: out + changed_when: false + check_mode: false + + - name: Verify ssh -vvv output is included + assert: + that: + - >- + out.stdout is search('debug1: Reading configuration data') + fail_msg: | + out={{ out }}