[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: MarkInstall resets candidate, breaks interactive problem resolution



On Thu, Mar 06, 2014 at 10:24:37AM +0800, Daniel Hartwig wrote:
> A common use case in aptitude, but also perhaps synaptic and others, is
> to mark a version for install, inspect the broken dependencies, and
> resolve the issues manually [1].  A recent change to MarkInstall has
> upset this process by changing the candidate if some kind of broken
> dependencies are found:

Why I am not surprised…

Or, actually, I am. I nearly assumed that something would break, but
aptitude was actually the least of my worries as I was under the
impression that it doesn't do AutoInst=true at all.


>  commit 446551c8ffd2c9cb9dcd707c94590e73009f7dd9
[…]
> I need to investigate also whether a previous change to call MarkDelete
> under the same situation also impacts this use case.

No idea really, but I would presume that if this is called for a "leaf"
package it is just another unsatisfied dependency to be resolved.
If on the other hand it is a request coming from the user it is
protected by FromUser (assuming MarkInstall is called this way).

I wonder a bit how this all works at all though with this loopbreaking
(the MarkDelete is just the topping) as it was introduced in df77d8a5
(May 2011) by - surprise surprise - me. For interactive use it would
probably be better to continue and let the user fix the breakage later.

I guess we should move this check out into a IsInstallOk submethod so
that you can at least disable this check (and we can stop at the
beginning rather than somewhere in the middle). Will see if I can make
this work.


> Have you ideas about addressing the issue in an other way than modifying
> candidate version in MarkInstall?  Perhaps this logic is too frontend
> specific for that function, although I see it is strictly related to the
> solver.

I am going to commit the attached 'compromise' which looks if there
is a chance by candidate switching to make it work and if it is really
impossible to make it work reset the candidate. This should deal with
the initial problem of "package has no available version at all" and
with more general "all available versions are crap" without going the
shortcut over "the candidate version is crap". As I presume (even)
interactive solvers can't make versions appear out of thin air,
I hope that this works for all of us to some extend.


> Ideally I would like to have the flexibility in libapt and not have to
> hack around issues or duplicate code inside aptitude, which has been
> done extensively in the past and continues to cause issues.

Sounds good. :) MarkInstall isn't the holy grail at the moment either
though, unfortunately. It does way too much for my taste without a proper
way to observe what it does from the outside. That it can't tell its
caller (which most of the time is itself) that it is useless to explore
certain dependency trees again (and again and again) is bad. Workarounds
like this one only take us so far…


Best regards

David Kalnischkies
commit aa605dca86bae69d2fd8052d2f07d04c71a3b02b
Author: David Kalnischkies <david@kalnischkies.de>
Date:   Tue Mar 11 10:31:44 2014 +0100

    only discard candidates in MarkInstall if none would work
    
    In commit 446551c8 I changed MarkInstall to discard the candidate if the
    candidate can't satisfy the dependency. This breaks interactive solvers
    like aptitude which can change the candidate on-the-fly later.
    
    As a compromise it will now go over all possible versions to see if
    there is a chance that a candidate switch could make this work and only
    discard the upgrade option if not a single version satisfies the
    requirement.
    
    This brings apt-get and co back to an 'Internal error' if one version
    would satisfy the request but isn't the candidate, but it at least deals
    with the bug the code was introduced to fix (no version at all).

diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index e2c4127..9218959 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -1146,7 +1146,27 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 	 if (Pkg->CurrentVer == 0)
 	    MarkDelete(Pkg,false,Depth + 1, false);
 	 else
-	    SetCandidateVersion(Pkg.CurrentVer());
+	 {
+	    bool impossible = true;
+	    if (Start->Version != 0)
+	    {
+	       for (pkgCache::VerIterator V = Start.TargetPkg().VersionList(); V.end() == false; ++V)
+		  if (Start.IsSatisfied(V) == true)
+		  {
+		     impossible = false;
+		     break;
+		  }
+	       if (impossible == true)
+		  for (PrvIterator P = Start.TargetPkg().ProvidesList(); P.end() != true; ++P)
+		     if (Start.IsSatisfied(P) == true)
+		     {
+			impossible = false;
+			break;
+		     }
+	    }
+	    if (impossible == true)
+	       SetCandidateVersion(Pkg.CurrentVer());
+	 }
 	 return false;
       }
 
diff --git a/test/integration/test-bug-735967-lib32-to-i386-unavailable b/test/integration/test-bug-735967-lib32-to-i386-unavailable
index 4dbe1d2..e9f3bf9 100755
--- a/test/integration/test-bug-735967-lib32-to-i386-unavailable
+++ b/test/integration/test-bug-735967-lib32-to-i386-unavailable
@@ -12,6 +12,9 @@ insertpackage 'unstable' 'libnss-mdns' 'amd64,i386' '0.10-6' 'Multi-Arch: same
 Breaks: lib32nss-mdns (<< 0.10-6)'
 insertpackage 'unstable' 'libnss-mdns-i386' 'i386' '0.10-6' 'Multi-Arch: foreign
 Depends: libnss-mdns'
+# introduce some dummies so that there are versions, but none works
+insertpackage 'unstable' 'libnss-mdns-i386' 'amd64' '0.1-6'
+insertpackage 'experimental' 'libnss-mdns-amd64' 'i386,amd64' '0.10-6' 'Provides: libnss-mdns-i386'
 
 insertpackage 'unstable' 'foo' 'amd64' '1' 'Depends: libfoo'
 insertpackage 'unstable' 'libfoo' 'amd64' '1' 'Depends: libfoo-bin'

Attachment: signature.asc
Description: Digital signature


Reply to: