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

Re: arch-specific dependencies and M-A: foreign



Hi,

merging some of guillem's mails into a single reply.

Quoting Guillem Jover (2015-04-19 01:23:43)
> On Sat, 2015-04-18 at 19:33:25 +0200, Johannes Schauer wrote:
> > The deb-control(5) man page in dpkg git says that all Provides: are implicitly
> > :any if no architecture qualifier is explicitly given:
> > http://anonscm.debian.org/cgit/dpkg/dpkg.git/tree/man/deb-control.5#n264
>
> That's just incorrect, I might have read Replaces: where there was
> Provides: there, I'll fix the man page today, sorry for making this
> more confusing than necessary. :)

thanks, this makes much more sense now.

Quoting Guillem Jover (2015-04-19 01:38:35)
> On Fri, 2015-04-17 at 15:39:14 +0200, Johannes Schauer wrote:
> > Yes, if bar:amd64 would not also really provide bar:i386, then it should not be
> > M-A:foreign.
>
> Ah, I guess this might be where the different interpretations come
> from. The way I see it, a M-A:foreign has a defined architecture,
> which is relevant, because you might need to run it, and it does not
> really provide :any, it is just able to satisfy unqualified
> dependencies. When you explicitly provide another arch then *that*
> counts as actually providing that arch.

Okay, I see now where our understanding differs. It seems to be a subtle
difference of how to think about this.

Suppose there is package foo which is m-a:foreign and arch:amd64.

Now pkg1 is arch:armel and depends on "foo" and pkg2 is arch:mipsel and depends
on "foo" as well. Since pkg1 is arch:armel it will require foo to be arch:armel
too, except that foo is m-a:foreign so foo in arch:amd64 works as well. Same
goes for pkg2 but for mipsel instead of armel. So while pkg1 would normally
require foo to be armel and pkg2 would normally require foo to be mipsel, since
foo is m-a:foreign it is able to satisfy both as if it would provide foo:armel
as well as foo:mipsel.

This is how dose3 is able to treat m-a:foreign packages. Internally it converts
the problem into a cudf representation and since cudf does not understand
architectures, it lets a m-a:foreign package provide itself for all foreign
architectures.

This is where my way of thinking about this matter comes from.

Quoting Guillem Jover (2015-04-19 01:17:42)
> On Fri, 2015-04-17 at 11:27:07 +0200, David Kalnischkies wrote:
> > Consider this situation:
> > 
> > Native Architecture: amd64
> > Foreign Architecture(s): i386
> > 
> > and these two packages:
> > 
> > Package: foo
> > Architecture: amd64
> > Depends: bar:i386
> > 
> > Package: bar
> > Architecture: amd64
> > Multi-Arch: foreign
> 
> > Do you think 'foo' is installable?
> 
> No.
> 
> > What if we change the architecture of 'bar' to 'i386' and let 'foo'
> > depend on 'bar:amd64', does that change anything?
> 
> No.
> 
> > What if we let 'foo' depend on 'bar' instead?
> 
> Yes.
> 
> > I ran some tests and dpkg and APT¹ disagree quite fundamentally here. dpkg
> > declares 'foo' uninstallable in the first two cases and only the last
> > one as okay, while APT is willing to accept all three situations.
> 
> Well, this was implemented, and subsequently fixed on purpose in dpkg to
> match the docs (see commit 5631564609ec8855cdcab384139ca2e81c2519ce and
> cdfd9738c03b772574443a61a2335ae934f0998e). The rationale is that if
> you ask for an explicit arch-qualified dependency, then it means you
> really want that one, otherwise why would you arch-qualify it if you
> don't care which arch it is? Ignoring the arch-qualifier, regardless
> of the package being M-A:foreign seems very wrong to me.

At the time when somebody wrote down "Depends: bar:i386", the package "bar"
might not've been m-a:foreign but instead contain some arch-specific stuff
which required the explicit arch-qualified dependency. Or there might not've
even be a real package "bar" but another package might've "Provides: bar:i386".

Now there appears a real package "bar" which happens to be m-a:foreign. To me,
m-a:foreign means: no matter what architecture you require "bar" to be in, this
package will be able to satisfy the dependency.

What possible situation could there be in which you'd like a m-a:foreign
package of a specific architecture? If it is a data package containing
different data per architecture, then it should probably not be m-a:foreign. If
it's an executable with an arch-independent interface, then why would you want
to depend on it with an explicit arch? In that case all you care about is that
you can somehow run the tool (which is a different problem).

> Check the lib/dpkg/depcon.c:deparchsatisfied() function comment, which has
> not changed since the initial implementation.

For reference, here is said comment:

> /**
>  * Check if the architecture qualifier in the dependency is satisfied.
>  *
>  * The rules are supposed to be:
>  * - unqualified Depends/Pre-Depends/Recommends/Suggests are only
>  *   satisfied by a package of a different architecture if the target
>  *   package is Multi-Arch: foreign.
>  * - Depends/Pre-Depends/Recommends/Suggests on pkg:any are satisfied by
>  *   a package of a different architecture if the target package is
>  *   Multi-Arch: allowed.
>  * - all other Depends/Pre-Depends/Recommends/Suggests are only
>  *   satisfied by packages of the same architecture.
>  * - Architecture: all packages are treated the same as packages of the
>  *   native architecture.
>  * - Conflicts/Replaces/Breaks are assumed to apply to packages of any arch.
>  */

This comment could be a bit more verbose to better document all the corner
cases:

 - architecture qualified Depends/Pre-Depends/Recommends/Suggests are only
   satisfied by a package of that architecture (this is the discussion above)
 - Depends/Pre-Depends/Recommends/Suggests on pkg:any are only satisfied by a
   package which is Multi-Arch:allowed

I want to also take this opportunity to talk about the second point. Consider
the following situation:

Package: pkga
Depends: pkgb:any
Architecture: amd64
Version: 1

Package: pkgb
Architecture: amd64
Version: 1

If the native architecture is amd64, then currently apt and dpkg will refuse to
install pkga because the pkgb:any dependency is not satisfied. But why? As the
dpkg comment above says, pkg:any dependencies are satisfied by a package of a
*different* arch if the target package is m-a:allowed. The target package is
not m-a:allowed here but it is also not of a different architecture than pkga.
So why can neither apt nor dpkg install pkga?

> > Now, imagine instead of 'bar' we had three other packages which provide
> > 'bar'. Some of those providers are M-A:foreign, some not. What now?  And to
> > turn this up to eleven: Lets change 'Depends' to 'Conflicts' …
> 
> I guess I don't see the problem, either the metadata is wrong or the
> packages will or will not have satisfiable dependencies.

I guess the problem here is what a specific piece of metadata is supposed to
*mean*. Only then can we answer the question whether the metadata is wrong.
Currently, the documentation on this is sparse, resulting in the many
disagreements between dpkg, apt and dose3 when it comes to multiarch (see my
other email).

> > In other words my questions are: Is "bar:i386" referring to "bar:i386 only"
> > or is it referring to "everything implementing bar:i386"?
> 
> Anything implementing bar:i386 (assuming you mean a real package with
> the former and a real or virtual package with the latter?).
> 
> > And is therefore also "bar" the same as "bar:amd64" (, "bar:native" and
> > "bar:all") or not?
> 
> That depends on what bar is, or who is providing it.
> 
> dpkg does distinguish between implicit and explicit arch-qualified
> dependencies when doing M-A:foreign checks. Let me give an example
> to clarify all this:
> 
> ,---
> Package: pkg-a
> Architecture: amd64
> Depends: pkg-b, pkg-c:i386
> Conflicts: pkg-d, pkg-e:amd64
> Provides: virtual-a, virtual-b:armel
> `---
> 
> These are the equivalences:
> 
> ,---
> pkg-b:amd64     implicit
> pkg-c:i386      explicit
> pkg-d:any       implicit
> pkg-e:amd64     explicit
> virtual-a:amd64 implicit
> virtual-b:armel explicit
> `---
> 
> Conflicts, Breaks, Replaces → :any is implicit.
> 
> Pre-Depends, Depends, Recommends, Suggests, Enhances, Provides → :<arch>
> is implicit, where <arch> is the architecture of the package with those
> fields.
> 
> > My personal opinion is (unsurprisingly perhaps) APT's interpretation as
> > the point of M-A: foreign is satisfying dependencies of another
> > architecture. If there really is a meaningful difference between
> > architectures a reverse-dependency could observe, perhaps bar should be
> > M-A: allowed instead…
> 
> This removes expressiveness. If you don't care about the arch just do not
> arch-qualify it, otherwise the arch-qualifier is relevant.

It only removes expressiveness for a target package for which it should not
matter because it claims to offer an architecture independent interface and
thus was marked m-a:foreign.

For a dependency "foo:amd4", an architecture qualifier might be relevant even
if the real package "foo" is m-a:foreign. Imagine for example another package
which provides "foo:amd64". Then the dependency would be meaningful because
both packages, "foo" as well as the provider of "foo:amd64" would satisfy the
dependency.

> And this works nicely with both implicit :any or :<arch>.

You lost me here - where is the implicit :any or :<arch> here?

> > Beside this, I think it also provides us with some interesting benefits
> > while changing a package from arch:all to arch:any (or v.v.) or a package
> > moves from M-A:none to M-A:foreign (or v.v.). It could also be interesting
> > if we ever get stuff like partial architectures…
> 
> I guess you'll have to spell these out, because I don't see any obvious
> benefit, just drawbacks. :)

If I didn't miss anything then the one drawback you bring up is, that it is
then not anymore possible to depend on a m-a:foreign package of a specific
architecture.

My argument is that if it would make a difference (other than which
architectures it is able to be executed for) which architecture of a
m-a:foreign to pick to satisfy a given dependency, then the package should not
be m-a:foreign.

Expressing an architecture qualified dependency on a m-a:foreign package might
even be meaningful in the event that the m-a value of that package is changing
or there are multiple providers of that package, some of them not being
m-a:foreign but explicitly providing the package of that architecture.

So is there actually a case where you'd want to depend on a specific
architecture of an otherwise valid m-a:foreign package?

Let me also point out that I don't have a very strong opinion about this topic
and just want to weight the arguments I can come up with against others. I find
it way more important that all tools agree on the same thing than to discuss
about corner cases without real-life examples (which I do not see existing).
As far as dose3 is concerned, me (and as I understand it also Pietro) have no
problem with just following what dpkg does. I think it's more important that we
pick one way to interpret these things and implement the same behaviour in all
tools resolving dependencies now. If these decisions turn out to become
problems, then they can still be changed in the future.

cheers, josch

Attachment: signature.asc
Description: signature


Reply to: