mirror of
https://github.com/ansible-collections/ansible.posix.git
synced 2026-03-27 05:43:28 +00:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
727efe9fd2 | ||
|
|
bbc511dbc8 | ||
|
|
04b8a5f918 | ||
|
|
f109c162b0 | ||
|
|
a2ab6881db | ||
|
|
ec72fdc3ab | ||
|
|
d6a997b37d | ||
|
|
d537e7ded8 | ||
|
|
bd9aa64a2b | ||
|
|
6b7dc6ee0a | ||
|
|
a831f22b83 | ||
|
|
cf8e77cf7d | ||
|
|
c4742cfa81 | ||
|
|
bf0ad4aad2 | ||
|
|
0fff8fde30 | ||
|
|
adcb28f806 | ||
|
|
d0e1504f8a | ||
|
|
090706b581 | ||
|
|
e52ae8a9bc | ||
|
|
7df358d74f | ||
|
|
dcd9598e48 | ||
|
|
fc5894171d | ||
|
|
a3b8fdbf25 | ||
|
|
69228e79d2 | ||
|
|
d1fbbb7905 | ||
|
|
50f87b0d15 | ||
|
|
4512e7b1e9 | ||
|
|
297a10fec7 | ||
|
|
139e103b0f | ||
|
|
83a933772c | ||
|
|
6c9616291e | ||
|
|
0224e4d415 | ||
|
|
cc20deaad2 | ||
|
|
5e0a6592ca | ||
|
|
acd5a2b17e | ||
|
|
e629ae2d7c | ||
|
|
abfe36c62f | ||
|
|
6c0b91a3ee | ||
|
|
f7fac90009 | ||
|
|
c4be75114b | ||
|
|
6da0cbb3d3 | ||
|
|
17fc3bcce6 | ||
|
|
d7c7d1d2c8 | ||
|
|
b8ed919011 | ||
|
|
04089e80fb | ||
|
|
55bd196e82 | ||
|
|
f451f2211b | ||
|
|
18c847a8a0 | ||
|
|
ee65205607 | ||
|
|
2c9c3a0f54 | ||
|
|
c1f830f3df | ||
|
|
553b0ea4f7 | ||
|
|
20e294e026 | ||
|
|
18469dbb3e |
@@ -36,7 +36,7 @@ variables:
|
||||
resources:
|
||||
containers:
|
||||
- container: default
|
||||
image: quay.io/ansible/azure-pipelines-test-container:1.9.0
|
||||
image: quay.io/ansible/azure-pipelines-test-container:3.0.0
|
||||
|
||||
pool: Standard
|
||||
|
||||
@@ -53,16 +53,32 @@ stages:
|
||||
targets:
|
||||
- name: CentOS 7
|
||||
test: centos7
|
||||
- name: Fedora 34
|
||||
test: fedora34
|
||||
- name: Fedora 35
|
||||
test: fedora35
|
||||
- name: Fedora 37
|
||||
test: fedora37
|
||||
- name: openSUSE 15 py3
|
||||
test: opensuse15
|
||||
- name: Ubuntu 18.04
|
||||
test: ubuntu1804
|
||||
- name: Ubuntu 20.04
|
||||
test: ubuntu2004
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu2204
|
||||
- stage: Docker_2_14
|
||||
displayName: Docker 2.14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.14/linux/{0}/1
|
||||
targets:
|
||||
- name: CentOS 7
|
||||
test: centos7
|
||||
- name: Fedora 36
|
||||
test: fedora36
|
||||
- name: openSUSE 15 py3
|
||||
test: opensuse15
|
||||
- name: Ubuntu 20.04
|
||||
test: ubuntu2004
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu2204
|
||||
- stage: Docker_2_13
|
||||
displayName: Docker 2.13
|
||||
dependsOn: []
|
||||
@@ -193,12 +209,34 @@ stages:
|
||||
test: macos/12.0
|
||||
- name: RHEL 7.9
|
||||
test: rhel/7.9
|
||||
- name: RHEL 8.5
|
||||
test: rhel/8.5
|
||||
- name: RHEL 8.7
|
||||
test: rhel/8.7
|
||||
- name: RHEL 9.1
|
||||
test: rhel/9.1
|
||||
- name: FreeBSD 12.4
|
||||
test: freebsd/12.4
|
||||
- name: FreeBSD 13.1
|
||||
test: freebsd/13.1
|
||||
- stage: Remote_2_14
|
||||
displayName: Remote 2.14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/matrix.yml
|
||||
parameters:
|
||||
testFormat: 2.14/{0}/1
|
||||
targets:
|
||||
- name: MacOS 12.0
|
||||
test: macos/12.0
|
||||
- name: RHEL 7.9
|
||||
test: rhel/7.9
|
||||
- name: RHEL 8.6
|
||||
test: rhel/8.6
|
||||
- name: RHEL 9.0
|
||||
test: rhel/9.0
|
||||
- name: FreeBSD 12.3
|
||||
test: freebsd/12.3
|
||||
- name: FreeBSD 13.0
|
||||
test: freebsd/13.0
|
||||
- name: FreeBSD 13.1
|
||||
test: freebsd/13.1
|
||||
- stage: Remote_2_13
|
||||
displayName: Remote 2.13
|
||||
dependsOn: []
|
||||
@@ -249,8 +287,6 @@ stages:
|
||||
test: rhel/7.9
|
||||
- name: RHEL 8.3
|
||||
test: rhel/8.3
|
||||
- name: FreeBSD 11.4
|
||||
test: freebsd/11.4
|
||||
- name: FreeBSD 12.2
|
||||
test: freebsd/12.2
|
||||
- stage: Remote_2_10
|
||||
@@ -267,11 +303,6 @@ stages:
|
||||
test: rhel/7.9
|
||||
- name: RHEL 8.2
|
||||
test: rhel/8.2
|
||||
- name: FreeBSD 11.1
|
||||
test: freebsd/11.1
|
||||
- name: FreeBSD 12.1
|
||||
test: freebsd/12.1
|
||||
|
||||
- stage: Remote_2_9
|
||||
displayName: Remote 2.9
|
||||
dependsOn: []
|
||||
@@ -286,10 +317,7 @@ stages:
|
||||
test: rhel/7.9
|
||||
- name: RHEL 8.1
|
||||
test: rhel/8.1
|
||||
- name: FreeBSD 11.1
|
||||
test: freebsd/11.1
|
||||
- name: FreeBSD 12.0
|
||||
test: freebsd/12.0
|
||||
|
||||
## Finally
|
||||
|
||||
- stage: Summary
|
||||
@@ -305,6 +333,8 @@ stages:
|
||||
- Docker_2_12
|
||||
- Remote_2_13
|
||||
- Docker_2_13
|
||||
- Remote_2_14
|
||||
- Docker_2_14
|
||||
- Remote_devel
|
||||
- Docker_devel
|
||||
jobs:
|
||||
|
||||
@@ -5,6 +5,27 @@ ansible.posix Release Notes
|
||||
.. contents:: Topics
|
||||
|
||||
|
||||
v1.5.1
|
||||
======
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- mount - Add ``absent_from_fstab`` state (https://github.com/ansible-collections/ansible.posix/pull/166).
|
||||
- mount - Add ``ephemeral`` value for the ``state`` parameter, that allows to mount a filesystem without altering the ``fstab`` file (https://github.com/ansible-collections/ansible.posix/pull/267).
|
||||
- r4e_rpm_ostree - new module for validating package state on RHEL for Edge
|
||||
- rhel_facts - new facts module to handle RHEL specific facts
|
||||
- rhel_rpm_ostree - new module to handle RHEL rpm-ostree specific package management functionality
|
||||
- rpm_ostree_upgrade - new module to automate rpm-ostree upgrades
|
||||
- rpm_ostree_upgrade - new module to manage upgrades for rpm-ostree based systems
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Removed contentious terminology to match reference documentation in profile_tasks.
|
||||
- firewall - Fixed to output a more complete missing library message.
|
||||
- synchronize - Fixed hosts involved in rsync require the same password
|
||||
|
||||
v1.4.0
|
||||
======
|
||||
|
||||
|
||||
@@ -260,3 +260,37 @@ releases:
|
||||
- sanity_fixes.yml
|
||||
- shell_escape_full_path_for_rsync.yml
|
||||
release_date: '2022-05-23'
|
||||
1.5.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Removed contentious terminology to match reference documentation in profile_tasks.
|
||||
- firewall - Fixed to output a more complete missing library message.
|
||||
- synchronize - Fixed hosts involved in rsync require the same password
|
||||
minor_changes:
|
||||
- mount - Add ``absent_from_fstab`` state (https://github.com/ansible-collections/ansible.posix/pull/166).
|
||||
- mount - Add ``ephemeral`` value for the ``state`` parameter, that allows to
|
||||
mount a filesystem without altering the ``fstab`` file (https://github.com/ansible-collections/ansible.posix/pull/267).
|
||||
- r4e_rpm_ostree - new module for validating package state on RHEL for Edge
|
||||
- rhel_facts - new facts module to handle RHEL specific facts
|
||||
- rhel_rpm_ostree - new module to handle RHEL rpm-ostree specific package management
|
||||
functionality
|
||||
- rpm_ostree_upgrade - new module to automate rpm-ostree upgrades
|
||||
- rpm_ostree_upgrade - new module to manage upgrades for rpm-ostree based systems
|
||||
fragments:
|
||||
- 166_mount_absent_fstab.yml
|
||||
- 267_mount_ephemeral.yml
|
||||
- 366_update_version_number_for_galaxy.yml
|
||||
- 371_refactoring_ci_process_202206.yml
|
||||
- 373_firewall_fix_missing_library_message.yml
|
||||
- 375_update_azp_container.yml
|
||||
- 380_update_usage_profile_tasks.yml
|
||||
- 386_follow_ci_testing_rules.yml
|
||||
- 389_ci_add_stable_214.yml
|
||||
- 390_hosts_involved_same_password.yml
|
||||
- 393-rpm-ostree.yml
|
||||
- 393_rhel_for_edge.yml
|
||||
- 400-fix-boolean-values-in-docs.yml
|
||||
- 401_document_module_default_values.yml
|
||||
- 407_fix_firewalld_port_test.yml
|
||||
- 409_update_azp_matrix.yml
|
||||
release_date: '2023-01-20'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace: ansible
|
||||
name: posix
|
||||
version: 1.4.0
|
||||
version: 1.5.0
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (github.com/ansible)
|
||||
|
||||
@@ -225,7 +225,6 @@ class ActionModule(ActionBase):
|
||||
|
||||
# Parameter name needed by the ansible module
|
||||
_tmp_args['_local_rsync_path'] = task_vars.get('ansible_rsync_path') or 'rsync'
|
||||
_tmp_args['_local_rsync_password'] = task_vars.get('ansible_ssh_pass') or task_vars.get('ansible_password')
|
||||
|
||||
# rsync thinks that one end of the connection is localhost and the
|
||||
# other is the host we're running the task for (Note: We use
|
||||
@@ -333,8 +332,9 @@ class ActionModule(ActionBase):
|
||||
if src is None or dest is None:
|
||||
return dict(failed=True, msg="synchronize requires both src and dest parameters are set")
|
||||
|
||||
# Determine if we need a user@
|
||||
# Determine if we need a user@ and a password
|
||||
user = None
|
||||
password = task_vars.get('ansible_ssh_pass', None) or task_vars.get('ansible_password', None)
|
||||
if not dest_is_local:
|
||||
# Src and dest rsync "path" handling
|
||||
if boolean(_tmp_args.get('set_remote_user', 'yes'), strict=False):
|
||||
@@ -344,10 +344,12 @@ class ActionModule(ActionBase):
|
||||
user = task_vars.get('ansible_user') or self._play_context.remote_user
|
||||
if not user:
|
||||
user = C.DEFAULT_REMOTE_USER
|
||||
|
||||
else:
|
||||
user = task_vars.get('ansible_user') or self._play_context.remote_user
|
||||
|
||||
if self._templar is not None:
|
||||
user = self._templar.template(user)
|
||||
|
||||
# Private key handling
|
||||
# Use the private_key parameter if passed else use context private_key_file
|
||||
_tmp_args['private_key'] = _tmp_args.get('private_key', self._play_context.private_key_file)
|
||||
@@ -361,12 +363,17 @@ class ActionModule(ActionBase):
|
||||
# src is a local path, dest is a remote path: <user>@<host>
|
||||
src = self._process_origin(src_host, src, user)
|
||||
dest = self._process_remote(_tmp_args, dest_host, dest, user, inv_port in localhost_ports)
|
||||
|
||||
password = dest_host_inventory_vars.get('ansible_ssh_pass', None) or dest_host_inventory_vars.get('ansible_password', None)
|
||||
if self._templar is not None:
|
||||
password = self._templar.template(password)
|
||||
else:
|
||||
# Still need to munge paths (to account for roles) even if we aren't
|
||||
# copying files between hosts
|
||||
src = self._get_absolute_path(path=src)
|
||||
dest = self._get_absolute_path(path=dest)
|
||||
|
||||
_tmp_args['_local_rsync_password'] = password
|
||||
_tmp_args['src'] = src
|
||||
_tmp_args['dest'] = dest
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ DOCUMENTATION = '''
|
||||
- It also lists the top/bottom time consuming tasks in the summary (configurable)
|
||||
- Before 2.4 only the environment variables were available for configuration.
|
||||
requirements:
|
||||
- whitelisting in configuration - see examples section below for details.
|
||||
- enable in configuration - see examples section below for details.
|
||||
options:
|
||||
output_limit:
|
||||
description: Number of tasks to display in the summary
|
||||
@@ -46,7 +46,7 @@ EXAMPLES = '''
|
||||
example: >
|
||||
To enable, add this to your ansible.cfg file in the defaults block
|
||||
[defaults]
|
||||
callback_whitelist = ansible.posix.profile_tasks
|
||||
callbacks_enabled=ansible.posix.profile_tasks
|
||||
sample output: >
|
||||
#
|
||||
# TASK: [ensure messaging security group exists] ********************************
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
from ansible_collections.ansible.posix.plugins.module_utils.version import LooseVersion
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
@@ -314,6 +315,5 @@ class FirewallTransaction(object):
|
||||
|
||||
if import_failure:
|
||||
module.fail_json(
|
||||
msg='Python Module not found: firewalld and its python module are required for this module, \
|
||||
version 0.2.11 or newer required (0.3.9 or newer for offline operations)'
|
||||
msg=missing_required_lib('firewall') + '. Version 0.2.11 or newer required (0.3.9 or newer for offline operations)'
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ options:
|
||||
description:
|
||||
- The full path of the file or object.
|
||||
type: path
|
||||
required: yes
|
||||
required: true
|
||||
aliases: [ name ]
|
||||
state:
|
||||
description:
|
||||
@@ -33,17 +33,18 @@ options:
|
||||
description:
|
||||
- Whether to follow symlinks on the path if a symlink is encountered.
|
||||
type: bool
|
||||
default: yes
|
||||
default: true
|
||||
default:
|
||||
description:
|
||||
- If the target is a directory, setting this to C(yes) will make it the default ACL for entities created inside the directory.
|
||||
- Setting C(default) to C(yes) causes an error if the path is a file.
|
||||
- If the target is a directory, setting this to C(true) will make it the default ACL for entities created inside the directory.
|
||||
- Setting C(default) to C(true) causes an error if the path is a file.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
entity:
|
||||
description:
|
||||
- The actual user or group that the ACL applies to when matching entity types user or group are selected.
|
||||
type: str
|
||||
default: ""
|
||||
etype:
|
||||
description:
|
||||
- The entity type of the ACL to apply, see C(setfacl) documentation for more info.
|
||||
@@ -69,13 +70,13 @@ options:
|
||||
- Incompatible with C(state=query).
|
||||
- Alias C(recurse) added in version 1.3.0.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
aliases: [ recurse ]
|
||||
use_nfsv4_acls:
|
||||
description:
|
||||
- Use NFSv4 ACLs instead of POSIX ACLs.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
recalculate_mask:
|
||||
description:
|
||||
- Select if and when to recalculate the effective right masks of the files.
|
||||
@@ -115,7 +116,7 @@ EXAMPLES = r'''
|
||||
entity: joe
|
||||
etype: user
|
||||
permissions: rw
|
||||
default: yes
|
||||
default: true
|
||||
state: present
|
||||
|
||||
- name: Same as previous but using entry shorthand
|
||||
|
||||
@@ -44,7 +44,7 @@ options:
|
||||
description:
|
||||
- If a matching job is present a new job will not be added.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
requirements:
|
||||
- at
|
||||
author:
|
||||
@@ -68,7 +68,7 @@ EXAMPLES = r'''
|
||||
command: ls -d / >/dev/null
|
||||
count: 20
|
||||
units: minutes
|
||||
unique: yes
|
||||
unique: true
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
@@ -34,13 +34,13 @@ options:
|
||||
manage_dir:
|
||||
description:
|
||||
- Whether this module should manage the directory of the authorized key file.
|
||||
- If set to C(yes), the module will create the directory, as well as set the owner and permissions
|
||||
- If set to C(true), the module will create the directory, as well as set the owner and permissions
|
||||
of an existing directory.
|
||||
- Be sure to set C(manage_dir=no) if you are using an alternate directory for authorized_keys,
|
||||
- Be sure to set C(manage_dir=false) if you are using an alternate directory for authorized_keys,
|
||||
as set with C(path), since you could lock yourself out of SSH access.
|
||||
- See the example below.
|
||||
type: bool
|
||||
default: yes
|
||||
default: true
|
||||
state:
|
||||
description:
|
||||
- Whether the given key (with the given key_options) should or should not be in the file.
|
||||
@@ -58,15 +58,15 @@ options:
|
||||
- This option is not loop aware, so if you use C(with_) , it will be exclusive per iteration of the loop.
|
||||
- If you want multiple keys in the file you need to pass them all to C(key) in a single batch as mentioned above.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
validate_certs:
|
||||
description:
|
||||
- This only applies if using a https url as the source of the keys.
|
||||
- If set to C(no), the SSL certificates will not be validated.
|
||||
- This should only set to C(no) used on personally controlled sites using self-signed certificates as it avoids verifying the source site.
|
||||
- Prior to 2.1 the code worked as if this was set to C(yes).
|
||||
- If set to C(false), the SSL certificates will not be validated.
|
||||
- This should only set to C(false) used on personally controlled sites using self-signed certificates as it avoids verifying the source site.
|
||||
- Prior to 2.1 the code worked as if this was set to C(true).
|
||||
type: bool
|
||||
default: yes
|
||||
default: true
|
||||
comment:
|
||||
description:
|
||||
- Change the comment on the public key.
|
||||
@@ -77,7 +77,7 @@ options:
|
||||
description:
|
||||
- Follow path symlink instead of replacing it.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
author: Ansible Core Team
|
||||
'''
|
||||
|
||||
@@ -106,7 +106,7 @@ EXAMPLES = r'''
|
||||
state: present
|
||||
key: "{{ lookup('file', '/home/charlie/.ssh/id_rsa.pub') }}"
|
||||
path: /etc/ssh/authorized_keys/charlie
|
||||
manage_dir: False
|
||||
manage_dir: false
|
||||
|
||||
- name: Set up multiple authorized keys
|
||||
ansible.posix.authorized_key:
|
||||
@@ -129,14 +129,14 @@ EXAMPLES = r'''
|
||||
user: charlie
|
||||
state: present
|
||||
key: https://github.com/user.keys
|
||||
validate_certs: False
|
||||
validate_certs: false
|
||||
|
||||
- name: Set authorized key, removing all the authorized keys already set
|
||||
ansible.posix.authorized_key:
|
||||
user: root
|
||||
key: "{{ lookup('file', 'public_keys/doe-jane') }}"
|
||||
state: present
|
||||
exclusive: True
|
||||
exclusive: true
|
||||
|
||||
- name: Set authorized key for user ubuntu copying it from current user
|
||||
ansible.posix.authorized_key:
|
||||
@@ -150,7 +150,7 @@ exclusive:
|
||||
description: If the key has been forced to be exclusive or not.
|
||||
returned: success
|
||||
type: bool
|
||||
sample: False
|
||||
sample: false
|
||||
key:
|
||||
description: The key that the module was running against.
|
||||
returned: success
|
||||
@@ -170,7 +170,7 @@ manage_dir:
|
||||
description: Whether this module managed the directory of the authorized key file.
|
||||
returned: success
|
||||
type: bool
|
||||
sample: True
|
||||
sample: true
|
||||
path:
|
||||
description: Alternate path to the authorized_keys file
|
||||
returned: success
|
||||
@@ -192,7 +192,7 @@ user:
|
||||
type: str
|
||||
sample: user
|
||||
validate_certs:
|
||||
description: This only applies if using a https url as the source of the keys. If set to C(no), the SSL certificates will not be validated.
|
||||
description: This only applies if using a https url as the source of the keys. If set to C(false), the SSL certificates will not be validated.
|
||||
returned: success
|
||||
type: bool
|
||||
sample: true
|
||||
@@ -347,6 +347,8 @@ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False)
|
||||
basedir = os.path.dirname(keysfile)
|
||||
if not os.path.exists(basedir):
|
||||
os.makedirs(basedir)
|
||||
|
||||
f = None
|
||||
try:
|
||||
f = open(keysfile, "w") # touches file so we can set ownership and perms
|
||||
finally:
|
||||
|
||||
@@ -82,13 +82,13 @@ options:
|
||||
description:
|
||||
- Should this configuration be in the running firewalld configuration or persist across reboots.
|
||||
- As of Ansible 2.3, permanent operations can operate on firewalld configs when it is not running (requires firewalld >= 0.3.9).
|
||||
- Note that if this is C(no), immediate is assumed C(yes).
|
||||
- Note that if this is C(false), immediate is assumed C(true).
|
||||
type: bool
|
||||
immediate:
|
||||
description:
|
||||
- Should this configuration be applied immediately, if set as permanent.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
state:
|
||||
description:
|
||||
- Enable or disable a setting.
|
||||
@@ -141,29 +141,29 @@ EXAMPLES = r'''
|
||||
- name: permit traffic in default zone for https service
|
||||
ansible.posix.firewalld:
|
||||
service: https
|
||||
permanent: yes
|
||||
permanent: true
|
||||
state: enabled
|
||||
|
||||
- name: do not permit traffic in default zone on port 8081/tcp
|
||||
ansible.posix.firewalld:
|
||||
port: 8081/tcp
|
||||
permanent: yes
|
||||
permanent: true
|
||||
state: disabled
|
||||
|
||||
- ansible.posix.firewalld:
|
||||
port: 161-162/udp
|
||||
permanent: yes
|
||||
permanent: true
|
||||
state: enabled
|
||||
|
||||
- ansible.posix.firewalld:
|
||||
zone: dmz
|
||||
service: http
|
||||
permanent: yes
|
||||
permanent: true
|
||||
state: enabled
|
||||
|
||||
- ansible.posix.firewalld:
|
||||
rich_rule: rule service name="ftp" audit limit value="1/m" accept
|
||||
permanent: yes
|
||||
permanent: true
|
||||
state: enabled
|
||||
|
||||
- ansible.posix.firewalld:
|
||||
@@ -174,44 +174,44 @@ EXAMPLES = r'''
|
||||
- ansible.posix.firewalld:
|
||||
zone: trusted
|
||||
interface: eth2
|
||||
permanent: yes
|
||||
permanent: true
|
||||
state: enabled
|
||||
|
||||
- ansible.posix.firewalld:
|
||||
masquerade: yes
|
||||
masquerade: true
|
||||
state: enabled
|
||||
permanent: yes
|
||||
permanent: true
|
||||
zone: dmz
|
||||
|
||||
- ansible.posix.firewalld:
|
||||
zone: custom
|
||||
state: present
|
||||
permanent: yes
|
||||
permanent: true
|
||||
|
||||
- ansible.posix.firewalld:
|
||||
zone: drop
|
||||
state: enabled
|
||||
permanent: yes
|
||||
icmp_block_inversion: yes
|
||||
permanent: true
|
||||
icmp_block_inversion: true
|
||||
|
||||
- ansible.posix.firewalld:
|
||||
zone: drop
|
||||
state: enabled
|
||||
permanent: yes
|
||||
permanent: true
|
||||
icmp_block: echo-request
|
||||
|
||||
- ansible.posix.firewalld:
|
||||
zone: internal
|
||||
state: present
|
||||
permanent: yes
|
||||
permanent: true
|
||||
target: ACCEPT
|
||||
|
||||
- name: Redirect port 443 to 8443 with Rich Rule
|
||||
ansible.posix.firewalld:
|
||||
rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443
|
||||
zone: public
|
||||
permanent: yes
|
||||
immediate: yes
|
||||
permanent: true
|
||||
immediate: true
|
||||
state: enabled
|
||||
'''
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ options:
|
||||
active_zones:
|
||||
description: Gather information about active zones.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
zones:
|
||||
description:
|
||||
- Gather information about specific zones.
|
||||
@@ -36,7 +36,7 @@ author:
|
||||
EXAMPLES = r'''
|
||||
- name: Gather information about active zones
|
||||
ansible.posix.firewalld_info:
|
||||
active_zones: yes
|
||||
active_zones: true
|
||||
|
||||
- name: Gather information about specific zones
|
||||
ansible.posix.firewalld_info:
|
||||
|
||||
@@ -31,12 +31,12 @@ options:
|
||||
src:
|
||||
description:
|
||||
- Device (or NFS volume, or something else) to be mounted on I(path).
|
||||
- Required when I(state) set to C(present) or C(mounted).
|
||||
- Required when I(state) set to C(present), C(mounted) or C(ephemeral).
|
||||
type: path
|
||||
fstype:
|
||||
description:
|
||||
- Filesystem type.
|
||||
- Required when I(state) is C(present) or C(mounted).
|
||||
- Required when I(state) is C(present), C(mounted) or C(ephemeral).
|
||||
type: str
|
||||
opts:
|
||||
description:
|
||||
@@ -48,7 +48,7 @@ options:
|
||||
- Note that if set to C(null) and I(state) set to C(present),
|
||||
it will cease to work and duplicate entries will be made
|
||||
with subsequent runs.
|
||||
- Has no effect on Solaris systems.
|
||||
- Has no effect on Solaris systems or when used with C(ephemeral).
|
||||
type: str
|
||||
default: '0'
|
||||
passno:
|
||||
@@ -57,7 +57,7 @@ options:
|
||||
- Note that if set to C(null) and I(state) set to C(present),
|
||||
it will cease to work and duplicate entries will be made
|
||||
with subsequent runs.
|
||||
- Deprecated on Solaris systems.
|
||||
- Deprecated on Solaris systems. Has no effect when used with C(ephemeral).
|
||||
type: str
|
||||
default: '0'
|
||||
state:
|
||||
@@ -68,6 +68,13 @@ options:
|
||||
- If C(unmounted), the device will be unmounted without changing I(fstab).
|
||||
- C(present) only specifies that the device is to be configured in
|
||||
I(fstab) and does not trigger or require a mount.
|
||||
- C(ephemeral) only specifies that the device is to be mounted, without changing
|
||||
I(fstab). If it is already mounted, a remount will be triggered.
|
||||
This will always return changed=True. If the mount point I(path)
|
||||
has already a device mounted on, and its source is different than I(src),
|
||||
the module will fail to avoid unexpected unmount or mount point override.
|
||||
If the mount point is not present, the mount point will be created.
|
||||
The I(fstab) is completely ignored. This option is added in version 1.5.0.
|
||||
- C(absent) specifies that the device mount's entry will be removed from
|
||||
I(fstab) and will also unmount the device and remove the mount
|
||||
point.
|
||||
@@ -77,10 +84,15 @@ options:
|
||||
applied to the remount, but will not change I(fstab). Additionally,
|
||||
if I(opts) is set, and the remount command fails, the module will
|
||||
error to prevent unexpected mount changes. Try using C(mounted)
|
||||
instead to work around this issue.
|
||||
instead to work around this issue. C(remounted) expects the mount point
|
||||
to be present in the I(fstab). To remount a mount point not registered
|
||||
in I(fstab), use C(ephemeral) instead, especially with BSD nodes.
|
||||
- C(absent_from_fstab) specifies that the device mount's entry will be
|
||||
removed from I(fstab). This option does not unmount it or delete the
|
||||
mountpoint.
|
||||
type: str
|
||||
required: true
|
||||
choices: [ absent, mounted, present, unmounted, remounted ]
|
||||
choices: [ absent, absent_from_fstab, mounted, present, unmounted, remounted, ephemeral ]
|
||||
fstab:
|
||||
description:
|
||||
- File to use instead of C(/etc/fstab).
|
||||
@@ -89,6 +101,7 @@ options:
|
||||
- OpenBSD does not allow specifying alternate fstab files with mount so do not
|
||||
use this on OpenBSD with any state that operates on the live filesystem.
|
||||
- This parameter defaults to /etc/fstab or /etc/vfstab on Solaris.
|
||||
- This parameter is ignored when I(state) is set to C(ephemeral).
|
||||
type: str
|
||||
boot:
|
||||
description:
|
||||
@@ -100,14 +113,15 @@ options:
|
||||
to mount options in I(/etc/fstab).
|
||||
- To avoid mount option conflicts, if C(noauto) specified in C(opts),
|
||||
mount module will ignore C(boot).
|
||||
- This parameter is ignored when I(state) is set to C(ephemeral).
|
||||
type: bool
|
||||
default: yes
|
||||
default: true
|
||||
backup:
|
||||
description:
|
||||
- Create a backup file including the timestamp information so you can get
|
||||
the original file back if you somehow clobbered it incorrectly.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
notes:
|
||||
- As of Ansible 2.3, the I(name) option has been changed to I(path) as
|
||||
default, but I(name) still works as well.
|
||||
@@ -181,9 +195,17 @@ EXAMPLES = r'''
|
||||
src: 192.168.1.100:/nfs/ssd/shared_data
|
||||
path: /mnt/shared_data
|
||||
opts: rw,sync,hard
|
||||
boot: no
|
||||
boot: false
|
||||
state: mounted
|
||||
fstype: nfs
|
||||
|
||||
- name: Mount ephemeral SMB volume
|
||||
ansible.posix.mount:
|
||||
src: //192.168.1.200/share
|
||||
path: /mnt/smb_share
|
||||
opts: "rw,vers=3,file_mode=0600,dir_mode=0700,dom={{ ad_domain }},username={{ ad_username }},password={{ ad_password }}"
|
||||
fstype: cifs
|
||||
state: ephemeral
|
||||
'''
|
||||
|
||||
import errno
|
||||
@@ -226,7 +248,7 @@ def _escape_fstab(v):
|
||||
if isinstance(v, int):
|
||||
return v
|
||||
else:
|
||||
return(
|
||||
return (
|
||||
v.
|
||||
replace('\\', '\\134').
|
||||
replace(' ', '\\040').
|
||||
@@ -430,6 +452,24 @@ def _set_fstab_args(fstab_file):
|
||||
return result
|
||||
|
||||
|
||||
def _set_ephemeral_args(args):
|
||||
result = []
|
||||
# Set fstype switch according to platform. SunOS/Solaris use -F
|
||||
if platform.system().lower() == 'sunos':
|
||||
result.append('-F')
|
||||
else:
|
||||
result.append('-t')
|
||||
result.append(args['fstype'])
|
||||
|
||||
# Even if '-o remount' is already set, specifying multiple -o is valid
|
||||
if args['opts'] != 'defaults':
|
||||
result += ['-o', args['opts']]
|
||||
|
||||
result.append(args['src'])
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def mount(module, args):
|
||||
"""Mount up a path or remount if needed."""
|
||||
|
||||
@@ -446,7 +486,11 @@ def mount(module, args):
|
||||
'OpenBSD does not support alternate fstab files. Do not '
|
||||
'specify the fstab parameter for OpenBSD hosts'))
|
||||
else:
|
||||
cmd += _set_fstab_args(args['fstab'])
|
||||
if module.params['state'] != 'ephemeral':
|
||||
cmd += _set_fstab_args(args['fstab'])
|
||||
|
||||
if module.params['state'] == 'ephemeral':
|
||||
cmd += _set_ephemeral_args(args)
|
||||
|
||||
cmd += [name]
|
||||
|
||||
@@ -498,18 +542,24 @@ def remount(module, args):
|
||||
'OpenBSD does not support alternate fstab files. Do not '
|
||||
'specify the fstab parameter for OpenBSD hosts'))
|
||||
else:
|
||||
cmd += _set_fstab_args(args['fstab'])
|
||||
if module.params['state'] != 'ephemeral':
|
||||
cmd += _set_fstab_args(args['fstab'])
|
||||
|
||||
if module.params['state'] == 'ephemeral':
|
||||
cmd += _set_ephemeral_args(args)
|
||||
|
||||
cmd += [args['name']]
|
||||
out = err = ''
|
||||
|
||||
try:
|
||||
if platform.system().lower().endswith('bsd'):
|
||||
if module.params['state'] != 'ephemeral' and platform.system().lower().endswith('bsd'):
|
||||
# Note: Forcing BSDs to do umount/mount due to BSD remount not
|
||||
# working as expected (suspect bug in the BSD mount command)
|
||||
# Interested contributor could rework this to use mount options on
|
||||
# the CLI instead of relying on fstab
|
||||
# https://github.com/ansible/ansible-modules-core/issues/5591
|
||||
# Note: this does not affect ephemeral state as all options
|
||||
# are set on the CLI and fstab is expected to be ignored.
|
||||
rc = 1
|
||||
else:
|
||||
rc, out, err = module.run_command(cmd)
|
||||
@@ -663,6 +713,47 @@ def get_linux_mounts(module, mntinfo_file="/proc/self/mountinfo"):
|
||||
return mounts
|
||||
|
||||
|
||||
def _is_same_mount_src(module, src, mountpoint, linux_mounts):
|
||||
"""Return True if the mounted fs on mountpoint is the same source than src. Return False if mountpoint is not a mountpoint"""
|
||||
# If the provided mountpoint is not a mountpoint, don't waste time
|
||||
if (
|
||||
not ismount(mountpoint) and
|
||||
not is_bind_mounted(module, linux_mounts, mountpoint)):
|
||||
return False
|
||||
|
||||
# Treat Linux bind mounts
|
||||
if platform.system() == 'Linux' and linux_mounts is not None:
|
||||
# For Linux bind mounts only: the mount command does not return
|
||||
# the actual source for bind mounts, but the device of the source.
|
||||
# is_bind_mounted() called with the 'src' parameter will return True if
|
||||
# the mountpoint is a bind mount AND the source FS is the same than 'src'.
|
||||
# is_bind_mounted() is not reliable on Solaris, NetBSD and OpenBSD.
|
||||
# But we can rely on 'mount -v' on all other platforms, and Linux non-bind mounts.
|
||||
if is_bind_mounted(module, linux_mounts, mountpoint, src):
|
||||
return True
|
||||
|
||||
# mount with parameter -v has a close behavior on Linux, *BSD, SunOS
|
||||
# Requires -v with SunOS. Without -v, source and destination are reversed
|
||||
# Output format differs from a system to another, but field[0:3] are consistent: [src, 'on', dest]
|
||||
cmd = '%s -v' % module.get_bin_path('mount', required=True)
|
||||
rc, out, err = module.run_command(cmd)
|
||||
mounts = []
|
||||
|
||||
if len(out):
|
||||
mounts = to_native(out).strip().split('\n')
|
||||
else:
|
||||
module.fail_json(msg="Unable to retrieve mount info with command '%s'" % cmd)
|
||||
|
||||
for mnt in mounts:
|
||||
fields = mnt.split()
|
||||
mp_src = fields[0]
|
||||
mp_dst = fields[2]
|
||||
if mp_src == src and mp_dst == mountpoint:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
@@ -675,12 +766,13 @@ def main():
|
||||
passno=dict(type='str', no_log=False, default='0'),
|
||||
src=dict(type='path'),
|
||||
backup=dict(type='bool', default=False),
|
||||
state=dict(type='str', required=True, choices=['absent', 'mounted', 'present', 'unmounted', 'remounted']),
|
||||
state=dict(type='str', required=True, choices=['absent', 'absent_from_fstab', 'mounted', 'present', 'unmounted', 'remounted', 'ephemeral']),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
required_if=(
|
||||
['state', 'mounted', ['src', 'fstype']],
|
||||
['state', 'present', ['src', 'fstype']],
|
||||
['state', 'ephemeral', ['src', 'fstype']]
|
||||
),
|
||||
)
|
||||
|
||||
@@ -751,15 +843,17 @@ def main():
|
||||
|
||||
# If fstab file does not exist, we first need to create it. This mainly
|
||||
# happens when fstab option is passed to the module.
|
||||
if not os.path.exists(args['fstab']):
|
||||
if not os.path.exists(os.path.dirname(args['fstab'])):
|
||||
os.makedirs(os.path.dirname(args['fstab']))
|
||||
try:
|
||||
open(args['fstab'], 'a').close()
|
||||
except PermissionError as e:
|
||||
module.fail_json(msg="Failed to open %s due to permission issue" % args['fstab'])
|
||||
except Exception as e:
|
||||
module.fail_json(msg="Failed to open %s due to %s" % (args['fstab'], to_native(e)))
|
||||
# If state is 'ephemeral', we do not need fstab file
|
||||
if module.params['state'] != 'ephemeral':
|
||||
if not os.path.exists(args['fstab']):
|
||||
if not os.path.exists(os.path.dirname(args['fstab'])):
|
||||
os.makedirs(os.path.dirname(args['fstab']))
|
||||
try:
|
||||
open(args['fstab'], 'a').close()
|
||||
except PermissionError as e:
|
||||
module.fail_json(msg="Failed to open %s due to permission issue" % args['fstab'])
|
||||
except Exception as e:
|
||||
module.fail_json(msg="Failed to open %s due to %s" % (args['fstab'], to_native(e)))
|
||||
|
||||
# absent:
|
||||
# Remove from fstab and unmounted.
|
||||
@@ -770,12 +864,16 @@ def main():
|
||||
# mounted:
|
||||
# Add to fstab if not there and make sure it is mounted. If it has
|
||||
# changed in fstab then remount it.
|
||||
# ephemeral:
|
||||
# Do not change fstab state, but mount.
|
||||
|
||||
state = module.params['state']
|
||||
name = module.params['path']
|
||||
changed = False
|
||||
|
||||
if state == 'absent':
|
||||
if state == 'absent_from_fstab':
|
||||
name, changed = unset_mount(module, args)
|
||||
elif state == 'absent':
|
||||
name, changed = unset_mount(module, args)
|
||||
|
||||
if changed and not module.check_mode:
|
||||
@@ -801,7 +899,7 @@ def main():
|
||||
msg="Error unmounting %s: %s" % (name, msg))
|
||||
|
||||
changed = True
|
||||
elif state == 'mounted':
|
||||
elif state == 'mounted' or state == 'ephemeral':
|
||||
dirs_created = []
|
||||
if not os.path.exists(name) and not module.check_mode:
|
||||
try:
|
||||
@@ -829,7 +927,11 @@ def main():
|
||||
module.fail_json(
|
||||
msg="Error making dir %s: %s" % (name, to_native(e)))
|
||||
|
||||
name, backup_lines, changed = _set_mount_save_old(module, args)
|
||||
# ephemeral: completely ignore fstab
|
||||
if state != 'ephemeral':
|
||||
name, backup_lines, changed = _set_mount_save_old(module, args)
|
||||
else:
|
||||
name, backup_lines, changed = args['name'], [], False
|
||||
res = 0
|
||||
|
||||
if (
|
||||
@@ -839,7 +941,26 @@ def main():
|
||||
if changed and not module.check_mode:
|
||||
res, msg = remount(module, args)
|
||||
changed = True
|
||||
|
||||
# When 'state' == 'ephemeral', we don't know what is in fstab, and 'changed' is always False
|
||||
if state == 'ephemeral':
|
||||
# If state == 'ephemeral', check if the mountpoint src == module.params['src']
|
||||
# If it doesn't, fail to prevent unwanted unmount or unwanted mountpoint override
|
||||
if _is_same_mount_src(module, args['src'], args['name'], linux_mounts):
|
||||
changed = True
|
||||
if not module.check_mode:
|
||||
res, msg = remount(module, args)
|
||||
else:
|
||||
module.fail_json(
|
||||
msg=(
|
||||
'Ephemeral mount point is already mounted with a different '
|
||||
'source than the specified one. Failing in order to prevent an '
|
||||
'unwanted unmount or override operation. Try replacing this command with '
|
||||
'a "state: unmounted" followed by a "state: ephemeral", or use '
|
||||
'a different destination path.'))
|
||||
|
||||
else:
|
||||
# If not already mounted, mount it
|
||||
changed = True
|
||||
|
||||
if not module.check_mode:
|
||||
@@ -851,7 +972,8 @@ def main():
|
||||
# A non-working fstab entry may break the system at the reboot,
|
||||
# so undo all the changes if possible.
|
||||
try:
|
||||
write_fstab(module, backup_lines, args['fstab'])
|
||||
if state != 'ephemeral':
|
||||
write_fstab(module, backup_lines, args['fstab'])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@@ -50,10 +50,10 @@ options:
|
||||
default: present
|
||||
remote_src:
|
||||
description:
|
||||
- If C(no), it will search for src at originating/controller machine, if C(yes) it will
|
||||
- If C(false), it will search for src at originating/controller machine, if C(true) it will
|
||||
go to the remote/target machine for the C(src).
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
strip:
|
||||
description:
|
||||
- Number that indicates the smallest prefix containing leading slashes
|
||||
@@ -65,20 +65,20 @@ options:
|
||||
description:
|
||||
- Passes C(--backup --version-control=numbered) to patch, producing numbered backup copies.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
binary:
|
||||
description:
|
||||
- Setting to C(yes) will disable patch's heuristic for transforming CRLF
|
||||
- Setting to C(true) will disable patch's heuristic for transforming CRLF
|
||||
line endings into LF.
|
||||
- Line endings of src and dest must match.
|
||||
- If set to C(no), C(patch) will replace CRLF in C(src) files on POSIX.
|
||||
- If set to C(false), C(patch) will replace CRLF in C(src) files on POSIX.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
ignore_whitespace:
|
||||
description:
|
||||
- Setting to C(yes) will ignore white space changes between patch and input..
|
||||
- Setting to C(true) will ignore white space changes between patch and input.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
notes:
|
||||
- This module requires GNU I(patch) utility to be installed on the remote host.
|
||||
'''
|
||||
|
||||
76
plugins/modules/rhel_facts.py
Normal file
76
plugins/modules/rhel_facts.py
Normal file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: Red Hat Inc.
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rhel_facts
|
||||
version_added: 1.5.0
|
||||
short_description: Facts module to set or override RHEL specific facts.
|
||||
description:
|
||||
- Compatibility layer for using the "package" module for rpm-ostree based systems via setting the "pkg_mgr" fact correctly.
|
||||
author:
|
||||
- Adam Miller (@maxamillion)
|
||||
requirements:
|
||||
- rpm-ostree
|
||||
seealso:
|
||||
- module: ansible.builtin.package
|
||||
options: {}
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Playbook to use the package module on all RHEL footprints
|
||||
vars:
|
||||
ansible_facts_modules:
|
||||
- setup # REQUIRED to be run before all custom fact modules
|
||||
- ansible.posix.rhel_facts
|
||||
tasks:
|
||||
- name: Ensure packages are installed
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
- htop
|
||||
- ansible
|
||||
state: present
|
||||
'''
|
||||
|
||||
RETURN = """
|
||||
ansible_facts:
|
||||
description: Relevant Ansible Facts
|
||||
returned: when needed
|
||||
type: complex
|
||||
contains:
|
||||
pkg_mgr:
|
||||
description: System-level package manager override
|
||||
returned: when needed
|
||||
type: str
|
||||
sample: {'pkg_mgr': 'ansible.posix.rhel_facts'}
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_facts = {}
|
||||
|
||||
# Verify that the platform is an rpm-ostree based system
|
||||
if os.path.exists("/run/ostree-booted"):
|
||||
ansible_facts['pkg_mgr'] = 'ansible.posix.rhel_rpm_ostree'
|
||||
|
||||
module.exit_json(ansible_facts, changed=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
124
plugins/modules/rhel_rpm_ostree.py
Normal file
124
plugins/modules/rhel_rpm_ostree.py
Normal file
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: Red Hat Inc.
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rhel_rpm_ostree
|
||||
version_added: 1.5.0
|
||||
short_description: Ensure packages exist in a RHEL for Edge rpm-ostree based system
|
||||
description:
|
||||
- Compatibility layer for using the "package" module for RHEL for Edge systems utilizing the RHEL System Roles.
|
||||
author:
|
||||
- Adam Miller (@maxamillion)
|
||||
requirements:
|
||||
- rpm-ostree
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
- A package name or package specifier with version, like C(name-1.0).
|
||||
- Comparison operators for package version are valid here C(>), C(<), C(>=), C(<=). Example - C(name>=1.0)
|
||||
- If a previous version is specified, the task also needs to turn C(allow_downgrade) on.
|
||||
See the C(allow_downgrade) documentation for caveats with downgrading packages.
|
||||
- When using state=latest, this can be C('*') which means run C(yum -y update).
|
||||
- You can also pass a url or a local path to a rpm file (using state=present).
|
||||
To operate on several packages this can accept a comma separated string of packages or (as of 2.0) a list of packages.
|
||||
aliases: [ pkg ]
|
||||
type: list
|
||||
elements: str
|
||||
default: []
|
||||
state:
|
||||
description:
|
||||
- Whether to install (C(present) or C(installed), C(latest)), or remove (C(absent) or C(removed)) a package.
|
||||
- C(present) and C(installed) will simply ensure that a desired package is installed.
|
||||
- C(latest) will update the specified package if it's not of the latest available version.
|
||||
- C(absent) and C(removed) will remove the specified package.
|
||||
- Default is C(None), however in effect the default action is C(present) unless the C(autoremove) option is
|
||||
enabled for this module, then C(absent) is inferred.
|
||||
type: str
|
||||
choices: [ absent, installed, latest, present, removed ]
|
||||
notes:
|
||||
- This module does not support installing or removing packages to/from an overlay as this is not supported
|
||||
by RHEL for Edge, packages needed should be defined in the osbuild Blueprint and provided to Image Builder
|
||||
at build time. This module exists only for C(package) module compatibility.
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Ensure htop and ansible are installed on rpm-ostree based RHEL
|
||||
ansible.posix.rhel_rpm_ostree:
|
||||
name:
|
||||
- htop
|
||||
- ansible
|
||||
state: present
|
||||
'''
|
||||
|
||||
RETURN = """
|
||||
msg:
|
||||
description: status of rpm transaction
|
||||
returned: always
|
||||
type: str
|
||||
sample: "No changes made."
|
||||
"""
|
||||
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_text
|
||||
|
||||
|
||||
def locally_installed(module, pkgname):
|
||||
(rc, out, err) = module.run_command('{0} -q {1}'.format(module.get_bin_path("rpm"), pkgname).split())
|
||||
return (rc == 0)
|
||||
|
||||
|
||||
def rpm_ostree_transaction(module):
|
||||
pkgs = []
|
||||
|
||||
if module.params['state'] in ['present', 'installed', 'latest']:
|
||||
for pkg in module.params['name']:
|
||||
if not locally_installed(module, pkg):
|
||||
pkgs.append(pkg)
|
||||
elif module.params['state'] in ['absent', 'removed']:
|
||||
for pkg in module.params['name']:
|
||||
if locally_installed(module, pkg):
|
||||
pkgs.append(pkg)
|
||||
|
||||
if not pkgs:
|
||||
module.exit_json(msg="No changes made.")
|
||||
else:
|
||||
if module.params['state'] in ['present', 'installed', 'latest']:
|
||||
module.fail_json(msg="The following packages are absent in the currently booted rpm-ostree commit: %s" ' '.join(pkgs))
|
||||
else:
|
||||
module.fail_json(msg="The following packages are present in the currently booted rpm-ostree commit: %s" ' '.join(pkgs))
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
name=dict(type='list', elements='str', aliases=['pkg'], default=[]),
|
||||
state=dict(type='str', default=None, choices=['absent', 'installed', 'latest', 'present', 'removed']),
|
||||
),
|
||||
)
|
||||
|
||||
# Verify that the platform is an rpm-ostree based system
|
||||
if not os.path.exists("/run/ostree-booted"):
|
||||
module.fail_json(msg="Module rpm_ostree is only applicable for rpm-ostree based systems.")
|
||||
|
||||
try:
|
||||
rpm_ostree_transaction(module)
|
||||
except Exception as e:
|
||||
module.fail_json(msg=to_text(e), exception=traceback.format_exc())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
125
plugins/modules/rpm_ostree_upgrade.py
Normal file
125
plugins/modules/rpm_ostree_upgrade.py
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: Red Hat Inc.
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: rpm_ostree_upgrade
|
||||
short_description: Manage rpm-ostree upgrade transactions
|
||||
description:
|
||||
- Manage an rpm-ostree upgrade transactions.
|
||||
version_added: 1.5.0
|
||||
author:
|
||||
- Adam Miller (@maxamillion)
|
||||
requirements:
|
||||
- rpm-ostree
|
||||
options:
|
||||
os:
|
||||
description:
|
||||
- The OSNAME upon which to operate.
|
||||
type: str
|
||||
default: ""
|
||||
required: false
|
||||
cache_only:
|
||||
description:
|
||||
- Perform the transaction using only pre-cached data, do not download.
|
||||
type: bool
|
||||
default: false
|
||||
required: false
|
||||
allow_downgrade:
|
||||
description:
|
||||
- Allow for the upgrade to be a chronologically older tree.
|
||||
type: bool
|
||||
default: false
|
||||
required: false
|
||||
peer:
|
||||
description:
|
||||
- Force peer-to-peer connection instead of using a system message bus.
|
||||
type: bool
|
||||
default: false
|
||||
required: false
|
||||
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Upgrade the rpm-ostree image without options, accept all defaults
|
||||
ansible.posix.rpm_ostree_upgrade:
|
||||
|
||||
- name: Upgrade the rpm-ostree image allowing downgrades
|
||||
ansible.posix.rpm_ostree_upgrade:
|
||||
allow_downgrade: true
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
msg:
|
||||
description: The command standard output
|
||||
returned: always
|
||||
type: str
|
||||
sample: 'No upgrade available.'
|
||||
'''
|
||||
|
||||
import os
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
|
||||
|
||||
def rpm_ostree_transaction(module):
|
||||
cmd = []
|
||||
cmd.append(module.get_bin_path("rpm-ostree"))
|
||||
cmd.append('upgrade')
|
||||
|
||||
if module.params['os']:
|
||||
cmd += ['--os', module.params['os']]
|
||||
if module.params['cache_only']:
|
||||
cmd += ['--cache-only']
|
||||
if module.params['allow_downgrade']:
|
||||
cmd += ['--allow-downgrade']
|
||||
if module.params['peer']:
|
||||
cmd += ['--peer']
|
||||
|
||||
module.run_command_environ_update = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C')
|
||||
|
||||
rc, out, err = module.run_command(cmd)
|
||||
|
||||
if rc != 0:
|
||||
module.fail_json(rc=rc, msg=err)
|
||||
else:
|
||||
if to_text("No upgrade available.") in to_text(out):
|
||||
module.exit_json(msg=out, changed=False)
|
||||
else:
|
||||
module.exit_json(msg=out, changed=True)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
os=dict(type='str', default=''),
|
||||
cache_only=dict(type='bool', default=False),
|
||||
allow_downgrade=dict(type='bool', default=False),
|
||||
peer=dict(type='bool', default=False),
|
||||
),
|
||||
)
|
||||
|
||||
# Verify that the platform is an rpm-ostree based system
|
||||
if not os.path.exists("/run/ostree-booted"):
|
||||
module.fail_json(msg="Module rpm_ostree_upgrade is only applicable for rpm-ostree based systems.")
|
||||
|
||||
try:
|
||||
rpm_ostree_transaction(module)
|
||||
except Exception as e:
|
||||
module.fail_json(msg=to_native(e), exception=traceback.format_exc())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -22,9 +22,9 @@ options:
|
||||
type: str
|
||||
persistent:
|
||||
description:
|
||||
- Set to C(yes) if the boolean setting should survive a reboot.
|
||||
- Set to C(true) if the boolean setting should survive a reboot.
|
||||
type: bool
|
||||
default: 'no'
|
||||
default: false
|
||||
state:
|
||||
description:
|
||||
- Desired boolean value
|
||||
@@ -49,8 +49,8 @@ EXAMPLES = r'''
|
||||
- name: Set httpd_can_network_connect flag on and keep it persistent across reboots
|
||||
ansible.posix.seboolean:
|
||||
name: httpd_can_network_connect
|
||||
state: yes
|
||||
persistent: yes
|
||||
state: true
|
||||
persistent: true
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
@@ -32,7 +32,7 @@ options:
|
||||
description:
|
||||
- If set to I(true), will update also the kernel boot parameters when disabling/enabling SELinux.
|
||||
- The C(grubby) tool must be present on the target system for this to work.
|
||||
default: no
|
||||
default: false
|
||||
type: bool
|
||||
version_added: '1.4.0'
|
||||
configfile:
|
||||
|
||||
@@ -53,36 +53,36 @@ options:
|
||||
description:
|
||||
- Mirrors the rsync archive flag, enables recursive, links, perms, times, owner, group flags and -D.
|
||||
type: bool
|
||||
default: yes
|
||||
default: true
|
||||
checksum:
|
||||
description:
|
||||
- Skip based on checksum, rather than mod-time & size; Note that that "archive" option is still enabled by default - the "checksum" option will
|
||||
not disable it.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
compress:
|
||||
description:
|
||||
- Compress file data during the transfer.
|
||||
- In most cases, leave this enabled unless it causes problems.
|
||||
type: bool
|
||||
default: yes
|
||||
default: true
|
||||
existing_only:
|
||||
description:
|
||||
- Skip creating new files on receiver.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
delete:
|
||||
description:
|
||||
- Delete files in I(dest) that do not exist (after transfer, not before) in the I(src) path.
|
||||
- This option requires I(recursive=yes).
|
||||
- This option requires I(recursive=true).
|
||||
- This option ignores excluded files and behaves like the rsync opt C(--delete-after).
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
dirs:
|
||||
description:
|
||||
- Transfer directories without recursing.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
recursive:
|
||||
description:
|
||||
- Recurse into directories.
|
||||
@@ -97,7 +97,7 @@ options:
|
||||
description:
|
||||
- Copy symlinks as the item that they point to (the referent) is copied, rather than the symlink.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
perms:
|
||||
description:
|
||||
- Preserve permissions.
|
||||
@@ -132,26 +132,26 @@ options:
|
||||
description:
|
||||
- Put user@ for the remote paths.
|
||||
- If you have a custom ssh config to define the remote user for a host
|
||||
that does not match the inventory user, you should set this parameter to C(no).
|
||||
that does not match the inventory user, you should set this parameter to C(false).
|
||||
type: bool
|
||||
default: yes
|
||||
default: true
|
||||
use_ssh_args:
|
||||
description:
|
||||
- In Ansible 2.10 and lower, it uses the ssh_args specified in C(ansible.cfg).
|
||||
- In Ansible 2.11 and onwards, when set to C(true), it uses all SSH connection configurations like
|
||||
C(ansible_ssh_args), C(ansible_ssh_common_args), and C(ansible_ssh_extra_args).
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
ssh_connection_multiplexing:
|
||||
description:
|
||||
- SSH connection multiplexing for rsync is disabled by default to prevent misconfigured ControlSockets from resulting in failed SSH connections.
|
||||
This is accomplished by setting the SSH C(ControlSocket) to C(none).
|
||||
- Set this option to C(yes) to allow multiplexing and reduce SSH connection overhead.
|
||||
- Note that simply setting this option to C(yes) is not enough;
|
||||
- Set this option to C(true) to allow multiplexing and reduce SSH connection overhead.
|
||||
- Note that simply setting this option to C(true) is not enough;
|
||||
You must also configure SSH connection multiplexing in your SSH client config by setting values for
|
||||
C(ControlMaster), C(ControlPersist) and C(ControlPath).
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
rsync_opts:
|
||||
description:
|
||||
- Specify additional rsync options by passing in an array.
|
||||
@@ -163,12 +163,12 @@ options:
|
||||
description:
|
||||
- Tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
verify_host:
|
||||
description:
|
||||
- Verify destination host key.
|
||||
type: bool
|
||||
default: no
|
||||
default: false
|
||||
private_key:
|
||||
description:
|
||||
- Specify the private key to use for SSH-based rsync connections (e.g. C(~/.ssh/id_rsa)).
|
||||
@@ -184,7 +184,7 @@ options:
|
||||
- This option puts the temporary file from each updated file into a holding directory until the end of the transfer,
|
||||
at which time all the files are renamed into place in rapid succession.
|
||||
type: bool
|
||||
default: yes
|
||||
default: true
|
||||
version_added: '1.3.0'
|
||||
|
||||
notes:
|
||||
@@ -252,27 +252,27 @@ EXAMPLES = r'''
|
||||
ansible.posix.synchronize:
|
||||
src: some/relative/path
|
||||
dest: /some/absolute/path
|
||||
archive: no
|
||||
archive: false
|
||||
|
||||
- name: Synchronization with --archive options enabled except for --recursive
|
||||
ansible.posix.synchronize:
|
||||
src: some/relative/path
|
||||
dest: /some/absolute/path
|
||||
recursive: no
|
||||
recursive: false
|
||||
|
||||
- name: Synchronization with --archive options enabled except for --times, with --checksum option enabled
|
||||
ansible.posix.synchronize:
|
||||
src: some/relative/path
|
||||
dest: /some/absolute/path
|
||||
checksum: yes
|
||||
times: no
|
||||
checksum: true
|
||||
times: false
|
||||
|
||||
- name: Synchronization without --archive options enabled except use --links
|
||||
ansible.posix.synchronize:
|
||||
src: some/relative/path
|
||||
dest: /some/absolute/path
|
||||
archive: no
|
||||
links: yes
|
||||
archive: false
|
||||
links: true
|
||||
|
||||
- name: Synchronization of two paths both on the control machine
|
||||
ansible.posix.synchronize:
|
||||
@@ -302,8 +302,8 @@ EXAMPLES = r'''
|
||||
ansible.posix.synchronize:
|
||||
src: some/relative/path
|
||||
dest: /some/absolute/path
|
||||
delete: yes
|
||||
recursive: yes
|
||||
delete: true
|
||||
recursive: true
|
||||
|
||||
# This specific command is granted su privileges on the destination
|
||||
- name: Synchronize using an alternate rsync command
|
||||
|
||||
@@ -38,14 +38,14 @@ options:
|
||||
description:
|
||||
- Use this option to ignore errors about unknown keys.
|
||||
type: bool
|
||||
default: 'no'
|
||||
default: false
|
||||
reload:
|
||||
description:
|
||||
- If C(yes), performs a I(/sbin/sysctl -p) if the C(sysctl_file) is
|
||||
updated. If C(no), does not reload I(sysctl) even if the
|
||||
- If C(true), performs a I(/sbin/sysctl -p) if the C(sysctl_file) is
|
||||
updated. If C(false), does not reload I(sysctl) even if the
|
||||
C(sysctl_file) is updated.
|
||||
type: bool
|
||||
default: 'yes'
|
||||
default: true
|
||||
sysctl_file:
|
||||
description:
|
||||
- Specifies the absolute path to C(sysctl.conf), if not C(/etc/sysctl.conf).
|
||||
@@ -53,9 +53,9 @@ options:
|
||||
type: path
|
||||
sysctl_set:
|
||||
description:
|
||||
- Verify token value with the sysctl command and set with -w if necessary
|
||||
- Verify token value with the sysctl command and set with -w if necessary.
|
||||
type: bool
|
||||
default: 'no'
|
||||
default: false
|
||||
author:
|
||||
- David CHANIAL (@davixx)
|
||||
'''
|
||||
@@ -78,21 +78,21 @@ EXAMPLES = r'''
|
||||
name: kernel.panic
|
||||
value: '3'
|
||||
sysctl_file: /tmp/test_sysctl.conf
|
||||
reload: no
|
||||
reload: false
|
||||
|
||||
# Set ip forwarding on in /proc and verify token value with the sysctl command
|
||||
- ansible.posix.sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: '1'
|
||||
sysctl_set: yes
|
||||
sysctl_set: true
|
||||
|
||||
# Set ip forwarding on in /proc and in the sysctl file and reload if necessary
|
||||
- ansible.posix.sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: '1'
|
||||
sysctl_set: yes
|
||||
sysctl_set: true
|
||||
state: present
|
||||
reload: yes
|
||||
reload: true
|
||||
'''
|
||||
|
||||
# ==============================================================
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# -------------------------------------------------------------
|
||||
# Setup steps
|
||||
- name: Clean up the working directory and files
|
||||
file:
|
||||
path: '{{ output_dir }}'
|
||||
state: absent
|
||||
|
||||
- name: Create the working directory
|
||||
file:
|
||||
path: '{{ output_dir }}'
|
||||
state: directory
|
||||
|
||||
- name: copy an existing file in place with comments
|
||||
copy:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
- name: firewalld port range test permanent enabled
|
||||
firewalld:
|
||||
port: 5500-6950/tcp
|
||||
port: 5500-6850/tcp
|
||||
permanent: true
|
||||
state: enabled
|
||||
register: result
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
- name: firewalld port range test permanent enabled rerun (verify not changed)
|
||||
firewalld:
|
||||
port: 5500-6950/tcp
|
||||
port: 5500-6850/tcp
|
||||
permanent: true
|
||||
state: enabled
|
||||
register: result
|
||||
@@ -57,7 +57,7 @@
|
||||
state: disabled
|
||||
loop:
|
||||
- 6900/tcp
|
||||
- 5500-6950/tcp
|
||||
- 5500-6850/tcp
|
||||
|
||||
- name: firewalld port test permanent enabled
|
||||
firewalld:
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
- name: Install dependencies
|
||||
ansible.builtin.package:
|
||||
name: e2fsprogs
|
||||
state: present
|
||||
when: ansible_system == 'Linux'
|
||||
|
||||
- name: Create the mount point
|
||||
file:
|
||||
state: directory
|
||||
@@ -406,3 +412,270 @@
|
||||
- /tmp/myfs1
|
||||
- /tmp/test_fstab
|
||||
when: ansible_system in ('Linux')
|
||||
|
||||
- name: Block to test ephemeral option
|
||||
environment:
|
||||
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
block:
|
||||
- name: Create empty file A
|
||||
community.general.filesize:
|
||||
path: /tmp/myfs_A.img
|
||||
size: 20M
|
||||
|
||||
- name: Create empty file B
|
||||
community.general.filesize:
|
||||
path: /tmp/myfs_B.img
|
||||
size: 20M
|
||||
|
||||
- name: Register facts on Linux
|
||||
ansible.builtin.set_fact:
|
||||
ephemeral_device_A: /tmp/myfs_A.img
|
||||
ephemeral_device_B: /tmp/myfs_B.img
|
||||
ephemeral_fstype: ext3
|
||||
ephemeral_fstab: /etc/fstab
|
||||
when: ansible_system == 'Linux'
|
||||
|
||||
- name: Register facts on Solaris/SunOS
|
||||
ansible.builtin.set_fact:
|
||||
ephemeral_device_A: /dev/lofi/1
|
||||
ephemeral_device_B: /dev/lofi/2
|
||||
ephemeral_create_loop_dev_cmd: >
|
||||
lofiadm -a /tmp/myfs_A.img /dev/lofi/1 &&
|
||||
lofiadm -a /tmp/myfs_B.img /dev/lofi/2
|
||||
ephemeral_remove_loop_dev_cmd: >
|
||||
lofiadm -d /dev/lofi/1 &&
|
||||
lofiadm -d /dev/lofi/2 || true
|
||||
ephemeral_fstype: ufs
|
||||
ephemeral_fstab: /etc/vfstab
|
||||
when: ansible_system == 'SunOS'
|
||||
|
||||
- name: Register facts on FreeBSD
|
||||
ansible.builtin.set_fact:
|
||||
ephemeral_device_A: /dev/md1
|
||||
ephemeral_device_B: /dev/md2
|
||||
ephemeral_create_loop_dev_cmd: >
|
||||
mdconfig -a -t vnode -f /tmp/myfs_A.img -u /dev/md1 &&
|
||||
mdconfig -a -t vnode -f /tmp/myfs_B.img -u /dev/md2
|
||||
ephemeral_remove_loop_dev_cmd: >
|
||||
mdconfig -d -u /dev/md1 &&
|
||||
mdconfig -d -u /dev/md2
|
||||
ephemeral_fstype: ufs
|
||||
ephemeral_fstab: /etc/fstab
|
||||
when: ansible_system == 'FreeBSD'
|
||||
|
||||
- name: Register facts on NetBSD
|
||||
ansible.builtin.set_fact:
|
||||
ephemeral_device_A: /dev/vnd1
|
||||
ephemeral_device_B: /dev/vnd2
|
||||
ephemeral_create_loop_dev_cmd: >
|
||||
vnconfig /dev/vnd1 /tmp/myfs_A.img &&
|
||||
vnconfig /dev/vnd2 /tmp/myfs_B.img
|
||||
ephemeral_remove_loop_dev_cmd: >
|
||||
vnconfig -u /dev/vnd1 &&
|
||||
vnconfig -u /dev/vnd2
|
||||
ephemeral_fstype: ufs
|
||||
ephemeral_fstab: /etc/fstab
|
||||
when: ansible_system == 'NetBSD'
|
||||
|
||||
- name: Register format fs command on Non-Linux and Non-OpenBSD
|
||||
ansible.builtin.set_fact:
|
||||
ephemeral_format_fs_cmd: >
|
||||
yes | newfs {{ ephemeral_device_A }} &&
|
||||
yes | newfs {{ ephemeral_device_B }}
|
||||
when: ansible_system in ('SunOS', 'FreeBSD', 'NetBSD')
|
||||
|
||||
- name: Register facts on OpenBSD
|
||||
ansible.builtin.set_fact:
|
||||
ephemeral_device_A: /dev/vnd1c
|
||||
ephemeral_device_B: /dev/vnd2c
|
||||
ephemeral_create_loop_dev_cmd: >
|
||||
vnconfig vnd1 /tmp/myfs_A.img &&
|
||||
vnconfig vnd2 /tmp/myfs_B.img
|
||||
ephemeral_remove_loop_dev_cmd: >
|
||||
vnconfig -u vnd1 &&
|
||||
vnconfig -u vnd2
|
||||
ephemeral_format_fs_cmd: >
|
||||
yes | newfs /dev/rvnd1c &&
|
||||
yes | newfs /dev/rvnd2c
|
||||
ephemeral_fstype: ffs
|
||||
ephemeral_fstab: /etc/fstab
|
||||
when: ansible_system == 'OpenBSD'
|
||||
|
||||
##### FORMAT FS ON LINUX
|
||||
|
||||
- name: Block to format FS on Linux
|
||||
block:
|
||||
- name: Format FS A on Linux
|
||||
community.general.filesystem:
|
||||
fstype: ext3
|
||||
dev: /tmp/myfs_A.img
|
||||
|
||||
- name: Format FS B on Linux
|
||||
community.general.filesystem:
|
||||
fstype: ext3
|
||||
dev: /tmp/myfs_B.img
|
||||
when: ansible_system == 'Linux'
|
||||
|
||||
##### FORMAT FS ON SOLARIS AND BSD
|
||||
|
||||
- name: Create loop devices on Solaris and BSD
|
||||
ansible.builtin.shell: "{{ ephemeral_create_loop_dev_cmd }}"
|
||||
when: ephemeral_create_loop_dev_cmd is defined
|
||||
|
||||
- name: Format FS A and B on Solaris and BSD
|
||||
ansible.builtin.shell: "{{ ephemeral_format_fs_cmd }}"
|
||||
when: ephemeral_format_fs_cmd is defined
|
||||
|
||||
##### TESTS
|
||||
|
||||
- name: Create fstab if it does not exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ ephemeral_fstab }}"
|
||||
state: touch
|
||||
|
||||
- name: Get checksum of /etc/fstab before mounting anything
|
||||
stat:
|
||||
path: '{{ ephemeral_fstab }}'
|
||||
register: fstab_stat_before_mount
|
||||
|
||||
- name: Mount the FS A with ephemeral state
|
||||
mount:
|
||||
path: /tmp/myfs
|
||||
src: '{{ ephemeral_device_A }}'
|
||||
fstype: '{{ ephemeral_fstype }}'
|
||||
opts: rw
|
||||
state: ephemeral
|
||||
register: ephemeral_mount_info
|
||||
|
||||
- name: Put something in the directory so we can do additional checks later on
|
||||
copy:
|
||||
content: 'Testing'
|
||||
dest: /tmp/myfs/test_file
|
||||
|
||||
- name: Get checksum of /etc/fstab after an ephemeral mount
|
||||
stat:
|
||||
path: '{{ ephemeral_fstab }}'
|
||||
register: fstab_stat_after_mount
|
||||
|
||||
- name: Get mountinfo
|
||||
shell: mount -v | awk '{print $3}' | grep '^/tmp/myfs$' | wc -l
|
||||
register: check_mountinfo
|
||||
changed_when: no
|
||||
|
||||
- name: Assert the mount occured and the fstab is unchanged
|
||||
assert:
|
||||
that:
|
||||
- check_mountinfo.stdout|int == 1
|
||||
- ephemeral_mount_info['changed']
|
||||
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
|
||||
|
||||
- name: Get first mount record
|
||||
shell: mount -v | grep '/tmp/myfs'
|
||||
register: ephemeral_mount_record_1
|
||||
changed_when: no
|
||||
|
||||
- name: Try to mount FS A where FS A is already mounted (should trigger remount and changed)
|
||||
mount:
|
||||
path: /tmp/myfs
|
||||
src: '{{ ephemeral_device_A }}'
|
||||
fstype: '{{ ephemeral_fstype }}'
|
||||
opts: ro
|
||||
state: ephemeral
|
||||
register: ephemeral_mount_info
|
||||
|
||||
- name: Get second mount record (should be different than the first)
|
||||
shell: mount -v | grep '/tmp/myfs'
|
||||
register: ephemeral_mount_record_2
|
||||
changed_when: no
|
||||
|
||||
- name: Get mountinfo
|
||||
shell: mount -v | awk '{print $3}' | grep '^/tmp/myfs$' | wc -l
|
||||
register: check_mountinfo
|
||||
changed_when: no
|
||||
|
||||
- name: Assert the FS A is still mounted, the options changed and the fstab unchanged
|
||||
assert:
|
||||
that:
|
||||
- check_mountinfo.stdout|int == 1
|
||||
- ephemeral_mount_record_1.stdout != ephemeral_mount_record_2.stdout
|
||||
- ephemeral_mount_info['changed']
|
||||
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
|
||||
|
||||
- name: Try to mount file B on file A mountpoint (should fail)
|
||||
mount:
|
||||
path: /tmp/myfs
|
||||
src: '{{ ephemeral_device_B }}'
|
||||
fstype: '{{ ephemeral_fstype }}'
|
||||
state: ephemeral
|
||||
register: ephemeral_mount_b_info
|
||||
ignore_errors: true
|
||||
|
||||
- name: Get third mount record (should be the same than the second)
|
||||
shell: mount -v | grep '/tmp/myfs'
|
||||
register: ephemeral_mount_record_3
|
||||
changed_when: no
|
||||
|
||||
- name: Get mountinfo
|
||||
shell: mount -v | awk '{print $3}' | grep '^/tmp/myfs$' | wc -l
|
||||
register: check_mountinfo
|
||||
changed_when: no
|
||||
|
||||
- name: Try to stat our test file
|
||||
stat:
|
||||
path: /tmp/myfs/test_file
|
||||
register: test_file_stat
|
||||
|
||||
- name: Assert that mounting FS B over FS A failed
|
||||
assert:
|
||||
that:
|
||||
- check_mountinfo.stdout|int == 1
|
||||
- ephemeral_mount_record_2.stdout == ephemeral_mount_record_3.stdout
|
||||
- test_file_stat['stat']['exists']
|
||||
- ephemeral_mount_b_info is failed
|
||||
|
||||
- name: Unmount FS with state = unmounted
|
||||
mount:
|
||||
path: /tmp/myfs
|
||||
state: unmounted
|
||||
|
||||
- name: Get fstab checksum after unmounting an ephemeral mount with state = unmounted
|
||||
stat:
|
||||
path: '{{ ephemeral_fstab }}'
|
||||
register: fstab_stat_after_unmount
|
||||
|
||||
- name: Get mountinfo
|
||||
shell: mount -v | awk '{print $3}' | grep '^/tmp/myfs$' | wc -l
|
||||
register: check_mountinfo
|
||||
changed_when: no
|
||||
|
||||
- name: Try to stat our test file
|
||||
stat:
|
||||
path: /tmp/myfs/test_file
|
||||
register: test_file_stat
|
||||
|
||||
- name: Assert that fstab is unchanged after unmounting an ephemeral mount with state = unmounted
|
||||
assert:
|
||||
that:
|
||||
- check_mountinfo.stdout|int == 0
|
||||
- not test_file_stat['stat']['exists']
|
||||
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_unmount['stat']['checksum']
|
||||
|
||||
always:
|
||||
- name: Unmount potential failure relicas
|
||||
mount:
|
||||
path: /tmp/myfs
|
||||
state: unmounted
|
||||
|
||||
- name: Remove loop devices on Solaris and BSD
|
||||
ansible.builtin.shell: "{{ ephemeral_remove_loop_dev_cmd }}"
|
||||
when: ephemeral_remove_loop_dev_cmd is defined
|
||||
|
||||
- name: Remove the test FS
|
||||
file:
|
||||
path: '{{ item }}'
|
||||
state: absent
|
||||
loop:
|
||||
- /tmp/myfs_A.img
|
||||
- /tmp/myfs_B.img
|
||||
- /tmp/myfs
|
||||
when: ansible_system in ('Linux', 'SunOS', 'FreeBSD', 'NetBSD', 'OpenBSD')
|
||||
|
||||
8
tests/sanity/ignore-2.15.txt
Normal file
8
tests/sanity/ignore-2.15.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
plugins/modules/synchronize.py pylint:disallowed-name
|
||||
plugins/modules/synchronize.py use-argspec-type-path
|
||||
plugins/modules/synchronize.py validate-modules:doc-default-does-not-match-spec
|
||||
plugins/modules/synchronize.py validate-modules:nonexistent-parameter-documented
|
||||
plugins/modules/synchronize.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/synchronize.py validate-modules:undocumented-parameter
|
||||
tests/utils/shippable/check_matrix.py replace-urlopen
|
||||
tests/utils/shippable/timing.py shebang
|
||||
@@ -74,7 +74,14 @@ else
|
||||
fi
|
||||
|
||||
# START: HACK install dependencies
|
||||
retry ansible-galaxy collection install community.general
|
||||
if [ "${ansible_version}" == "2.9" ] || [ "${ansible_version}" == "2.10" ]; then
|
||||
# Note: Since community.general 5.x, Ansible Core versions prior to 2.11 are not supported.
|
||||
# So we need to use 4.8.1 for Ansible 2.9 and Ansible Engine 2.10.
|
||||
retry git clone --depth=1 --single-branch -b 4.8.1 https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/general"
|
||||
else
|
||||
retry git clone --depth=1 --single-branch https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/general"
|
||||
fi
|
||||
# Note: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
|
||||
# END: HACK
|
||||
|
||||
export PYTHONIOENCODING='utf-8'
|
||||
|
||||
Reference in New Issue
Block a user