apt: fix virtual package install version detection (#76781)

* apt: fix virtual package install version detection

Change 4a62c4e3e4 introduced version
matching in installation.

The problem stems from

 if version_installable or version:
     pkg_list.append("'%s=%s'" % (name, version_installable or version))

When the package is a virtual-package, package_status() is returning
the "version_installable" of the package *satisfying* the
virtual-package; but then this is trying to install the
virtual-package with this version pin.

For example, "yaml-mode" is a virtual package satisifed by
"elpa-yaml-mode" (currently 0.0.14-1) and trying to install it fails
with

 $ usr/bin/apt-get -y ... install 'yaml-mode=0.0.14-1'
 ... failed: E: Version '0.0.14-1' for 'yaml-mode' was not found ...

In the case of a virtual-package with nothing installed to satisfy it,
we should just return blank values to allow apt-get to do it's thing.

The tests are updated to install and remove this package.

Fixes: #76779
pull/77916/head
Ian Wienand 3 years ago committed by GitHub
parent 6fbc8bd2bc
commit e4c0bbf885
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- apt module now correctly handles virtual packages.

@ -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

@ -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

Loading…
Cancel
Save