diff --git a/changelogs/fragments/apt_virtual_fix.yml b/changelogs/fragments/apt_virtual_fix.yml new file mode 100644 index 00000000000..5aa79a7083f --- /dev/null +++ b/changelogs/fragments/apt_virtual_fix.yml @@ -0,0 +1,2 @@ +bugfixes: + - apt module now correctly handles virtual packages. diff --git a/lib/ansible/modules/apt.py b/lib/ansible/modules/apt.py index 70e28eb0a48..121eff935c3 100644 --- a/lib/ansible/modules/apt.py +++ b/lib/ansible/modules/apt.py @@ -510,17 +510,20 @@ def package_status(m, pkgname, version_cmp, version, default_release, cache, sta try: provided_packages = cache.get_providing_packages(pkgname) if provided_packages: - is_installed = False - version_installable = None - version_ok = False - # when virtual package providing only one package, look up status of target package + # When this is a virtual package satisfied by only + # one installed package, return the status of the target + # package to avoid requesting re-install if cache.is_virtual_package(pkgname) and len(provided_packages) == 1: package = provided_packages[0] - installed, version_ok, version_installable, has_files = \ + installed, installed_version, version_installable, has_files = \ package_status(m, package.name, version_cmp, version, default_release, cache, state='install') if installed: - is_installed = True - return is_installed, version_ok, version_installable, False + return installed, installed_version, version_installable, has_files + + # Otherwise return nothing so apt will sort out + # what package to satisfy this with + return False, False, None, False + m.fail_json(msg="No package matching '%s' is available" % pkgname) except AttributeError: # python-apt version too old to detect virtual packages diff --git a/test/integration/targets/apt/tasks/apt.yml b/test/integration/targets/apt/tasks/apt.yml index 816141183d8..5b1a24a3b4f 100644 --- a/test/integration/targets/apt/tasks/apt.yml +++ b/test/integration/targets/apt/tasks/apt.yml @@ -507,3 +507,25 @@ that: - "allow_change_held_packages_no_update is not changed" - "allow_change_held_packages_hello_version.stdout == allow_change_held_packages_hello_version_again.stdout" + +# Virtual package +- name: Install a virtual package + apt: + package: + - emacs-nox + - yaml-mode # <- the virtual package + state: latest + register: install_virtual_package_result + +- name: Check the virtual package install result + assert: + that: + - install_virtual_package_result is changed + +- name: Clean up virtual-package install + apt: + package: + - emacs-nox + - elpa-yaml-mode + state: absent + purge: yes