[gnome-software] rpm-ostree: Correctly resolve installed appdata files to package names
- From: Kalev Lember <klember src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] rpm-ostree: Correctly resolve installed appdata files to package names
- Date: Wed, 23 Jan 2019 13:45:32 +0000 (UTC)
commit cea79cd9419e6dc53d701c220de804a6691c86bf
Author: Kalev Lember <klember redhat com>
Date: Wed Jan 23 14:16:55 2019 +0100
rpm-ostree: Correctly resolve installed appdata files to package names
This makes use of the custom "appstream::source-file" metadata key that
was added in commit c7bdc2f to map locally installed appdata files to
packages.
rpm-ostree doesn't expose enough API to query locally installed files,
but we can just as well directly ask librpm.
.gitlab-ci.yml | 1 +
contrib/gnome-software.spec.in | 1 +
meson.build | 1 +
plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 97 +++++++++++++++++++++++++++----
plugins/rpm-ostree/meson.build | 2 +-
5 files changed, 90 insertions(+), 12 deletions(-)
---
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 90093205..fa9c73f5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -9,6 +9,7 @@ before_script:
- dnf install -y
https://people.freedesktop.org/~hughsient/temp/libappstream-glib-0.7.14-0.641.20181015git.fc29.x86_64.rpm
https://people.freedesktop.org/~hughsient/temp/libappstream-glib-devel-0.7.14-0.641.20181015git.fc29.x86_64.rpm
- dnf --enablerepo updates-testing -y builddep gnome-software
# Some deps may not be sync'd
+ - dnf -y install rpm-devel
- dnf -y install rpm-ostree-devel
- dnf -y install libstemmer-devel
- dnf -y install gnome-online-accounts-devel
diff --git a/contrib/gnome-software.spec.in b/contrib/gnome-software.spec.in
index e5974895..07be3cfe 100644
--- a/contrib/gnome-software.spec.in
+++ b/contrib/gnome-software.spec.in
@@ -41,6 +41,7 @@ BuildRequires: PackageKit-glib-devel >= %{packagekit_version}
BuildRequires: polkit-devel
BuildRequires: flatpak-devel >= %{flatpak_version}
BuildRequires: ostree-devel
+BuildRequires: rpm-devel
BuildRequires: rpm-ostree-devel
BuildRequires: libgudev1-devel
BuildRequires: valgrind-devel
diff --git a/meson.build b/meson.build
index b3bf29c4..cd971a62 100644
--- a/meson.build
+++ b/meson.build
@@ -159,6 +159,7 @@ endif
if get_option('rpm_ostree')
ostree = dependency('ostree-1')
+ rpm = dependency('rpm')
rpm_ostree = dependency('rpm-ostree-1', version : '>= 2018.4')
endif
diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
index 3ed325a7..80abca30 100644
--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
- * Copyright (C) 2017-2018 Kalev Lember <klember redhat com>
+ * Copyright (C) 2017-2019 Kalev Lember <klember redhat com>
*
* Licensed under the GNU General Public License Version 2
*
@@ -21,11 +21,15 @@
#include <config.h>
+#include <gnome-software.h>
+
+#include <fcntl.h>
#include <gio/gio.h>
#include <glib/gstdio.h>
-
-#include <gnome-software.h>
#include <ostree.h>
+#include <rpm/rpmdb.h>
+#include <rpm/rpmlib.h>
+#include <rpm/rpmts.h>
#include <rpmostree.h>
#include "gs-rpmostree-generated.h"
@@ -35,6 +39,9 @@
*/
#define GS_RPMOSTREE_CLIENT_ID PACKAGE_NAME
+G_DEFINE_AUTO_CLEANUP_FREE_FUNC(rpmts, rpmtsFree, NULL);
+G_DEFINE_AUTO_CLEANUP_FREE_FUNC(rpmdbMatchIterator, rpmdbFreeIterator, NULL);
+
struct GsPluginData {
GsRPMOSTreeOS *os_proxy;
GsRPMOSTreeSysroot *sysroot_proxy;
@@ -54,6 +61,9 @@ gs_plugin_initialize (GsPlugin *plugin)
return;
}
+ /* open transaction */
+ rpmReadConfigFiles(NULL, NULL);
+
/* rpm-ostree is already a daemon with a DBus API; hence it makes
* more sense to use a custom plugin instead of using PackageKit.
*/
@@ -772,6 +782,60 @@ resolve_packages_app (GsPlugin *plugin,
}
}
+static gboolean
+resolve_appstream_source_file_to_package_name (GsPlugin *plugin,
+ GsApp *app,
+ GsPluginRefineFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ Header h;
+ const gchar *fn;
+ gint rc;
+ g_auto(rpmdbMatchIterator) mi = NULL;
+ g_auto(rpmts) ts = NULL;
+
+ /* open db readonly */
+ ts = rpmtsCreate();
+ rpmtsSetRootDir (ts, NULL);
+ rc = rpmtsOpenDB (ts, O_RDONLY);
+ if (rc != 0) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_NOT_SUPPORTED,
+ "Failed to open rpmdb: %i", rc);
+ return FALSE;
+ }
+
+ /* look for a specific file */
+ fn = gs_app_get_metadata_item (app, "appstream::source-file");
+ if (fn == NULL)
+ return TRUE;
+
+ mi = rpmtsInitIterator (ts, RPMDBI_INSTFILENAMES, fn, 0);
+ if (mi == NULL) {
+ g_debug ("rpm: no search results for %s", fn);
+ return TRUE;
+ }
+
+ /* process any results */
+ g_debug ("rpm: querying for %s with %s", gs_app_get_id (app), fn);
+ while ((h = rpmdbNextIterator (mi)) != NULL) {
+ const gchar *name;
+
+ /* add default source */
+ name = headerGetString (h, RPMTAG_NAME);
+ if (gs_app_get_source_default (app) == NULL) {
+ g_debug ("rpm: setting source to %s", name);
+ gs_app_add_source (app, name);
+ gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
+ gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE);
+ }
+ }
+
+ return TRUE;
+}
+
gboolean
gs_plugin_refine (GsPlugin *plugin,
GsAppList *list,
@@ -804,19 +868,30 @@ gs_plugin_refine (GsPlugin *plugin,
for (guint i = 0; i < gs_app_list_length (list); i++) {
GsApp *app = gs_app_list_index (list, i);
- GPtrArray *sources;
+
if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD))
continue;
- if (gs_app_get_kind (app) == AS_APP_KIND_WEB_APP)
- continue;
- if (g_strcmp0 (gs_app_get_management_plugin (app), "rpm-ostree") != 0)
+ /* set management plugin for apps where appstream just added the source package name in
refine() */
+ if (gs_app_get_management_plugin (app) == NULL &&
+ gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_PACKAGE &&
+ gs_app_get_scope (app) == AS_APP_SCOPE_SYSTEM &&
+ gs_app_get_source_default (app) != NULL) {
+ gs_app_set_management_plugin (app, gs_plugin_get_name (plugin));
+ }
+ /* resolve the source package name based on installed appdata/desktop file name */
+ if (gs_app_get_management_plugin (app) == NULL &&
+ gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_UNKNOWN &&
+ gs_app_get_scope (app) == AS_APP_SCOPE_SYSTEM &&
+ gs_app_get_source_default (app) == NULL) {
+ if (!resolve_appstream_source_file_to_package_name (plugin, app, flags, cancellable,
error))
+ return FALSE;
+ }
+ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0)
continue;
- sources = gs_app_get_sources (app);
- if (sources->len == 0)
+ if (gs_app_get_source_default (app) == NULL)
continue;
- if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN)
- resolve_packages_app (plugin, pkglist, layered_packages, app);
+ resolve_packages_app (plugin, pkglist, layered_packages, app);
}
return TRUE;
diff --git a/plugins/rpm-ostree/meson.build b/plugins/rpm-ostree/meson.build
index 8cf509db..7c2b5eeb 100644
--- a/plugins/rpm-ostree/meson.build
+++ b/plugins/rpm-ostree/meson.build
@@ -18,7 +18,7 @@ shared_module(
install : true,
install_dir: plugin_dir,
c_args : cargs,
- dependencies : [ plugin_libs, ostree, rpm_ostree ],
+ dependencies : [ plugin_libs, ostree, rpm, rpm_ostree ],
link_with : [
libgnomesoftware
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]