I have encountered a problem where a package, at a specific version, requires another package, also at a specific version, but Apt-Get selects a newer version of the dependency and then fails.
I have experienced this with Puppet Lab's MCollective and the Nginx Mainline PPAs and likely other packages so my question is about the general approach to Apt-Get dependency resolution but I will use Nginx as my example.
I have a package mirror (built with Aptly) containing the v1.7.5 of the nginx-full package and all its dependencies and also the newer v1.7.6 package and all its dependencies.
If I execute apt-get install nginx-full=1.7.5-1+trusty1
then the install fails with the message:
The following packages have unmet dependencies:
nginx-full : Depends: nginx-common (= 1.7.5-1+trusty1) but 1.7.6-1+trusty1 is to be installed
However, if I execute apt-get install nginx-full=1.7.5-1+trusty1 nginx-common=1.7.5-1+trusty1
then installation succeeds.
When I have both versions 1.7.5 and 1.7.6 of the nginx-common package on the mirror and the nginx-full package explicitly states it requires 1.7.5 of nginx-common, and nginx-full is the package I've requested, why does apt-get still select the incompatible 1.7.6 version of nginx-common?
Here is the output of dpkg -s nginx-full
after installing 1.7.5 showing the exact version dependency constraint:
Version: 1.7.5-1+trusty1
Depends: nginx-common (= 1.7.5-1+trusty1), libc6 (>= 2.14), ...
In this instance, the chain of exact versions required is short so the workaround is easy but there are at least two problems for me:
- Other packages have much longer chains of dependencies that are tedious to discover and then append to the apt-get command line.
- Until a newer version of a dependency is published to a package mirror it is easy to be unaware of the impending issue.
What I can't comprehend is why the dependency resolution is apparently ignoring the exact version constraint on the specified package. More importantly I'd like to know how I can ask Apt-Get to honour the constraints without having to manually replicate the package metadata onto my apt-get parameters.
Best Answer
What you're experiencing is the problem with
apt
/apt-get
not being as smart as you think it is.This problem happens when trying to downgrade your package(s) or install an older package version than the version the repositories have as the latest candidate (with regard to your
apt
priority pinning and other policies regarding repository priorities). When you downgrade your package, you actually have to specify for each individual dependency which version you're downgrading to, or in this case which specific version you actually want to install.In the case of the
nginx
packages, wherenginx-full
andnginx-common
depend on each other, you have to explicitly tell apt to install each of the packages of the specified version(s). This is because1.7.6-1+trusty1
supersedes1.7.5-1+trusty1
by version number. As a result, you have to specifically say "Only install the package of this specific version" because of the superseded version(s) existing, i.e.apt-get install nginx-full=1.7.5-1+trusty1 nginx-common=1.7.5-1+trusty1
Not relevant to your question, but this also happens when you install from a repository that has a lower
apt
pinning priority than another version, in which case you have to specify the versions and/or source(s) to install from manually, i.e.sudo apt-get install nginx-full/trusty-proposed nginx-common/trusty-proposed
being a prime example of trying to install a package and dependencies from the proposed repository, which has a much lowerapt
priority than PPAs or the main repositories.