add the wsl connection plugin (#9795)

* add the wsl connection plugin

* move the banner_timeout required paramiko version to its own line

* document the proxy_command required paramiko version

* document the timeout required paramiko version

* simplify the sending of the become_pass value

* add Connection.__init__ type hints

* add MyAddPolicy.missing_host_key type hints

* normalize the Connection._parse_proxy_command replacers dict values to the str type

* add the user_known_hosts_file option

* modify the private_key_file option type to path
This commit is contained in:
Rui Lopes 2025-04-19 08:01:36 +01:00 committed by GitHub
commit 96b493002c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 1551 additions and 0 deletions

View file

@ -0,0 +1,11 @@
# Derived from ../connection_proxmox_pct_remote/aliases Copyright (c) 2025 Nils Stein (@mietzen) <github.nstein@mailbox.org>
# Copyright (c) 2025 Rui Lopes (@rgl) <ruilopes.com>
# Copyright (c) 2025 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
azp/posix/3
destructive
needs/root
needs/target/connection
skip/macos

View file

@ -0,0 +1,19 @@
---
# Derived from ../connection_proxmox_pct_remote/dependencies.yml Copyright (c) 2025 Nils Stein (@mietzen) <github.nstein@mailbox.org>
# Copyright (c) 2025 Rui Lopes (@rgl) <ruilopes.com>
# Copyright (c) 2025 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- hosts: localhost
gather_facts: true
serial: 1
tasks:
- name: Copy wsl.exe mock
copy:
src: files/wsl.exe
dest: /usr/local/bin/wsl.exe
mode: '0755'
- name: Install paramiko
pip:
name: "paramiko>=3.0.0"

View file

@ -0,0 +1,72 @@
#!/usr/bin/env bash
# Derived from ../../connection_proxmox_pct_remote/files/pct Copyright (c) 2025 Nils Stein (@mietzen) <github.nstein@mailbox.org>
# Copyright (c) 2025 Rui Lopes (@rgl) <ruilopes.com>
# Copyright (c) 2025 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Shell script to mock wsl.exe behavior
set -euo pipefail
function quote_args {
local quoted_args=()
for arg in "$@"; do
if [[ -z "$arg" || "$arg" =~ [^a-zA-Z0-9@%+=:,./-] ]]; then
local escaped_arg=${arg//\'/\'\\\'\'}
quoted_args+=("'$escaped_arg'")
else
quoted_args+=("$arg")
fi
done
echo -n "${quoted_args[@]}"
}
declare -a mock_args=()
declare -a cmd_args=()
wsl_distribution=""
wsl_user=""
while [[ $# -gt 0 ]]; do
case $1 in
--distribution|-d)
wsl_distribution="$2"
mock_args+=("$1" "$2")
shift 2
;;
--user|-u)
wsl_user="$2"
mock_args+=("$1" "$2")
shift 2
;;
--)
mock_args+=("$1")
shift
while [[ $# -gt 0 ]]; do
mock_args+=("$1")
cmd_args+=("$1")
shift
done
;;
*)
>&2 echo "unexpected args: $@"
exit 1
;;
esac
done
mock_cmd="wsl.exe $(quote_args "${mock_args[@]}")"
cmd="$(quote_args "${cmd_args[@]}")"
>&2 echo "[INFO] MOCKING: $mock_cmd"
>&2 echo "[INFO] CMD: $cmd"
tmp_dir="/tmp/ansible-remote/wsl/integration_test/wsl_distribution_${wsl_distribution}"
mkdir -p "$tmp_dir"
pushd "$tmp_dir" >/dev/null
eval "$cmd"
popd >/dev/null

View file

@ -0,0 +1,31 @@
---
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
- hosts: "{{ target_hosts }}"
gather_facts: false
tasks:
- name: create file without content
copy:
content: ""
dest: "{{ remote_tmp }}/test_empty.txt"
force: no
mode: '0644'
- name: assert file without content exists
stat:
path: "{{ remote_tmp }}/test_empty.txt"
register: empty_file_stat
- name: verify file without content exists
assert:
that:
- empty_file_stat.stat.exists
fail_msg: "The file {{ remote_tmp }}/test_empty.txt does not exist."
- name: verify file without content is empty
assert:
that:
- empty_file_stat.stat.size == 0
fail_msg: "The file {{ remote_tmp }}/test_empty.txt is not empty."

View file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Derived from ../connection_proxmox_pct_remote/runme.sh Copyright (c) 2025 Nils Stein (@mietzen) <github.nstein@mailbox.org>
# Copyright (c) 2025 Rui Lopes (@rgl) <ruilopes.com>
# Copyright (c) 2025 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
set -eux
# signal the wsl connection plugin that its running under the integration testing mode.
# NB while running integration tests, the mock wsl.exe implementation is actually
# running on unix, instead of on running windows, so the wsl.exe command line
# construction must use unix rules instead of windows rules.
export _ANSIBLE_TEST_WSL_CONNECTION_PLUGIN_Waeri5tepheeSha2fae8=1
ANSIBLE_ROLES_PATH=../ \
ansible-playbook dependencies.yml -v "$@"
./test.sh "$@"
ansible-playbook plugin-specific-tests.yml -i "./test_connection.inventory" \
-e target_hosts=wsl \
-e action_prefix= \
-e local_tmp=/tmp/ansible-local \
-e remote_tmp=/tmp/ansible-remote \
"$@"

View file

@ -0,0 +1 @@
../connection_posix/test.sh

View file

@ -0,0 +1,15 @@
# Derived from ../connection_proxmox_pct_remote/test_connection.inventory Copyright (c) 2025 Nils Stein (@mietzen) <github.nstein@mailbox.org>
# Copyright (c) 2025 Rui Lopes (@rgl) <ruilopes.com>
# Copyright (c) 2025 Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
[wsl]
wsl-pipelining ansible_ssh_pipelining=true
wsl-no-pipelining ansible_ssh_pipelining=false
[wsl:vars]
ansible_host=localhost
ansible_user=root
ansible_python_interpreter="{{ ansible_playbook_python }}"
ansible_connection=community.general.wsl
wsl_distribution=test