Files
ansible.posix/plugins/modules/rhel_rpm_ostree.py
Hideki Saito 0b197ad440 Merge pull request #690 from barpavel/fix-686-module-utils-deprecation (#734)
Fix all deprecated module_utils imports before ansible-core 2.24 removal

SUMMARY
Fixes all deprecated ansible.module_utils imports across the entire collection that will be removed in ansible-core 2.24.
This PR comprehensively addresses deprecation warnings reported in #686 by updating import statements in 20 files to use the new recommended import paths, and removes 8 unused test utility files that contained deprecated imports.
Deprecated imports replaced:

Deprecated import
Replacement

ansible.module_utils._text
ansible.module_utils.common.text.converters

ansible.module_utils.common._collections_compat
collections.abc

ansible.module_utils.six.moves.shlex_quote
shlex.quote

ansible.module_utils.six.moves.reduce
functools.reduce

ansible.module_utils.six.moves.urllib.parse.urlparse
urllib.parse.urlparse

ansible.module_utils.six.string_types
basestring/str (Python 2/3 compatible)

ansible.module_utils.six.text_type
str

ansible.module_utils.six.PY3
Removed (simplified Python 2/3 conditionals)

ansible.module_utils.six.with_metaclass
Native metaclass= syntax

ansible.module_utils.six.iteritems
dict.items()

Files fixed (20 files, 1 commit per file for easier review):

plugins/action/patch.py
plugins/action/synchronize.py
plugins/callback/cgroup_perf_recap.py
plugins/callback/json.py
plugins/callback/jsonl.py
plugins/callback/profile_roles.py
plugins/callback/profile_tasks.py
plugins/modules/acl.py
plugins/modules/authorized_key.py
plugins/modules/firewalld_info.py
plugins/modules/mount.py
plugins/modules/patch.py
plugins/modules/rhel_rpm_ostree.py
plugins/modules/rpm_ostree_upgrade.py
plugins/modules/seboolean.py
plugins/modules/synchronize.py
plugins/modules/sysctl.py
plugins/shell/csh.py
plugins/shell/fish.py
tests/unit/modules/system/test_mount.py

Files deleted (8 unused test utility files):
These files are dead code - none of them are imported or used anywhere in the test suite or the collection. Removing them also addresses Python 2.7 compatibility concerns raised in code review, as several contained deprecated imports that would be incorrect to fix for Python 2.

tests/unit/compat/builtins.py
tests/unit/mock/loader.py
tests/unit/mock/path.py
tests/unit/mock/procenv.py
tests/unit/mock/vault_helper.py
tests/unit/mock/yaml_helper.py
tests/unit/modules/conftest.py
tests/unit/modules/utils.py

Completeness verified with:
git grep -n -P '_compat|utils._text|utils.six' -- '*.py' | grep -v yml

This command returns no results, confirming all deprecated imports have been replaced.
Notes on Python 2.7 compatibility:
For modules that may run on Python 2.7 managed hosts (e.g., authorized_key.py, synchronize.py, sysctl.py), Python 2/3 compatible fallbacks were used instead of direct Python 3 replacements:

authorized_key.py: try/except ImportError for urllib.parse.urlparse (falls back to urlparse on Python 2)
synchronize.py: try/except ImportError for shlex.quote (falls back to pipes.quote on Python 2)
sysctl.py: uses sys.version_info to set string_types to str on Python 3 (basestring on Python 2)

Also removes corresponding pylint:ansible-bad-import-from entries from tests/sanity/ignore-2.21.txt and tests/sanity/ignore-2.22.txt where applicable.
Fixes #686
ISSUE TYPE

Bugfix Pull Request

ADDITIONAL INFORMATION
Approach:
Each file is fixed in a separate commit for easier code review. The changelog fragment is added in a final commit. Corresponding pylint:ansible-bad-import-from ignore entries in tests/sanity/ignore-2.21.txt and tests/sanity/ignore-2.22.txt are removed in the same commit as the file fix (or the file removal commit).
CI results:
All 59 checks passing (Azure Pipelines sanity, units, lint, Docker, Remote across ansible-core 2.17 through devel, and Zuul ansible/check).

Reviewed-by: Felix Fontein <felix@fontein.de>
Reviewed-by: Pavel Bar
Reviewed-by: Abhijeet Kasurde
(cherry picked from commit 2022c1bd86)

Co-authored-by: centosinfra-prod-github-app[bot] <161850885+centosinfra-prod-github-app[bot]@users.noreply.github.com>
2026-05-18 11:23:20 +09:00

122 lines
4.4 KiB
Python

#!/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_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 V(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 O(state=latest), this can be V('*') which means run C(yum -y update).
- You can also pass a url or a local path to a rpm file (using O(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 (V(present) or V(installed), V(latest)), or remove (V(absent) or V(removed)) a package.
- V(present) and V(installed) will simply ensure that a desired package is installed.
- V(latest) will update the specified package if it's not of the latest available version.
- V(absent) and V(removed) will remove the specified package.
- Default is C(null), however in effect the default action is V(present) unless the C(autoremove) option is
enabled for this module, then V(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.common.text.converters 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()