summaryrefslogtreecommitdiffstats
path: root/lib/ansible/modules/dnf5.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/modules/dnf5.py')
-rw-r--r--lib/ansible/modules/dnf5.py100
1 files changed, 57 insertions, 43 deletions
diff --git a/lib/ansible/modules/dnf5.py b/lib/ansible/modules/dnf5.py
index c55b673..7af1f4a 100644
--- a/lib/ansible/modules/dnf5.py
+++ b/lib/ansible/modules/dnf5.py
@@ -2,9 +2,8 @@
# Copyright 2023 Ansible Project
# 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
+from __future__ import annotations
-__metaclass__ = type
DOCUMENTATION = """
module: dnf5
@@ -152,7 +151,7 @@ options:
validate_certs:
description:
- This is effectively a no-op in the dnf5 module as dnf5 itself handles downloading a https url as the source of the rpm,
- but is an accepted parameter for feature parity/compatibility with the M(ansible.builtin.yum) module.
+ but is an accepted parameter for feature parity/compatibility with the M(ansible.builtin.dnf) module.
type: bool
default: "yes"
sslverify:
@@ -175,8 +174,8 @@ options:
default: "no"
install_repoquery:
description:
- - This is effectively a no-op in DNF as it is not needed with DNF, but is an accepted parameter for feature
- parity/compatibility with the M(ansible.builtin.yum) module.
+ - This is effectively a no-op in DNF as it is not needed with DNF.
+ - This option is deprecated and will be removed in ansible-core 2.20.
type: bool
default: "yes"
download_only:
@@ -209,10 +208,18 @@ options:
default: "no"
nobest:
description:
- - Set best option to False, so that transactions are not limited to best candidates only.
+ - This is the opposite of the O(best) option kept for backwards compatibility.
+ - Since ansible-core 2.17 the default value is set by the operating system distribution.
required: false
type: bool
- default: "no"
+ best:
+ description:
+ - When set to V(true), either use a package with the highest version available or fail.
+ - When set to V(false), if the latest version cannot be installed go with the lower version.
+ - Default is set by the operating system distribution.
+ required: false
+ type: bool
+ version_added: "2.17"
cacheonly:
description:
- Tells dnf to run entirely from system cache; does not download or update metadata.
@@ -223,7 +230,7 @@ extends_documentation_fragment:
- action_common_attributes.flow
attributes:
action:
- details: In the case of dnf, it has 2 action plugins that use it under the hood, M(ansible.builtin.yum) and M(ansible.builtin.package).
+ details: dnf5 has 2 action plugins that use it under the hood, M(ansible.builtin.dnf) and M(ansible.builtin.package).
support: partial
async:
support: none
@@ -357,23 +364,47 @@ def is_installed(base, spec):
def is_newer_version_installed(base, spec):
+ # FIXME investigate whether this function can be replaced by dnf5's allow_downgrade option
+ if "/" in spec:
+ spec = spec.split("/")[-1]
+ if spec.endswith(".rpm"):
+ spec = spec[:-4]
+
try:
spec_nevra = next(iter(libdnf5.rpm.Nevra.parse(spec)))
- except RuntimeError:
+ except (RuntimeError, StopIteration):
return False
- spec_name = spec_nevra.get_name()
- v = spec_nevra.get_version()
- r = spec_nevra.get_release()
- if not v or not r:
+
+ spec_version = spec_nevra.get_version()
+ if not spec_version:
return False
- spec_evr = "{}:{}-{}".format(spec_nevra.get_epoch() or "0", v, r)
- query = libdnf5.rpm.PackageQuery(base)
- query.filter_installed()
- query.filter_name([spec_name])
- query.filter_evr([spec_evr], libdnf5.common.QueryCmp_GT)
+ installed = libdnf5.rpm.PackageQuery(base)
+ installed.filter_installed()
+ installed.filter_name([spec_nevra.get_name()])
+ installed.filter_latest_evr()
+ try:
+ installed_package = list(installed)[-1]
+ except IndexError:
+ return False
+
+ target = libdnf5.rpm.PackageQuery(base)
+ target.filter_name([spec_nevra.get_name()])
+ target.filter_version([spec_version])
+ spec_release = spec_nevra.get_release()
+ if spec_release:
+ target.filter_release([spec_release])
+ spec_epoch = spec_nevra.get_epoch()
+ if spec_epoch:
+ target.filter_epoch([spec_epoch])
+ target.filter_latest_evr()
+ try:
+ target_package = list(target)[-1]
+ except IndexError:
+ return False
- return query.size() > 0
+ # FIXME https://github.com/rpm-software-management/dnf5/issues/1104
+ return libdnf5.rpm.rpmvercmp(installed_package.get_evr(), target_package.get_evr()) == 1
def package_to_dict(package):
@@ -394,8 +425,7 @@ def get_unneeded_pkgs(base):
query = libdnf5.rpm.PackageQuery(base)
query.filter_installed()
query.filter_unneeded()
- for pkg in query:
- yield pkg
+ yield from query
class Dnf5Module(YumDnf):
@@ -403,14 +433,8 @@ class Dnf5Module(YumDnf):
super(Dnf5Module, self).__init__(module)
self._ensure_dnf()
- # FIXME https://github.com/rpm-software-management/dnf5/issues/402
- self.lockfile = ""
self.pkg_mgr_name = "dnf5"
- # DNF specific args that are not part of YumDnf
- self.allowerasing = self.module.params["allowerasing"]
- self.nobest = self.module.params["nobest"]
-
def _ensure_dnf(self):
locale = get_best_parsable_locale(self.module)
os.environ["LC_ALL"] = os.environ["LC_MESSAGES"] = locale
@@ -452,10 +476,6 @@ class Dnf5Module(YumDnf):
failures=[],
)
- def is_lockfile_pid_valid(self):
- # FIXME https://github.com/rpm-software-management/dnf5/issues/402
- return True
-
def run(self):
if sys.version_info.major < 3:
self.module.fail_json(
@@ -503,7 +523,11 @@ class Dnf5Module(YumDnf):
self.disable_excludes = "*"
conf.disable_excludes = self.disable_excludes
conf.skip_broken = self.skip_broken
- conf.best = not self.nobest
+ # best and nobest are mutually exclusive
+ if self.nobest is not None:
+ conf.best = not self.nobest
+ elif self.best is not None:
+ conf.best = self.best
conf.install_weak_deps = self.install_weak_deps
conf.gpgcheck = not self.disable_gpg_check
conf.localpkg_gpgcheck = not self.disable_gpg_check
@@ -606,13 +630,7 @@ class Dnf5Module(YumDnf):
for spec in self.names:
if is_newer_version_installed(base, spec):
if self.allow_downgrade:
- if upgrade:
- if is_installed(base, spec):
- goal.add_upgrade(spec, settings)
- else:
- goal.add_install(spec, settings)
- else:
- goal.add_install(spec, settings)
+ goal.add_install(spec, settings)
elif is_installed(base, spec):
if upgrade:
goal.add_upgrade(spec, settings)
@@ -706,10 +724,6 @@ class Dnf5Module(YumDnf):
def main():
- # Extend yumdnf_argument_spec with dnf-specific features that will never be
- # backported to yum because yum is now in "maintenance mode" upstream
- yumdnf_argument_spec["argument_spec"]["allowerasing"] = dict(default=False, type="bool")
- yumdnf_argument_spec["argument_spec"]["nobest"] = dict(default=False, type="bool")
Dnf5Module(AnsibleModule(**yumdnf_argument_spec)).run()