mirror of
https://github.com/ansible-collections/ansible.posix.git
synced 2026-01-11 15:15:26 +01:00
Merge branch 'main' into ephemeral_state
This commit is contained in:
commit
bd9aa64a2b
22 changed files with 440 additions and 16 deletions
|
|
@ -36,7 +36,7 @@ variables:
|
||||||
resources:
|
resources:
|
||||||
containers:
|
containers:
|
||||||
- container: default
|
- 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
|
pool: Standard
|
||||||
|
|
||||||
|
|
@ -53,8 +53,24 @@ stages:
|
||||||
targets:
|
targets:
|
||||||
- name: CentOS 7
|
- name: CentOS 7
|
||||||
test: centos7
|
test: centos7
|
||||||
- name: Fedora 35
|
- name: Fedora 36
|
||||||
test: fedora35
|
test: fedora36
|
||||||
|
- name: openSUSE 15 py3
|
||||||
|
test: opensuse15
|
||||||
|
- 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
|
- name: Fedora 36
|
||||||
test: fedora36
|
test: fedora36
|
||||||
- name: openSUSE 15 py3
|
- name: openSUSE 15 py3
|
||||||
|
|
@ -197,8 +213,24 @@ stages:
|
||||||
test: rhel/8.6
|
test: rhel/8.6
|
||||||
- name: RHEL 9.0
|
- name: RHEL 9.0
|
||||||
test: rhel/9.0
|
test: rhel/9.0
|
||||||
- name: FreeBSD 12.3
|
- name: FreeBSD 13.1
|
||||||
test: freebsd/12.3
|
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 13.1
|
- name: FreeBSD 13.1
|
||||||
test: freebsd/13.1
|
test: freebsd/13.1
|
||||||
- stage: Remote_2_13
|
- stage: Remote_2_13
|
||||||
|
|
@ -297,6 +329,8 @@ stages:
|
||||||
- Docker_2_12
|
- Docker_2_12
|
||||||
- Remote_2_13
|
- Remote_2_13
|
||||||
- Docker_2_13
|
- Docker_2_13
|
||||||
|
- Remote_2_14
|
||||||
|
- Docker_2_14
|
||||||
- Remote_devel
|
- Remote_devel
|
||||||
- Docker_devel
|
- Docker_devel
|
||||||
jobs:
|
jobs:
|
||||||
|
|
|
||||||
2
changelogs/fragments/166_mount_absent_fstab.yml
Normal file
2
changelogs/fragments/166_mount_absent_fstab.yml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- mount - Add ``absent_from_fstab`` state (https://github.com/ansible-collections/ansible.posix/pull/166).
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
bugfixes:
|
||||||
|
- firewall - Fixed to output a more complete missing library message.
|
||||||
3
changelogs/fragments/375_update_azp_container.yml
Normal file
3
changelogs/fragments/375_update_azp_container.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
trivial:
|
||||||
|
- CI - AZP test container to 3.0.0 (https://github.com/ansible-collections/news-for-maintainers/issues/18).
|
||||||
3
changelogs/fragments/380_update_usage_profile_tasks.yml
Normal file
3
changelogs/fragments/380_update_usage_profile_tasks.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
bugfixes:
|
||||||
|
- Removed contentious terminology to match reference documentation in profile_tasks.
|
||||||
3
changelogs/fragments/386_follow_ci_testing_rules.yml
Normal file
3
changelogs/fragments/386_follow_ci_testing_rules.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
trivial:
|
||||||
|
- CI - following the new CI testing rule ansible-test-sanity-docker-devel.
|
||||||
3
changelogs/fragments/389_ci_add_stable_214.yml
Normal file
3
changelogs/fragments/389_ci_add_stable_214.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
trivial:
|
||||||
|
- CI - Add stable-2.14 to AZP (https://github.com/ansible-collections/ansible.posix/issues/388).
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
bugfixes:
|
||||||
|
- synchronize - Fixed hosts involved in rsync require the same password
|
||||||
5
changelogs/fragments/393-rpm-ostree.yml
Normal file
5
changelogs/fragments/393-rpm-ostree.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
minor_changes:
|
||||||
|
- 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
|
||||||
4
changelogs/fragments/393_rhel_for_edge.yml
Normal file
4
changelogs/fragments/393_rhel_for_edge.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
minor_changes:
|
||||||
|
- r4e_rpm_ostree - new module for validating package state on RHEL for Edge
|
||||||
|
- rpm_ostree_upgrade - new module to manage upgrades for rpm-ostree based systems
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
trivial:
|
||||||
|
- acl - document default value for the ``entry`` parameter
|
||||||
|
- rhel_rpm_ostree - document default value for the ``name`` parameter
|
||||||
|
|
@ -225,7 +225,6 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
# Parameter name needed by the ansible module
|
# Parameter name needed by the ansible module
|
||||||
_tmp_args['_local_rsync_path'] = task_vars.get('ansible_rsync_path') or 'rsync'
|
_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
|
# 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
|
# 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:
|
if src is None or dest is None:
|
||||||
return dict(failed=True, msg="synchronize requires both src and dest parameters are set")
|
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
|
user = None
|
||||||
|
password = task_vars.get('ansible_ssh_pass', None) or task_vars.get('ansible_password', None)
|
||||||
if not dest_is_local:
|
if not dest_is_local:
|
||||||
# Src and dest rsync "path" handling
|
# Src and dest rsync "path" handling
|
||||||
if boolean(_tmp_args.get('set_remote_user', 'yes'), strict=False):
|
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
|
user = task_vars.get('ansible_user') or self._play_context.remote_user
|
||||||
if not user:
|
if not user:
|
||||||
user = C.DEFAULT_REMOTE_USER
|
user = C.DEFAULT_REMOTE_USER
|
||||||
|
|
||||||
else:
|
else:
|
||||||
user = task_vars.get('ansible_user') or self._play_context.remote_user
|
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
|
# Private key handling
|
||||||
# Use the private_key parameter if passed else use context private_key_file
|
# 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)
|
_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 is a local path, dest is a remote path: <user>@<host>
|
||||||
src = self._process_origin(src_host, src, user)
|
src = self._process_origin(src_host, src, user)
|
||||||
dest = self._process_remote(_tmp_args, dest_host, dest, user, inv_port in localhost_ports)
|
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:
|
else:
|
||||||
# Still need to munge paths (to account for roles) even if we aren't
|
# Still need to munge paths (to account for roles) even if we aren't
|
||||||
# copying files between hosts
|
# copying files between hosts
|
||||||
src = self._get_absolute_path(path=src)
|
src = self._get_absolute_path(path=src)
|
||||||
dest = self._get_absolute_path(path=dest)
|
dest = self._get_absolute_path(path=dest)
|
||||||
|
|
||||||
|
_tmp_args['_local_rsync_password'] = password
|
||||||
_tmp_args['src'] = src
|
_tmp_args['src'] = src
|
||||||
_tmp_args['dest'] = dest
|
_tmp_args['dest'] = dest
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ DOCUMENTATION = '''
|
||||||
- It also lists the top/bottom time consuming tasks in the summary (configurable)
|
- It also lists the top/bottom time consuming tasks in the summary (configurable)
|
||||||
- Before 2.4 only the environment variables were available for configuration.
|
- Before 2.4 only the environment variables were available for configuration.
|
||||||
requirements:
|
requirements:
|
||||||
- whitelisting in configuration - see examples section below for details.
|
- enable in configuration - see examples section below for details.
|
||||||
options:
|
options:
|
||||||
output_limit:
|
output_limit:
|
||||||
description: Number of tasks to display in the summary
|
description: Number of tasks to display in the summary
|
||||||
|
|
@ -46,7 +46,7 @@ EXAMPLES = '''
|
||||||
example: >
|
example: >
|
||||||
To enable, add this to your ansible.cfg file in the defaults block
|
To enable, add this to your ansible.cfg file in the defaults block
|
||||||
[defaults]
|
[defaults]
|
||||||
callback_whitelist = ansible.posix.profile_tasks
|
callbacks_enabled=ansible.posix.profile_tasks
|
||||||
sample output: >
|
sample output: >
|
||||||
#
|
#
|
||||||
# TASK: [ensure messaging security group exists] ********************************
|
# TASK: [ensure messaging security group exists] ********************************
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
from ansible_collections.ansible.posix.plugins.module_utils.version import LooseVersion
|
from ansible_collections.ansible.posix.plugins.module_utils.version import LooseVersion
|
||||||
|
from ansible.module_utils.basic import missing_required_lib
|
||||||
|
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
@ -314,6 +315,5 @@ class FirewallTransaction(object):
|
||||||
|
|
||||||
if import_failure:
|
if import_failure:
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg='Python Module not found: firewalld and its python module are required for this module, \
|
msg=missing_required_lib('firewall') + '. Version 0.2.11 or newer required (0.3.9 or newer for offline operations)'
|
||||||
version 0.2.11 or newer required (0.3.9 or newer for offline operations)'
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ options:
|
||||||
description:
|
description:
|
||||||
- The actual user or group that the ACL applies to when matching entity types user or group are selected.
|
- The actual user or group that the ACL applies to when matching entity types user or group are selected.
|
||||||
type: str
|
type: str
|
||||||
|
default: ""
|
||||||
etype:
|
etype:
|
||||||
description:
|
description:
|
||||||
- The entity type of the ACL to apply, see C(setfacl) documentation for more info.
|
- The entity type of the ACL to apply, see C(setfacl) documentation for more info.
|
||||||
|
|
|
||||||
|
|
@ -347,6 +347,8 @@ def keyfile(module, user, write=False, path=None, manage_dir=True, follow=False)
|
||||||
basedir = os.path.dirname(keysfile)
|
basedir = os.path.dirname(keysfile)
|
||||||
if not os.path.exists(basedir):
|
if not os.path.exists(basedir):
|
||||||
os.makedirs(basedir)
|
os.makedirs(basedir)
|
||||||
|
|
||||||
|
f = None
|
||||||
try:
|
try:
|
||||||
f = open(keysfile, "w") # touches file so we can set ownership and perms
|
f = open(keysfile, "w") # touches file so we can set ownership and perms
|
||||||
finally:
|
finally:
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,12 @@ options:
|
||||||
instead to work around this issue. C(remounted) expects the mount point
|
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
|
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.
|
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
|
type: str
|
||||||
required: true
|
required: true
|
||||||
choices: [ absent, mounted, present, unmounted, remounted, ephemeral ]
|
choices: [ absent, absent_from_fstab, mounted, present, unmounted, remounted, ephemeral ]
|
||||||
fstab:
|
fstab:
|
||||||
description:
|
description:
|
||||||
- File to use instead of C(/etc/fstab).
|
- File to use instead of C(/etc/fstab).
|
||||||
|
|
@ -245,7 +248,7 @@ def _escape_fstab(v):
|
||||||
if isinstance(v, int):
|
if isinstance(v, int):
|
||||||
return v
|
return v
|
||||||
else:
|
else:
|
||||||
return(
|
return (
|
||||||
v.
|
v.
|
||||||
replace('\\', '\\134').
|
replace('\\', '\\134').
|
||||||
replace(' ', '\\040').
|
replace(' ', '\\040').
|
||||||
|
|
@ -763,7 +766,7 @@ def main():
|
||||||
passno=dict(type='str', no_log=False, default='0'),
|
passno=dict(type='str', no_log=False, default='0'),
|
||||||
src=dict(type='path'),
|
src=dict(type='path'),
|
||||||
backup=dict(type='bool', default=False),
|
backup=dict(type='bool', default=False),
|
||||||
state=dict(type='str', required=True, choices=['absent', 'mounted', 'present', 'unmounted', 'remounted', 'ephemeral']),
|
state=dict(type='str', required=True, choices=['absent', 'absent_from_fstab', 'mounted', 'present', 'unmounted', 'remounted', 'ephemeral']),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
required_if=(
|
required_if=(
|
||||||
|
|
@ -868,7 +871,9 @@ def main():
|
||||||
name = module.params['path']
|
name = module.params['path']
|
||||||
changed = False
|
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)
|
name, changed = unset_mount(module, args)
|
||||||
|
|
||||||
if changed and not module.check_mode:
|
if changed and not module.check_mode:
|
||||||
|
|
|
||||||
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()
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
# Setup steps
|
# 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
|
- name: copy an existing file in place with comments
|
||||||
copy:
|
copy:
|
||||||
|
|
|
||||||
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
|
||||||
Loading…
Reference in a new issue