Bug 369521 - multiarch not supported (installing wrong package!)
Summary: multiarch not supported (installing wrong package!)
Status: RESOLVED FIXED
Alias: None
Product: Discover
Classification: Applications
Component: PackageKit (show other bugs)
Version: 5.7.2
Platform: Other Linux
: NOR major
Target Milestone: ---
Assignee: Aleix Pol
URL:
Keywords:
: 370509 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-09-29 10:02 UTC by Harald Sitter
Modified: 2016-10-15 06:38 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Harald Sitter 2016-09-29 10:02:47 UTC
On systems where multiple architectures can be installed (e.g. debian on x64 also can install and run x32) discover has a 50:50 chance of installing the wrong package if a package is both available for both architectures.

The reason for this is that discover never uses the packagekit ARCH filter (PackageKit::Transaction::FilterArch) to limit the selection to the preferred architecture, ultimately resulting in all architectures being returned in arbitrary order (or rather, the API makes no assertions about the order).

This for example results in kipi-plugins on neon installing the i386 package (or trying to) when really it should pick amd64.

When changing the resolve call to
> PackageKit::Transaction * t = PackageKit::Daemon::resolve(names, PackageKit::Transaction::FilterArch);
only native architecture will be tracked. Supposedly this would be unsuitable as well as then one can't install i386 packages (e.g. potential third party binary blob packages that only are available as i386).

The way I understand it this needs a bit of a restructuring WRT how applications are mapped to packages.

a) A Resource could stop holding packageids. Specifically the backend would get all apps from appstream, resolve them via packagekit and note that a given resource is resolved (or not) BUT not keep the packageid in the resource. Since PK can resolve the name we don't need the pkgid and can later simply call install(packagename, filter_ARCH) and if that fails install(packagename, filter_NO_ARCH) as fallback to pick a secondary architecutre package if no primary arch is available.

b) Backend does two resolve queries. One with ARCH and once that is done for all resources that were not resolved it does another resolve run with NO_ARCH. i.e. a Resources has a packagelist that is either from the primary arch or a !primary arch, but not both. Since we map one app to one  packageid for installation this might be the best and most efficient option since we effectively want either-or for installation.

c) A combination of a) and b) might be possible. By default the backend requests two resolves, one with ARCH and one with NO_ARCH. It keeps both sets of information so a discover resource knows which packageids it maps to for the primary architecture as well as !primary. Upon installation request discover could request primary and fall back to !primary if primary installation failed (not sure that is good).

NB: limiting the packageids to ARCH filtered ones may impact update listing as update listing ought to be a complete list of all packages, so only option c) could be a viable option. I am unclear about the implications.

It's also worth noting that if discover has daemon interaction where it throws packagenames (rather than packageids) at the daemon those need to have their need for filtering reviewed as well.

Reproducible: Always
Comment 1 Aleix Pol 2016-09-29 11:27:24 UTC
Could you test if that works for you?
diff --git a/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp b/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp
index 54625f8..c15e4a1 100644
--- a/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp
+++ b/libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp
@@ -147,7 +147,7 @@ void PackageKitBackend::reloadPackageList()
 
 void PackageKitBackend::resolvePackages(const QStringList &packageNames)
 {
-    PackageKit::Transaction * t = PackageKit::Daemon::resolve(packageNames);
+    PackageKit::Transaction * t = PackageKit::Daemon::resolve(packageNames, PackageKit::Transaction::FilterArch);
     connect(t, &PackageKit::Transaction::finished, this, &PackageKitBackend::getPackagesFinished);
     connect(t, &PackageKit::Transaction::package, this, &PackageKitBackend::addPackage);
     connect(t, &PackageKit::Transaction::errorCode, this, &PackageKitBackend::transactionError);
Comment 2 Harald Sitter 2016-09-29 11:32:02 UTC
That is the line I was pasting :P

The problem is this isn't enough. FilterArch will filter everything that is not native (i.e. amd64). There are however things that are only available from i386 (skype, what have you). So we need both, we just need to prefer a native package when there is one.
Comment 3 Aleix Pol 2016-09-30 11:55:29 UTC
Git commit ac11ba0fed2df5eaefa6ef4c8bb41f697dcc42a2 by Aleix Pol.
Committed on 30/09/2016 at 11:54.
Pushed by apol into branch 'Plasma/5.8'.

Prioritize packages from the right architecture

M  +54   -12   libdiscover/backends/PackageKitBackend/PackageKitBackend.cpp
M  +4    -2    libdiscover/backends/PackageKitBackend/PackageKitBackend.h
M  +7    -4    libdiscover/backends/PackageKitBackend/PackageKitResource.cpp
M  +1    -1    libdiscover/backends/PackageKitBackend/PackageKitResource.h

http://commits.kde.org/discover/ac11ba0fed2df5eaefa6ef4c8bb41f697dcc42a2
Comment 4 Aleix Pol 2016-10-14 20:50:45 UTC
*** Bug 370509 has been marked as a duplicate of this bug. ***
Comment 5 Mustafa Muhammad 2016-10-15 06:38:31 UTC
*** Bug 370509 has been marked as a duplicate of this bug. ***