diff --git a/changelogs/fragments/80590-dnf-skip_broken-unavailable-pkgs.yml b/changelogs/fragments/80590-dnf-skip_broken-unavailable-pkgs.yml new file mode 100644 index 00000000000..f82c7aef72a --- /dev/null +++ b/changelogs/fragments/80590-dnf-skip_broken-unavailable-pkgs.yml @@ -0,0 +1,2 @@ +bugfixes: + - dnf - properly skip unavailable packages when ``skip_broken`` is enabled (https://github.com/ansible/ansible/issues/80590) diff --git a/lib/ansible/modules/dnf.py b/lib/ansible/modules/dnf.py index d83c9a89971..e03661f78f3 100644 --- a/lib/ansible/modules/dnf.py +++ b/lib/ansible/modules/dnf.py @@ -855,6 +855,7 @@ class DnfModule(YumDnf): """Mark the package for install.""" is_newer_version_installed = self._is_newer_version_installed(pkg_spec) is_installed = self._is_installed(pkg_spec) + msg = '' try: if is_newer_version_installed: if self.allow_downgrade: @@ -888,18 +889,16 @@ class DnfModule(YumDnf): pass else: # Case 7, The package is not installed, simply install it self.base.install(pkg_spec, strict=self.base.conf.strict) - - return {'failed': False, 'msg': '', 'failure': '', 'rc': 0} - except dnf.exceptions.MarkingError as e: - return { - 'failed': True, - 'msg': "No package {0} available.".format(pkg_spec), - 'failure': " ".join((pkg_spec, to_native(e))), - 'rc': 1, - "results": [] - } - + msg = "No package {0} available.".format(pkg_spec) + if self.base.conf.strict: + return { + 'failed': True, + 'msg': msg, + 'failure': " ".join((pkg_spec, to_native(e))), + 'rc': 1, + "results": [] + } except dnf.exceptions.DepsolveError as e: return { 'failed': True, @@ -908,7 +907,6 @@ class DnfModule(YumDnf): 'rc': 1, "results": [] } - except dnf.exceptions.Error as e: if to_text("already installed") in to_text(e): return {'failed': False, 'msg': '', 'failure': ''} @@ -921,6 +919,8 @@ class DnfModule(YumDnf): "results": [] } + return {'failed': False, 'msg': msg, 'failure': '', 'rc': 0} + def _whatprovides(self, filepath): self.base.read_all_repos() available = self.base.sack.query().available() diff --git a/test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml b/test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml index f54c0a83d95..95c875a2f0d 100644 --- a/test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml +++ b/test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml @@ -304,7 +304,26 @@ that: - res is not changed - # Case 7 is already tested quite extensively above in the earlier tests. + # Case 7 is already tested quite extensively above in the earlier tests. + # ###################################################################### + + - block: + - name: Test available package is installed while unavailable one is skipped due to skip_broken=true + dnf: + name: + - dinginessentail + - not-in-repo + skip_broken: true + register: res + + - assert: + that: + - res is changed + # There is a change in dnf5 that splits skip_broken into two options: + # skip_broken and skip_unavailable. + # TODO: for this test to pass on dnf5 the skip_unavailable option would have to be + # added to the dnf5 module and used here instead of skip_broken. + when: not dnf5|default(false) always: - name: Remove test yum repo @@ -316,4 +335,5 @@ yum: name: - broken-* + - dinginessentail state: absent