Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

package_facts add alias support #83149

Merged
merged 9 commits into from May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions 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.
53 changes: 42 additions & 11 deletions lib/ansible/modules/package_facts.py
Expand Up @@ -14,30 +14,43 @@
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)
Expand Down Expand Up @@ -247,6 +260,13 @@
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'
Expand Down Expand Up @@ -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)
Expand All @@ -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:
Expand Down
32 changes: 15 additions & 17 deletions test/integration/targets/package_facts/tasks/main.yml
@@ -1,20 +1,5 @@
# Test playbook for the package_facts module
# (c) 2017, Adam Miller <[email protected]>

# 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 <http://www.gnu.org/licenses/>.
# 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:
Expand Down Expand Up @@ -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:
Expand Down