initial project commit
This commit is contained in:
6
collections/ansible_collections/community/general/tests/.gitignore
vendored
Normal file
6
collections/ansible_collections/community/general/tests/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
# 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
|
||||
|
||||
output/
|
||||
integration/inventory
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
# See template for more information:
|
||||
# https://github.com/ansible/ansible/blob/devel/test/lib/ansible_test/config/config.yml
|
||||
modules:
|
||||
python_requires: default
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
collections:
|
||||
- ansible.posix
|
||||
- community.crypto
|
||||
- community.docker
|
@ -0,0 +1,6 @@
|
||||
# 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
|
||||
|
||||
# No AIX LPAR available
|
||||
unsupported
|
@ -0,0 +1,81 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# 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
|
||||
|
||||
- name: Scan new devices.
|
||||
aix_devices:
|
||||
device: all
|
||||
state: present
|
||||
|
||||
- name: Scan new virtual devices (vio0).
|
||||
aix_devices:
|
||||
device: vio0
|
||||
state: present
|
||||
|
||||
- name: Removing IP alias to en0
|
||||
aix_devices:
|
||||
device: en0
|
||||
attributes:
|
||||
delalias4: 10.0.0.100,255.255.255.0
|
||||
|
||||
- name: Removes ent2.
|
||||
aix_devices:
|
||||
device: ent2
|
||||
state: absent
|
||||
|
||||
- name: Put device en2 in Defined
|
||||
aix_devices:
|
||||
device: en2
|
||||
state: defined
|
||||
|
||||
- name: Removes ent4 (inexistent).
|
||||
aix_devices:
|
||||
device: ent4
|
||||
state: absent
|
||||
|
||||
- name: Put device en4 in Defined (inexistent)
|
||||
aix_devices:
|
||||
device: en4
|
||||
state: defined
|
||||
|
||||
- name: Put vscsi1 and children devices in Defined state.
|
||||
aix_devices:
|
||||
device: vscsi1
|
||||
recursive: true
|
||||
state: defined
|
||||
|
||||
- name: Removes vscsi1 and children devices.
|
||||
aix_devices:
|
||||
device: vscsi1
|
||||
recursive: true
|
||||
state: absent
|
||||
|
||||
- name: Changes en1 mtu to 9000 and disables arp.
|
||||
aix_devices:
|
||||
device: en1
|
||||
attributes:
|
||||
mtu: 900
|
||||
arp: 'off'
|
||||
state: present
|
||||
|
||||
- name: Configure IP, netmask and set en1 up.
|
||||
aix_devices:
|
||||
device: en1
|
||||
attributes:
|
||||
netaddr: 192.168.0.100
|
||||
netmask: 255.255.255.0
|
||||
state: up
|
||||
state: present
|
||||
|
||||
- name: Adding IP alias to en0
|
||||
aix_devices:
|
||||
device: en0
|
||||
attributes:
|
||||
alias4: 10.0.0.100,255.255.255.0
|
||||
state: present
|
@ -0,0 +1,5 @@
|
||||
# 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
|
||||
|
||||
unsupported
|
@ -0,0 +1,130 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# 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
|
||||
|
||||
- name: Umounting /testfs
|
||||
aix_filesystem:
|
||||
filesystem: /testfs
|
||||
state: unmounted
|
||||
|
||||
- name: Removing /testfs
|
||||
aix_filesystem:
|
||||
filesystem: /testfs
|
||||
state: absent
|
||||
|
||||
- name: Creating a new file system
|
||||
aix_filesystem:
|
||||
filesystem: /newfs
|
||||
size: 1G
|
||||
state: present
|
||||
vg: datavg
|
||||
|
||||
# It requires a host (nfshost) exporting the NFS
|
||||
- name: Creating NFS filesystem from nfshost (Linux NFS server)
|
||||
aix_filesystem:
|
||||
device: /home/ftp
|
||||
nfs_server: nfshost
|
||||
filesystem: /nfs/ftp
|
||||
state: present
|
||||
|
||||
# It requires a volume group named datavg (next three actions)
|
||||
- name: Creating a logical volume testlv (aix_lvol module)
|
||||
aix_lvol:
|
||||
vg: datavg
|
||||
lv: testlv
|
||||
size: 2G
|
||||
state: present
|
||||
|
||||
- name: Create filesystem in a previously defined logical volume
|
||||
aix_filesystem:
|
||||
device: testlv
|
||||
filesystem: /testfs
|
||||
state: present
|
||||
|
||||
- name: Create an already existing filesystem using existing logical volume.
|
||||
aix_filesystem:
|
||||
vg: datavg
|
||||
device: mksysblv
|
||||
filesystem: /mksysb
|
||||
state: present
|
||||
|
||||
- name: Create a filesystem in a non-existing VG
|
||||
aix_filesystem:
|
||||
vg: nonexistvg
|
||||
filesystem: /newlv
|
||||
state: present
|
||||
|
||||
- name: Resizing /mksysb to 1G
|
||||
aix_filesystem:
|
||||
filesystem: /mksysb
|
||||
size: 1G
|
||||
state: present
|
||||
|
||||
- name: Resizing /mksysb to +512M
|
||||
aix_filesystem:
|
||||
filesystem: /mksysb
|
||||
size: +512M
|
||||
state: present
|
||||
|
||||
- name: Resizing /mksysb to 11G
|
||||
aix_filesystem:
|
||||
filesystem: /mksysb
|
||||
size: 11G
|
||||
state: present
|
||||
|
||||
- name: Resizing /mksysb to 11G (already done)
|
||||
aix_filesystem:
|
||||
filesystem: /mksysb
|
||||
size: 11G
|
||||
state: present
|
||||
|
||||
- name: Resizing /mksysb to -2G
|
||||
aix_filesystem:
|
||||
filesystem: /mksysb
|
||||
size: -2G
|
||||
state: present
|
||||
|
||||
- name: Resizing /mksysb to 100G (not enough space)
|
||||
aix_filesystem:
|
||||
filesystem: /mksysb
|
||||
size: +100G
|
||||
state: present
|
||||
|
||||
- name: Unmount filesystem /home/ftp
|
||||
aix_filesystem:
|
||||
filesystem: /home/ftp
|
||||
state: unmounted
|
||||
|
||||
- name: Remove NFS filesystem /home/ftp
|
||||
aix_filesystem:
|
||||
filesystem: /home/ftp
|
||||
rm_mount_point: true
|
||||
state: absent
|
||||
|
||||
- name: Mount filesystem /newfs
|
||||
aix_filesystem:
|
||||
filesystem: /newfs
|
||||
state: mounted
|
||||
|
||||
- name: Remove mounted /newfs
|
||||
aix_filesystem:
|
||||
filesystem: /newfs
|
||||
rm_mount_point: true
|
||||
state: absent
|
||||
|
||||
- name: Umount /newfs
|
||||
aix_filesystem:
|
||||
filesystem: /newfs
|
||||
state: unmounted
|
||||
|
||||
- name: Remove /newfs
|
||||
aix_filesystem:
|
||||
filesystem: /newfs
|
||||
rm_mount_point: true
|
||||
state: absent
|
@ -0,0 +1,6 @@
|
||||
# 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
|
||||
|
||||
azp/posix/1
|
||||
disabled
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
alerta_url: http://localhost:8080/
|
||||
alerta_user: admin@example.com
|
||||
alerta_password: password
|
||||
alerta_key: demo-key
|
@ -0,0 +1,156 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# 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
|
||||
|
||||
- name: Create customer (check mode)
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_username: "{{ alerta_user }}"
|
||||
api_password: "{{ alerta_password }}"
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
check_mode: true
|
||||
register: result
|
||||
|
||||
- name: Check result (check mode)
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Create customer
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_username: "{{ alerta_user }}"
|
||||
api_password: "{{ alerta_password }}"
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
register: result
|
||||
|
||||
- name: Check customer creation
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Test customer creation idempotency
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_username: "{{ alerta_user }}"
|
||||
api_password: "{{ alerta_password }}"
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
register: result
|
||||
|
||||
- name: Check customer creation idempotency
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Delete customer (check mode)
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_username: "{{ alerta_user }}"
|
||||
api_password: "{{ alerta_password }}"
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
state: absent
|
||||
check_mode: true
|
||||
register: result
|
||||
|
||||
- name: Check customer deletion (check mode)
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Delete customer
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_username: "{{ alerta_user }}"
|
||||
api_password: "{{ alerta_password }}"
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- name: Check customer deletion
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Test customer deletion idempotency
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_username: "{{ alerta_user }}"
|
||||
api_password: "{{ alerta_password }}"
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- name: Check customer deletion idempotency
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Delete non-existing customer (check mode)
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_username: "{{ alerta_user }}"
|
||||
api_password: "{{ alerta_password }}"
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
state: absent
|
||||
check_mode: true
|
||||
register: result
|
||||
|
||||
- name: Check non-existing customer deletion (check mode)
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Create customer with api key
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_key: "{{ alerta_key }}"
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
register: result
|
||||
|
||||
- name: Check customer creation with api key
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Delete customer with api key
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_key: "{{ alerta_key }}"
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- name: Check customer deletion with api key
|
||||
assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Use wrong api key
|
||||
alerta_customer:
|
||||
alerta_url: "{{ alerta_url }}"
|
||||
api_key: wrong_key
|
||||
customer: customer1
|
||||
match: admin@admin.admin
|
||||
register: result
|
||||
ignore_errors: true
|
||||
|
||||
- name: Check customer creation with api key
|
||||
assert:
|
||||
that:
|
||||
- result is not changed
|
||||
- result is failed
|
@ -0,0 +1,11 @@
|
||||
# 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
|
||||
|
||||
azp/posix/3
|
||||
destructive
|
||||
needs/root
|
||||
skip/aix
|
||||
skip/freebsd
|
||||
skip/osx
|
||||
skip/macos
|
@ -0,0 +1,93 @@
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# Copyright (c) 2017 Pierre-Louis Bonicoli <pierre-louis.bonicoli@libregerbil.fr>
|
||||
# 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
|
||||
|
||||
- name: 'setup: create a dummy alternative'
|
||||
block:
|
||||
- import_tasks: setup.yml
|
||||
|
||||
##############
|
||||
# Test parameters:
|
||||
# link parameter present / absent ('with_link' variable)
|
||||
# with / without alternatives defined in alternatives file ('with_alternatives' variable)
|
||||
# auto / manual ('mode' variable)
|
||||
|
||||
- include_tasks: tests.yml
|
||||
with_nested:
|
||||
- [ true, false ] # with_link
|
||||
- [ true, false ] # with_alternatives
|
||||
- [ 'auto', 'manual' ] # mode
|
||||
loop_control:
|
||||
loop_var: test_conf
|
||||
|
||||
##########
|
||||
# Priority
|
||||
- block:
|
||||
- include_tasks: remove_links.yml
|
||||
- include_tasks: setup_test.yml
|
||||
# at least two iterations again
|
||||
- include_tasks: tests_set_priority.yml
|
||||
with_sequence: start=3 end=4
|
||||
vars:
|
||||
with_alternatives: true
|
||||
mode: auto
|
||||
|
||||
- block:
|
||||
- include_tasks: remove_links.yml
|
||||
- include_tasks: setup_test.yml
|
||||
# at least two iterations again
|
||||
- include_tasks: tests_set_priority.yml
|
||||
with_sequence: start=3 end=4
|
||||
vars:
|
||||
with_alternatives: false
|
||||
mode: auto
|
||||
|
||||
# Test that path is checked: alternatives must fail when path is nonexistent
|
||||
- import_tasks: path_is_checked.yml
|
||||
|
||||
# Test that subcommands commands work
|
||||
- import_tasks: subcommands.yml
|
||||
|
||||
# Test operation of the 'state' parameter
|
||||
- block:
|
||||
- include_tasks: remove_links.yml
|
||||
- include_tasks: tests_state.yml
|
||||
|
||||
# Cleanup
|
||||
always:
|
||||
- include_tasks: remove_links.yml
|
||||
|
||||
- file:
|
||||
path: '{{ item }}'
|
||||
state: absent
|
||||
with_items:
|
||||
- '{{ alternatives_dir }}/dummy'
|
||||
- '{{ alternatives_dir }}/dummymain'
|
||||
- '{{ alternatives_dir }}/dummysubcmd'
|
||||
|
||||
- file:
|
||||
path: '/usr/bin/dummy{{ item }}'
|
||||
state: absent
|
||||
with_sequence: start=1 end=4
|
||||
|
||||
# *Disable tests on Fedora 24*
|
||||
# Shippable Fedora 24 image provides chkconfig-1.7-2.fc24.x86_64 but not the
|
||||
# latest available version (chkconfig-1.8-1.fc24.x86_64). update-alternatives
|
||||
# in chkconfig-1.7-2 fails when /etc/alternatives/dummy link is missing,
|
||||
# error is: 'failed to read link /usr/bin/dummy: No such file or directory'.
|
||||
# Moreover Fedora 24 is no longer maintained.
|
||||
#
|
||||
# *Disable tests on Arch Linux*
|
||||
# TODO: figure out whether there is an alternatives tool for Arch Linux
|
||||
#
|
||||
# *Disable tests on Alpine*
|
||||
# TODO: figure out whether there is an alternatives tool for Alpine
|
||||
when:
|
||||
- ansible_distribution != 'Fedora' or ansible_distribution_major_version|int > 24
|
||||
- ansible_distribution != 'Archlinux'
|
||||
- ansible_distribution != 'Alpine'
|
@ -0,0 +1,17 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: Try with nonexistent path
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: '/non/existent/path/there'
|
||||
link: '/usr/bin/dummy'
|
||||
ignore_errors: true
|
||||
register: alternative
|
||||
|
||||
- name: Check previous task failed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is failed'
|
@ -0,0 +1,13 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: remove links
|
||||
file:
|
||||
path: '{{ item }}'
|
||||
state: absent
|
||||
with_items:
|
||||
- "{{ alternatives_dir }}/dummy"
|
||||
- /etc/alternatives/dummy
|
||||
- /usr/bin/dummy
|
@ -0,0 +1,19 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- include_vars: '{{ item }}'
|
||||
with_first_found:
|
||||
- files:
|
||||
- '{{ ansible_os_family }}-{{ ansible_distribution_version }}.yml'
|
||||
- '{{ ansible_os_family }}.yml'
|
||||
- default.yml
|
||||
paths: ../vars
|
||||
- template:
|
||||
src: dummy_command
|
||||
dest: /usr/bin/dummy{{ item }}
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0755'
|
||||
with_sequence: start=1 end=4
|
@ -0,0 +1,16 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- template:
|
||||
src: dummy_alternative
|
||||
dest: '{{ alternatives_dir }}/dummy'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
when: with_alternatives or ansible_os_family != 'RedHat'
|
||||
- file:
|
||||
path: '{{ alternatives_dir }}/dummy'
|
||||
state: absent
|
||||
when: not with_alternatives and ansible_os_family == 'RedHat'
|
@ -0,0 +1,222 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: Try with subcommands
|
||||
alternatives:
|
||||
name: dummymain
|
||||
path: '/usr/bin/dummy1'
|
||||
link: '/usr/bin/dummymain'
|
||||
subcommands:
|
||||
- name: dummysubcmd
|
||||
path: '/usr/bin/dummy2'
|
||||
link: '/usr/bin/dummysubcmd'
|
||||
register: alternative
|
||||
|
||||
- name: Check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is changed'
|
||||
|
||||
- name: Execute the current dummymain command
|
||||
command: dummymain
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy1"
|
||||
|
||||
- name: Execute the current dummysubcmd command
|
||||
command: dummysubcmd
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy2"
|
||||
|
||||
- name: Get dummymain alternatives output
|
||||
command:
|
||||
cmd: '{{ alternatives_command }} --display dummymain'
|
||||
register: result
|
||||
|
||||
- name: Print result
|
||||
debug:
|
||||
var: result.stdout_lines
|
||||
|
||||
- name: Subcommands are not removed if not specified
|
||||
alternatives:
|
||||
name: dummymain
|
||||
path: '/usr/bin/dummy1'
|
||||
link: '/usr/bin/dummymain'
|
||||
register: alternative
|
||||
|
||||
- name: Check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is not changed'
|
||||
|
||||
- name: Execute the current dummysubcmd command
|
||||
command: dummysubcmd
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy2"
|
||||
|
||||
- name: Subcommands are removed if set to an empty list
|
||||
alternatives:
|
||||
name: dummymain
|
||||
path: '/usr/bin/dummy1'
|
||||
link: '/usr/bin/dummymain'
|
||||
subcommands: []
|
||||
register: alternative
|
||||
|
||||
- name: Check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is changed'
|
||||
|
||||
- name: Execute the current dummysubcmd command
|
||||
command: dummysubcmd
|
||||
register: cmd
|
||||
ignore_errors: true
|
||||
|
||||
- name: Ensure that the subcommand is gone
|
||||
assert:
|
||||
that:
|
||||
- cmd.rc == 2
|
||||
- '"No such file" in cmd.msg'
|
||||
|
||||
- name: Get dummymain alternatives output
|
||||
command:
|
||||
cmd: '{{ alternatives_command }} --display dummymain'
|
||||
register: result
|
||||
|
||||
- name: Print result
|
||||
debug:
|
||||
var: result.stdout_lines
|
||||
|
||||
- name: Install other alternative with subcommands
|
||||
alternatives:
|
||||
name: dummymain
|
||||
path: '/usr/bin/dummy3'
|
||||
link: '/usr/bin/dummymain'
|
||||
subcommands:
|
||||
- name: dummysubcmd
|
||||
path: '/usr/bin/dummy4'
|
||||
link: '/usr/bin/dummysubcmd'
|
||||
register: alternative
|
||||
|
||||
- name: Check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is changed'
|
||||
|
||||
- name: Execute the current dummymain command
|
||||
command: dummymain
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy3"
|
||||
|
||||
- name: Execute the current dummysubcmd command
|
||||
command: dummysubcmd
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy4"
|
||||
|
||||
- name: Get dummymain alternatives output
|
||||
command:
|
||||
cmd: '{{ alternatives_command }} --display dummymain'
|
||||
register: result
|
||||
|
||||
- name: Print result
|
||||
debug:
|
||||
var: result.stdout_lines
|
||||
|
||||
- name: Switch to first alternative
|
||||
alternatives:
|
||||
name: dummymain
|
||||
path: '/usr/bin/dummy1'
|
||||
register: alternative
|
||||
|
||||
- name: Check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is changed'
|
||||
|
||||
- name: Execute the current dummymain command
|
||||
command: dummymain
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy1"
|
||||
|
||||
- name: Execute the current dummysubcmd command
|
||||
command: dummysubcmd
|
||||
register: cmd
|
||||
ignore_errors: true
|
||||
|
||||
- name: Ensure that the subcommand is gone
|
||||
assert:
|
||||
that:
|
||||
- cmd.rc == 2
|
||||
- '"No such file" in cmd.msg'
|
||||
|
||||
- name: Get dummymain alternatives output
|
||||
command:
|
||||
cmd: '{{ alternatives_command }} --display dummymain'
|
||||
register: result
|
||||
|
||||
- name: Print result
|
||||
debug:
|
||||
var: result.stdout_lines
|
||||
|
||||
- name: Switch to second alternative
|
||||
alternatives:
|
||||
name: dummymain
|
||||
path: '/usr/bin/dummy3'
|
||||
register: alternative
|
||||
|
||||
- name: Check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is changed'
|
||||
|
||||
- name: Execute the current dummymain command
|
||||
command: dummymain
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy3"
|
||||
|
||||
- name: Execute the current dummysubcmd command
|
||||
command: dummysubcmd
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy4"
|
||||
|
||||
- name: Get dummymain alternatives output
|
||||
command:
|
||||
cmd: '{{ alternatives_command }} --display dummymain'
|
||||
register: result
|
||||
|
||||
- name: Print result
|
||||
debug:
|
||||
var: result.stdout_lines
|
@ -0,0 +1,56 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- debug:
|
||||
msg: ' with_alternatives: {{ with_alternatives }}, mode: {{ mode }}'
|
||||
|
||||
- block:
|
||||
- name: set alternative (using link parameter)
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: '/usr/bin/dummy{{ item }}'
|
||||
link: '/usr/bin/dummy'
|
||||
register: alternative
|
||||
|
||||
- name: check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is successful'
|
||||
- 'alternative is changed'
|
||||
when: with_link
|
||||
|
||||
- block:
|
||||
- name: set alternative (without link parameter)
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: '/usr/bin/dummy{{ item }}'
|
||||
register: alternative
|
||||
|
||||
- name: check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is successful'
|
||||
- 'alternative is changed'
|
||||
when: not with_link
|
||||
|
||||
- name: execute dummy command
|
||||
shell: dummy
|
||||
register: cmd
|
||||
|
||||
- name: check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'cmd.stdout == "dummy" ~ item'
|
||||
|
||||
- name: 'check mode (manual: alternatives file existed, it has been updated)'
|
||||
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
|
||||
when: ansible_os_family != 'RedHat' or with_alternatives or item != 1
|
||||
|
||||
- name: 'check mode (auto: alternatives file didn''t exist, it has been created)'
|
||||
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^auto$"'
|
||||
when: ansible_os_family == 'RedHat' and not with_alternatives and item == 1
|
||||
|
||||
- name: check that alternative has been updated
|
||||
command: "grep -Pzq '/bin/dummy{{ item }}\\n' '{{ alternatives_dir }}/dummy'"
|
@ -0,0 +1,20 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- block:
|
||||
- include_tasks: remove_links.yml
|
||||
- include_tasks: setup_test.yml
|
||||
# at least two iterations:
|
||||
# - first will use 'link currently absent',
|
||||
# - second will receive 'link currently points to'
|
||||
- include_tasks: test.yml
|
||||
with_sequence: start=1 end=2
|
||||
vars:
|
||||
with_link: '{{ test_conf[0] }}'
|
||||
with_alternatives: '{{ test_conf[1] }}'
|
||||
mode: '{{ test_conf[2] }}'
|
||||
# update-alternatives included in Fedora 26 (1.10) & Red Hat 7.4 (1.8) doesn't provide
|
||||
# '--query' switch, 'link' is mandatory for these distributions.
|
||||
when: ansible_os_family != 'RedHat' or test_conf[0]
|
@ -0,0 +1,54 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: update dummy alternative
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: '/usr/bin/dummy{{ item }}'
|
||||
link: /usr/bin/dummy
|
||||
priority: '{{ 60 + item|int }}'
|
||||
register: alternative
|
||||
|
||||
- name: execute dummy command
|
||||
shell: dummy
|
||||
register: cmd
|
||||
|
||||
- name: check if link group is in manual mode
|
||||
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
|
||||
|
||||
- name: check expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is changed'
|
||||
- 'cmd.stdout == "dummy" ~ item'
|
||||
|
||||
- name: check that alternative has been updated
|
||||
command: "grep -Pzq '/bin/dummy{{ item }}\\n{{ 60 + item|int }}' '{{ alternatives_dir }}/dummy'"
|
||||
|
||||
- name: update dummy priority
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: '/usr/bin/dummy{{ item }}'
|
||||
link: /usr/bin/dummy
|
||||
priority: '{{ 70 + item|int }}'
|
||||
register: alternative
|
||||
|
||||
- name: check that alternative priority has been updated
|
||||
command: "grep -Pzq '/bin/dummy{{ item }}\\n{{ 70 + item|int }}' '{{ alternatives_dir }}/dummy'"
|
||||
|
||||
- name: no change without priority
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: '/usr/bin/dummy{{ item }}'
|
||||
link: /usr/bin/dummy
|
||||
register: alternative
|
||||
|
||||
- name: check no change was triggered without priority
|
||||
assert:
|
||||
that:
|
||||
- 'alternative is not changed'
|
||||
|
||||
- name: check that alternative priority has not been changed
|
||||
command: "grep -Pzq '/bin/dummy{{ item }}\\n{{ 70 + item|int }}' '{{ alternatives_dir }}/dummy'"
|
@ -0,0 +1,120 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
# Add a few dummy alternatives with state = present and make sure that the
|
||||
# group is in 'auto' mode and the highest priority alternative is selected.
|
||||
- name: Add some dummy alternatives with state = present
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: "/usr/bin/dummy{{ item.n }}"
|
||||
link: /usr/bin/dummy
|
||||
priority: "{{ item.priority }}"
|
||||
state: present
|
||||
loop:
|
||||
- { n: 1, priority: 50 }
|
||||
- { n: 2, priority: 70 }
|
||||
- { n: 3, priority: 25 }
|
||||
|
||||
- name: Ensure that the link group is in auto mode
|
||||
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^auto$"'
|
||||
|
||||
# Execute current selected 'dummy' and ensure it's the alternative we expect
|
||||
- name: Execute the current dummy command
|
||||
shell: dummy
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy2"
|
||||
|
||||
# Add another alternative with state = 'selected' and make sure that
|
||||
# this change results in the group being set to manual mode, and the
|
||||
# new alternative being the selected one.
|
||||
- name: Add another dummy alternative with state = selected
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: /usr/bin/dummy4
|
||||
link: /usr/bin/dummy
|
||||
priority: 10
|
||||
state: selected
|
||||
|
||||
- name: Ensure that the link group is in manual mode
|
||||
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
|
||||
|
||||
- name: Execute the current dummy command
|
||||
shell: dummy
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy4"
|
||||
|
||||
# Set the currently selected alternative to state = 'present' (was previously
|
||||
# selected), and ensure that this results in the group not being set to 'auto'
|
||||
# mode, and the alternative is still selected.
|
||||
- name: Set current selected dummy to state = present
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: /usr/bin/dummy4
|
||||
link: /usr/bin/dummy
|
||||
state: present
|
||||
|
||||
- name: Ensure that the link group is in auto mode
|
||||
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
|
||||
|
||||
- name: Execute the current dummy command
|
||||
shell: dummy
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy4"
|
||||
|
||||
# Set the currently selected alternative to state = 'auto' (was previously
|
||||
# selected), and ensure that this results in the group being set to 'auto'
|
||||
# mode, and the highest priority alternative is selected.
|
||||
- name: Set current selected dummy to state = present
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: /usr/bin/dummy4
|
||||
link: /usr/bin/dummy
|
||||
state: auto
|
||||
|
||||
- name: Ensure that the link group is in auto mode
|
||||
shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^auto$"'
|
||||
|
||||
- name: Execute the current dummy command
|
||||
shell: dummy
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy2"
|
||||
|
||||
# Remove an alternative with state = 'absent' and make sure that
|
||||
# this change results in the alternative being removed.
|
||||
- name: Remove best dummy alternative with state = absent
|
||||
alternatives:
|
||||
name: dummy
|
||||
path: /usr/bin/dummy2
|
||||
state: absent
|
||||
|
||||
- name: Ensure that the link group is in auto mode
|
||||
shell: 'grep "/usr/bin/dummy2" {{ alternatives_dir }}/dummy'
|
||||
register: cmd
|
||||
failed_when: cmd.rc == 0
|
||||
|
||||
- name: Execute the current dummy command
|
||||
shell: dummy
|
||||
register: cmd
|
||||
|
||||
- name: Ensure that the expected command was executed
|
||||
assert:
|
||||
that:
|
||||
- cmd.stdout == "dummy1"
|
@ -0,0 +1,17 @@
|
||||
{#
|
||||
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
|
||||
#}
|
||||
{{ mode }}
|
||||
/usr/bin/dummy
|
||||
|
||||
{% if with_alternatives %}
|
||||
/usr/bin/dummy1
|
||||
40
|
||||
/usr/bin/dummy2
|
||||
30
|
||||
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
# 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
|
||||
|
||||
echo dummy{{ item }}
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
alternatives_dir: /var/lib/dpkg/alternatives/
|
||||
alternatives_command: update-alternatives
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
alternatives_dir: /var/lib/rpm/alternatives/
|
||||
alternatives_command: update-alternatives
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
alternatives_dir: /var/lib/alternatives/
|
||||
alternatives_command: update-alternatives
|
@ -0,0 +1,7 @@
|
||||
# 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
|
||||
|
||||
azp/posix/3
|
||||
destructive
|
||||
context/controller # While this is not really true, this module mainly is run on the controller, *and* needs access to the ansible-galaxy CLI tool
|
@ -0,0 +1,15 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
roles:
|
||||
# Install a role from Ansible Galaxy.
|
||||
- name: geerlingguy.java
|
||||
version: 1.9.6
|
||||
|
||||
collections:
|
||||
# Install a collection from Ansible Galaxy.
|
||||
- name: geerlingguy.php_roles
|
||||
version: 0.9.3
|
||||
source: https://galaxy.ansible.com
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
dependencies:
|
||||
- setup_remote_tmp_dir
|
@ -0,0 +1,88 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
###################################################
|
||||
- name: Install collection netbox.netbox
|
||||
community.general.ansible_galaxy_install:
|
||||
type: collection
|
||||
name: netbox.netbox
|
||||
register: install_c0
|
||||
|
||||
- name: Assert collection netbox.netbox was installed
|
||||
assert:
|
||||
that:
|
||||
- install_c0 is changed
|
||||
- '"netbox.netbox" in install_c0.new_collections'
|
||||
|
||||
- name: Install collection netbox.netbox (again)
|
||||
community.general.ansible_galaxy_install:
|
||||
type: collection
|
||||
name: netbox.netbox
|
||||
register: install_c1
|
||||
|
||||
- name: Assert collection was not installed
|
||||
assert:
|
||||
that:
|
||||
- install_c1 is not changed
|
||||
|
||||
###################################################
|
||||
- name: Install role ansistrano.deploy
|
||||
community.general.ansible_galaxy_install:
|
||||
type: role
|
||||
name: ansistrano.deploy
|
||||
register: install_r0
|
||||
|
||||
- name: Assert collection ansistrano.deploy was installed
|
||||
assert:
|
||||
that:
|
||||
- install_r0 is changed
|
||||
- '"ansistrano.deploy" in install_r0.new_roles'
|
||||
|
||||
- name: Install role ansistrano.deploy (again)
|
||||
community.general.ansible_galaxy_install:
|
||||
type: role
|
||||
name: ansistrano.deploy
|
||||
register: install_r1
|
||||
|
||||
- name: Assert role was not installed
|
||||
assert:
|
||||
that:
|
||||
- install_r1 is not changed
|
||||
|
||||
###################################################
|
||||
- name: Set requirements file path
|
||||
set_fact:
|
||||
reqs_file: '{{ remote_tmp_dir }}/reqs.yaml'
|
||||
|
||||
- name: Copy requirements file
|
||||
copy:
|
||||
src: 'files/test.yml'
|
||||
dest: '{{ reqs_file }}'
|
||||
|
||||
- name: Install from requirements file
|
||||
community.general.ansible_galaxy_install:
|
||||
type: both
|
||||
requirements_file: "{{ reqs_file }}"
|
||||
register: install_rq0
|
||||
ignore_errors: true
|
||||
|
||||
- name: Assert requirements file was installed
|
||||
assert:
|
||||
that:
|
||||
- install_rq0 is changed
|
||||
- '"geerlingguy.java" in install_rq0.new_roles'
|
||||
- '"geerlingguy.php_roles" in install_rq0.new_collections'
|
||||
|
||||
- name: Install from requirements file (again)
|
||||
community.general.ansible_galaxy_install:
|
||||
type: both
|
||||
requirements_file: "{{ reqs_file }}"
|
||||
register: install_rq1
|
||||
ignore_errors: true
|
||||
|
||||
- name: Assert requirements file was not installed
|
||||
assert:
|
||||
that:
|
||||
- install_rq1 is not changed
|
@ -0,0 +1,7 @@
|
||||
# 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
|
||||
|
||||
azp/posix/3
|
||||
destructive
|
||||
skip/aix
|
@ -0,0 +1,47 @@
|
||||
---
|
||||
# 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
|
||||
# This test represent the misleading behavior of the following issue: https://github.com/ansible-collections/community.general/issues/635
|
||||
- name: Disable MPM event module
|
||||
apache2_module:
|
||||
name: "{{ item.module}}"
|
||||
state: "{{ item.state}}"
|
||||
ignore_configcheck: true
|
||||
register: disable_mpm_modules
|
||||
with_items:
|
||||
- { module: mpm_event, state: absent }
|
||||
- { module: mpm_prefork, state: present }
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "'warnings' in disable_mpm_modules"
|
||||
- disable_mpm_modules["warnings"] == [
|
||||
"No MPM module loaded! apache2 reload AND other module actions will fail if no MPM module is loaded immediately.",
|
||||
"No MPM module loaded! apache2 reload AND other module actions will fail if no MPM module is loaded immediately."
|
||||
]
|
||||
|
||||
- name: Enable MPM event module - Revert previous change
|
||||
apache2_module:
|
||||
name: "{{ item.module}}"
|
||||
state: "{{ item.state}}"
|
||||
ignore_configcheck: true
|
||||
register: disable_mpm_modules
|
||||
with_items:
|
||||
- { module: mpm_prefork, state: absent }
|
||||
- { module: mpm_event, state: present }
|
||||
|
||||
- name: Disable MPM event module
|
||||
apache2_module:
|
||||
name: "{{ item.module}}"
|
||||
state: "{{ item.state}}"
|
||||
ignore_configcheck: true
|
||||
warn_mpm_absent: false
|
||||
register: disable_mpm_modules
|
||||
with_items:
|
||||
- { module: mpm_event, state: absent }
|
||||
- { module: mpm_prefork, state: present }
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "'warnings' not in disable_mpm_modules"
|
@ -0,0 +1,207 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: disable userdir module
|
||||
community.general.apache2_module:
|
||||
name: userdir
|
||||
state: absent
|
||||
register: userdir_first_disable
|
||||
|
||||
- name: disable userdir module, second run
|
||||
community.general.apache2_module:
|
||||
name: userdir
|
||||
state: absent
|
||||
register: disable
|
||||
|
||||
- name: ensure community.general.apache2_module is idempotent
|
||||
assert:
|
||||
that:
|
||||
- disable is not changed
|
||||
|
||||
- name: enable userdir module
|
||||
community.general.apache2_module:
|
||||
name: userdir
|
||||
state: present
|
||||
register: enable
|
||||
|
||||
- name: ensure changed on successful enable
|
||||
assert:
|
||||
that:
|
||||
- enable is changed
|
||||
|
||||
- name: enable userdir module, second run
|
||||
community.general.apache2_module:
|
||||
name: userdir
|
||||
state: present
|
||||
register: enabletwo
|
||||
|
||||
- name: ensure community.general.apache2_module is idempotent
|
||||
assert:
|
||||
that:
|
||||
- 'not enabletwo.changed'
|
||||
|
||||
- name: disable userdir module, final run
|
||||
community.general.apache2_module:
|
||||
name: userdir
|
||||
state: absent
|
||||
register: disablefinal
|
||||
|
||||
- name: ensure changed on successful disable
|
||||
assert:
|
||||
that:
|
||||
- 'disablefinal.changed'
|
||||
|
||||
- name: set userdir to original state
|
||||
community.general.apache2_module:
|
||||
name: userdir
|
||||
state: present
|
||||
when: userdir_first_disable is changed
|
||||
|
||||
- name: ensure autoindex enabled
|
||||
community.general.apache2_module:
|
||||
name: autoindex
|
||||
state: present
|
||||
|
||||
- name: Debian/Ubuntu specific tests
|
||||
when: "ansible_os_family == 'Debian'"
|
||||
block:
|
||||
- name: force disable of autoindex # bug #2499
|
||||
community.general.apache2_module:
|
||||
name: autoindex
|
||||
state: absent
|
||||
force: true
|
||||
|
||||
- name: re-enable autoindex
|
||||
community.general.apache2_module:
|
||||
name: autoindex
|
||||
state: present
|
||||
|
||||
# mod_evasive is enabled by default upon the installation, so disable first and enable second, to preserve the config
|
||||
- name: disable evasive module
|
||||
community.general.apache2_module:
|
||||
name: evasive
|
||||
state: absent
|
||||
|
||||
- name: enable evasive module, test https://github.com/ansible/ansible/issues/22635
|
||||
community.general.apache2_module:
|
||||
name: evasive
|
||||
state: present
|
||||
|
||||
- name: use identifier to enable module, fix for https://github.com/ansible/ansible/issues/33669
|
||||
community.general.apache2_module:
|
||||
name: dump_io
|
||||
state: present
|
||||
ignore_errors: true
|
||||
register: enable_dumpio_wrong
|
||||
|
||||
- name: disable dump_io
|
||||
community.general.apache2_module:
|
||||
name: dump_io
|
||||
identifier: dumpio_module
|
||||
state: absent
|
||||
|
||||
- name: use identifier to enable module, fix for https://github.com/ansible/ansible/issues/33669
|
||||
community.general.apache2_module:
|
||||
name: dump_io
|
||||
identifier: dumpio_module
|
||||
state: present
|
||||
register: enable_dumpio_correct_1
|
||||
|
||||
- name: ensure idempotency with identifier
|
||||
community.general.apache2_module:
|
||||
name: dump_io
|
||||
identifier: dumpio_module
|
||||
state: present
|
||||
register: enable_dumpio_correct_2
|
||||
|
||||
- name: disable dump_io
|
||||
community.general.apache2_module:
|
||||
name: dump_io
|
||||
identifier: dumpio_module
|
||||
state: absent
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- enable_dumpio_wrong is failed
|
||||
- enable_dumpio_correct_1 is changed
|
||||
- enable_dumpio_correct_2 is not changed
|
||||
|
||||
- name: disable mpm modules
|
||||
community.general.apache2_module:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
ignore_configcheck: true
|
||||
with_items:
|
||||
- mpm_worker
|
||||
- mpm_event
|
||||
- mpm_prefork
|
||||
|
||||
- name: enabled mpm_event
|
||||
community.general.apache2_module:
|
||||
name: mpm_event
|
||||
state: present
|
||||
ignore_configcheck: true
|
||||
register: enabledmpmevent
|
||||
|
||||
- name: ensure changed mpm_event
|
||||
assert:
|
||||
that:
|
||||
- 'enabledmpmevent.changed'
|
||||
|
||||
- name: switch between mpm_event and mpm_worker
|
||||
community.general.apache2_module:
|
||||
name: "{{ item.name }}"
|
||||
state: "{{ item.state }}"
|
||||
ignore_configcheck: true
|
||||
with_items:
|
||||
- name: mpm_event
|
||||
state: absent
|
||||
- name: mpm_worker
|
||||
state: present
|
||||
|
||||
- name: ensure mpm_worker is already enabled
|
||||
community.general.apache2_module:
|
||||
name: mpm_worker
|
||||
state: present
|
||||
register: enabledmpmworker
|
||||
|
||||
- name: ensure mpm_worker unchanged
|
||||
assert:
|
||||
that:
|
||||
- 'not enabledmpmworker.changed'
|
||||
|
||||
- name: try to disable all mpm modules with configcheck
|
||||
community.general.apache2_module:
|
||||
name: "{{item}}"
|
||||
state: absent
|
||||
with_items:
|
||||
- mpm_worker
|
||||
- mpm_event
|
||||
- mpm_prefork
|
||||
ignore_errors: true
|
||||
register: remove_with_configcheck
|
||||
|
||||
- name: ensure configcheck fails task with when run without mpm modules
|
||||
assert:
|
||||
that:
|
||||
- "{{ item.failed }}"
|
||||
with_items: "{{ remove_with_configcheck.results }}"
|
||||
|
||||
- name: try to disable all mpm modules without configcheck
|
||||
community.general.apache2_module:
|
||||
name: "{{item}}"
|
||||
state: absent
|
||||
ignore_configcheck: true
|
||||
with_items:
|
||||
- mpm_worker
|
||||
- mpm_event
|
||||
- mpm_prefork
|
||||
|
||||
- name: enabled mpm_event to restore previous state
|
||||
community.general.apache2_module:
|
||||
name: mpm_event
|
||||
state: present
|
||||
ignore_configcheck: true
|
||||
register: enabledmpmevent
|
@ -0,0 +1,52 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# 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
|
||||
|
||||
- name: install apache via apt
|
||||
apt:
|
||||
name: "{{item}}"
|
||||
state: present
|
||||
when: "ansible_os_family == 'Debian'"
|
||||
with_items:
|
||||
- apache2
|
||||
- libapache2-mod-evasive
|
||||
|
||||
- name: install apache via zypper
|
||||
community.general.zypper:
|
||||
name: apache2
|
||||
state: present
|
||||
when: "ansible_os_family == 'Suse'"
|
||||
|
||||
- name: test apache2_module
|
||||
block:
|
||||
- name: get list of enabled modules
|
||||
shell: apache2ctl -M | sort
|
||||
register: modules_before
|
||||
- name: include only on supported systems
|
||||
include_tasks: actualtest.yml
|
||||
always:
|
||||
- name: get list of enabled modules
|
||||
shell: apache2ctl -M | sort
|
||||
register: modules_after
|
||||
- name: modules_before
|
||||
debug:
|
||||
var: modules_before
|
||||
- name: modules_after
|
||||
debug:
|
||||
var: modules_after
|
||||
- name: ensure that all test modules are disabled again
|
||||
assert:
|
||||
that: modules_before.stdout == modules_after.stdout
|
||||
when: ansible_os_family in ['Debian', 'Suse']
|
||||
# centos/RHEL does not have a2enmod/a2dismod
|
||||
|
||||
- name: include misleading warning test
|
||||
include_tasks: 635-apache2-misleading-warning.yml
|
||||
when: ansible_os_family in ['Debian']
|
||||
# Suse has mpm_event module compiled within the base apache2
|
@ -0,0 +1,9 @@
|
||||
# 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
|
||||
|
||||
azp/posix/2
|
||||
needs/root
|
||||
destructive
|
||||
skip/aix
|
||||
skip/osx # FIXME
|
@ -0,0 +1,5 @@
|
||||
# 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
|
||||
|
||||
bar.txt
|
@ -0,0 +1,5 @@
|
||||
# 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
|
||||
|
||||
foo.txt
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
dependencies:
|
||||
- setup_pkg_mgr
|
||||
- setup_remote_tmp_dir
|
@ -0,0 +1,145 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# Test code for the archive module.
|
||||
# Copyright (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
|
||||
# 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
|
||||
|
||||
# Make sure we start fresh
|
||||
|
||||
# Test setup
|
||||
- name: prep our files
|
||||
copy: src={{ item }} dest={{remote_tmp_dir}}/{{ item }}
|
||||
with_items:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
- empty.txt
|
||||
- sub
|
||||
- sub/subfile.txt
|
||||
|
||||
# Run twice without lzma backport installed, to make sure it does not crash
|
||||
- name: Archive - pre-test - first run
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_pretest_1.tar"
|
||||
format: "tar"
|
||||
register: pretest_1
|
||||
|
||||
- name: Archive - pre-test - second run
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_pretest_1.tar"
|
||||
format: "tar"
|
||||
register: pretest_2
|
||||
|
||||
- name: Archive - validate pre-test
|
||||
assert:
|
||||
that:
|
||||
- pretest_1 is changed
|
||||
- pretest_2 is not changed
|
||||
|
||||
# Install dependencies
|
||||
- name: Ensure zip is present to create test archive (yum)
|
||||
yum: name=zip state=latest
|
||||
when: ansible_facts.pkg_mgr == 'yum'
|
||||
|
||||
- name: Ensure zip is present to create test archive (apt)
|
||||
apt: name=zip state=latest
|
||||
when: ansible_facts.pkg_mgr == 'apt'
|
||||
|
||||
- name: Install prerequisites for backports.lzma when using python2 (non OSX)
|
||||
block:
|
||||
- name: Set liblzma package name depending on the OS
|
||||
set_fact:
|
||||
liblzma_dev_package:
|
||||
Debian: liblzma-dev
|
||||
RedHat: xz-devel
|
||||
Suse: xz-devel
|
||||
- name: Ensure liblzma-dev is present to install backports-lzma
|
||||
package: name={{ liblzma_dev_package[ansible_os_family] }} state=latest
|
||||
when: ansible_os_family in liblzma_dev_package.keys()
|
||||
when:
|
||||
- ansible_python_version.split('.')[0] == '2'
|
||||
- ansible_os_family != 'Darwin'
|
||||
|
||||
- name: Install prerequisites for backports.lzma when using python2 (OSX)
|
||||
block:
|
||||
- name: Find brew binary
|
||||
command: which brew
|
||||
register: brew_which
|
||||
- name: Get owner of brew binary
|
||||
stat: path="{{ brew_which.stdout }}"
|
||||
register: brew_stat
|
||||
- name: "Install package"
|
||||
homebrew:
|
||||
name: xz
|
||||
state: present
|
||||
update_homebrew: false
|
||||
become: true
|
||||
become_user: "{{ brew_stat.stat.pw_name }}"
|
||||
# Newer versions of brew want to compile a package which takes a long time. Do not upgrade homebrew until a
|
||||
# proper solution can be found
|
||||
environment:
|
||||
HOMEBREW_NO_AUTO_UPDATE: "True"
|
||||
when:
|
||||
- ansible_python_version.split('.')[0] == '2'
|
||||
- ansible_os_family == 'Darwin'
|
||||
|
||||
- name: Ensure backports.lzma is present to create test archive (pip)
|
||||
pip: name=backports.lzma state=latest
|
||||
when: ansible_python_version.split('.')[0] == '2'
|
||||
register: backports_lzma_pip
|
||||
|
||||
- name: Define formats to test
|
||||
set_fact:
|
||||
formats:
|
||||
- tar
|
||||
- zip
|
||||
- gz
|
||||
- bz2
|
||||
- xz
|
||||
|
||||
# Run tests
|
||||
- name: Run core tests
|
||||
include_tasks:
|
||||
file: ../tests/core.yml
|
||||
loop: "{{ formats }}"
|
||||
loop_control:
|
||||
loop_var: format
|
||||
|
||||
- name: Run exclusions tests
|
||||
include_tasks:
|
||||
file: ../tests/exclusions.yml
|
||||
loop: "{{ formats }}"
|
||||
loop_control:
|
||||
loop_var: format
|
||||
|
||||
- name: Run remove tests
|
||||
include_tasks:
|
||||
file: ../tests/remove.yml
|
||||
loop: "{{ formats }}"
|
||||
loop_control:
|
||||
loop_var: format
|
||||
|
||||
- name: Run broken link tests
|
||||
include_tasks:
|
||||
file: ../tests/broken-link.yml
|
||||
loop: "{{ formats }}"
|
||||
loop_control:
|
||||
loop_var: format
|
||||
|
||||
- name: Run Idempotency tests
|
||||
include_tasks:
|
||||
file: ../tests/idempotency.yml
|
||||
loop: "{{ formats }}"
|
||||
loop_control:
|
||||
loop_var: format
|
||||
|
||||
# Test cleanup
|
||||
- name: Remove backports.lzma if previously installed (pip)
|
||||
pip: name=backports.lzma state=absent
|
||||
when: backports_lzma_pip is changed
|
@ -0,0 +1,35 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- block:
|
||||
- name: Create link - broken link ({{ format }})
|
||||
file:
|
||||
src: /nowhere
|
||||
dest: "{{ remote_tmp_dir }}/nowhere.txt"
|
||||
state: link
|
||||
force: true
|
||||
|
||||
- name: Archive - broken link ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_broken_link.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
|
||||
- name: Verify archive exists - broken link ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_broken_link.{{ format }}"
|
||||
state: file
|
||||
|
||||
- name: Remove archive - broken link ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_broken_link.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove link - broken link ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/nowhere.txt"
|
||||
state: absent
|
||||
# 'zip' does not support symlink's
|
||||
when: format != 'zip'
|
@ -0,0 +1,177 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# Test code for the archive module.
|
||||
# Copyright (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
|
||||
# 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
|
||||
|
||||
# Make sure we start fresh
|
||||
|
||||
# Core functionality tests
|
||||
- name: Archive - no options ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_no_opts.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: archive_no_options
|
||||
|
||||
- name: Verify that archive exists - no options ({{ format }})
|
||||
file:
|
||||
path: "{{remote_tmp_dir}}/archive_no_opts.{{ format }}"
|
||||
state: file
|
||||
|
||||
- name: Verify that archive result is changed and includes all files - no options ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_no_options is changed
|
||||
- "archive_no_options.dest_state == 'archive'"
|
||||
- "archive_no_options.archived | length == 3"
|
||||
|
||||
- name: Remove the archive - no options ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_no_options.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Archive - file options ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_file_options.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
mode: "u+rwX,g-rwx,o-rwx"
|
||||
register: archive_file_options
|
||||
|
||||
- name: Retrieve archive file information - file options ({{ format }})
|
||||
stat:
|
||||
path: "{{ remote_tmp_dir }}/archive_file_options.{{ format }}"
|
||||
register: archive_file_options_stat
|
||||
|
||||
- name: Test that the file modes were changed
|
||||
assert:
|
||||
that:
|
||||
- archive_file_options_stat is not changed
|
||||
- "archive_file_options.mode == '0600'"
|
||||
- "archive_file_options.archived | length == 3"
|
||||
|
||||
- name: Remove the archive - file options ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_file_options.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Archive - non-ascii ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_nonascii_くらとみ.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: archive_nonascii
|
||||
|
||||
- name: Retrieve archive file information - non-ascii ({{ format }})
|
||||
stat:
|
||||
path: "{{ remote_tmp_dir }}/archive_nonascii_くらとみ.{{ format }}"
|
||||
register: archive_nonascii_stat
|
||||
|
||||
- name: Test that archive exists - non-ascii ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_nonascii is changed
|
||||
- archive_nonascii_stat.stat.exists == true
|
||||
|
||||
- name: Remove the archive - non-ascii ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_nonascii_くらとみ.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Archive - single target ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/foo.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_single_target.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: archive_single_target
|
||||
|
||||
- name: Assert archive has correct state - single target ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_single_target.dest_state == state_map[format]
|
||||
vars:
|
||||
state_map:
|
||||
tar: archive
|
||||
zip: archive
|
||||
gz: compress
|
||||
bz2: compress
|
||||
xz: compress
|
||||
|
||||
- block:
|
||||
- name: Retrieve contents of archive - single target ({{ format }})
|
||||
ansible.builtin.unarchive:
|
||||
src: "{{ remote_tmp_dir }}/archive_single_target.{{ format }}"
|
||||
dest: .
|
||||
list_files: true
|
||||
check_mode: true
|
||||
ignore_errors: true
|
||||
register: archive_single_target_contents
|
||||
|
||||
- name: Assert that file names are preserved - single target ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- "'oo.txt' not in archive_single_target_contents.files"
|
||||
- "'foo.txt' in archive_single_target_contents.files"
|
||||
# ``unarchive`` fails for RHEL and FreeBSD on ansible 2.x
|
||||
when: archive_single_target_contents is success and archive_single_target_contents is not skipped
|
||||
when: "format == 'zip'"
|
||||
|
||||
- name: Remove archive - single target ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_single_target.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Archive - path list ({{ format }})
|
||||
archive:
|
||||
path:
|
||||
- "{{ remote_tmp_dir }}/empty.txt"
|
||||
- "{{ remote_tmp_dir }}/foo.txt"
|
||||
- "{{ remote_tmp_dir }}/bar.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_path_list.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: archive_path_list
|
||||
|
||||
- name: Verify that archive exists - path list ({{ format }})
|
||||
file:
|
||||
path: "{{remote_tmp_dir}}/archive_path_list.{{ format }}"
|
||||
state: file
|
||||
|
||||
- name: Assert that archive contains all files - path list ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_path_list is changed
|
||||
- "archive_path_list.archived | length == 3"
|
||||
|
||||
- name: Remove archive - path list ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_path_list.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Archive - missing paths ({{ format }})
|
||||
archive:
|
||||
path:
|
||||
- "{{ remote_tmp_dir }}/*.txt"
|
||||
- "{{ remote_tmp_dir }}/dne.txt"
|
||||
exclude_path: "{{ remote_tmp_dir }}/foo.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_missing_paths.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: archive_missing_paths
|
||||
|
||||
- name: Assert that incomplete archive has incomplete state - missing paths ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_missing_paths is changed
|
||||
- "archive_missing_paths.dest_state == 'incomplete'"
|
||||
- "(remote_tmp_dir ~ '/dne.txt') in archive_missing_paths.missing"
|
||||
- "(remote_tmp_dir ~ '/foo.txt') not in archive_missing_paths.missing"
|
||||
|
||||
- name: Remove archive - missing paths ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_missing_paths.{{ format }}"
|
||||
state: absent
|
@ -0,0 +1,44 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: Archive - exclusion patterns ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_exclusion_patterns.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
exclusion_patterns: b?r.*
|
||||
register: archive_exclusion_patterns
|
||||
|
||||
- name: Assert that only included files are archived - exclusion patterns ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_exclusion_patterns is changed
|
||||
- "'bar.txt' not in archive_exclusion_patterns.archived"
|
||||
|
||||
- name: Remove archive - exclusion patterns ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_exclusion_patterns.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Archive - exclude path ({{ format }})
|
||||
archive:
|
||||
path:
|
||||
- "{{ remote_tmp_dir }}/sub/subfile.txt"
|
||||
- "{{ remote_tmp_dir }}"
|
||||
exclude_path:
|
||||
- "{{ remote_tmp_dir }}"
|
||||
dest: "{{ remote_tmp_dir }}/archive_exclude_paths.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: archive_excluded_paths
|
||||
|
||||
- name: Assert that excluded paths do not influence archive root - exclude path ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_excluded_paths.arcroot != remote_tmp_dir
|
||||
|
||||
- name: Remove archive - exclude path ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_exclude_paths.{{ format }}"
|
||||
state: absent
|
@ -0,0 +1,144 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: Archive - file content idempotency ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_file_content_idempotency.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: file_content_idempotency_before
|
||||
|
||||
- name: Modify file - file content idempotency ({{ format }})
|
||||
lineinfile:
|
||||
line: bar.txt
|
||||
regexp: "^foo.txt$"
|
||||
path: "{{ remote_tmp_dir }}/foo.txt"
|
||||
|
||||
- name: Archive second time - file content idempotency ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_file_content_idempotency.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: file_content_idempotency_after
|
||||
|
||||
- name: Assert task status is changed - file content idempotency ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- file_content_idempotency_after is changed
|
||||
# Only ``zip`` archives are guaranteed to compare file content checksums rather than header checksums
|
||||
when: "format == 'zip'"
|
||||
|
||||
- name: Remove archive - file content idempotency ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_file_content_idempotency.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Modify file back - file content idempotency ({{ format }})
|
||||
lineinfile:
|
||||
line: foo.txt
|
||||
regexp: "^bar.txt$"
|
||||
path: "{{ remote_tmp_dir }}/foo.txt"
|
||||
|
||||
- name: Archive - file name idempotency ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_file_name_idempotency.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: file_name_idempotency_before
|
||||
|
||||
- name: Rename file - file name idempotency ({{ format }})
|
||||
command: "mv {{ remote_tmp_dir }}/foo.txt {{ remote_tmp_dir }}/fii.txt"
|
||||
|
||||
- name: Archive again - file name idempotency ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_file_name_idempotency.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: file_name_idempotency_after
|
||||
|
||||
- name: Check task status - file name idempotency ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- file_name_idempotency_after is changed
|
||||
|
||||
- name: Remove archive - file name idempotency ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_file_name_idempotency.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Rename file back - file name idempotency ({{ format }})
|
||||
command: "mv {{ remote_tmp_dir }}/fii.txt {{ remote_tmp_dir }}/foo.txt"
|
||||
|
||||
- name: Archive - single file content idempotency ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/foo.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_single_file_content_idempotency.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: single_file_content_idempotency_before
|
||||
|
||||
- name: Modify file - single file content idempotency ({{ format }})
|
||||
lineinfile:
|
||||
line: bar.txt
|
||||
regexp: "^foo.txt$"
|
||||
path: "{{ remote_tmp_dir }}/foo.txt"
|
||||
|
||||
- name: Archive second time - single file content idempotency ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/foo.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_single_file_content_idempotency.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: single_file_content_idempotency_after
|
||||
|
||||
- name: Assert task status is changed - single file content idempotency ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- single_file_content_idempotency_after is changed
|
||||
# ``tar`` archives are not guaranteed to identify changes to file content if the file meta properties are unchanged.
|
||||
when: "format != 'tar'"
|
||||
|
||||
- name: Remove archive - single file content idempotency ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_single_file_content_idempotency.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Modify file back - single file content idempotency ({{ format }})
|
||||
lineinfile:
|
||||
line: foo.txt
|
||||
regexp: "^bar.txt$"
|
||||
path: "{{ remote_tmp_dir }}/foo.txt"
|
||||
|
||||
- name: Archive - single file name idempotency ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/foo.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_single_file_name_idempotency.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: single_file_name_idempotency_before
|
||||
|
||||
- name: Rename file - single file name idempotency ({{ format }})
|
||||
command: "mv {{ remote_tmp_dir }}/foo.txt {{ remote_tmp_dir }}/fii.txt"
|
||||
|
||||
- name: Archive again - single file name idempotency ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/fii.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_single_file_name_idempotency.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
register: single_file_name_idempotency_after
|
||||
|
||||
|
||||
# The gz, bz2, and xz formats do not store the original file name
|
||||
# so it is not possible to identify a change in this scenario.
|
||||
- name: Check task status - single file name idempotency ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- single_file_name_idempotency_after is changed
|
||||
when: "format in ('tar', 'zip')"
|
||||
|
||||
- name: Remove archive - single file name idempotency ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_single_file_name_idempotency.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Rename file back - single file name idempotency ({{ format }})
|
||||
command: "mv {{ remote_tmp_dir }}/fii.txt {{ remote_tmp_dir }}/foo.txt"
|
@ -0,0 +1,225 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: Archive - remove source files ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/*.txt"
|
||||
dest: "{{ remote_tmp_dir }}/archive_remove_source_files.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
remove: true
|
||||
register: archive_remove_source_files
|
||||
|
||||
- name: Verify archive exists - remove source files ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_files.{{ format }}"
|
||||
state: file
|
||||
|
||||
- name: Verify all files were archived - remove source files ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_remove_source_files is changed
|
||||
- "archive_remove_source_files.archived | length == 3"
|
||||
|
||||
- name: Remove Archive - remove source files ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_files.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove source files in check mode ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/{{ item }}"
|
||||
state: absent
|
||||
check_mode: true
|
||||
with_items:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
- empty.txt
|
||||
register: remove_files
|
||||
|
||||
- name: Assert that source files were removed - remove source files ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- remove_files is not changed
|
||||
|
||||
- name: Copy source files - remove source directory ({{ format }})
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ remote_tmp_dir }}/{{ item }}"
|
||||
with_items:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
- empty.txt
|
||||
|
||||
- name: Create temporary directory - remove source directory ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/tmpdir"
|
||||
state: directory
|
||||
|
||||
- name: Copy source files to temporary directory - remove source directory ({{ format }})
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ remote_tmp_dir }}/tmpdir/{{ item }}"
|
||||
with_items:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
- empty.txt
|
||||
|
||||
- name: Archive - remove source directory ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/tmpdir"
|
||||
dest: "{{ remote_tmp_dir }}/archive_remove_source_directory.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
remove: true
|
||||
register: archive_remove_source_directory
|
||||
|
||||
- name: Verify archive exists - remove source directory ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_directory.{{ format }}"
|
||||
state: file
|
||||
|
||||
- name: Verify archive contains all files - remove source directory ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_remove_source_directory is changed
|
||||
- "archive_remove_source_directory.archived | length == 3"
|
||||
|
||||
- name: Remove archive - remove source directory ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_directory.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove source source directory in check mode ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/tmpdir"
|
||||
state: absent
|
||||
check_mode: true
|
||||
register: remove_dir
|
||||
|
||||
- name: Verify source directory was removed - remove source directory ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- remove_dir is not changed
|
||||
|
||||
- name: Create temporary directory - remove source excluding path ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/tmpdir"
|
||||
state: directory
|
||||
|
||||
- name: Copy source files to temporary directory - remove source excluding path ({{ format }})
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ remote_tmp_dir }}/tmpdir/{{ item }}"
|
||||
with_items:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
- empty.txt
|
||||
|
||||
- name: Archive - remove source excluding path ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/tmpdir/*"
|
||||
dest: "{{ remote_tmp_dir }}/archive_remove_source_excluding_path.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
remove: true
|
||||
exclude_path: "{{ remote_tmp_dir }}/tmpdir/empty.txt"
|
||||
register: archive_remove_source_excluding_path
|
||||
|
||||
- name: Verify archive exists - remove source excluding path ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_excluding_path.{{ format }}"
|
||||
state: file
|
||||
|
||||
- name: Verify all files except excluded are archived - remove source excluding path ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_remove_source_excluding_path is changed
|
||||
- "archive_remove_source_excluding_path.archived | length == 2"
|
||||
|
||||
- name: Remove archive - remove source excluding path ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_excluding_path.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Verify that excluded file still exists - remove source excluding path ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/tmpdir/empty.txt"
|
||||
state: file
|
||||
|
||||
- name: Copy source files to temporary directory - remove source excluding sub path ({{ format }})
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ remote_tmp_dir }}/tmpdir/{{ item }}"
|
||||
with_items:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
- empty.txt
|
||||
- sub
|
||||
- sub/subfile.txt
|
||||
|
||||
- name: Archive - remove source excluding sub path ({{ format }})
|
||||
archive:
|
||||
path:
|
||||
- "{{ remote_tmp_dir }}/tmpdir/*.txt"
|
||||
- "{{ remote_tmp_dir }}/tmpdir/sub/*"
|
||||
dest: "{{ remote_tmp_dir }}/archive_remove_source_excluding_sub_path.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
remove: true
|
||||
exclude_path: "{{ remote_tmp_dir }}/tmpdir/sub/subfile.txt"
|
||||
register: archive_remove_source_excluding_sub_path
|
||||
|
||||
- name: Verify archive exists - remove source excluding sub path ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_excluding_sub_path.{{ format }}"
|
||||
state: file
|
||||
|
||||
- name: Remove archive - remove source excluding sub path ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_excluding_sub_path.{{ format }}"
|
||||
state: absent
|
||||
|
||||
- name: Verify that sub path still exists - remove source excluding sub path ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/tmpdir/sub/subfile.txt"
|
||||
state: file
|
||||
|
||||
- name: Copy source files to temporary directory - remove source with nested paths ({{ format }})
|
||||
copy:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ remote_tmp_dir }}/tmpdir/{{ item }}"
|
||||
with_items:
|
||||
- foo.txt
|
||||
- bar.txt
|
||||
- empty.txt
|
||||
- sub
|
||||
- sub/subfile.txt
|
||||
|
||||
- name: Archive - remove source with nested paths ({{ format }})
|
||||
archive:
|
||||
path: "{{ remote_tmp_dir }}/tmpdir/"
|
||||
dest: "{{ remote_tmp_dir }}/archive_remove_source_nested_paths.{{ format }}"
|
||||
format: "{{ format }}"
|
||||
remove: true
|
||||
register: archive_remove_nested_paths
|
||||
|
||||
- name: Verify archive exists - remove source with nested paths ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_nested_paths.{{ format }}"
|
||||
state: file
|
||||
|
||||
- name: Verify source files were removed - remove source with nested paths ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/tmpdir"
|
||||
state: absent
|
||||
register: archive_remove_nested_paths_status
|
||||
|
||||
- name: Assert tasks status - remove source with nested paths ({{ format }})
|
||||
assert:
|
||||
that:
|
||||
- archive_remove_nested_paths is success
|
||||
- archive_remove_nested_paths_status is not changed
|
||||
|
||||
- name: Remove archive - remove source with nested paths ({{ format }})
|
||||
file:
|
||||
path: "{{ remote_tmp_dir }}/archive_remove_source_nested_paths.{{ format }}"
|
||||
state: absent
|
@ -0,0 +1,12 @@
|
||||
# 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
|
||||
|
||||
azp/posix/3
|
||||
azp/posix/vm
|
||||
destructive
|
||||
needs/privileged
|
||||
skip/aix
|
||||
skip/freebsd
|
||||
skip/osx
|
||||
skip/macos
|
@ -0,0 +1,20 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
btrfs_subvolume_single_configs:
|
||||
- file: "/tmp/disks0.img"
|
||||
loop: "/dev/loop95"
|
||||
btrfs_subvolume_multiple_configs:
|
||||
- file: "/tmp/diskm0.img"
|
||||
loop: "/dev/loop97"
|
||||
- file: "/tmp/diskm1.img"
|
||||
loop: "/dev/loop98"
|
||||
- file: "/tmp/diskm2.img"
|
||||
loop: "/dev/loop99"
|
||||
btrfs_subvolume_configs: "{{ btrfs_subvolume_single_configs + btrfs_subvolume_multiple_configs }}"
|
||||
btrfs_subvolume_single_devices: "{{ btrfs_subvolume_single_configs | map(attribute='loop') }}"
|
||||
btrfs_subvolume_single_label: "single"
|
||||
btrfs_subvolume_multiple_devices: "{{ btrfs_subvolume_multiple_configs | map(attribute='loop') }}"
|
||||
btrfs_subvolume_multiple_label: "multiple"
|
@ -0,0 +1,29 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Install required packages
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- btrfs-progs # btrfs userspace
|
||||
- util-linux # losetup
|
||||
ignore_errors: True
|
||||
register: btrfs_installed
|
||||
|
||||
- name: Execute integration tests tests
|
||||
block:
|
||||
- ansible.builtin.include_tasks: 'setup.yml'
|
||||
|
||||
- name: "Execute test scenario for single device filesystem"
|
||||
ansible.builtin.include_tasks: 'run_filesystem_tests.yml'
|
||||
vars:
|
||||
btrfs_subvolume_target_device: "{{ btrfs_subvolume_single_devices | first }}"
|
||||
btrfs_subvolume_target_label: "{{ btrfs_subvolume_single_label }}"
|
||||
|
||||
- name: "Execute test scenario for multiple device configuration"
|
||||
ansible.builtin.include_tasks: 'run_filesystem_tests.yml'
|
||||
vars:
|
||||
btrfs_subvolume_target_device: "{{ btrfs_subvolume_multiple_devices | first }}"
|
||||
btrfs_subvolume_target_label: "{{ btrfs_subvolume_multiple_label }}"
|
||||
when: btrfs_installed is success
|
@ -0,0 +1,15 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- ansible.builtin.include_tasks: 'test_subvolume_simple.yml'
|
||||
- ansible.builtin.include_tasks: 'test_subvolume_nested.yml'
|
||||
- ansible.builtin.include_tasks: 'test_subvolume_recursive.yml'
|
||||
- ansible.builtin.include_tasks: 'test_subvolume_default.yml'
|
||||
|
||||
- ansible.builtin.include_tasks: 'test_snapshot_skip.yml'
|
||||
- ansible.builtin.include_tasks: 'test_snapshot_clobber.yml'
|
||||
- ansible.builtin.include_tasks: 'test_snapshot_error.yml'
|
||||
|
||||
- ansible.builtin.include_tasks: 'test_subvolume_whitespace.yml'
|
@ -0,0 +1,32 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- ansible.builtin.include_tasks: 'test_filesystem_matching.yml'
|
||||
|
||||
- name: "Execute all test scenario for unmounted filesystem"
|
||||
ansible.builtin.include_tasks: 'run_common_tests.yml'
|
||||
|
||||
- name: "Execute test scenarios where non-root subvolume is mounted"
|
||||
block:
|
||||
- name: Create subvolume '/nonroot'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
name: "/nonroot"
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
state: "present"
|
||||
register: nonroot
|
||||
- name: "Mount subvolume '/nonroot'"
|
||||
ansible.posix.mount:
|
||||
src: "{{ nonroot.filesystem.devices | first }}"
|
||||
path: /mnt
|
||||
opts: "subvolid={{ nonroot.target_subvolume_id }}"
|
||||
fstype: btrfs
|
||||
state: mounted
|
||||
- name: "Run tests for explicit, mounted single device configuration"
|
||||
ansible.builtin.include_tasks: 'run_common_tests.yml'
|
||||
- name: "Unmount subvolume /nonroot"
|
||||
ansible.posix.mount:
|
||||
path: /mnt
|
||||
state: absent
|
@ -0,0 +1,37 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: "Create file {{ item.file }} to back loop device {{ item.loop }}"
|
||||
ansible.builtin.command:
|
||||
cmd: "dd if=/dev/zero of={{ item.file }} bs=1M count=200" ## minimum count 109
|
||||
creates: "{{ item.file }}"
|
||||
with_items: "{{ btrfs_subvolume_configs }}"
|
||||
|
||||
- name: "Setup loop device {{ item.loop }}"
|
||||
ansible.builtin.command:
|
||||
cmd: "losetup {{ item.loop }} {{ item.file }}"
|
||||
creates: "{{ item.loop }}"
|
||||
with_items: "{{ btrfs_subvolume_configs }}"
|
||||
|
||||
- name: Create single device btrfs filesystem
|
||||
ansible.builtin.command:
|
||||
cmd: "mkfs.btrfs --label {{ btrfs_subvolume_single_label }} -f {{ btrfs_subvolume_single_devices | first }}"
|
||||
changed_when: True
|
||||
|
||||
- name: Create multiple device btrfs filesystem
|
||||
ansible.builtin.command:
|
||||
cmd: "mkfs.btrfs --label {{ btrfs_subvolume_multiple_label }} -f -d raid0 {{ btrfs_subvolume_multiple_devices | join(' ') }}"
|
||||
changed_when: True
|
||||
|
||||
# Typically created by udev, but apparently missing on Alpine
|
||||
- name: Create btrfs control device node
|
||||
ansible.builtin.command:
|
||||
cmd: "mknod /dev/btrfs-control c 10 234"
|
||||
creates: "/dev/btrfs-control"
|
||||
|
||||
- name: Force rescan to ensure all device are detected
|
||||
ansible.builtin.command:
|
||||
cmd: "btrfs device scan"
|
||||
changed_when: True
|
@ -0,0 +1,80 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: "Match targeted filesystem by label"
|
||||
block:
|
||||
- name: Match '{{ btrfs_subvolume_target_label }}' filesystem by label
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
name: "/match_label"
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
state: "present"
|
||||
register: result
|
||||
|
||||
- name: Validate the '{{ btrfs_subvolume_target_label }}' filesystem was chosen
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result.filesystem.label == btrfs_subvolume_target_label
|
||||
|
||||
- name: "Match targeted filesystem by uuid"
|
||||
block:
|
||||
- name: Match '{{ btrfs_subvolume_target_label }}' filesystem by uuid
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
name: "/match_uuid"
|
||||
filesystem_uuid: "{{ result.filesystem.uuid }}"
|
||||
state: "present"
|
||||
register: result
|
||||
|
||||
- name: Validate the '{{ btrfs_subvolume_target_label }}' filesystem was chosen
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result.filesystem.label == btrfs_subvolume_target_label
|
||||
|
||||
- name: "Match targeted filesystem by devices"
|
||||
block:
|
||||
- name: Match '{{ btrfs_subvolume_target_label }}' filesystem by device
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
name: "/match_device"
|
||||
filesystem_device: "{{ result.filesystem.devices | first }}"
|
||||
state: "present"
|
||||
register: result
|
||||
|
||||
- name: Validate the '{{ btrfs_subvolume_target_label }}' filesystem was chosen
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result.filesystem.label == btrfs_subvolume_target_label
|
||||
|
||||
- name: "Match only mounted filesystem"
|
||||
block:
|
||||
- name: "Mount filesystem '{{ btrfs_subvolume_target_label }}'"
|
||||
ansible.posix.mount:
|
||||
src: "{{ result.filesystem.devices | first }}"
|
||||
path: /mnt
|
||||
opts: "subvolid={{ 5 }}"
|
||||
fstype: btrfs
|
||||
state: mounted
|
||||
|
||||
- name: Print current status
|
||||
community.general.btrfs_info:
|
||||
|
||||
- name: Match '{{ btrfs_subvolume_target_label }}' filesystem when only mount
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
name: "/match_only_mounted"
|
||||
state: "present"
|
||||
register: result
|
||||
|
||||
- name: "Unmount filesystem '{{ btrfs_subvolume_target_label }}'"
|
||||
ansible.posix.mount:
|
||||
path: /mnt
|
||||
state: absent
|
||||
|
||||
- name: Validate the '{{ btrfs_subvolume_target_label }}' filesystem was chosen
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result.filesystem.label == btrfs_subvolume_target_label
|
||||
when: False # TODO don't attempt this if the host already has a pre-existing btrfs filesystem
|
@ -0,0 +1,41 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Create a snapshot, overwriting if one already exists at path
|
||||
block:
|
||||
- name: Create a snapshot named 'snapshot_clobber'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/snapshot_clobber"
|
||||
snapshot_source: "/"
|
||||
snapshot_conflict: "clobber"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Snapshot 'snapshot_clobber' created
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Create a snapshot named 'snapshot_clobber' (no idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/snapshot_clobber"
|
||||
snapshot_source: "/"
|
||||
snapshot_conflict: "clobber"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Snapshot 'snapshot_clobber' created (no idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Cleanup created snapshot
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/snapshot_clobber"
|
||||
state: "absent"
|
@ -0,0 +1,42 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Create a snapshot, erroring if one already exists at path
|
||||
block:
|
||||
- name: Create a snapshot named 'snapshot_error'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/snapshot_error"
|
||||
snapshot_source: "/"
|
||||
snapshot_conflict: "error"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Snapshot 'snapshot_error' created
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Create a snapshot named 'snapshot_error' (no idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/snapshot_error"
|
||||
snapshot_source: "/"
|
||||
snapshot_conflict: "error"
|
||||
state: "present"
|
||||
register: result
|
||||
ignore_errors: true
|
||||
- name: Snapshot 'snapshot_error' created (no idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Cleanup created snapshot
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/snapshot_error"
|
||||
state: "absent"
|
@ -0,0 +1,41 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Create a snapshot if one does not already exist at path
|
||||
block:
|
||||
- name: Create a snapshot named 'snapshot_skip'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/snapshot_skip"
|
||||
snapshot_source: "/"
|
||||
snapshot_conflict: "skip"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Snapshot 'snapshot_skip' created
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Create a snapshot named 'snapshot_skip' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/snapshot_skip"
|
||||
snapshot_source: "/"
|
||||
snapshot_conflict: "skip"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Snapshot 'snapshot_skip' created (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Cleanup created snapshot
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/snapshot_skip"
|
||||
state: "absent"
|
@ -0,0 +1,99 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Change the default subvolume
|
||||
block:
|
||||
- name: Update filesystem default subvolume to '@'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
default: True
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/@"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume '@' set to default
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
- name: Update filesystem default subvolume to '@' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
default: True
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/@"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume '@' set to default (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Revert the default subvolume
|
||||
block:
|
||||
- name: Revert filesystem default subvolume to '/'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
default: True
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume '/' set to default
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
- name: Revert filesystem default subvolume to '/' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
default: True
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume '/' set to default (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
|
||||
- name: Change the default subvolume again
|
||||
block:
|
||||
- name: Update filesystem default subvolume to '@'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
default: True
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/@"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume '@' set to default
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Revert custom default subvolume to fs_tree root when deleted
|
||||
block:
|
||||
- name: Delete custom default subvolume '@'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/@"
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume '@' deleted
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
- name: Delete custom default subvolume '@' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/@"
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume '@' deleted (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
@ -0,0 +1,61 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Create parent subvolume 'container'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container"
|
||||
state: "present"
|
||||
|
||||
- name: Create a nested subvolume
|
||||
block:
|
||||
- name: Create a subvolume named 'nested' inside 'container'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container/nested"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume 'container/nested' created
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
- name: Create a subvolume named 'nested' inside 'container' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container/nested"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume 'container/nested' created (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Remove a nested subvolume
|
||||
block:
|
||||
- name: Remove a subvolume named 'nested' inside 'container'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container/nested"
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume 'container/nested' removed
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
- name: Remove a subvolume named 'nested' inside 'container' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container/nested"
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume 'container/nested' removed (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
@ -0,0 +1,86 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Recursively create subvolumes
|
||||
block:
|
||||
- name: Create a subvolume named '/recursive/son/grandson'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/recursive/son/grandson"
|
||||
recursive: Yes
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume named '/recursive/son/grandson' created
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Create a subvolume named '/recursive/son/grandson' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/recursive/son/grandson"
|
||||
recursive: Yes
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume named '/recursive/son/grandson' created (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Create a subvolume named '/recursive/daughter/granddaughter'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/recursive/daughter/granddaughter"
|
||||
recursive: Yes
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume named '/recursive/son/grandson' created
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Create a subvolume named '/recursive/daughter/granddaughter' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/recursive/daughter/granddaughter"
|
||||
recursive: Yes
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume named '/recursive/son/grandson' created (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Recursively remove subvolumes
|
||||
block:
|
||||
- name: Remove subvolume '/recursive' and all descendents
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/recursive"
|
||||
recursive: Yes
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume '/recursive' removed
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Remove subvolume '/recursive' and all descendents (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/recursive"
|
||||
recursive: Yes
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume '/recursive' removed (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
@ -0,0 +1,54 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Create a simple subvolume
|
||||
block:
|
||||
- name: Create a subvolume named 'simple'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/simple"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume named 'simple' created
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
- name: Create a subvolume named 'simple' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/simple"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume named 'simple' created (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Remove a simple subvolume
|
||||
block:
|
||||
- name: Remove a subvolume named 'simple'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/simple"
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume named 'simple' removed
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
- name: Remove a subvolume named 'simple' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/simple"
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume named 'simple' removed (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
@ -0,0 +1,62 @@
|
||||
---
|
||||
# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Create a subvolume named 'container'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container"
|
||||
state: "present"
|
||||
|
||||
- name: Create a subvolume with whitespace in the name
|
||||
block:
|
||||
- name: Create a subvolume named 'container/my data'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container/my data"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume named 'container/my data' created
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
- name: Create a subvolume named 'container/my data' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container/my data"
|
||||
state: "present"
|
||||
register: result
|
||||
- name: Subvolume named 'container/my data' created (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
||||
|
||||
- name: Remove a subvolume with whitespace in the name
|
||||
block:
|
||||
- name: Remove a subvolume named 'container/my data'
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container/my data"
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume named 'container/my data' removed
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is changed
|
||||
|
||||
- name: Remove a subvolume named 'container/my data' (idempotency)
|
||||
community.general.btrfs_subvolume:
|
||||
automount: Yes
|
||||
filesystem_label: "{{ btrfs_subvolume_target_label }}"
|
||||
name: "/container/my data"
|
||||
state: "absent"
|
||||
register: result
|
||||
- name: Subvolume named 'container/my data' removed (idempotency)
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result is not changed
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
all:
|
||||
hosts:
|
||||
testhost:
|
||||
ansible_connection: local
|
@ -0,0 +1,100 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# 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
|
||||
|
||||
- block:
|
||||
- name: Create temporary playbook files
|
||||
tempfile:
|
||||
state: file
|
||||
suffix: temp
|
||||
loop: "{{ tests }}"
|
||||
loop_control:
|
||||
loop_var: test
|
||||
label: "{{ test.name }}"
|
||||
register: temporary_playbook_files
|
||||
|
||||
- name: Set temporary playbook file content
|
||||
copy:
|
||||
content: "{{ test.playbook }}"
|
||||
dest: "{{ temporary_playbook_files.results[test_idx].path }}"
|
||||
loop: "{{ tests }}"
|
||||
loop_control:
|
||||
loop_var: test
|
||||
index_var: test_idx
|
||||
label: "{{ test.name }}"
|
||||
|
||||
- name: Collect outputs
|
||||
command: "ansible-playbook -i {{ inventory }} {{ playbook }}"
|
||||
environment: "{{ test.environment }}"
|
||||
loop: "{{ tests }}"
|
||||
loop_control:
|
||||
loop_var: test
|
||||
label: "{{ test.name }}"
|
||||
register: outputs
|
||||
changed_when: false
|
||||
vars:
|
||||
inventory: "{{ role_path }}/inventory.yml"
|
||||
playbook: "
|
||||
{%- for result in temporary_playbook_files.results -%}
|
||||
{%- if result.test.name == test.name -%}
|
||||
{{- result.path -}}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}"
|
||||
|
||||
- name: Assert test output equals expected output
|
||||
assert:
|
||||
that: result.output.differences | length == 0
|
||||
loop: "{{ results }}"
|
||||
loop_control:
|
||||
loop_var: result
|
||||
label: "{{ result.name }}"
|
||||
register: assertions
|
||||
vars:
|
||||
results: >-
|
||||
{%- set results = [] -%}
|
||||
{%- for result in outputs.results -%}
|
||||
{%- set differences = [] -%}
|
||||
{%- for i in range([result.test.expected_output | count, result.stdout_lines | count] | max) -%}
|
||||
{%- set line = "line_%s" | format(i+1) -%}
|
||||
{%- set test_line = result.stdout_lines[i] | default(none) -%}
|
||||
{%- set expected_lines = result.test.expected_output[i] | default(none) -%}
|
||||
{%- if expected_lines is not string and expected_lines is not none -%}
|
||||
{%- if test_line not in expected_lines -%}
|
||||
{{- differences.append({
|
||||
line: {
|
||||
'expected_one_of': expected_lines,
|
||||
'got': test_line }}) -}}
|
||||
{%- endif -%}
|
||||
{%- else -%}
|
||||
{%- if expected_lines != test_line -%}
|
||||
{{- differences.append({
|
||||
line: {
|
||||
'expected': expected_lines,
|
||||
'got': test_line }}) -}}
|
||||
{%- endif -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{{- results.append({
|
||||
'name': result.test.name,
|
||||
'output': {
|
||||
'differences': differences,
|
||||
'expected': result.test.expected_output,
|
||||
'got': result.stdout_lines }}) -}}
|
||||
{%- endfor -%}
|
||||
{{- results -}}
|
||||
|
||||
always:
|
||||
- name: Remove temporary playbooks
|
||||
file:
|
||||
path: "{{ temporary_file.path }}"
|
||||
state: absent
|
||||
loop: "{{ temporary_playbook_files.results }}"
|
||||
loop_control:
|
||||
loop_var: temporary_file
|
||||
label: "{{ temporary_file.test.name }}: {{ temporary_file.path }}"
|
@ -0,0 +1,6 @@
|
||||
# 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
|
||||
|
||||
azp/posix/3
|
||||
needs/target/callback
|
@ -0,0 +1,462 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# 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
|
||||
|
||||
- name: Run tests
|
||||
include_role:
|
||||
name: callback
|
||||
vars:
|
||||
tests:
|
||||
- name: Not using diy callback options
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"ok: [testhost] => {",
|
||||
" \"msg\": \"sample debug msg\"",
|
||||
"}",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set playbook_on_start_msg callback using environment variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
ANSIBLE_CALLBACK_DIY_PLAYBOOK_ON_START_MSG: "Sample output Sample playbook message"
|
||||
playbook: |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
expected_output: [
|
||||
"Sample output Sample playbook message",
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"ok: [testhost] => {",
|
||||
" \"msg\": \"sample debug msg\"",
|
||||
"}",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set playbook_on_play_start_msg callback using play variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- name: Sample play name
|
||||
hosts: testhost
|
||||
gather_facts: false
|
||||
vars:
|
||||
ansible_callback_diy_playbook_on_play_start_msg: Sample output {{ ansible_callback_diy.play.name }}
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
expected_output: [
|
||||
"Sample output Sample play name",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"ok: [testhost] => {",
|
||||
" \"msg\": \"sample debug msg\"",
|
||||
"}",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set playbook_on_task_start_msg callback using play variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
vars:
|
||||
ansible_callback_diy_playbook_on_task_start_msg: Sample output {{ ansible_callback_diy.task.name }}
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"Sample output Sample task name",
|
||||
"ok: [testhost] => {",
|
||||
" \"msg\": \"sample debug msg\"",
|
||||
"}",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set playbook_on_task_start_msg callback using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
vars:
|
||||
ansible_callback_diy_playbook_on_task_start_msg: Sample output {{ ansible_callback_diy.task.name }}
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"Sample output Sample task name",
|
||||
"ok: [testhost] => {",
|
||||
" \"msg\": \"sample debug msg\"",
|
||||
"}",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set runner_on_ok_msg callback using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
vars:
|
||||
ansible_callback_diy_runner_on_ok_msg: Sample output {{ ansible_callback_diy.result.output.msg }}
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"Sample output sample debug msg",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set runner_on_failed_msg callback using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
failed_when: true
|
||||
ignore_errors: true
|
||||
vars:
|
||||
ansible_callback_diy_runner_on_failed_msg: Sample output Sample failure message
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"Sample output Sample failure message",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1 "
|
||||
]
|
||||
|
||||
- name: Set runner_on_skipped_msg callback using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
when: false
|
||||
vars:
|
||||
ansible_callback_diy_runner_on_skipped_msg: Sample output Skipped {{ ansible_callback_diy.task.name }}
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"Sample output Skipped Sample task name",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=0 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set runner_item_on_ok_msg callback using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg {{ item }}
|
||||
loop:
|
||||
- sample item 1
|
||||
- sample item 2
|
||||
- sample item 3
|
||||
vars:
|
||||
ansible_callback_diy_runner_item_on_ok_msg: Sample output Looping {{ ansible_callback_diy.result.output.msg }}
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"Sample output Looping sample debug msg sample item 1",
|
||||
"Sample output Looping sample debug msg sample item 2",
|
||||
"Sample output Looping sample debug msg sample item 3",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set runner_item_on_failed_msg callback using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg {{ item }}
|
||||
loop:
|
||||
- sample item 1
|
||||
- sample item 2
|
||||
- sample item 3
|
||||
failed_when: item == 'sample item 2'
|
||||
ignore_errors: true
|
||||
vars:
|
||||
ansible_callback_diy_runner_item_on_failed_msg: Sample output Looping sample failure message
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"ok: [testhost] => (item=sample item 1) => {",
|
||||
" \"msg\": \"sample debug msg sample item 1\"",
|
||||
"}",
|
||||
"Sample output Looping sample failure message",
|
||||
"ok: [testhost] => (item=sample item 3) => {",
|
||||
" \"msg\": \"sample debug msg sample item 3\"",
|
||||
"}",
|
||||
[
|
||||
# Apparently a bug was fixed in Ansible, as before it ran through with "All items completed"
|
||||
"fatal: [testhost]: FAILED! => {\"msg\": \"All items completed\"}",
|
||||
"fatal: [testhost]: FAILED! => {\"msg\": \"One or more items failed\"}",
|
||||
],
|
||||
"...ignoring",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1 "
|
||||
]
|
||||
|
||||
- name: Set runner_item_on_skipped_msg callback using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg {{ item }}
|
||||
loop:
|
||||
- sample item 1
|
||||
- sample item 2
|
||||
- sample item 3
|
||||
when: item != 'sample item 2'
|
||||
vars:
|
||||
ansible_callback_diy_runner_item_on_skipped_msg: Sample output Looping Skipped {{ ansible_callback_diy.result.output.item }}
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"ok: [testhost] => (item=sample item 1) => {",
|
||||
" \"msg\": \"sample debug msg sample item 1\"",
|
||||
"}",
|
||||
"Sample output Looping Skipped sample item 2",
|
||||
"ok: [testhost] => (item=sample item 3) => {",
|
||||
" \"msg\": \"sample debug msg sample item 3\"",
|
||||
"}",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set playbook_on_stats_msg callback using play variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
vars:
|
||||
ansible_callback_diy_playbook_on_stats_msg: |+2
|
||||
Sample output stats
|
||||
===============================
|
||||
{% for key in ansible_callback_diy.stats | sort %}
|
||||
{% set color_one = "" %}
|
||||
{% set color_two = "" %}
|
||||
{% if ansible_callback_diy.stats[key] %}
|
||||
{% if key == 'ok' %}
|
||||
{% set prefix = ' ' %}
|
||||
{% set suffix = ' ' %}
|
||||
{% elif key == 'changed' %}
|
||||
{% set prefix = ' ' %}
|
||||
{% set suffix = ' ' %}
|
||||
{% elif key == 'processed' %}
|
||||
{% set prefix = ' ' %}
|
||||
{% set suffix = ' ' %}
|
||||
{% elif key == 'skipped' %}
|
||||
{% set prefix = ' ' %}
|
||||
{% set suffix = ' ' %}
|
||||
{% else %}
|
||||
{% set prefix = "" %}
|
||||
{% set suffix = "" %}
|
||||
{% endif %}
|
||||
{{ color_one }}{{ "%s%s%s" | format(prefix,key,suffix) }}{{ color_two }}: {{ ansible_callback_diy.stats[key] | to_nice_yaml }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"ok: [testhost] => {",
|
||||
" \"msg\": \"sample debug msg\"",
|
||||
"}",
|
||||
" Sample output stats",
|
||||
"===============================",
|
||||
" ok : testhost: 1",
|
||||
"",
|
||||
" processed : testhost: 1"
|
||||
]
|
||||
|
||||
- name: Suppress output on playbook_on_task_start_msg callback using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
vars:
|
||||
ansible_callback_diy_playbook_on_task_start_msg: ''
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"ok: [testhost] => {",
|
||||
" \"msg\": \"sample debug msg\"",
|
||||
"}",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Suppress output on runner_on_ok_msg callback using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
vars:
|
||||
ansible_callback_diy_runner_on_ok_msg: ''
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
|
||||
- name: Set runner_on_ok_msg_color using task variable
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.diy
|
||||
playbook: !unsafe |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
vars:
|
||||
ansible_callback_diy_runner_on_ok_msg: Sample output {{ ansible_callback_diy.result.output.msg }}
|
||||
ansible_callback_diy_runner_on_ok_msg_color: blue
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"Sample output sample debug msg",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
@ -0,0 +1,5 @@
|
||||
# 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
|
||||
|
||||
azp/posix/3
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
# 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: localhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- ping:
|
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# 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
|
||||
|
||||
set -eux
|
||||
|
||||
# ANSIBLE_CALLBACK_WHITELIST has been deprecated in ansible-base 2.11, ANSIBLE_CALLBACKS_ENABLED should be used
|
||||
export ANSIBLE_CALLBACK_WHITELIST="community.general.log_plays,${ANSIBLE_CALLBACK_WHITELIST:-}"
|
||||
export ANSIBLE_CALLBACKS_ENABLED="community.general.log_plays,${ANSIBLE_CALLBACKS_ENABLED:-}"
|
||||
|
||||
# run play, should create log and dir if needed
|
||||
export ANSIBLE_LOG_FOLDER="logit"
|
||||
ansible-playbook ping_log.yml -v "$@"
|
||||
[[ -f "${ANSIBLE_LOG_FOLDER}/localhost" ]]
|
||||
|
||||
# now force it to fail
|
||||
export ANSIBLE_LOG_FOLDER="logit.file"
|
||||
touch "${ANSIBLE_LOG_FOLDER}"
|
||||
ansible-playbook ping_log.yml -v "$@" 2>&1| grep 'Failure using method (v2_runner_on_ok) in callback plugin'
|
||||
[[ ! -f "${ANSIBLE_LOG_FOLDER}/localhost" ]]
|
@ -0,0 +1,6 @@
|
||||
# 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
|
||||
|
||||
azp/posix/1
|
||||
needs/target/callback
|
@ -0,0 +1,101 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# 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
|
||||
|
||||
- name: Run tests
|
||||
include_role:
|
||||
name: callback
|
||||
vars:
|
||||
tests:
|
||||
- name: Basic run
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.yaml
|
||||
playbook: |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Sample task name
|
||||
debug:
|
||||
msg: sample debug msg
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Sample task name] ********************************************************",
|
||||
"ok: [testhost] => ",
|
||||
" msg: sample debug msg",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
- name: Test umlauts in multiline
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.yaml
|
||||
playbook: |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Umlaut output
|
||||
debug:
|
||||
msg: "äöü\néêè\nßï☺"
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Umlaut output] ***********************************************************",
|
||||
"ok: [testhost] => ",
|
||||
" msg: |-",
|
||||
" äöü",
|
||||
" éêè",
|
||||
" ßï☺",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
||||
- name: Test to_yaml
|
||||
environment:
|
||||
ANSIBLE_NOCOLOR: 'true'
|
||||
ANSIBLE_FORCE_COLOR: 'false'
|
||||
ANSIBLE_STDOUT_CALLBACK: community.general.yaml
|
||||
playbook: |
|
||||
- hosts: testhost
|
||||
gather_facts: false
|
||||
vars:
|
||||
data: |
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
tasks:
|
||||
- name: Test to_yaml
|
||||
debug:
|
||||
msg: "{{ '{{' }}'{{ '{{' }}'{{ '}}' }} data | to_yaml {{ '{{' }}'{{ '}}' }}'{{ '}}' }}"
|
||||
# The above should be: msg: "{{ data | to_yaml }}"
|
||||
# Unfortunately, the way Ansible handles templating, we need to do some funny 'escaping' tricks...
|
||||
expected_output: [
|
||||
"",
|
||||
"PLAY [testhost] ****************************************************************",
|
||||
"",
|
||||
"TASK [Test to_yaml] ************************************************************",
|
||||
"ok: [testhost] => ",
|
||||
" msg: |-",
|
||||
" 'line 1",
|
||||
" ",
|
||||
" line 2",
|
||||
" ",
|
||||
" line 3",
|
||||
" ",
|
||||
" '",
|
||||
"",
|
||||
"PLAY RECAP *********************************************************************",
|
||||
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
||||
]
|
@ -0,0 +1,7 @@
|
||||
# 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
|
||||
|
||||
azp/posix/2
|
||||
destructive
|
||||
skip/aix
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
dependencies:
|
||||
- setup_pkg_mgr
|
@ -0,0 +1,22 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- import_tasks: setup.yml
|
||||
- name: Set default environment
|
||||
set_fact:
|
||||
cargo_environment: {}
|
||||
- name: Set special environment to work around cargo bugs
|
||||
set_fact:
|
||||
cargo_environment:
|
||||
# See https://github.com/rust-lang/cargo/issues/10230#issuecomment-1201662729:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
|
||||
when: has_cargo | default(false) and ansible_distribution == 'Alpine'
|
||||
- block:
|
||||
- import_tasks: test_general.yml
|
||||
- import_tasks: test_version.yml
|
||||
environment: "{{ cargo_environment }}"
|
||||
when: has_cargo | default(false)
|
||||
- import_tasks: test_rustup_cargo.yml
|
||||
when: rustup_cargo_bin | default(false)
|
@ -0,0 +1,42 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- block:
|
||||
- name: Install cargo
|
||||
package:
|
||||
name: cargo
|
||||
state: present
|
||||
- set_fact:
|
||||
has_cargo: true
|
||||
when:
|
||||
- ansible_system != 'FreeBSD'
|
||||
- ansible_distribution != 'MacOSX'
|
||||
- ansible_distribution != 'RedHat' or ansible_distribution_version is version('8.0', '>=')
|
||||
- ansible_distribution != 'CentOS' or ansible_distribution_version is version('7.0', '>=')
|
||||
- ansible_distribution != 'Ubuntu' or ansible_distribution_version is version('18', '>=')
|
||||
|
||||
- block:
|
||||
- name: Install rust (containing cargo)
|
||||
package:
|
||||
name: rust
|
||||
state: present
|
||||
- set_fact:
|
||||
has_cargo: true
|
||||
when:
|
||||
- ansible_system == 'FreeBSD' and ansible_distribution_version is version('13.0', '>')
|
||||
|
||||
- block:
|
||||
- name: Download rustup
|
||||
get_url:
|
||||
url: https://sh.rustup.rs
|
||||
dest: /tmp/sh.rustup.rs
|
||||
mode: "0750"
|
||||
force: true
|
||||
- name: Install rustup cargo
|
||||
command: /tmp/sh.rustup.rs -y
|
||||
- set_fact:
|
||||
rustup_cargo_bin: "{{ lookup('env', 'HOME') }}/.cargo/bin/cargo"
|
||||
when:
|
||||
- ansible_distribution != 'CentOS' or ansible_distribution_version is version('7.0', '>=')
|
@ -0,0 +1,35 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: Ensure application helloworld is uninstalled
|
||||
community.general.cargo:
|
||||
state: absent
|
||||
name: helloworld
|
||||
register: uninstall_absent_helloworld
|
||||
|
||||
- name: Install application helloworld
|
||||
community.general.cargo:
|
||||
name: helloworld
|
||||
register: install_absent_helloworld
|
||||
|
||||
- name: Install application helloworld again
|
||||
community.general.cargo:
|
||||
name: helloworld
|
||||
register: install_present_helloworld
|
||||
ignore_errors: true
|
||||
|
||||
- name: Uninstall application helloworld
|
||||
community.general.cargo:
|
||||
state: absent
|
||||
name: helloworld
|
||||
register: uninstall_present_helloworld
|
||||
|
||||
- name: Check assertions helloworld
|
||||
assert:
|
||||
that:
|
||||
- uninstall_absent_helloworld is not changed
|
||||
- install_absent_helloworld is changed
|
||||
- install_present_helloworld is not changed
|
||||
- uninstall_present_helloworld is changed
|
@ -0,0 +1,23 @@
|
||||
---
|
||||
# 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
|
||||
#
|
||||
- name: Install application helloworld
|
||||
community.general.cargo:
|
||||
executable: "{{ rustup_cargo_bin }}"
|
||||
name: helloworld
|
||||
register: rustup_install_absent_helloworld
|
||||
|
||||
- name: Uninstall application helloworld
|
||||
community.general.cargo:
|
||||
executable: "{{ rustup_cargo_bin }}"
|
||||
state: absent
|
||||
name: helloworld
|
||||
register: rustup_uninstall_present_helloworld
|
||||
|
||||
- name: Check assertions helloworld
|
||||
assert:
|
||||
that:
|
||||
- rustup_install_absent_helloworld is changed
|
||||
- rustup_uninstall_present_helloworld is changed
|
@ -0,0 +1,50 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: Install application helloworld-yliu 0.1.0
|
||||
community.general.cargo:
|
||||
name: helloworld-yliu
|
||||
version: 0.1.0
|
||||
register: install_helloworld_010
|
||||
|
||||
- name: Install application helloworld-yliu 0.1.0 (idempotent)
|
||||
community.general.cargo:
|
||||
name: helloworld-yliu
|
||||
version: 0.1.0
|
||||
register: install_helloworld_010_idem
|
||||
|
||||
- name: Upgrade helloworld-yliu 0.1.0
|
||||
community.general.cargo:
|
||||
name: helloworld-yliu
|
||||
state: latest
|
||||
register: upgrade_helloworld_010
|
||||
|
||||
- name: Upgrade helloworld-yliu 0.1.0 (idempotent)
|
||||
community.general.cargo:
|
||||
name: helloworld-yliu
|
||||
state: latest
|
||||
register: upgrade_helloworld_010_idem
|
||||
|
||||
- name: Downgrade helloworld-yliu 0.1.0
|
||||
community.general.cargo:
|
||||
name: helloworld-yliu
|
||||
version: 0.1.0
|
||||
register: downgrade_helloworld_010
|
||||
|
||||
- name: Downgrade helloworld-yliu 0.1.0 (idempotent)
|
||||
community.general.cargo:
|
||||
name: helloworld-yliu
|
||||
version: 0.1.0
|
||||
register: downgrade_helloworld_010_idem
|
||||
|
||||
- name: Check assertions helloworld-yliu
|
||||
assert:
|
||||
that:
|
||||
- install_helloworld_010 is changed
|
||||
- install_helloworld_010_idem is not changed
|
||||
- upgrade_helloworld_010 is changed
|
||||
- upgrade_helloworld_010_idem is not changed
|
||||
- downgrade_helloworld_010 is changed
|
||||
- downgrade_helloworld_010_idem is not changed
|
@ -0,0 +1,10 @@
|
||||
# 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
|
||||
|
||||
azp/posix/1
|
||||
destructive
|
||||
skip/aix
|
||||
skip/osx
|
||||
skip/macos
|
||||
skip/freebsd
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
dependencies:
|
||||
- setup_pkg_mgr
|
@ -0,0 +1,68 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# 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
|
||||
|
||||
- name: test cloud-init
|
||||
# TODO: check for a workaround
|
||||
# install 'cloud-init'' failed: dpkg-divert: error: `diversion of /etc/init/ureadahead.conf
|
||||
# to /etc/init/ureadahead.conf.disabled by cloud-init' clashes with `local diversion of
|
||||
# /etc/init/ureadahead.conf to /etc/init/ureadahead.conf.distrib
|
||||
# https://bugs.launchpad.net/ubuntu/+source/ureadahead/+bug/997838
|
||||
# Will also have to skip on OpenSUSE when running on Python 2 on newer Leap versions
|
||||
# (!= 42 and >= 15) ascloud-init will install the Python 3 package, breaking our build on py2.
|
||||
when:
|
||||
- not (ansible_distribution == "Ubuntu" and ansible_distribution_major_version|int == 14)
|
||||
- not (ansible_os_family == "Suse" and ansible_distribution_major_version|int != 42 and ansible_python.version.major != 3)
|
||||
- not (ansible_distribution == "CentOS" and ansible_distribution_major_version|int == 8) # TODO: cannot start service
|
||||
- not (ansible_distribution == 'Archlinux') # TODO: package seems to be broken, cannot be downloaded from mirrors?
|
||||
- not (ansible_distribution == 'Alpine') # TODO: not sure what's wrong here, the module doesn't return what the tests expect
|
||||
block:
|
||||
- name: setup install cloud-init
|
||||
package:
|
||||
name:
|
||||
- cloud-init
|
||||
- udev
|
||||
|
||||
- name: Ensure systemd-network user exists
|
||||
user:
|
||||
name: systemd-network
|
||||
state: present
|
||||
when: ansible_distribution == 'Fedora' and ansible_distribution_major_version|int >= 37
|
||||
|
||||
- name: setup run cloud-init
|
||||
service:
|
||||
name: cloud-init-local
|
||||
state: restarted
|
||||
|
||||
- name: test gather cloud-init facts in check mode
|
||||
cloud_init_data_facts:
|
||||
check_mode: true
|
||||
register: result
|
||||
- name: verify test gather cloud-init facts in check mode
|
||||
assert:
|
||||
that:
|
||||
- result.cloud_init_data_facts.status.v1 is defined
|
||||
- result.cloud_init_data_facts.status.v1.stage is defined
|
||||
- not result.cloud_init_data_facts.status.v1.stage
|
||||
- cloud_init_data_facts.status.v1 is defined
|
||||
- cloud_init_data_facts.status.v1.stage is defined
|
||||
- not cloud_init_data_facts.status.v1.stage
|
||||
|
||||
- name: test gather cloud-init facts
|
||||
cloud_init_data_facts:
|
||||
register: result
|
||||
- name: verify test gather cloud-init facts
|
||||
assert:
|
||||
that:
|
||||
- result.cloud_init_data_facts.status.v1 is defined
|
||||
- result.cloud_init_data_facts.status.v1.stage is defined
|
||||
- not result.cloud_init_data_facts.status.v1.stage
|
||||
- cloud_init_data_facts.status.v1 is defined
|
||||
- cloud_init_data_facts.status.v1.stage is defined
|
||||
- not cloud_init_data_facts.status.v1.stage
|
@ -0,0 +1,56 @@
|
||||
# Copyright 2012, Dag Wieers <dag@wieers.com>
|
||||
# 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
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.playbook.conditional import Conditional
|
||||
from ansible.plugins.action import ActionBase
|
||||
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
''' Fail with custom message '''
|
||||
|
||||
_requires_connection = False
|
||||
|
||||
_VALID_ARGS = frozenset(('msg', 'that'))
|
||||
|
||||
def _make_safe(self, text):
|
||||
# A simple str(text) won't do it since AnsibleUnsafeText is clever :-)
|
||||
return ''.join(chr(ord(x)) for x in text)
|
||||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
if task_vars is None:
|
||||
task_vars = dict()
|
||||
|
||||
result = super(ActionModule, self).run(tmp, task_vars)
|
||||
del tmp # tmp no longer has any effect
|
||||
|
||||
if 'that' not in self._task.args:
|
||||
raise AnsibleError('conditional required in "that" string')
|
||||
|
||||
fail_msg = 'Assertion failed'
|
||||
success_msg = 'All assertions passed'
|
||||
|
||||
thats = self._task.args['that']
|
||||
|
||||
cond = Conditional(loader=self._loader)
|
||||
result['_ansible_verbose_always'] = True
|
||||
|
||||
for that in thats:
|
||||
cond.when = [str(self._make_safe(that))]
|
||||
test_result = cond.evaluate_conditional(templar=self._templar, all_vars=task_vars)
|
||||
if not test_result:
|
||||
result['failed'] = True
|
||||
result['evaluated_to'] = test_result
|
||||
result['assertion'] = that
|
||||
|
||||
result['msg'] = fail_msg
|
||||
|
||||
return result
|
||||
|
||||
result['changed'] = False
|
||||
result['msg'] = success_msg
|
||||
return result
|
@ -0,0 +1,5 @@
|
||||
# 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
|
||||
|
||||
azp/posix/2
|
@ -0,0 +1,58 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2022, Alexei Znamensky <russoz@gmail.com>
|
||||
# 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
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
DOCUMENTATION = ""
|
||||
|
||||
EXAMPLES = ""
|
||||
|
||||
RETURN = ""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt as fmt
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
cmd=dict(type="str", default="echo"),
|
||||
path_prefix=dict(type="str"),
|
||||
arg_formats=dict(type="dict", default={}),
|
||||
arg_order=dict(type="raw", required=True),
|
||||
arg_values=dict(type="dict", default={}),
|
||||
check_mode_skip=dict(type="bool", default=False),
|
||||
aa=dict(type="raw"),
|
||||
tt=dict(),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
p = module.params
|
||||
|
||||
info = None
|
||||
|
||||
arg_formats = {}
|
||||
for arg, fmt_spec in p['arg_formats'].items():
|
||||
func = getattr(fmt, fmt_spec['func'])
|
||||
args = fmt_spec.get("args", [])
|
||||
|
||||
arg_formats[arg] = func(*args)
|
||||
|
||||
runner = CmdRunner(module, [module.params["cmd"], '--'], arg_formats=arg_formats, path_prefix=module.params["path_prefix"])
|
||||
|
||||
with runner.context(p['arg_order'], check_mode_skip=p['check_mode_skip']) as ctx:
|
||||
result = ctx.run(**p['arg_values'])
|
||||
info = ctx.run_info
|
||||
check = "check"
|
||||
rc, out, err = result if result is not None else (None, None, None)
|
||||
|
||||
module.exit_json(rc=rc, out=out, err=err, info=info)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
dependencies:
|
||||
- setup_remote_tmp_dir
|
@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2022, Alexei Znamensky
|
||||
# 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
|
||||
|
||||
- name: parameterized test cmd_echo
|
||||
ansible.builtin.include_tasks:
|
||||
file: test_cmd_echo.yml
|
||||
loop: "{{ cmd_echo_tests }}"
|
||||
when: item.condition | default(true) | bool
|
@ -0,0 +1,28 @@
|
||||
---
|
||||
# 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
|
||||
|
||||
- name: create copy of /bin/echo ({{ item.name }})
|
||||
ansible.builtin.copy:
|
||||
src: /bin/echo
|
||||
dest: "{{ item.copy_to }}/echo"
|
||||
mode: "755"
|
||||
when: item.copy_to is defined
|
||||
|
||||
- name: test cmd_echo module ({{ item.name }})
|
||||
cmd_echo:
|
||||
cmd: "{{ item.cmd | default(omit) }}"
|
||||
path_prefix: "{{ item.path_prefix | default(omit) }}"
|
||||
arg_formats: "{{ item.arg_formats | default(omit) }}"
|
||||
arg_order: "{{ item.arg_order }}"
|
||||
arg_values: "{{ item.arg_values | default(omit) }}"
|
||||
check_mode_skip: "{{ item.check_mode_skip | default(omit) }}"
|
||||
aa: "{{ item.aa | default(omit) }}"
|
||||
register: test_result
|
||||
check_mode: "{{ item.check_mode | default(omit) }}"
|
||||
ignore_errors: "{{ item.expect_error | default(omit) }}"
|
||||
|
||||
- name: check results ({{ item.name }})
|
||||
_unsafe_assert:
|
||||
that: "{{ item.assertions }}"
|
@ -0,0 +1,262 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2022, Alexei Znamensky
|
||||
# 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
|
||||
|
||||
cmd_echo_tests:
|
||||
- name: set aa and bb value
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
bb:
|
||||
func: as_bool
|
||||
args: [--bb-here]
|
||||
arg_order: 'aa bb'
|
||||
arg_values:
|
||||
bb: true
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --bb-here\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: default aa value
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
bb:
|
||||
func: as_bool
|
||||
args: [--bb-here]
|
||||
arg_order: ['aa', 'bb']
|
||||
arg_values:
|
||||
aa: 43
|
||||
bb: true
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=43 --bb-here\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: implicit aa format
|
||||
arg_formats:
|
||||
bb:
|
||||
func: as_bool
|
||||
args: [--bb-here]
|
||||
arg_order: ['aa', 'bb']
|
||||
arg_values:
|
||||
bb: true
|
||||
aa: 1984
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --aa 1984 --bb-here\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: missing bb format
|
||||
arg_order: ['aa', 'bb']
|
||||
arg_values:
|
||||
bb: true
|
||||
aa: 1984
|
||||
expect_error: true
|
||||
assertions:
|
||||
- test_result is failed
|
||||
- test_result.rc == 1
|
||||
- '"out" not in test_result'
|
||||
- '"err" not in test_result'
|
||||
- >-
|
||||
"MissingArgumentFormat: Cannot find format for parameter bb"
|
||||
in test_result.module_stderr
|
||||
|
||||
- name: missing bb value
|
||||
arg_formats:
|
||||
bb:
|
||||
func: as_bool
|
||||
args: [--bb-here]
|
||||
arg_order: 'aa bb'
|
||||
aa: 1984
|
||||
expect_error: true
|
||||
assertions:
|
||||
- test_result is failed
|
||||
- test_result.rc == 1
|
||||
- '"out" not in test_result'
|
||||
- '"err" not in test_result'
|
||||
- >-
|
||||
"MissingArgumentValue: Cannot find value for parameter bb"
|
||||
in test_result.module_stderr
|
||||
|
||||
- name: set aa and bb value with check_mode on
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
bb:
|
||||
func: as_bool
|
||||
args: [--bb-here]
|
||||
arg_order: 'aa bb'
|
||||
arg_values:
|
||||
bb: true
|
||||
aa: 11
|
||||
check_mode: true
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --bb-here\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: set aa and bb value with check_mode and check_mode_skip on
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
bb:
|
||||
func: as_bool
|
||||
args: [--bb-here]
|
||||
arg_order: 'aa bb'
|
||||
arg_values:
|
||||
bb: true
|
||||
check_mode_skip: true
|
||||
aa: 11
|
||||
check_mode: true
|
||||
expect_error: true # because if result contains rc != 0, ansible assumes error
|
||||
assertions:
|
||||
- test_result.rc == None
|
||||
- test_result.out == None
|
||||
- test_result.err == None
|
||||
|
||||
- name: set aa and tt value
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: use cmd echo
|
||||
cmd: echo
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: use cmd /bin/echo
|
||||
cmd: /bin/echo
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
# this will not be in the regular set of paths get_bin_path() searches
|
||||
- name: use cmd {{ remote_tmp_dir }}/echo
|
||||
condition: >
|
||||
{{
|
||||
ansible_distribution != "MacOSX" and
|
||||
not (ansible_distribution == "CentOS" and ansible_distribution_major_version is version('7.0', '<'))
|
||||
}}
|
||||
copy_to: "{{ remote_tmp_dir }}"
|
||||
cmd: "{{ remote_tmp_dir }}/echo"
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: use cmd echo with path_prefix {{ remote_tmp_dir }}
|
||||
cmd: echo
|
||||
condition: >
|
||||
{{
|
||||
ansible_distribution != "MacOSX" and
|
||||
not (ansible_distribution == "CentOS" and ansible_distribution_major_version is version('7.0', '<'))
|
||||
}}
|
||||
copy_to: "{{ remote_tmp_dir }}"
|
||||
path_prefix: "{{ remote_tmp_dir }}"
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
- name: use cmd never-existed
|
||||
cmd: never-existed
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
expect_error: true
|
||||
assertions:
|
||||
- >
|
||||
"Failed to find required executable" in test_result.msg
|
||||
|
||||
- name: use cmd /usr/bin/never-existed
|
||||
cmd: /usr/bin/never-existed
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
expect_error: true
|
||||
assertions:
|
||||
- >
|
||||
"No such file or directory" in test_result.msg
|
@ -0,0 +1,5 @@
|
||||
# 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
|
||||
|
||||
hidden
|
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
# 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
|
||||
|
||||
set -eux
|
||||
|
||||
[ -f "${INVENTORY}" ]
|
||||
|
||||
# Run connection tests with both the default and C locale.
|
||||
|
||||
ansible-playbook test_connection.yml -i "${INVENTORY}" "$@"
|
||||
|
||||
if ansible --version | grep ansible | grep -E ' 2\.(9|10|11|12|13)\.'; then
|
||||
LC_ALL=C LANG=C ansible-playbook test_connection.yml -i "${INVENTORY}" "$@"
|
||||
fi
|
@ -0,0 +1,48 @@
|
||||
---
|
||||
# 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
|
||||
serial: 1
|
||||
tasks:
|
||||
|
||||
### raw with unicode arg and output
|
||||
|
||||
- name: raw with unicode arg and output
|
||||
raw: echo 汉语
|
||||
register: command
|
||||
- name: check output of raw with unicode arg and output
|
||||
assert:
|
||||
that:
|
||||
- "'汉语' in command.stdout"
|
||||
- command is changed # as of 2.2, raw should default to changed: true for consistency w/ shell/command/script modules
|
||||
|
||||
### copy local file with unicode filename and content
|
||||
|
||||
- name: create local file with unicode filename and content
|
||||
local_action: lineinfile dest={{ local_tmp }}-汉语/汉语.txt create=true line=汉语
|
||||
- name: remove remote file with unicode filename and content
|
||||
action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语/汉语.txt state=absent"
|
||||
- name: create remote directory with unicode name
|
||||
action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语 state=directory"
|
||||
- name: copy local file with unicode filename and content
|
||||
action: "{{ action_prefix }}copy src={{ local_tmp }}-汉语/汉语.txt dest={{ remote_tmp }}-汉语/汉语.txt"
|
||||
|
||||
### fetch remote file with unicode filename and content
|
||||
|
||||
- name: remove local file with unicode filename and content
|
||||
local_action: file path={{ local_tmp }}-汉语/汉语.txt state=absent
|
||||
- name: fetch remote file with unicode filename and content
|
||||
fetch: src={{ remote_tmp }}-汉语/汉语.txt dest={{ local_tmp }}-汉语/汉语.txt fail_on_missing=true validate_checksum=true flat=true
|
||||
|
||||
### remove local and remote temp files
|
||||
|
||||
- name: remove local temp file
|
||||
local_action: file path={{ local_tmp }}-汉语 state=absent
|
||||
- name: remove remote temp file
|
||||
action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语 state=absent"
|
||||
|
||||
### test wait_for_connection plugin
|
||||
- ansible.builtin.wait_for_connection:
|
@ -0,0 +1,7 @@
|
||||
# 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
|
||||
|
||||
azp/posix/3
|
||||
needs/root
|
||||
skip/macos # Skipped due to limitation of macOS 10.15 SIP, please read https://github.com/ansible-collections/community.general/issues/1017#issuecomment-755088895
|
@ -0,0 +1 @@
|
||||
../connection_posix/test.sh
|
@ -0,0 +1,11 @@
|
||||
# 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
|
||||
|
||||
[chroot]
|
||||
chroot-pipelining ansible_ssh_pipelining=true
|
||||
chroot-no-pipelining ansible_ssh_pipelining=false
|
||||
[chroot:vars]
|
||||
ansible_host=/
|
||||
ansible_connection=community.general.chroot
|
||||
ansible_python_interpreter="{{ ansible_playbook_python }}"
|
@ -0,0 +1,6 @@
|
||||
# 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
|
||||
|
||||
non_local
|
||||
unsupported
|
@ -0,0 +1 @@
|
||||
../connection_posix/test.sh
|
@ -0,0 +1,11 @@
|
||||
# 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
|
||||
|
||||
[incus]
|
||||
incus-pipelining ansible_ssh_pipelining=true
|
||||
incus-no-pipelining ansible_ssh_pipelining=false
|
||||
[incus:vars]
|
||||
ansible_host=ubuntu-2204
|
||||
ansible_connection=community.general.incus
|
||||
ansible_python_interpreter=python3
|
@ -0,0 +1,5 @@
|
||||
# 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
|
||||
|
||||
unsupported
|
@ -0,0 +1 @@
|
||||
../connection_posix/test.sh
|
@ -0,0 +1,11 @@
|
||||
# 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
|
||||
|
||||
[jail]
|
||||
jail-pipelining ansible_ssh_pipelining=true
|
||||
jail-no-pipelining ansible_ssh_pipelining=false
|
||||
[jail:vars]
|
||||
ansible_host=freebsd_10_2
|
||||
ansible_connection=community.general.jail
|
||||
ansible_python_interpreter=/usr/local/bin/python
|
@ -0,0 +1,5 @@
|
||||
# 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
|
||||
|
||||
unsupported
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user