From 2d690d7bdcc450332793b1c1342caec89e763fb2 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 26 Apr 2024 10:39:41 -0400 Subject: [PATCH 1/9] package_facts add alias support fixes #83143 --- .../fragments/package_facts_aliases.yml | 2 + lib/ansible/modules/package_facts.py | 52 +++++++++++++++---- 2 files changed, 43 insertions(+), 11 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 00000000000000..083789262f530c --- /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 11a8f61fdb0bf2..7c2eddcf0d3722 100644 --- a/lib/ansible/modules/package_facts.py +++ b/lib/ansible/modules/package_facts.py @@ -14,30 +14,42 @@ 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 managaer/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: means it will return only information for the first supported package manager available. + all: will return 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. author: - Matthew Jones (@matburt) - Brian Coca (@bcoca) @@ -247,6 +259,13 @@ from ansible.module_utils.facts.packages import LibMgr, CLIMgr, get_all_pkg_managers +ALIASES = { + 'rpm': ['dnf', 'dfn5','yum' , 'zypper'], + 'pkg': ['pkg5', 'pkgng'], + 'pkg_info': ['openbsd_pkg'], +} + + class RPM(LibMgr): LIB = 'rpm' @@ -485,9 +504,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 +536,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: + if pkgmgr in ALIASES[aliased] + pkgmgr = aliased + break + # dedupe as per above if pkgmgr in seen: continue + seen.add(pkgmgr) try: try: From 13738ff123aa177ffe0b7e1e3f7cd6be88bdaaeb Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 26 Apr 2024 10:52:47 -0400 Subject: [PATCH 2/9] fix tpoy --- lib/ansible/modules/package_facts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ansible/modules/package_facts.py b/lib/ansible/modules/package_facts.py index 7c2eddcf0d3722..24fd61fbdba7fe 100644 --- a/lib/ansible/modules/package_facts.py +++ b/lib/ansible/modules/package_facts.py @@ -540,8 +540,8 @@ def main(): break # substitute aliases for aliased - for aliased in ALIASES: - if pkgmgr in ALIASES[aliased] + for aliased in ALIASES.keys(): + if pkgmgr in ALIASES[aliased]: pkgmgr = aliased break From e32fba31819304e2a6079b5ff14d91f005c4cd74 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 26 Apr 2024 11:01:34 -0400 Subject: [PATCH 3/9] full colon, semi is just not enough --- changelogs/fragments/package_facts_aliases.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/fragments/package_facts_aliases.yml b/changelogs/fragments/package_facts_aliases.yml index 083789262f530c..9e408ff6eba277 100644 --- a/changelogs/fragments/package_facts_aliases.yml +++ b/changelogs/fragments/package_facts_aliases.yml @@ -1,2 +1,2 @@ -minor_changes; +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. From 821fe6e8bd26729aafac5f7daa7533999f6e0f2c Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 26 Apr 2024 11:15:17 -0400 Subject: [PATCH 4/9] req note --- lib/ansible/modules/package_facts.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ansible/modules/package_facts.py b/lib/ansible/modules/package_facts.py index 24fd61fbdba7fe..61fbe2692ec849 100644 --- a/lib/ansible/modules/package_facts.py +++ b/lib/ansible/modules/package_facts.py @@ -50,6 +50,7 @@ version_added: "2.8" version_added: "2.5" requirements: + - See details per package manager in the O(manager) option. author: - Matthew Jones (@matburt) - Brian Coca (@bcoca) @@ -260,7 +261,7 @@ ALIASES = { - 'rpm': ['dnf', 'dfn5','yum' , 'zypper'], + 'rpm': ['dnf', 'dfn5', 'yum' , 'zypper'], 'pkg': ['pkg5', 'pkgng'], 'pkg_info': ['openbsd_pkg'], } From 831f672d349ac1b50c0435e9ec134cc570a71949 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 26 Apr 2024 12:33:55 -0400 Subject: [PATCH 5/9] added alias test --- .../targets/package_facts/tasks/main.yml | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/test/integration/targets/package_facts/tasks/main.yml b/test/integration/targets/package_facts/tasks/main.yml index 12dfcf03164d4e..904da487a535a5 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) +# (c) Ansible Project - name: Prep package_fact tests - Debian Family block: @@ -65,6 +50,17 @@ 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 + when: ansible_facts['os_family'] in ["openSUSE Leap", "Suse", "RedHat", "Debian"] + # Check that auto detection works also - name: Gather package facts package_facts: From dcf7dfac36456d894853b8276f5004fd9671fc75 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 26 Apr 2024 14:19:07 -0400 Subject: [PATCH 6/9] Apply suggestions from code review Co-authored-by: Abhijeet Kasurde --- lib/ansible/modules/package_facts.py | 14 +++++++------- .../targets/package_facts/tasks/main.yml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/ansible/modules/package_facts.py b/lib/ansible/modules/package_facts.py index 61fbe2692ec849..cdba2b4b9b53bb 100644 --- a/lib/ansible/modules/package_facts.py +++ b/lib/ansible/modules/package_facts.py @@ -23,20 +23,20 @@ default: ['auto'] 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) + 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 + 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 managaer/builder - apk: Alpine linux package manager + pacman: Archlinux package manager/builder + apk: Alpine Linux package manager pkg_info: OpenBSD package manager - openbsd_pkg: Alias To pkg_info + openbsd_pkg: Alias to pkg_info type: list elements: str strategy: @@ -44,7 +44,7 @@ - This option controls how the module queries the package managers on the system. choices: first: means it will return only information for the first supported package manager available. - all: will return information for all supported and available package managers on the system. + all: returns information for all supported and available package managers on the system. default: 'first' type: str version_added: "2.8" @@ -261,7 +261,7 @@ ALIASES = { - 'rpm': ['dnf', 'dfn5', 'yum' , 'zypper'], + 'rpm': ['dnf', 'dnf5', 'yum' , 'zypper'], 'pkg': ['pkg5', 'pkgng'], 'pkg_info': ['openbsd_pkg'], } diff --git a/test/integration/targets/package_facts/tasks/main.yml b/test/integration/targets/package_facts/tasks/main.yml index 904da487a535a5..d1ae258ad6a47d 100644 --- a/test/integration/targets/package_facts/tasks/main.yml +++ b/test/integration/targets/package_facts/tasks/main.yml @@ -1,5 +1,5 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -# (c) Ansible Project +# Copyright: Contributors to the Ansible project - name: Prep package_fact tests - Debian Family block: From 35cd677d2fd586c50f19dd161e62d32ae2181dea Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Fri, 26 Apr 2024 14:19:22 -0400 Subject: [PATCH 7/9] Update lib/ansible/modules/package_facts.py Co-authored-by: Abhijeet Kasurde --- lib/ansible/modules/package_facts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/package_facts.py b/lib/ansible/modules/package_facts.py index cdba2b4b9b53bb..370e7d60b447d1 100644 --- a/lib/ansible/modules/package_facts.py +++ b/lib/ansible/modules/package_facts.py @@ -43,7 +43,7 @@ description: - This option controls how the module queries the package managers on the system. choices: - first: means it will return only information for the first supported package manager available. + 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 From e532d900ed72928f543c0a63209949395ccdf4e7 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 2 May 2024 14:12:18 -0400 Subject: [PATCH 8/9] Update test/integration/targets/package_facts/tasks/main.yml Co-authored-by: Abhijeet Kasurde --- test/integration/targets/package_facts/tasks/main.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/integration/targets/package_facts/tasks/main.yml b/test/integration/targets/package_facts/tasks/main.yml index d1ae258ad6a47d..4d70b30cc1169a 100644 --- a/test/integration/targets/package_facts/tasks/main.yml +++ b/test/integration/targets/package_facts/tasks/main.yml @@ -58,7 +58,9 @@ - name: check for ansible_facts.packages exists assert: - that: ansible_facts.packages is defined + 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 From 39e751d7e0b13d3c9dedf4467df81efb530a64f5 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Thu, 2 May 2024 14:21:08 -0400 Subject: [PATCH 9/9] fix format --- test/integration/targets/package_facts/tasks/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/targets/package_facts/tasks/main.yml b/test/integration/targets/package_facts/tasks/main.yml index 4d70b30cc1169a..144fa784f70ea1 100644 --- a/test/integration/targets/package_facts/tasks/main.yml +++ b/test/integration/targets/package_facts/tasks/main.yml @@ -59,8 +59,8 @@ - name: check for ansible_facts.packages exists assert: that: - - ansible_facts.packages is defined - - ansible_facts.packages | length > 1 + - 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