From ad777cba5ad197c3ed25cc4321f10bd68be8440e Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 2 May 2024 14:33:12 -0400 Subject: [PATCH] package_facts add alias support (#83149) * package_facts add alias support fixes #83143 Co-authored-by: Abhijeet Kasurde --- .../fragments/package_facts_aliases.yml | 2 + lib/ansible/modules/package_facts.py | 53 +++++++++++++++---- .../targets/package_facts/tasks/main.yml | 32 ++++++----- 3 files changed, 59 insertions(+), 28 deletions(-) create mode 100644 changelogs/fragments/package_facts_aliases.yml diff --git a/changelogs/fragments/package_facts_aliases.yml b/changelogs/fragments/package_facts_aliases.yml new file mode 100644 index 00000000000..9e408ff6eba --- /dev/null +++ b/changelogs/fragments/package_facts_aliases.yml @@ -0,0 +1,2 @@ +minor_changes: + - package_facts module now supports using aliases for supported package managers, for example managers=yum or managers=dnf will resolve to using the underlying rpm. diff --git a/lib/ansible/modules/package_facts.py b/lib/ansible/modules/package_facts.py index 11a8f61fdb0..370e7d60b44 100644 --- a/lib/ansible/modules/package_facts.py +++ b/lib/ansible/modules/package_facts.py @@ -14,30 +14,43 @@ description: options: manager: description: - - The package manager used by the system so we can query the package information. - - Since 2.8 this is a list and can support multiple package managers per system. + - The package manager(s) used by the system so we can query the package information. + This is a list and can support multiple package managers per system, since version 2.8. - The 'portage' and 'pkg' options were added in version 2.8. - The 'apk' option was added in version 2.11. - The 'pkg_info' option was added in version 2.13. + - Aliases were added in 2.18, to support using C(auto={{ansible_facts['pkg_mgr']}}) default: ['auto'] - choices: ['auto', 'rpm', 'apt', 'portage', 'pkg', 'pacman', 'apk', 'pkg_info'] + choices: + auto: Depending on O(strategy), will match the first or all package managers provided, in order + rpm: For RPM based distros, requires RPM Python bindings, not installed by default on Suse (python3-rpm) + yum: Alias to rpm + dnf: Alias to rpm + dnf5: Alias to rpm + zypper: Alias to rpm + apt: For DEB based distros, C(python-apt) package must be installed on targeted hosts + portage: Handles ebuild packages, it requires the C(qlist) utility, which is part of 'app-portage/portage-utils' + pkg: libpkg front end (FreeBSD) + pkg5: Alias to pkg + pkgng: Alias to pkg + pacman: Archlinux package manager/builder + apk: Alpine Linux package manager + pkg_info: OpenBSD package manager + openbsd_pkg: Alias to pkg_info type: list elements: str strategy: description: - This option controls how the module queries the package managers on the system. - V(first) means it will return only information for the first supported package manager available. - V(all) will return information for all supported and available package managers on the system. - choices: ['first', 'all'] + choices: + first: returns only information for the first supported package manager available. + all: returns information for all supported and available package managers on the system. default: 'first' type: str version_added: "2.8" version_added: "2.5" requirements: - - For 'portage' support it requires the C(qlist) utility, which is part of 'app-portage/portage-utils'. - - For Debian-based systems C(python-apt) package must be installed on targeted hosts. - - For SUSE-based systems C(python3-rpm) package must be installed on targeted hosts. - This package is required because SUSE does not include RPM Python bindings by default. + - See details per package manager in the O(manager) option. author: - Matthew Jones (@matburt) - Brian Coca (@bcoca) @@ -247,6 +260,13 @@ from ansible.module_utils.common.respawn import has_respawned, probe_interpreter from ansible.module_utils.facts.packages import LibMgr, CLIMgr, get_all_pkg_managers +ALIASES = { + 'rpm': ['dnf', 'dnf5', 'yum' , 'zypper'], + 'pkg': ['pkg5', 'pkgng'], + 'pkg_info': ['openbsd_pkg'], +} + + class RPM(LibMgr): LIB = 'rpm' @@ -485,9 +505,13 @@ def main(): # get supported pkg managers PKG_MANAGERS = get_all_pkg_managers() PKG_MANAGER_NAMES = [x.lower() for x in PKG_MANAGERS.keys()] + # add aliases + PKG_MANAGER_NAMES.extend([alias for alist in ALIASES.values() for alias in alist]) # start work global module + + # choices are not set for 'manager' as they are computed dynamically and validated below instead of in argspec module = AnsibleModule(argument_spec=dict(manager={'type': 'list', 'elements': 'str', 'default': ['auto']}, strategy={'choices': ['first', 'all'], 'default': 'first'}), supports_check_mode=True) @@ -513,12 +537,19 @@ def main(): seen = set() for pkgmgr in managers: - if found and strategy == 'first': + if strategy == 'first' and found: break + # substitute aliases for aliased + for aliased in ALIASES.keys(): + if pkgmgr in ALIASES[aliased]: + pkgmgr = aliased + break + # dedupe as per above if pkgmgr in seen: continue + seen.add(pkgmgr) try: try: diff --git a/test/integration/targets/package_facts/tasks/main.yml b/test/integration/targets/package_facts/tasks/main.yml index 12dfcf03164..144fa784f70 100644 --- a/test/integration/targets/package_facts/tasks/main.yml +++ b/test/integration/targets/package_facts/tasks/main.yml @@ -1,20 +1,5 @@ -# Test playbook for the package_facts module -# (c) 2017, Adam Miller - -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# Copyright: Contributors to the Ansible project - name: Prep package_fact tests - Debian Family block: @@ -65,6 +50,19 @@ that: ansible_facts.packages is defined when: (ansible_os_family == "openSUSE Leap") or (ansible_os_family == "Suse") +- name: Same as those above, but based on pkg_mgr, tests aliases + block: + - name: Gather package facts + package_facts: + manager: '{{ ansible_facts["pkg_mgr"] }}' + + - name: check for ansible_facts.packages exists + assert: + that: + - ansible_facts.packages is defined + - ansible_facts.packages | length > 1 + when: ansible_facts['os_family'] in ["openSUSE Leap", "Suse", "RedHat", "Debian"] + # Check that auto detection works also - name: Gather package facts package_facts: