From 55b0ece0e79ee208e7872452d2830efbae66d9c0 Mon Sep 17 00:00:00 2001 From: Alex Willmer Date: Thu, 19 Jun 2025 12:55:19 +0100 Subject: [PATCH] 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 =