On Thu, Dec 11, 2014 at 01:02:35PM +1000, Russell Stuart wrote: > On Thu, 2014-12-11 at 02:07 +0100, David Kalnischkies wrote: > > Beside from compatibility concerns (old clients might be confused) it is > > also wrong from an architectual point of view: A dependency usually is > > declared on a package in the same architecture space, so that is the > > safest bet. > > Safe bet maybe (it wasn't in this case), but surely wrong is too a > strong word. By definition a package declaring itself to be M-A foreign > is saying the arch doesn't matter. It may be a safer bet because of > bugs mean the package isn't really the same, but in that case the bug is > in the mistaken M-A foreign declaration, not installer thinking M-A > foreign doesn't mean what its documentation says. You are giving TargetPkg() too much credit. This isn't more than a link from one datastructure (dependency) to another (package) where the later is supposed to contain all possible solutions (and some) to the earlier. The link is created while parsing files, so at a time we have no complete information at what we are pointing to, we just know that at the place we are pointing to all the information needed will be available later. This link hence points to a place where all (if any) possible solutions can be found, not to the 'best' possible solution, if such a thing even exists (at that point in time or at all). Beside, while the real package foo might be M-A: foreign, packages providing foo might not, so if I have a bar:foreign depends on foo, foo:foreign and foo:native are potential choices and foo:native probably the best one, but foo-provider:native providing foo might not be a solution at all, but it is what we get with TargetPkg().ProvidesList() which used to work in the past and for all M-A: none/same packages. (I am not even trying to imagine what that would mean for allowed) > architecture" seems wrong to me. Both sides of their dependency have to > declare their willingness to accept M-A: foreign. (The depends declares > package:any, and the package declares M-A: foreign.) If the version You are mixing this up with 'M-A: allowed'. 'M-A: foreign' isn't opt-in from the depender side. Especially of note is in this regard that an 'M-A: foreign' package can NOT satisfy a 'package:any' dependency. > > You might have noticed that I said "provides" in the paragraph above and > > that is in fact what is happening here: An M-A:foreign package is > > internally mapped as a (versioned) provides, which on one hand is > > a giant hack, but on the other hand I am increadibly proud of it as this > > helps tremendously in making M-A:foreign "just work" even for old > > clients which have never heard of M-A. > > Yeah, I saw package:any:i386. I recall cleaning my glasses and looking > again, and then asking on Debian-mentors what it was I just saw. No one > knew. This is also refering to 'M-A: allowed'. I am not suprised nobody answered (well, I am a bit as I am subscribed to debian-mentors@, so I wonder what made me miss it) as this is "super top secret" information. I would guess only 10 people in the world know about it… Claiming I said that in binary would be a bit much - I counted very generously in decimal as I explained that once in a room with 3 people present as a tongue-in-check remark on how they could do M-A in their tool (CUDF). The more interesting claim might be: More associates to various national agencies know about this than associates to Debian (one of the 3 people was the [at that time] DPL, so that isn't totally unrealistic). And now you know, too! But remember, with great knowledge comes great responsibility… ;) > > It puts the candidate version (if any) of the target package as well as > > every candidate version (if any) of the packages providing the target > > package (if any) in a list and then sorts the list considering various > > properties (see CompareProviders here: [0]) to pick the best provider, > > which for M-A:foreign packages happens to be the one from the native > > architecture, but there are other things to consider as well (which got > > added over time. This started very innocently with just priorities…). > > Here we get the heart of the problem. I presume before multiarch > apt_get.Depends.target_pkg target had only one possible package it could > point at. Now it potentially has several because there are separate > package objects per architecture. You are essentially saying "we should > always choose the same architecture as the depends, as that is what we > did before". Yes and no, as I explained further above, TargetPkg() [which is the C++ version of whatever python has; I don't speak parseltongue^Wpython] is a one-to-one mapping as such, but that only works because the package structure itself contains pointers to other structures (versions of the real package in the architecture this structure has and providers of the virtual package with this name in this architecture, which itself link back to packages structures…). I know that heritage is not the most sexy argument, but it is something we have to considered in apt all the time as many tools are written on top of us, so implementing M-A was heavily constraint by the fact that we couldn't just go and reinvent everything. aptitude for example struggled with the introduction of M-A for a while as it had less than optimal first solutions to present, but it didn't explode in a big pile of useless code and that counts as changing package management is a lot harder than changing some boring stuff like init systems… (yes, I actually believe that, even through I fear reality would disappoint me greatly if that would ever happen) But that is hardly the only argument, which is why this was an aside in the initial mail and not the entire essence. > Well that breaks an underlying assumption I made that was true before: > some version of target_pkg would be installed. In the example I quoted > its not. Effectively that means everything in target_pkg except That assumption was never true, think: Provides (see example above) If you extend your assumption to include provides, it is magically true in single- as it is in multi-arch (which was the point of the exercise to begin with). > target_pkg.name is useless in the general case. If pointing it to the > right architecture is too hard depreciate it and replace it with > target_pkg_name (a string) which express the same thing in an > architecture independent way. Well, that is what TargetPkg() already is… the first thing you do with a package name is looking up the package structure for it, so instead of storing a pointer to the name of the package, we point to the package itself saving us a lookup at runtime. And please remember: M-A:foreign ALLOWS to install foo:native instead of foo:foreign, but that doesn't mean it has to. There are perfectly valid reasons not to do this, so "the right architecture" isn't always native, it is just most of the time in most usage cases. > > Now that it does far more than trivial stuff, I could imagine exporting > > this in some way, which this bugreport is actually asking for, but that > > needs time for someone to think about a sane API… > > any takers (after jessie) ? > > Again, the sane API to me is expressing is exposing it in > apt_pkg.Dependency.target_pkg. If you aren't going to do that then > surely apt_pkg.Dependency.smart_target_pkg() would be it - but currently > it also returns the wrong architecture in the case I example I gave. I have no idea what the API from the python side looks like, but the C++ one is one of the more ugly examples. The return of a single package is probably not ideal anyway, I think a list of versions would be better, but that would need constrains (only candidate versions? all versions?) and caller-defined sorting… Best regards David Kalnischkies
Attachment:
signature.asc
Description: Digital signature