#786609 apt: undesirable behaviour when installing from repositories with low pin priorities (like experimental)

Package:
apt
Source:
apt
Description:
commandline package manager
Submitter:
Johannes Schauer
Date:
2015-05-24 16:48:14 UTC
Severity:
wishlist
#786609#5
Date:
2015-05-23 12:46:23 UTC
From:
To:
Hi,

this bug is about installing a package from a repository with a low pin
priority. I will use experimental as an example but this really works
with any repository with low pin priority.

My problem is, that there seems to be no way to install a package from
experimental without either specifying all packages manually (and thus
giving apt the exact solution I want - this is stupid because apt should
find a solution for me) or specifying "-t experimental" which will then
get *all* packages from experimental even for those dependencies that
would be satisfied by packages from unstable (which is also stupid
because of course I only assigned a low pin priority to a repository
because I do *not* prefer packages from that repository, so please
minimize the amount of packages from there).

I created a small test suite that illustrates the problem:

https://gitlab.mister-muffin.de/josch/apt-install-low-pin

The script test.sh sets up two local apt repositories with different pin
values and then tries to install a package from the repository with
lower pin priority.

It shows the following problem:

When just using "apt-get install package-from-experimental" apt will not
automatically use experimental to satisfy the dependencies of that
package and will fail to install.

When using "apt-get install -t experimental package-from-experimental"
then apt will take *all* packages from experimental, even those that
would be satisfied by packages from unstable.

The last situation even leads to uninstallabilities where a package from
experimental has a versioned dependency which is only satisfied in
unstable and another versioned dependency which is only satisfied in
experimental. The test suite shows this situation. How can one install
such a package without specifying the solution manually?

In the end I show how the execution of:

apt-get install --simulate --solver aspcud \
	-o APT::Solver::Strict-Pinning=false \
	-o APT::Solver::aspcud::Preferences="-new,-removed,-changed,+sum(solution,apt-pin)" \
	pkg-a

does exactly what I expect would happen by default:  It takes only the
packages from experimental where it needs to and gets the rest of the
packages from the repository with higher pin priority (unstable).

Should it not be possible to do this with apt alone?

cheers, josch

#786609#10
Date:
2015-05-24 16:45:46 UTC
From:
To:
On Sat, May 23, 2015 at 02:46:23PM +0200, Johannes Schauer wrote:
[…]
is kinda unlikely to change soon. The interface this has/will have is
pkg/experimental as "pkg" and "pkg -t experimental" have a defined
behaviour already which would suprise others if we change here.

Long answer:
apt-get install pkg/experimental manages to get very simple situations
done like if pkg depends on foo>=experimental it will pick the
experimental version for foo and continue this for foos versioned
dependency on bar.

As said, simple situations. It e.g. doesn't work if bar conflicts with
foo at the moment. Has problems with provides. The error message if it
can't figure something out is borderline useless, … All in all its
implemented ATM as a hack. I added it around the time we got
ButAutomaticUpgrades and for the same user-group.

Also, while reading the title I was actually expecting a step further:
Having three repositories pin 900, 800 and 700 doesn't give you a "pick
the highest, but make it work in any case". That totally outside
anything you can express with apt at all currently…


The reason is partly in the design of APT itself: At startup it will
figure out the pin value for each version and based on the rules will
figure out which version is the installation candidate. This decision is
never questioned again. Either all candidates play nicely together or
they don't (In other words -t experimental, /experimental or =1.2.3.4 do
not say: Install this package from experimental, but create a temporary
infinite positive pin for this package version which makes this version
the installation candidate).

Then, first pass solving is installing all requested packages and acting
according to the dependencies these have aka installing the candidates
of these packages, too.

The last step is the actual resolving step, which we call "problem
resolver": It looks if any dependency is unsatisfied after the first
pass. That happens usually then two packages conflict with each other
for example. This resolver does 1vs1 comparisons (I nickname
these cagefights) and does either hold back or remove. Especially note
that it can't decide to install anything (else) / not in other versions
for fear of computational explosions.


The idea behind this solver is as old as apt, so I would actually be
surprised if 17 years of research wouldn't have achieved anything.¹ Some
screws are changed over the years of course, but nothing entirely
ground shacking.  This has some benefits actually as many people (and
tools) are used to apt functioning a certain way, but the disadvantages
are obvious. The reason I worked on EDSP was in fact to be able to
overcome this problem in the long run by making it possible to change
the resolver used by libapt without throwing away the entire ecosystem
as this tends to be a very painful thing just to change the resolver
(see yum vs. dnf).

¹ And frankly, also the requirements changed. I think 17 years ago any
kind of dependency solving was magic. It still very much is, but we are
so much used to it now, that we expect more and more. Unfortunately
without purring more resources into it. Instead we declare package
management a solved problem…


Best regards

David Kalnischkies