From f330c2b1588cf1e4afea74dd7e3cde96b308fe1f Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Mon, 23 Jun 2025 08:32:11 +0100 Subject: [PATCH 1/8] CI: replace stdout=yaml with result_format=yaml for Ansible >= 6 tests Ansible >= 12 (ansible-core >= 2.19) deprecates `stdout_callback=yaml`, superceded by `callback_result_format=yaml`. There is a change in behaviour: `callback_result_format` applies to output of both `ansible-playbook` _and_ `ansible`. Tests that run `ansible` in a subprocess are now explicitly configured to use json (even if they don't inspect that output yet) for more assert-able output across all versions of Ansible. --- docs/changelog.rst | 3 +++ tests/ansible/ansible.cfg | 6 ++++-- tests/ansible/integration/process/unix_socket_cleanup.yml | 2 ++ tests/ansible/integration/runner/missing_module.yml | 2 ++ tests/ansible/integration/ssh/timeouts.yml | 2 ++ tests/ansible/integration/ssh/variables.yml | 4 ++++ tests/ansible/integration/stub_connections/setns_lxc.yml | 2 ++ tests/ansible/integration/stub_connections/setns_lxd.yml | 2 ++ tox.ini | 3 +++ 9 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 78037347..224b40c4 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -32,6 +32,9 @@ Running Ansible 12 + Mitogen will currently print a deprecation warning Ansible + Mitogen will still work for now. Mitogen is considering alternatives to strategy plugins under :gh:issue:`1278`. +* :gh:issue:`1285` CI: use `result_format = yaml` for Ansible test output, + instead of deprecated `stdout_callback = yaml` + v0.3.25a2 (2025-06-21) ---------------------- diff --git a/tests/ansible/ansible.cfg b/tests/ansible/ansible.cfg index 48a4eec3..4060d9ea 100644 --- a/tests/ansible/ansible.cfg +++ b/tests/ansible/ansible.cfg @@ -1,5 +1,7 @@ [defaults] any_errors_fatal = true +# Ansible >= 6 (ansible-core >= 2.13) +callback_result_format = yaml # callbacks_enabled was added in Ansible 4 (ansible-core 2.11). # profile_tasks: Displays timing for each task and summary table of top N tasks # timer: Displays "Playbook run took 0 days, 0 hours, ..." @@ -17,13 +19,13 @@ strategy_plugins = ../../ansible_mitogen/plugins/strategy inventory_plugins = lib/inventory action_plugins = lib/action callback_plugins = lib/callback -stdout_callback = yaml vars_plugins = lib/vars library = lib/modules filter_plugins = lib/filters module_utils = lib/module_utils retry_files_enabled = False -show_task_path_on_failure = true # Added in ansible-core 2.11 +# Ansible >= 4 (ansible-core >= 2.11) +show_task_path_on_failure = true display_args_to_stdout = True forks = 100 diff --git a/tests/ansible/integration/process/unix_socket_cleanup.yml b/tests/ansible/integration/process/unix_socket_cleanup.yml index 21747494..4466aa2e 100644 --- a/tests/ansible/integration/process/unix_socket_cleanup.yml +++ b/tests/ansible/integration/process/unix_socket_cleanup.yml @@ -11,6 +11,8 @@ vars: ansible_python_interpreter: "{{ ansible_playbook_python }}" shell: >- + ANSIBLE_CALLBACK_RESULT_FORMAT=json + ANSIBLE_LOAD_CALLBACK_PLUGINS=false ANSIBLE_STRATEGY=mitogen_linear ANSIBLE_SSH_ARGS="-o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa" ANSIBLE_VERBOSITY="{{ ansible_verbosity }}" diff --git a/tests/ansible/integration/runner/missing_module.yml b/tests/ansible/integration/runner/missing_module.yml index b42e3af3..b641cbe3 100644 --- a/tests/ansible/integration/runner/missing_module.yml +++ b/tests/ansible/integration/runner/missing_module.yml @@ -5,6 +5,8 @@ - name: Run missing_module connection: local environment: + ANSIBLE_CALLBACK_RESULT_FORMAT: json + ANSIBLE_LOAD_CALLBACK_PLUGINS: "false" ANSIBLE_STRATEGY: "{{ lookup('env', 'ANSIBLE_STRATEGY') | mandatory }}" ANSIBLE_VERBOSITY: "{{ ansible_verbosity }}" vars: diff --git a/tests/ansible/integration/ssh/timeouts.yml b/tests/ansible/integration/ssh/timeouts.yml index 7ea905f5..0cb59422 100644 --- a/tests/ansible/integration/ssh/timeouts.yml +++ b/tests/ansible/integration/ssh/timeouts.yml @@ -13,6 +13,8 @@ - name: Cause Ansible connection timeout connection: local environment: + ANSIBLE_CALLBACK_RESULT_FORMAT: json + ANSIBLE_LOAD_CALLBACK_PLUGINS: "false" ANSIBLE_SSH_TIMEOUT: 10 ANSIBLE_STRATEGY: "{{ lookup('env', 'ANSIBLE_STRATEGY') | mandatory }}" ANSIBLE_VERBOSITY: "{{ ansible_verbosity }}" diff --git a/tests/ansible/integration/ssh/variables.yml b/tests/ansible/integration/ssh/variables.yml index bb4bd179..5eb54dde 100644 --- a/tests/ansible/integration/ssh/variables.yml +++ b/tests/ansible/integration/ssh/variables.yml @@ -19,6 +19,8 @@ - name: ansible_user, ansible_ssh_private_key_file shell: > ANSIBLE_ANY_ERRORS_FATAL=false + ANSIBLE_CALLBACK_RESULT_FORMAT=json + ANSIBLE_LOAD_CALLBACK_PLUGINS=false ANSIBLE_STRATEGY=mitogen_linear ANSIBLE_SSH_ARGS="-o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa" ANSIBLE_VERBOSITY="{{ ansible_verbosity }}" @@ -37,6 +39,8 @@ - name: ansible_user, wrong ansible_ssh_private_key_file shell: > ANSIBLE_ANY_ERRORS_FATAL=false + ANSIBLE_CALLBACK_RESULT_FORMAT=json + ANSIBLE_LOAD_CALLBACK_PLUGINS=false ANSIBLE_STRATEGY=mitogen_linear ANSIBLE_SSH_ARGS="-o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedKeyTypes=+ssh-rsa" ANSIBLE_VERBOSITY="{{ ansible_verbosity }}" diff --git a/tests/ansible/integration/stub_connections/setns_lxc.yml b/tests/ansible/integration/stub_connections/setns_lxc.yml index 584a6806..f7654ad8 100644 --- a/tests/ansible/integration/stub_connections/setns_lxc.yml +++ b/tests/ansible/integration/stub_connections/setns_lxc.yml @@ -15,6 +15,8 @@ - name: Run stub-lxc-info.py environment: + ANSIBLE_CALLBACK_RESULT_FORMAT: json + ANSIBLE_LOAD_CALLBACK_PLUGINS: "false" ANSIBLE_STRATEGY: "{{ lookup('env', 'ANSIBLE_STRATEGY') | mandatory }}" ANSIBLE_VERBOSITY: "{{ ansible_verbosity }}" command: | diff --git a/tests/ansible/integration/stub_connections/setns_lxd.yml b/tests/ansible/integration/stub_connections/setns_lxd.yml index 2e07aca3..c461845e 100644 --- a/tests/ansible/integration/stub_connections/setns_lxd.yml +++ b/tests/ansible/integration/stub_connections/setns_lxd.yml @@ -15,6 +15,8 @@ - name: Run ansible stub-lxc.py environment: + ANSIBLE_CALLBACK_RESULT_FORMAT: json + ANSIBLE_LOAD_CALLBACK_PLUGINS: "false" ANSIBLE_STRATEGY: "{{ lookup('env', 'ANSIBLE_STRATEGY') | mandatory }}" ANSIBLE_VERBOSITY: "{{ ansible_verbosity }}" command: | diff --git a/tox.ini b/tox.ini index 9f3be10f..3cad99c0 100644 --- a/tox.ini +++ b/tox.ini @@ -112,6 +112,9 @@ setenv = NOCOVERAGE_ERASE = 1 NOCOVERAGE_REPORT = 1 PIP_CONSTRAINT={toxinidir}/tests/constraints.txt + # Superceded in Ansible >= 6 (ansible-core >= 2.13) by result_format=yaml + # Deprecated in Ansible 12 (ansible-core 2.19) + ansible{2.10,3-5}: DEFAULT_STDOUT_CALLBACK=yaml # Print warning on the first occurence at each module:linenno in Mitogen. Available Python 2.7, 3.2+. PYTHONWARNINGS=default:::ansible_mitogen,default:::mitogen # Ansible 6 - 8 (ansible-core 2.13 - 2.15) require Python 2.7 or >= 3.5 on targets From 3cba11a126f3e48f5cb1adde59672b4abdb1968e Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Tue, 1 Jul 2025 09:16:37 +0100 Subject: [PATCH 2/8] CI: Fix ansible_version comparison with ansible-core 2.19.0rc1 Note that tests/ansible/integration/ssh/templated_by_play_taskvar.yml was previously erroniously being skipped with ansible-core 2.19.0a and 2.19.0b. fixes #1293 refs #1175 --- docs/changelog.rst | 2 ++ tests/ansible/hosts/group_vars/all.yml | 11 +++++-- .../integration/_expected_ssh_port.yml | 6 ++-- .../integration/action/transfer_data.yml | 2 +- .../async/result_shell_echo_hi.yml | 6 ++-- .../integration/async/runner_one_job.yml | 8 ++--- .../async/runner_two_simultaneous_jobs.yml | 2 +- .../ansible/integration/connection/reset.yml | 4 +-- .../integration/connection/reset_become.yml | 4 +-- .../delegate_to_template.yml | 2 +- .../context_service/disconnect_cleanup.yml | 2 +- .../ansible_2_8_tests.yml | 10 +++---- .../interpreter_discovery/complex_args.yml | 2 +- .../runner/custom_bash_hashbang_argument.yml | 2 +- .../runner/custom_perl_json_args_module.yml | 2 +- .../runner/custom_perl_want_json_module.yml | 2 +- .../ssh/templated_by_play_taskvar.yml | 2 +- .../_end_play_if_not_sudo_linux.yml | 2 +- .../integration/stub_connections/kubectl.yml | 2 +- .../stub_connections/setns_lxc.yml | 2 +- .../stub_connections/setns_lxd.yml | 2 +- .../integration/transport_config/password.yml | 30 ++++++++++++------- .../transport_config/python_path.yml | 8 ++--- ...ssue_1066__add_host__host_key_checking.yml | 4 +-- ..._109__target_has_old_ansible_installed.yml | 2 +- .../issue_590__sys_modules_crap.yml | 2 +- .../issue_655__wait_for_connection_error.yml | 2 +- .../issue_766__get_with_context.yml | 6 ++-- .../issue_776__load_plugins_called_twice.yml | 2 +- tests/image_prep/_container_setup.yml | 2 +- tests/image_prep/group_vars/all.yml | 2 ++ 31 files changed, 80 insertions(+), 57 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 224b40c4..bd98a835 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -34,6 +34,8 @@ to strategy plugins under :gh:issue:`1278`. * :gh:issue:`1285` CI: use `result_format = yaml` for Ansible test output, instead of deprecated `stdout_callback = yaml` +* :gh:issue:`1293` CI: Fix ``ansible_version`` comparisons when an Ansible + release candidate is under test v0.3.25a2 (2025-06-21) diff --git a/tests/ansible/hosts/group_vars/all.yml b/tests/ansible/hosts/group_vars/all.yml index 6f518cad..7ec10d6a 100644 --- a/tests/ansible/hosts/group_vars/all.yml +++ b/tests/ansible/hosts/group_vars/all.yml @@ -1,4 +1,11 @@ --- +# Avoid `ansible_version.full is version(..., strict=True)` limitations. +# Pre-release info (alpha/beta/rc) is intentionally ignored. +# Behaviour that is present or expected in ansible-core 2.50.x should be +# tested even if ansible-core 2.50.0a1 or 2.50.0rc1 is under test. +ansible_version_major_minor: "{{ ansible_version.major }}.{{ ansible_version.minor }}" +ansible_version_major_minor_patch: "{{ ansible_version.major }}.{{ ansible_version.minor }}.{{ ansible_version.revision | regex_search('^[0-9]+') }}" + become_unpriv_available: >- {# Vanilla Ansible >= 4 (ansible-core >= 2.11) can use `setfacl` for @@ -13,7 +20,7 @@ become_unpriv_available: >- ( not is_mitogen and is_macos_controller - and ansible_version.full is version("2.11", ">=", strict=True) + and ansible_version_major_minor is version("2.11", ">=", strict=True) ) or ( is_mitogen @@ -22,7 +29,7 @@ become_unpriv_available: >- or ( is_mitogen and ansible_python_interpreter is not defined - and ansible_version.full is version("2.18", "<", strict=True) + and ansible_version_major_minor is version("2.18", "<", strict=True) ) -}} diff --git a/tests/ansible/integration/_expected_ssh_port.yml b/tests/ansible/integration/_expected_ssh_port.yml index 442659a5..f85ec3e2 100644 --- a/tests/ansible/integration/_expected_ssh_port.yml +++ b/tests/ansible/integration/_expected_ssh_port.yml @@ -11,8 +11,10 @@ - set_fact: expected_ssh_port: null - when: ansible_version.full is version('2.11.1', '>=', strict=True) + when: + - ansible_version_major_minor_patch is version('2.11.1', '>=', strict=True) - set_fact: expected_ssh_port: 22 - when: ansible_version.full is version('2.11.1', '<', strict=True) + when: + - ansible_version_major_minor_patch is version('2.11.1', '<', strict=True) diff --git a/tests/ansible/integration/action/transfer_data.yml b/tests/ansible/integration/action/transfer_data.yml index 7dd726ed..c36dd463 100644 --- a/tests/ansible/integration/action/transfer_data.yml +++ b/tests/ansible/integration/action/transfer_data.yml @@ -6,7 +6,7 @@ when: # Ansible >= 12 (ansible-core >= 2.19) only allows bytes|str through # `ansible.plugins.action.ActionBase._transfer_data()`. - - ansible_version.full is version('2.18.999', '>', strict=True) + - ansible_version_major_minor is version('2.19', '>=', strict=True) - not is_mitogen - name: Cleanup transfer data diff --git a/tests/ansible/integration/async/result_shell_echo_hi.yml b/tests/ansible/integration/async/result_shell_echo_hi.yml index d3f9d42c..6e726fc5 100644 --- a/tests/ansible/integration/async/result_shell_echo_hi.yml +++ b/tests/ansible/integration/async/result_shell_echo_hi.yml @@ -35,8 +35,8 @@ # | Ansible <= 3 | ansible-core <= 2.10 | present | True | # | Ansible 4 - 6 | ansible-core 2.11 - 2.13 | deprecated | False | # | Ansible >= 7 | ansible-core >= 2.14 | absent | n/a | - - (ansible_version.full is version("2.14", ">=", strict=True) and async_out.invocation.module_args.warn is not defined) - or (ansible_version.full is version("2.11", ">=", strict=True) and async_out.invocation.module_args.warn == False) + - (ansible_version_major_minor is version("2.14", ">=", strict=True) and async_out.invocation.module_args.warn is not defined) + or (ansible_version_major_minor is version("2.11", ">=", strict=True) and async_out.invocation.module_args.warn == False) or (async_out.invocation.module_args.warn == True) - async_out.rc == 0 - async_out.start.startswith("20") @@ -53,7 +53,7 @@ fail_msg: | async_out={{ async_out }} when: - - ansible_version.full is version('2.4', '>=', strict=True) + - ansible_version_major_minor is version('2.4', '>=', strict=True) vars: async_out: "{{result.content|b64decode|from_json}}" tags: diff --git a/tests/ansible/integration/async/runner_one_job.yml b/tests/ansible/integration/async/runner_one_job.yml index de7a22e6..db9b126f 100644 --- a/tests/ansible/integration/async/runner_one_job.yml +++ b/tests/ansible/integration/async/runner_one_job.yml @@ -41,9 +41,9 @@ - result1.changed == True # ansible/b72e989e1837ccad8dcdc926c43ccbc4d8cdfe44 - | - (ansible_version.full is version('2.8', ">=", strict=True) and + (ansible_version_major_minor is version('2.8', ">=", strict=True) and result1.cmd == "echo alldone;\nsleep 1;\n") or - (ansible_version.full is version('2.8', '<', strict=True) and + (ansible_version_major_minor is version('2.8', '<', strict=True) and result1.cmd == "echo alldone;\n sleep 1;") - result1.delta|length == 14 - result1.start|length == 26 @@ -61,7 +61,7 @@ fail_msg: | result1={{ result1 }} when: - - ansible_version.full is version('2.8', '>', strict=True) # ansible#51393 + - ansible_version_major_minor is version('2.8', '>', strict=True) # ansible#51393 - assert: that: @@ -69,6 +69,6 @@ fail_msg: | result1={{ result1 }} when: - - ansible_version.full is version('2.4', '>', strict=True) + - ansible_version_major_minor is version('2.4', '>', strict=True) tags: - runner_one_job diff --git a/tests/ansible/integration/async/runner_two_simultaneous_jobs.yml b/tests/ansible/integration/async/runner_two_simultaneous_jobs.yml index 74a50318..8c462ec2 100644 --- a/tests/ansible/integration/async/runner_two_simultaneous_jobs.yml +++ b/tests/ansible/integration/async/runner_two_simultaneous_jobs.yml @@ -66,6 +66,6 @@ fail_msg: | result2={{ result2 }} when: - - ansible_version.full is version('2.8', '>=', strict=True) # ansible#51393 + - ansible_version_major_minor is version('2.8', '>=', strict=True) # ansible#51393 tags: - runner_two_simultaneous_jobs diff --git a/tests/ansible/integration/connection/reset.yml b/tests/ansible/integration/connection/reset.yml index 2d7a75d3..9dea33ee 100644 --- a/tests/ansible/integration/connection/reset.yml +++ b/tests/ansible/integration/connection/reset.yml @@ -10,11 +10,11 @@ - debug: msg="reset.yml skipped on Ansible<2.5.6" when: - - ansible_version.full is version('2.5.6', '<', strict=True) + - ansible_version_major_minor_patch is version('2.5.6', '<', strict=True) - meta: end_play when: - - ansible_version.full is version('2.5.6', '<', strict=True) + - ansible_version_major_minor_patch is version('2.5.6', '<', strict=True) - custom_python_detect_environment: register: out diff --git a/tests/ansible/integration/connection/reset_become.yml b/tests/ansible/integration/connection/reset_become.yml index 2548df17..0e0aefa9 100644 --- a/tests/ansible/integration/connection/reset_become.yml +++ b/tests/ansible/integration/connection/reset_become.yml @@ -8,11 +8,11 @@ tasks: - debug: msg="reset_become.yml skipped on Ansible<2.5.6" when: - - ansible_version.full is version('2.5.6', '<', strict=True) + - ansible_version_major_minor_patch is version('2.5.6', '<', strict=True) - meta: end_play when: - - ansible_version.full is version('2.5.6', '<', strict=True) + - ansible_version_major_minor_patch is version('2.5.6', '<', strict=True) - name: save pid of the become acct custom_python_detect_environment: diff --git a/tests/ansible/integration/connection_delegation/delegate_to_template.yml b/tests/ansible/integration/connection_delegation/delegate_to_template.yml index 60a67b82..4cff57e1 100644 --- a/tests/ansible/integration/connection_delegation/delegate_to_template.yml +++ b/tests/ansible/integration/connection_delegation/delegate_to_template.yml @@ -19,7 +19,7 @@ - meta: end_play when: - - ansible_version.full is version('2.4', '<', strict=True) + - ansible_version_major_minor is version('2.4', '<', strict=True) - mitogen_get_stack: delegate_to: "{{ physical_host }}" diff --git a/tests/ansible/integration/context_service/disconnect_cleanup.yml b/tests/ansible/integration/context_service/disconnect_cleanup.yml index 22ba12eb..a87dae3d 100644 --- a/tests/ansible/integration/context_service/disconnect_cleanup.yml +++ b/tests/ansible/integration/context_service/disconnect_cleanup.yml @@ -8,7 +8,7 @@ - meta: end_play when: - - ansible_version.full is version('2.5.6', '<', strict=True) + - ansible_version_major_minor_patch is version('2.5.6', '<', strict=True) # Start with a clean slate. - mitogen_shutdown_all: diff --git a/tests/ansible/integration/interpreter_discovery/ansible_2_8_tests.yml b/tests/ansible/integration/interpreter_discovery/ansible_2_8_tests.yml index eddca199..451b4dc3 100644 --- a/tests/ansible/integration/interpreter_discovery/ansible_2_8_tests.yml +++ b/tests/ansible/integration/interpreter_discovery/ansible_2_8_tests.yml @@ -46,9 +46,9 @@ '20': /usr/bin/python3.8 discovered_interpreter_expected: >- - {%- if ansible_version.full is version('2.12', '<', strict=True) -%} + {%- if ansible_version_major_minor is version('2.12', '<', strict=True) -%} {{ DISCOVERED_INTERPRETER_EXPECTED_MAP__ANSIBLE_lt_2_12[distro][distro_major] }} - {%- elif ansible_version.full is version('2.17', '<', strict=True) -%} + {%- elif ansible_version_major_minor is version('2.17', '<', strict=True) -%} {{ DISCOVERED_INTERPRETER_EXPECTED_MAP__ANSIBLE_2_12_to_2_16[distro][distro_major] }} {%- else -%} {{ DISCOVERED_INTERPRETER_EXPECTED_MAP__ANSIBLE_ge_2_17[distro][distro_major] }} @@ -141,7 +141,7 @@ when: - legacy.ansible_facts.discovered_interpreter_python == '/usr/bin/python' - auto_out.ansible_facts.discovered_interpreter_python != '/usr/bin/python' - - ansible_version.full is version_compare('2.12.0', '<', strict=True) + - ansible_version_major_minor is version('2.12', '<', strict=True) - name: check for warning (only on platforms where auto result is not /usr/bin/python and legacy is) from ansible 2.12 on assert: @@ -153,7 +153,7 @@ when: - legacy.ansible_facts.discovered_interpreter_python == '/usr/bin/python' - auto_out.ansible_facts.discovered_interpreter_python != '/usr/bin/python' - - ansible_version.full is version_compare('2.12.0', '>=', strict=True) + - ansible_version_major_minor is version('2.12', '>=', strict=True) - name: test that auto_silent never warns and got the same answer as auto block: @@ -229,6 +229,6 @@ always: - meta: clear_facts when: - - ansible_version.full is version_compare('2.8.0', '>=', strict=True) + - ansible_version_major_minor is version('2.8', '>=', strict=True) tags: - ansible_2_8_tests diff --git a/tests/ansible/integration/interpreter_discovery/complex_args.yml b/tests/ansible/integration/interpreter_discovery/complex_args.yml index f9770876..555a676b 100644 --- a/tests/ansible/integration/interpreter_discovery/complex_args.yml +++ b/tests/ansible/integration/interpreter_discovery/complex_args.yml @@ -14,7 +14,7 @@ - meta: end_play when: - not is_mitogen - - ansible_version.full is version('2.17.1', '>=', strict=True) + - ansible_version_major_minor_patch is version('2.17.1', '>=', strict=True) - name: create temp file to source file: diff --git a/tests/ansible/integration/runner/custom_bash_hashbang_argument.yml b/tests/ansible/integration/runner/custom_bash_hashbang_argument.yml index 34a60e61..c750317a 100644 --- a/tests/ansible/integration/runner/custom_bash_hashbang_argument.yml +++ b/tests/ansible/integration/runner/custom_bash_hashbang_argument.yml @@ -7,7 +7,7 @@ - meta: end_play when: - not is_mitogen - - ansible_version.full is version('2.17.1', '>=', strict=True) + - ansible_version_major_minor_patch is version('2.17.1', '>=', strict=True) - custom_bash_old_style_module: foo: true diff --git a/tests/ansible/integration/runner/custom_perl_json_args_module.yml b/tests/ansible/integration/runner/custom_perl_json_args_module.yml index a34b6b75..c5c647cd 100644 --- a/tests/ansible/integration/runner/custom_perl_json_args_module.yml +++ b/tests/ansible/integration/runner/custom_perl_json_args_module.yml @@ -20,6 +20,6 @@ fail_msg: | out={{ out }} when: - - ansible_version.full is version('2.4', '>=', strict=True) + - ansible_version_major_minor is version('2.4', '>=', strict=True) tags: - custom_perl_json_args_module diff --git a/tests/ansible/integration/runner/custom_perl_want_json_module.yml b/tests/ansible/integration/runner/custom_perl_want_json_module.yml index 28ad7f7f..91ec5672 100644 --- a/tests/ansible/integration/runner/custom_perl_want_json_module.yml +++ b/tests/ansible/integration/runner/custom_perl_want_json_module.yml @@ -20,6 +20,6 @@ fail_msg: | out={{ out }} when: - - ansible_version.full is version('2.4', '>=', strict=True) + - ansible_version_major_minor is version('2.4', '>=', strict=True) tags: - custom_perl_want_json_module diff --git a/tests/ansible/integration/ssh/templated_by_play_taskvar.yml b/tests/ansible/integration/ssh/templated_by_play_taskvar.yml index c5c2e544..714d05dc 100644 --- a/tests/ansible/integration/ssh/templated_by_play_taskvar.yml +++ b/tests/ansible/integration/ssh/templated_by_play_taskvar.yml @@ -32,7 +32,7 @@ when: # https://github.com/ansible/ansible/issues/84238 - not is_mitogen - - ansible_version.full is version('2.19', '<', strict=True) + - ansible_version_major_minor is version('2.19', '<', strict=True) - meta: reset_connection - name: Templated variables in play, key authentication ping: diff --git a/tests/ansible/integration/stub_connections/_end_play_if_not_sudo_linux.yml b/tests/ansible/integration/stub_connections/_end_play_if_not_sudo_linux.yml index a53f75ed..3a4f4e6e 100644 --- a/tests/ansible/integration/stub_connections/_end_play_if_not_sudo_linux.yml +++ b/tests/ansible/integration/stub_connections/_end_play_if_not_sudo_linux.yml @@ -9,7 +9,7 @@ - command: sudo -n whoami args: - warn: "{{ False if ansible_version.full is version('2.10', '<=', strict=True) else omit }}" + warn: "{{ False if ansible_version_major_minor is version('2.10', '<=', strict=True) else omit }}" ignore_errors: true register: sudo_available diff --git a/tests/ansible/integration/stub_connections/kubectl.yml b/tests/ansible/integration/stub_connections/kubectl.yml index 8fe061d1..c9486d90 100644 --- a/tests/ansible/integration/stub_connections/kubectl.yml +++ b/tests/ansible/integration/stub_connections/kubectl.yml @@ -7,7 +7,7 @@ - meta: end_play when: - - ansible_version.full is version('2.5', '<', strict=True) + - ansible_version_major_minor is version('2.5', '<', strict=True) - custom_python_detect_environment: vars: diff --git a/tests/ansible/integration/stub_connections/setns_lxc.yml b/tests/ansible/integration/stub_connections/setns_lxc.yml index f7654ad8..dc7340a8 100644 --- a/tests/ansible/integration/stub_connections/setns_lxc.yml +++ b/tests/ansible/integration/stub_connections/setns_lxc.yml @@ -32,7 +32,7 @@ localhost args: chdir: ../.. - warn: "{{ False if ansible_version.full is version('2.10', '<=', strict=True) else omit }}" + warn: "{{ False if ansible_version_major_minor is version('2.10', '<=', strict=True) else omit }}" register: result - assert: diff --git a/tests/ansible/integration/stub_connections/setns_lxd.yml b/tests/ansible/integration/stub_connections/setns_lxd.yml index c461845e..127941f0 100644 --- a/tests/ansible/integration/stub_connections/setns_lxd.yml +++ b/tests/ansible/integration/stub_connections/setns_lxd.yml @@ -32,7 +32,7 @@ localhost args: chdir: ../.. - warn: "{{ False if ansible_version.full is version('2.10', '<=', strict=True) else omit }}" + warn: "{{ False if ansible_version_major_minor is version('2.10', '<=', strict=True) else omit }}" register: result - assert: diff --git a/tests/ansible/integration/transport_config/password.yml b/tests/ansible/integration/transport_config/password.yml index b447b8b6..34ed1a41 100644 --- a/tests/ansible/integration/transport_config/password.yml +++ b/tests/ansible/integration/transport_config/password.yml @@ -11,11 +11,13 @@ - assert_equal: left: out.result[0].kwargs.password right: null - when: ansible_version.full is version('2.18.999', '>=', strict=True) + when: + - ansible_version_major_minor is version('2.19', '>=', strict=True) - assert_equal: left: out.result[0].kwargs.password right: "" # actually null, but assert_equal limitation - when: ansible_version.full is version('2.18.999', '<', strict=True) + when: + - ansible_version_major_minor is version('2.19', '<', strict=True) tags: - mitogen_only @@ -31,11 +33,13 @@ - assert_equal: left: out.result[1].kwargs.password right: null - when: ansible_version.full is version('2.18.999', '>=', strict=True) + when: + - ansible_version_major_minor is version('2.19', '>=', strict=True) - assert_equal: left: out.result[1].kwargs.password right: "" - when: ansible_version.full is version('2.18.999', '<', strict=True) + when: + - ansible_version_major_minor is version('2.19', '<', strict=True) tags: - mitogen_only @@ -61,11 +65,13 @@ - assert_equal: left: out.result[0].kwargs.password right: null - when: ansible_version.full is version('2.18.999', '>=', strict=True) + when: + - ansible_version_major_minor is version('2.19', '>=', strict=True) - assert_equal: left: out.result[0].kwargs.password right: "" - when: ansible_version.full is version('2.18.999', '<', strict=True) + when: + - ansible_version_major_minor is version('2.19', '<', strict=True) - assert_equal: left: out.result[1].kwargs.password right: "ansi-ssh-pass" @@ -94,11 +100,13 @@ - assert_equal: left: out.result[0].kwargs.password right: null - when: ansible_version.full is version('2.18.999', '>=', strict=True) + when: + - ansible_version_major_minor is version('2.19', '>=', strict=True) - assert_equal: left: out.result[0].kwargs.password right: "" - when: ansible_version.full is version('2.18.999', '<', strict=True) + when: + - ansible_version_major_minor is version('2.19', '<', strict=True) - assert_equal: left: out.result[1].kwargs.password right: "ansi-pass" @@ -127,11 +135,13 @@ - assert_equal: left: out.result[0].kwargs.password right: null - when: ansible_version.full is version('2.18.999', '>=', strict=True) + when: + - ansible_version_major_minor is version('2.19', '>=', strict=True) - assert_equal: left: out.result[0].kwargs.password right: "" - when: ansible_version.full is version('2.18.999', '<', strict=True) + when: + - ansible_version_major_minor is version('2.19', '<', strict=True) - assert_equal: left: out.result[1].kwargs.password right: "c.b.a" diff --git a/tests/ansible/integration/transport_config/python_path.yml b/tests/ansible/integration/transport_config/python_path.yml index 21f3928c..b8bb286b 100644 --- a/tests/ansible/integration/transport_config/python_path.yml +++ b/tests/ansible/integration/transport_config/python_path.yml @@ -12,7 +12,7 @@ - include_tasks: ../_mitogen_only.yml - meta: end_play when: - - ansible_version.full is version('2.17', '>=', strict=True) + - ansible_version_major_minor is version('2.17', '>=', strict=True) - {mitogen_get_stack: {}, register: out} - assert_equal: left: out.result[0].kwargs.python_path @@ -27,7 +27,7 @@ - include_tasks: ../_mitogen_only.yml - meta: end_play when: - - ansible_version.full is version('2.17', '>=', strict=True) + - ansible_version_major_minor is version('2.17', '>=', strict=True) - {mitogen_get_stack: {}, register: out} - assert_equal: left: out.result[0].kwargs.python_path @@ -57,7 +57,7 @@ - include_tasks: ../_mitogen_only.yml - meta: end_play when: - - ansible_version.full is version('2.17', '>=', strict=True) + - ansible_version_major_minor is version('2.17', '>=', strict=True) - {mitogen_get_stack: {}, register: out} - assert_equal: left: out.result[0].kwargs.python_path @@ -87,7 +87,7 @@ - include_tasks: ../_mitogen_only.yml - meta: end_play when: - - ansible_version.full is version('2.17', '>=', strict=True) + - ansible_version_major_minor is version('2.17', '>=', strict=True) - {mitogen_get_stack: {}, register: out} - assert_equal: left: out.result[0].kwargs.python_path diff --git a/tests/ansible/regression/issue_1066__add_host__host_key_checking.yml b/tests/ansible/regression/issue_1066__add_host__host_key_checking.yml index dd754f84..cdc50fc3 100644 --- a/tests/ansible/regression/issue_1066__add_host__host_key_checking.yml +++ b/tests/ansible/regression/issue_1066__add_host__host_key_checking.yml @@ -31,7 +31,7 @@ # FIXME https://github.com/mitogen-hq/mitogen/issues/1096 - meta: end_play when: - - ansible_version.full is version('2.17', '>=', strict=True) + - ansible_version_major_minor is version('2.17', '>=', strict=True) - meta: reset_connection # The host key might be in ~/.ssh/known_hosts. If it's removed then no @@ -65,7 +65,7 @@ # ansible_host_key_checking don't work on Vanilla Ansible 2.10, even for # static inventory hosts (ansible/ansible#49254, ansible/ansible#73708). when: - - ansible_version.full is version('2.11', '>=', strict=True) + - ansible_version_major_minor is version('2.11', '>=', strict=True) or is_mitogen tags: - issue_1066 diff --git a/tests/ansible/regression/issue_109__target_has_old_ansible_installed.yml b/tests/ansible/regression/issue_109__target_has_old_ansible_installed.yml index 92bdfd7e..550a7f4c 100644 --- a/tests/ansible/regression/issue_109__target_has_old_ansible_installed.yml +++ b/tests/ansible/regression/issue_109__target_has_old_ansible_installed.yml @@ -7,7 +7,7 @@ tasks: - meta: end_play when: - - ansible_version.full is version('2.6', '<', strict=True) + - ansible_version_major_minor is version('2.6', '<', strict=True) - name: Copy the naughty ansible into place copy: diff --git a/tests/ansible/regression/issue_590__sys_modules_crap.yml b/tests/ansible/regression/issue_590__sys_modules_crap.yml index 2c2262f4..f2bda94c 100644 --- a/tests/ansible/regression/issue_590__sys_modules_crap.yml +++ b/tests/ansible/regression/issue_590__sys_modules_crap.yml @@ -3,7 +3,7 @@ tasks: - meta: end_play when: - - ansible_version.full is version('2.8', '<', strict=True) + - ansible_version_major_minor is version('2.8', '<', strict=True) - custom_python_uses_distro: register: out diff --git a/tests/ansible/regression/issue_655__wait_for_connection_error.yml b/tests/ansible/regression/issue_655__wait_for_connection_error.yml index 506d5516..297b6043 100644 --- a/tests/ansible/regression/issue_655__wait_for_connection_error.yml +++ b/tests/ansible/regression/issue_655__wait_for_connection_error.yml @@ -22,7 +22,7 @@ when: # Ansible 10 (ansible-core 2.17+) require Python 3.7+ on targets. # On CentOS 8 /usr/libexec/platform-python is Python 3.6 - - ansible_version.full is version('2.17', '>=', strict=True) + - ansible_version_major_minor is version('2.17', '>=', strict=True) - name: set up test container and run tests inside it block: diff --git a/tests/ansible/regression/issue_766__get_with_context.yml b/tests/ansible/regression/issue_766__get_with_context.yml index 09556939..5dae142f 100644 --- a/tests/ansible/regression/issue_766__get_with_context.yml +++ b/tests/ansible/regression/issue_766__get_with_context.yml @@ -25,15 +25,15 @@ # with Ansible 4 (ansible-core 2.11) & associated collections. # ansible.module_utils.connection.ConnectionError: Method not found # https://github.com/mitogen-hq/mitogen/actions/runs/12854359099/job/35838635886 - - ansible_version.full is version('2.11', '>=', strict=True) - - ansible_version.full is version('2.12', '<', strict=True) + - ansible_version_major_minor is version('2.11', '>=', strict=True) + - ansible_version_major_minor is version('2.12', '<', strict=True) - meta: end_play when: # TASK [Get running configuration and state data ] # Error: : Task failed: ActionBase._parse_returned_data() missing 1 required positional argument: 'profile' # https://github.com/ansible-collections/ansible.netcommon/issues/698#issuecomment-2910082548 - - ansible_version.full is version('2.18.999', '>=', strict=True) + - ansible_version_major_minor is version('2.19', '>=', strict=True) - block: - name: Start container diff --git a/tests/ansible/regression/issue_776__load_plugins_called_twice.yml b/tests/ansible/regression/issue_776__load_plugins_called_twice.yml index d482c41c..4a4cf7be 100755 --- a/tests/ansible/regression/issue_776__load_plugins_called_twice.yml +++ b/tests/ansible/regression/issue_776__load_plugins_called_twice.yml @@ -17,7 +17,7 @@ # support Python 2.x on targets. - meta: end_play when: - - ansible_version.full is version('2.17', '>=', strict=True) + - ansible_version_major_minor is version('2.17', '>=', strict=True) roles: - role: package_manager diff --git a/tests/image_prep/_container_setup.yml b/tests/image_prep/_container_setup.yml index 4aa3b46d..b95d67a9 100644 --- a/tests/image_prep/_container_setup.yml +++ b/tests/image_prep/_container_setup.yml @@ -66,7 +66,7 @@ dnf: dnf clean all command: "{{ clean_command[ansible_pkg_mgr] }}" args: - warn: "{{ False if ansible_version.full is version('2.10', '<=', strict=True) else omit }}" + warn: "{{ False if ansible_version_major_minor is version('2.10', '<=', strict=True) else omit }}" - name: Clean up apt package lists shell: rm -rf {{item}}/* diff --git a/tests/image_prep/group_vars/all.yml b/tests/image_prep/group_vars/all.yml index 91ff934d..6545e432 100644 --- a/tests/image_prep/group_vars/all.yml +++ b/tests/image_prep/group_vars/all.yml @@ -1,3 +1,5 @@ +ansible_version_major_minor: "{{ ansible_version.major }}.{{ ansible_version.minor }}" + common_packages: - openssh-server - rsync From 55b0ece0e79ee208e7872452d2830efbae66d9c0 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Thu, 19 Jun 2025 12:55:19 +0100 Subject: [PATCH 3/8] CI: Test SSH password authentication without sshpass command Ansible 12 (ansible-core 2.19) has gained support for specifying an SSH password, without requiring `sshpass`. It specifies the environment variable `SSH_ASKPASS` such that `ansible` itself is called. Mitogen is already able to support this. This change provides test coverage of the new feature by not installing `sshpass` on macOS runners. when Ansible 12 is under test. Ubuntu runners come with `sshpass` pre-installed. Required Ansible is also bumped to the latest pre-releases, for relevant fixes. --- .ci/install_sshpass | 18 ++++++++++++++++++ .ci/localhost_ansible_tests.py | 11 ----------- .github/workflows/tests.yml | 4 ++++ docs/changelog.rst | 2 ++ tests/ansible/integration/ssh/password.yml | 9 +++++++++ tox.ini | 6 ++---- 6 files changed, 35 insertions(+), 15 deletions(-) create mode 100755 .ci/install_sshpass diff --git a/.ci/install_sshpass b/.ci/install_sshpass new file mode 100755 index 00000000..05d7ebd6 --- /dev/null +++ b/.ci/install_sshpass @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +VERSION="$1" + +curl \ + --fail \ + --location \ + --no-progress-meter \ + --remote-name \ + "https://downloads.sourceforge.net/project/sshpass/sshpass/${VERSION}/sshpass-${VERSION}.tar.gz" +tar xvf "sshpass-${VERSION}.tar.gz" +cd "sshpass-${VERSION}" +./configure +sudo make install diff --git a/.ci/localhost_ansible_tests.py b/.ci/localhost_ansible_tests.py index 359dc195..9203f120 100755 --- a/.ci/localhost_ansible_tests.py +++ b/.ci/localhost_ansible_tests.py @@ -17,17 +17,6 @@ with ci_lib.Fold('unit_tests'): with ci_lib.Fold('job_setup'): os.chmod(ci_lib.TESTS_SSH_PRIVATE_KEY_FILE, int('0600', 8)) - # NOTE: sshpass v1.06 causes errors so pegging to 1.05 -> "msg": "Error when changing password","out": "passwd: DS error: eDSAuthFailed\n", - # there's a checksum error with "brew install http://git.io/sshpass.rb" though, so installing manually - if not ci_lib.exists_in_path('sshpass'): - subprocess.check_call( - "curl -O -L https://sourceforge.net/projects/sshpass/files/sshpass/1.05/sshpass-1.05.tar.gz && \ - tar xvf sshpass-1.05.tar.gz && \ - cd sshpass-1.05 && \ - ./configure && \ - sudo make install", - shell=True, - ) with ci_lib.Fold('machine_prep'): diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b48576ab..ac00d84b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -274,9 +274,11 @@ jobs: tox_env: py313-mode_mitogen - name: Loc_313_11 + sshpass_version: "1.10" tox_env: py313-mode_localhost-ansible11 - name: Van_313_11 + sshpass_version: "1.10" tox_env: py313-mode_localhost-ansible11-strategy_linear - name: Loc_313_12 @@ -317,6 +319,8 @@ jobs: # GitHub macOS 12 images: python2.7 is installed, but not on $PATH echo "/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7: sys.executable: $(/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7 -c 'import sys; print(sys.executable)')" fi + - run: .ci/install_sshpass ${{ matrix.sshpass_version }} + if: ${{ matrix.sshpass_version }} - name: Install tooling run: | set -o errexit -o nounset -o pipefail diff --git a/docs/changelog.rst b/docs/changelog.rst index bd98a835..c7b7ae49 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -36,6 +36,8 @@ to strategy plugins under :gh:issue:`1278`. instead of deprecated `stdout_callback = yaml` * :gh:issue:`1293` CI: Fix ``ansible_version`` comparisons when an Ansible release candidate is under test +* :gh:issue:`1275` CI: Test ``ansible_ssh_password`` behaviour without + ``sshpass`` installed v0.3.25a2 (2025-06-21) diff --git a/tests/ansible/integration/ssh/password.yml b/tests/ansible/integration/ssh/password.yml index 21ab6f15..ca08fa5b 100644 --- a/tests/ansible/integration/ssh/password.yml +++ b/tests/ansible/integration/ssh/password.yml @@ -31,6 +31,11 @@ - assert: that: - ssh_no_password_result.unreachable == True + - >- + ssh_no_password_result.msg is search('SSH password was requested, but none specified') + or ssh_no_password_result.msg is search('SSH password is incorrect') + or ssh_no_password_result.msg is search('Invalid/incorrect password') + or ssh_no_password_result.msg is search('Permission denied \(publickey,password(,keyboard-interactive)?\)') fail_msg: | ssh_no_password_result={{ ssh_no_password_result }} @@ -64,5 +69,9 @@ - assert: that: - ssh_wrong_password_result.unreachable == True + - >- + ssh_wrong_password_result.msg is search('SSH password is incorrect') + or ssh_wrong_password_result.msg is search('Invalid/incorrect password') + or ssh_wrong_password_result.msg is search('Permission denied \(publickey,password(,keyboard-interactive)?\)') fail_msg: | ssh_wrong_password_result={{ ssh_wrong_password_result }} diff --git a/tox.ini b/tox.ini index 3cad99c0..e2714b5e 100644 --- a/tox.ini +++ b/tox.ini @@ -88,10 +88,8 @@ deps = ansible9: ansible~=9.0 ansible10: ansible~=10.0 ansible11: ansible~=11.0 - ansible12: ansible>=12.0a - # Avoid yaml callback bug, https://github.com/mitogen-hq/mitogen/issues/1284 - ansible12: ansible!=12.0a6 - ansible12: ansible-core!=2.19b6 + ansible12: ansible>=12.0a7 + ansible12: ansible-core>=2.19rc1 install_command = python -m pip --no-python-version-warning --disable-pip-version-check install {opts} {packages} commands_pre = From c1296b5d75db3fb4654062518d12151af20c17ac Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Wed, 2 Jul 2025 11:29:37 +0100 Subject: [PATCH 4/8] 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 }} From 945933854ab6525be492a6151354fe742422910c Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Wed, 2 Jul 2025 21:36:53 +0100 Subject: [PATCH 5/8] Prepare v0.3.25a3 --- docs/changelog.rst | 4 ++++ mitogen/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index f2de5561..2593fbd2 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -32,6 +32,10 @@ Running Ansible 12 + Mitogen will currently print a deprecation warning Ansible + Mitogen will still work for now. Mitogen is considering alternatives to strategy plugins under :gh:issue:`1278`. + +v0.3.25a3 (2025-07-02) +---------------------- + * :gh:issue:`1285` CI: use `result_format = yaml` for Ansible test output, instead of deprecated `stdout_callback = yaml` * :gh:issue:`1293` CI: Fix ``ansible_version`` comparisons when an Ansible diff --git a/mitogen/__init__.py b/mitogen/__init__.py index baa59b45..5e0bbe0e 100644 --- a/mitogen/__init__.py +++ b/mitogen/__init__.py @@ -35,7 +35,7 @@ be expected. On the slave, it is built dynamically during startup. #: Library version as a tuple. -__version__ = (0, 3, 25, 'dev') +__version__ = (0, 3, 25, 'a3') #: This is :data:`False` in slave contexts. Previously it was used to prevent From 809094303116c399e1989aef1466b4c125483b27 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Wed, 2 Jul 2025 21:37:37 +0100 Subject: [PATCH 6/8] Resume 0.3.25dev --- mitogen/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mitogen/__init__.py b/mitogen/__init__.py index 5e0bbe0e..baa59b45 100644 --- a/mitogen/__init__.py +++ b/mitogen/__init__.py @@ -35,7 +35,7 @@ be expected. On the slave, it is built dynamically during startup. #: Library version as a tuple. -__version__ = (0, 3, 25, 'a3') +__version__ = (0, 3, 25, 'dev') #: This is :data:`False` in slave contexts. Previously it was used to prevent From 8ccaa48d2a10ef02ccc2ac883e05702378f52fa8 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Wed, 2 Jul 2025 22:25:11 +0100 Subject: [PATCH 7/8] Correct v0.3.25a3 __version__ tuple --- mitogen/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mitogen/__init__.py b/mitogen/__init__.py index baa59b45..042a0f12 100644 --- a/mitogen/__init__.py +++ b/mitogen/__init__.py @@ -35,7 +35,7 @@ be expected. On the slave, it is built dynamically during startup. #: Library version as a tuple. -__version__ = (0, 3, 25, 'dev') +__version__ = (0, 3, 25, 'a', 3) #: This is :data:`False` in slave contexts. Previously it was used to prevent From d4adce5d7eceeb5fb1d719e5ca5a1103ee463df5 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Wed, 2 Jul 2025 22:25:31 +0100 Subject: [PATCH 8/8] Resume 0.3.25dev --- mitogen/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mitogen/__init__.py b/mitogen/__init__.py index 042a0f12..baa59b45 100644 --- a/mitogen/__init__.py +++ b/mitogen/__init__.py @@ -35,7 +35,7 @@ be expected. On the slave, it is built dynamically during startup. #: Library version as a tuple. -__version__ = (0, 3, 25, 'a', 3) +__version__ = (0, 3, 25, 'dev') #: This is :data:`False` in slave contexts. Previously it was used to prevent