[gnome-software/wip/kalev/rpm-ostree-layered-package-install: 7/7] rpm-ostree: Use libdnf to figure out what packages are available
- From: Kalev Lember <klember src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/kalev/rpm-ostree-layered-package-install: 7/7] rpm-ostree: Use libdnf to figure out what packages are available
- Date: Sat, 23 Feb 2019 17:06:19 +0000 (UTC)
commit 0687e3cbff61573e79472663f0729c8c2c0671d8
Author: Kalev Lember <klember redhat com>
Date: Sat Feb 23 18:01:08 2019 +0100
rpm-ostree: Use libdnf to figure out what packages are available
This should really go in the rpm-ostree daemon, but let's prototype this
here first so that we know what interfaces we are actually going to
need.
meson.build | 1 +
plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 110 ++++++++++++++++++++++++++++--
plugins/rpm-ostree/meson.build | 2 +-
3 files changed, 105 insertions(+), 8 deletions(-)
---
diff --git a/meson.build b/meson.build
index cd971a62..5925c95d 100644
--- a/meson.build
+++ b/meson.build
@@ -158,6 +158,7 @@ if get_option('flatpak')
endif
if get_option('rpm_ostree')
+ libdnf = dependency('libdnf')
ostree = dependency('ostree-1')
rpm = dependency('rpm')
rpm_ostree = dependency('rpm-ostree-1', version : '>= 2018.4')
diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
index 6b8cf2d0..da3b1e39 100644
--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
@@ -13,6 +13,7 @@
#include <gio/gio.h>
#include <gio/gunixfdlist.h>
#include <glib/gstdio.h>
+#include <libdnf/libdnf.h>
#include <ostree.h>
#include <rpm/rpmdb.h>
#include <rpm/rpmlib.h>
@@ -31,17 +32,19 @@ G_DEFINE_AUTO_CLEANUP_FREE_FUNC(rpmts, rpmtsFree, NULL);
G_DEFINE_AUTO_CLEANUP_FREE_FUNC(rpmdbMatchIterator, rpmdbFreeIterator, NULL);
struct GsPluginData {
+ GMutex mutex;
GsRPMOSTreeOS *os_proxy;
GsRPMOSTreeSysroot *sysroot_proxy;
OstreeRepo *ot_repo;
OstreeSysroot *ot_sysroot;
+ DnfContext *dnf_context;
gboolean update_triggered;
};
void
gs_plugin_initialize (GsPlugin *plugin)
{
- gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
+ GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
/* only works on OSTree */
if (!g_file_test ("/run/ostree-booted", G_FILE_TEST_EXISTS)) {
@@ -49,6 +52,8 @@ gs_plugin_initialize (GsPlugin *plugin)
return;
}
+ g_mutex_init (&priv->mutex);
+
/* open transaction */
rpmReadConfigFiles (NULL, NULL);
@@ -84,6 +89,24 @@ gs_plugin_destroy (GsPlugin *plugin)
g_object_unref (priv->ot_sysroot);
if (priv->ot_repo != NULL)
g_object_unref (priv->ot_repo);
+ g_mutex_clear (&priv->mutex);
+}
+
+#define RPMOSTREE_CORE_CACHEDIR "/var/cache/rpm-ostree/"
+#define RPMOSTREE_DIR_CACHE_REPOMD "repomd"
+#define RPMOSTREE_DIR_CACHE_SOLV "solv"
+
+static DnfContext *
+gs_rpmostree_context_new (void)
+{
+ DnfContext *context = dnf_context_new ();
+
+ dnf_context_set_repo_dir (context, "/etc/yum.repos.d");
+ dnf_context_set_cache_dir (context, RPMOSTREE_CORE_CACHEDIR RPMOSTREE_DIR_CACHE_REPOMD);
+ dnf_context_set_solv_dir (context, RPMOSTREE_CORE_CACHEDIR RPMOSTREE_DIR_CACHE_SOLV);
+ dnf_context_set_cache_age (context, G_MAXUINT);
+
+ return context;
}
gboolean
@@ -165,6 +188,24 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
}
}
+ /* Set up libdnf context for querying remote metadata */
+ if (priv->dnf_context == NULL) {
+ g_autoptr(DnfContext) context = gs_rpmostree_context_new ();
+ g_autoptr(DnfState) state = dnf_state_new ();
+
+ if (!dnf_context_setup (context, cancellable, error)) {
+ gs_utils_error_convert_gio (error);
+ return FALSE;
+ }
+
+ if (!dnf_context_setup_sack_with_flags (context, state,
DNF_CONTEXT_SETUP_SACK_FLAG_SKIP_RPMDB, error)) {
+ gs_utils_error_convert_gio (error);
+ return FALSE;
+ }
+
+ g_set_object (&priv->dnf_context, context);
+ }
+
return TRUE;
}
@@ -960,11 +1001,28 @@ gs_plugin_app_remove (GsPlugin *plugin,
return TRUE;
}
-static void
-resolve_packages_app (GsPlugin *plugin,
- GPtrArray *pkglist,
- gchar **layered_packages,
- GsApp *app)
+static DnfPackage *
+find_package_by_name (DnfSack *sack,
+ const char *pkgname)
+{
+ g_autoptr(GPtrArray) pkgs = NULL;
+ hy_autoquery HyQuery query = hy_query_create (sack);
+
+ hy_query_filter (query, HY_PKG_NAME, HY_EQ, pkgname);
+ hy_query_filter_latest_per_arch (query, TRUE);
+
+ pkgs = hy_query_run (query);
+ if (pkgs->len == 0)
+ return NULL;
+
+ return g_object_ref (pkgs->pdata[pkgs->len-1]);
+}
+
+static gboolean
+resolve_installed_packages_app (GsPlugin *plugin,
+ GPtrArray *pkglist,
+ gchar **layered_packages,
+ GsApp *app)
{
for (guint i = 0; i < pkglist->len; i++) {
RpmOstreePackage *pkg = g_ptr_array_index (pkglist, i);
@@ -980,8 +1038,32 @@ resolve_packages_app (GsPlugin *plugin,
/* can't remove packages that are part of the base system */
gs_app_add_quirk (app, GS_APP_QUIRK_COMPULSORY);
}
+ return TRUE /* found */;
}
}
+
+ return FALSE /* not found */;
+}
+
+static gboolean
+resolve_available_packages_app (GsPlugin *plugin,
+ DnfSack *sack,
+ GsApp *app)
+{
+ g_autoptr(DnfPackage) pkg = NULL;
+
+ pkg = find_package_by_name (sack, gs_app_get_source_default (app));
+ if (pkg != NULL) {
+ gs_app_set_version (app, dnf_package_get_evr (pkg));
+ if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN)
+ gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+
+ /* anything not part of the base system can be removed */
+ gs_app_remove_quirk (app, GS_APP_QUIRK_COMPULSORY);
+ return TRUE /* found */;
+ }
+
+ return FALSE /* not found */;
}
static gboolean
@@ -1046,11 +1128,14 @@ gs_plugin_refine (GsPlugin *plugin,
GError **error)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_autoptr(GMutexLocker) locker = NULL;
g_autoptr(GPtrArray) pkglist = NULL;
g_autoptr(GVariant) booted_deployment = NULL;
g_auto(GStrv) layered_packages = NULL;
g_autofree gchar *checksum = NULL;
+ locker = g_mutex_locker_new (&priv->mutex);
+
/* ensure D-Bus properties are updated before reading them */
if (!gs_rpmostree_sysroot_call_reload_sync (priv->sysroot_proxy, cancellable, error)) {
gs_utils_error_convert_gio (error);
@@ -1073,6 +1158,7 @@ gs_plugin_refine (GsPlugin *plugin,
for (guint i = 0; i < gs_app_list_length (list); i++) {
GsApp *app = gs_app_list_index (list, i);
+ gboolean found;
if (gs_app_has_quirk (app, GS_APP_QUIRK_IS_WILDCARD))
continue;
@@ -1096,7 +1182,17 @@ gs_plugin_refine (GsPlugin *plugin,
if (gs_app_get_source_default (app) == NULL)
continue;
- resolve_packages_app (plugin, pkglist, layered_packages, app);
+ /* first try to resolve from installed packages */
+ found = resolve_installed_packages_app (plugin, pkglist, layered_packages, app);
+
+ /* if we didn't find anything, try resolving from available packages */
+ if (!found)
+ found = resolve_available_packages_app (plugin, dnf_context_get_sack
(priv->dnf_context), app);
+
+ /* if we still didn't find anything then it's likely a package
+ * that is still in appstream data, but removed from the repos */
+ if (!found)
+ g_debug ("failed to resolve %s", gs_app_get_unique_id (app));
}
return TRUE;
diff --git a/plugins/rpm-ostree/meson.build b/plugins/rpm-ostree/meson.build
index 7c2b5eeb..ee19768f 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, rpm_ostree ],
+ dependencies : [ plugin_libs, libdnf, ostree, rpm, rpm_ostree ],
link_with : [
libgnomesoftware
]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]