[gnome-software/554-keeps-rpm-ostreed-alive-forever] rpm-ostree: Disconnect from rpm-ostreed when inactive for some time



commit 461f24f9f01594bef025df4df45006964776f28e
Author: Milan Crha <mcrha redhat com>
Date:   Wed Mar 31 19:14:46 2021 +0200

    rpm-ostree: Disconnect from rpm-ostreed when inactive for some time
    
    Disconnect from the rpm-ostreed when there was no request to it for some
    time, to let it close and free the resources, instead of keep it alive
    forever.
    
    Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/554

 plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 433 +++++++++++++++++++++---------
 1 file changed, 311 insertions(+), 122 deletions(-)
---
diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
index fac0f3f91..c8aa5d199 100644
--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
+++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c
@@ -28,6 +28,11 @@
  */
 #define GS_RPMOSTREE_CLIENT_ID PACKAGE_NAME
 
+/* How long to wait between two consecutive requests, before considering
+ * the connection to the rpm-ostree daemon inactive and disconnect from it.
+ */
+#define INACTIVE_TIMEOUT_SECONDS 60
+
 G_DEFINE_AUTO_CLEANUP_FREE_FUNC(Header, headerFree, NULL)
 G_DEFINE_AUTO_CLEANUP_FREE_FUNC(rpmts, rpmtsFree, NULL);
 G_DEFINE_AUTO_CLEANUP_FREE_FUNC(rpmdbMatchIterator, rpmdbFreeIterator, NULL);
@@ -40,6 +45,7 @@ struct GsPluginData {
        OstreeSysroot           *ot_sysroot;
        DnfContext              *dnf_context;
        gboolean                 update_triggered;
+       guint                    inactive_timeout_id;
 };
 
 void
@@ -81,16 +87,15 @@ void
 gs_plugin_destroy (GsPlugin *plugin)
 {
        GsPluginData *priv = gs_plugin_get_data (plugin);
-       if (priv->os_proxy != NULL)
-               g_object_unref (priv->os_proxy);
-       if (priv->sysroot_proxy != NULL)
-               g_object_unref (priv->sysroot_proxy);
-       if (priv->ot_sysroot != NULL)
-               g_object_unref (priv->ot_sysroot);
-       if (priv->ot_repo != NULL)
-               g_object_unref (priv->ot_repo);
-       if (priv->dnf_context != NULL)
-               g_object_unref (priv->dnf_context);
+       if (priv->inactive_timeout_id) {
+               g_source_remove (priv->inactive_timeout_id);
+               priv->inactive_timeout_id = 0;
+       }
+       g_clear_object (&priv->os_proxy);
+       g_clear_object (&priv->sysroot_proxy);
+       g_clear_object (&priv->ot_sysroot);
+       g_clear_object (&priv->ot_repo);
+       g_clear_object (&priv->dnf_context);
        g_mutex_clear (&priv->mutex);
 }
 
@@ -130,14 +135,82 @@ gs_rpmostree_error_convert (GError **perror)
                return;
 }
 
-gboolean
-gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+static void
+gs_rpmostree_unregister_client_done_cb (GObject *source_object,
+                                       GAsyncResult *result,
+                                       gpointer user_data)
+{
+       g_autoptr(GError) error = NULL;
+
+       if (!gs_rpmostree_sysroot_call_unregister_client_finish (GS_RPMOSTREE_SYSROOT (source_object), 
result, &error))
+               g_debug ("Failed to unregister client: %s", error->message);
+}
+
+static gboolean
+gs_rpmostree_inactive_timeout_cb (gpointer user_data)
+{
+       GsPlugin *plugin = user_data;
+       GsPluginData *priv;
+       g_autoptr(GMutexLocker) locker = NULL;
+
+       if (g_source_is_destroyed (g_main_current_source ()))
+               return G_SOURCE_REMOVE;
+
+       priv = gs_plugin_get_data (plugin);
+       locker = g_mutex_locker_new (&priv->mutex);
+
+       /* In case it gets destroyed before the lock is acquired */
+       if (!g_source_is_destroyed (g_main_current_source ()) &&
+           priv->inactive_timeout_id == g_source_get_id (g_main_current_source ())) {
+               g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
+
+               if (priv->sysroot_proxy)
+                       sysroot_proxy = g_steal_pointer (&priv->sysroot_proxy);
+
+               g_clear_object (&priv->os_proxy);
+               g_clear_object (&priv->sysroot_proxy);
+               g_clear_object (&priv->ot_sysroot);
+               g_clear_object (&priv->ot_repo);
+               g_clear_object (&priv->dnf_context);
+               priv->inactive_timeout_id = 0;
+
+               g_clear_pointer (&locker, g_mutex_locker_free);
+
+               if (sysroot_proxy) {
+                       g_autoptr(GVariantBuilder) options_builder = NULL;
+                       options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+                       g_variant_builder_add (options_builder, "{sv}", "id",
+                                              g_variant_new_string (GS_RPMOSTREE_CLIENT_ID));
+                       gs_rpmostree_sysroot_call_unregister_client (sysroot_proxy,
+                                                                    g_variant_builder_end (options_builder),
+                                                                    NULL,
+                                                                    gs_rpmostree_unregister_client_done_cb,
+                                                                    NULL);
+               }
+       }
+
+       return G_SOURCE_REMOVE;
+}
+
+/* Hold the plugin mutex when called */
+static gboolean
+gs_rpmostree_ref_proxies_locked (GsPlugin *plugin,
+                                GsRPMOSTreeOS **out_os_proxy,
+                                GsRPMOSTreeSysroot **out_sysroot_proxy,
+                                GCancellable *cancellable,
+                                GError **error)
 {
        GsPluginData *priv = gs_plugin_get_data (plugin);
-       g_autoptr(GVariantBuilder) options_builder = NULL;
+
+       if (priv->inactive_timeout_id) {
+               g_source_remove (priv->inactive_timeout_id);
+               priv->inactive_timeout_id = 0;
+       }
 
        /* Create a proxy for sysroot */
        if (priv->sysroot_proxy == NULL) {
+               g_autoptr(GVariantBuilder) options_builder = NULL;
+
                priv->sysroot_proxy = gs_rpmostree_sysroot_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                                                                   G_DBUS_PROXY_FLAGS_NONE,
                                                                                   
"org.projectatomic.rpmostree1",
@@ -148,6 +221,19 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
                        gs_rpmostree_error_convert (error);
                        return FALSE;
                }
+
+               options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+               g_variant_builder_add (options_builder, "{sv}", "id",
+                                      g_variant_new_string (GS_RPMOSTREE_CLIENT_ID));
+               /* Register as a client so that the rpm-ostree daemon doesn't exit */
+               if (!gs_rpmostree_sysroot_call_register_client_sync (priv->sysroot_proxy,
+                                                                    g_variant_builder_end (options_builder),
+                                                                    cancellable,
+                                                                    error)) {
+                       g_clear_object (&priv->sysroot_proxy);
+                       gs_rpmostree_error_convert (error);
+                       return FALSE;
+               }
        }
 
        /* Create a proxy for currently booted OS */
@@ -162,6 +248,7 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
                                                            cancellable,
                                                            error)) {
                        gs_rpmostree_error_convert (error);
+                       g_clear_object (&priv->sysroot_proxy);
                        return FALSE;
                }
 
@@ -173,22 +260,11 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
                                                                         error);
                if (priv->os_proxy == NULL) {
                        gs_rpmostree_error_convert (error);
+                       g_clear_object (&priv->sysroot_proxy);
                        return FALSE;
                }
        }
 
-       options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
-       g_variant_builder_add (options_builder, "{sv}", "id",
-                              g_variant_new_string (GS_RPMOSTREE_CLIENT_ID));
-       /* Register as a client so that the rpm-ostree daemon doesn't exit */
-       if (!gs_rpmostree_sysroot_call_register_client_sync (priv->sysroot_proxy,
-                                                            g_variant_builder_end (options_builder),
-                                                            cancellable,
-                                                            error)) {
-               gs_rpmostree_error_convert (error);
-               return FALSE;
-       }
-
        /* Load ostree sysroot and repo */
        if (priv->ot_sysroot == NULL) {
                g_autofree gchar *sysroot_path = NULL;
@@ -200,18 +276,54 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
                priv->ot_sysroot = ostree_sysroot_new (sysroot_file);
                if (!ostree_sysroot_load (priv->ot_sysroot, cancellable, error)) {
                        gs_rpmostree_error_convert (error);
+                       g_clear_object (&priv->sysroot_proxy);
+                       g_clear_object (&priv->os_proxy);
+                       g_clear_object (&priv->ot_sysroot);
                        return FALSE;
                }
 
                if (!ostree_sysroot_get_repo (priv->ot_sysroot, &priv->ot_repo, cancellable, error)) {
                        gs_rpmostree_error_convert (error);
+                       g_clear_object (&priv->sysroot_proxy);
+                       g_clear_object (&priv->os_proxy);
+                       g_clear_object (&priv->ot_sysroot);
                        return FALSE;
                }
        }
 
+       priv->inactive_timeout_id = g_timeout_add_seconds (INACTIVE_TIMEOUT_SECONDS,
+               gs_rpmostree_inactive_timeout_cb, plugin);
+
+       if (out_os_proxy)
+               *out_os_proxy = g_object_ref (priv->os_proxy);
+
+       if (out_sysroot_proxy)
+               *out_sysroot_proxy = g_object_ref (priv->sysroot_proxy);
+
        return TRUE;
 }
 
+static gboolean
+gs_rpmostree_ref_proxies (GsPlugin *plugin,
+                         GsRPMOSTreeOS **out_os_proxy,
+                         GsRPMOSTreeSysroot **out_sysroot_proxy,
+                         GCancellable *cancellable,
+                         GError **error)
+{
+       GsPluginData *priv = gs_plugin_get_data (plugin);
+       g_autoptr(GMutexLocker) locker = NULL;
+
+       locker = g_mutex_locker_new (&priv->mutex);
+
+       return gs_rpmostree_ref_proxies_locked (plugin, out_os_proxy, out_sysroot_proxy, cancellable, error);
+}
+
+gboolean
+gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+{
+       return gs_rpmostree_ref_proxies (plugin, NULL, NULL, cancellable, error);
+}
+
 static void
 app_set_rpm_ostree_packaging_format (GsApp *app)
 {
@@ -240,6 +352,7 @@ typedef struct {
        GMainContext *context;
        GsApp *app;
        gboolean complete;
+       gboolean owner_changed;
 } TransactionProgress;
 
 static TransactionProgress *
@@ -332,6 +445,8 @@ on_owner_notify (GObject    *obj,
 {
        TransactionProgress *tp = user_data;
 
+       tp->owner_changed = TRUE;
+
        /* Wake up the context so it can notice the server has disappeared. */
        g_main_context_wakeup (tp->context);
 }
@@ -353,11 +468,12 @@ gs_rpmostree_transaction_get_response_sync (GsRPMOSTreeSysroot *sysroot_proxy,
 {
        GsRPMOSTreeTransaction *transaction = NULL;
        g_autoptr(GDBusConnection) peer_connection = NULL;
-       gint cancel_handler;
+       gint cancel_handler = 0;
        gulong signal_handler = 0;
        gulong notify_handler = 0;
        gboolean success = FALSE;
        gboolean just_started = FALSE;
+       gboolean saw_name_owner = FALSE;
        g_autofree gchar *name_owner = NULL;
 
        peer_connection = g_dbus_connection_new_for_address_sync (transaction_address,
@@ -378,10 +494,12 @@ gs_rpmostree_transaction_get_response_sync (GsRPMOSTreeSysroot *sysroot_proxy,
        if (transaction == NULL)
                goto out;
 
-       /* setup cancel handler */
-       cancel_handler = g_cancellable_connect (cancellable,
-                                               G_CALLBACK (cancelled_handler),
-                                               transaction, NULL);
+       if (cancellable) {
+               /* setup cancel handler */
+               cancel_handler = g_cancellable_connect (cancellable,
+                                                       G_CALLBACK (cancelled_handler),
+                                                       transaction, NULL);
+       }
 
        signal_handler = g_signal_connect (transaction, "g-signal",
                                           G_CALLBACK (on_transaction_progress),
@@ -399,15 +517,19 @@ gs_rpmostree_transaction_get_response_sync (GsRPMOSTreeSysroot *sysroot_proxy,
                goto out;
 
        /* Process all the signals until we receive the Finished signal or the
-        * daemon disappears (which can happen if it crashes). */
+        * daemon disappears (which can happen if it crashes).
+        *
+        * The property can be NULL right after connecting to it, before the D-Bus
+        * transfers the property value to the client. */
        while (!tp->complete &&
-              (name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (transaction))) != NULL) {
+              !g_cancellable_is_cancelled (cancellable) &&
+              ((name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (transaction))) != NULL ||
+               (!saw_name_owner && !tp->owner_changed))) {
+               saw_name_owner = saw_name_owner || name_owner != NULL;
                g_clear_pointer (&name_owner, g_free);
                g_main_context_iteration (tp->context, TRUE);
        }
 
-       g_cancellable_disconnect (cancellable, cancel_handler);
-
        if (!g_cancellable_set_error_if_cancelled (cancellable, error)) {
                if (tp->error) {
                        g_propagate_error (error, g_steal_pointer (&tp->error));
@@ -420,6 +542,8 @@ gs_rpmostree_transaction_get_response_sync (GsRPMOSTreeSysroot *sysroot_proxy,
        }
 
 out:
+       if (cancel_handler)
+               g_cancellable_disconnect (cancellable, cancel_handler);
        if (notify_handler != 0)
                g_signal_handler_disconnect (transaction, notify_handler);
        if (signal_handler)
@@ -649,8 +773,8 @@ rpmostree_update_deployment (GsRPMOSTreeOS *os_proxy,
 #define RPMOSTREE_DIR_CACHE_SOLV "solv"
 
 static DnfContext *
-create_bare_rpmostree_dnf_context (GCancellable *cancellable,
-                                  GError **error)
+gs_rpmostree_create_bare_dnf_context (GCancellable *cancellable,
+                                     GError **error)
 {
        g_autoptr(DnfContext) context = dnf_context_new ();
 
@@ -669,47 +793,35 @@ create_bare_rpmostree_dnf_context (GCancellable *cancellable,
 }
 
 static gboolean
-ensure_rpmostree_dnf_context (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+gs_rpmostree_ref_dnf_context_locked (GsPlugin *plugin,
+                                    GsRPMOSTreeOS **out_os_proxy,
+                                    GsRPMOSTreeSysroot **out_sysroot_proxy,
+                                    DnfContext **out_dnf_context,
+                                    GCancellable *cancellable,
+                                    GError **error)
 {
        GsPluginData *priv = gs_plugin_get_data (plugin);
        g_autoptr(DnfContext) context = NULL;
-       g_autofree gchar *transaction_address = NULL;
-       g_autoptr(GsApp) progress_app = NULL;
-       g_autoptr(GVariant) options = NULL;
-       g_autoptr(TransactionProgress) tp = NULL;
        g_autoptr(DnfState) state = NULL;
+       g_autoptr(GsRPMOSTreeOS) os_proxy = NULL;
+       g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
 
-       if (priv->dnf_context != NULL)
-               return TRUE;
-
-       context = create_bare_rpmostree_dnf_context (cancellable, error);
-       if (!context)
+       if (!gs_rpmostree_ref_proxies_locked (plugin, &os_proxy, &sysroot_proxy, cancellable, error))
                return FALSE;
 
-       progress_app = gs_app_new (gs_plugin_get_name (plugin));
-       tp = transaction_progress_new ();
-
-       tp->app = g_object_ref (progress_app);
-       tp->plugin = g_object_ref (plugin);
-
-       options = make_refresh_md_options_variant (FALSE /* force */);
-       if (!gs_rpmostree_os_call_refresh_md_sync (priv->os_proxy,
-                                                  options,
-                                                  &transaction_address,
-                                                  cancellable,
-                                                  error)) {
-               gs_rpmostree_error_convert (error);
-               return FALSE;
+       if (priv->dnf_context != NULL) {
+               if (out_os_proxy)
+                       *out_os_proxy = g_steal_pointer (&os_proxy);
+               if (out_sysroot_proxy)
+                       *out_sysroot_proxy = g_steal_pointer (&sysroot_proxy);
+               if (out_dnf_context)
+                       *out_dnf_context = g_object_ref (priv->dnf_context);
+               return TRUE;
        }
 
-       if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
-                                                        transaction_address,
-                                                        tp,
-                                                        cancellable,
-                                                        error)) {
-               gs_rpmostree_error_convert (error);
+       context = gs_rpmostree_create_bare_dnf_context (cancellable, error);
+       if (!context)
                return FALSE;
-       }
 
        state = dnf_state_new ();
 
@@ -719,6 +831,14 @@ ensure_rpmostree_dnf_context (GsPlugin *plugin, GCancellable *cancellable, GErro
        }
 
        g_set_object (&priv->dnf_context, context);
+
+       if (out_os_proxy)
+               *out_os_proxy = g_steal_pointer (&os_proxy);
+       if (out_sysroot_proxy)
+               *out_sysroot_proxy = g_steal_pointer (&sysroot_proxy);
+       if (out_dnf_context)
+               *out_dnf_context = g_object_ref (priv->dnf_context);
+
        return TRUE;
 }
 
@@ -728,14 +848,43 @@ gs_plugin_refresh (GsPlugin *plugin,
                    GCancellable *cancellable,
                    GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
-       g_autoptr(GMutexLocker) locker = NULL;
-
-       locker = g_mutex_locker_new (&priv->mutex);
+       g_autoptr(GsRPMOSTreeOS) os_proxy = NULL;
+       g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
 
-       if (!ensure_rpmostree_dnf_context (plugin, cancellable, error))
+       if (!gs_rpmostree_ref_proxies (plugin, &os_proxy, &sysroot_proxy, cancellable, error))
                return FALSE;
 
+       {
+               g_autofree gchar *transaction_address = NULL;
+               g_autoptr(GsApp) progress_app = NULL;
+               g_autoptr(GVariant) options = NULL;
+               g_autoptr(TransactionProgress) tp = NULL;
+
+               progress_app = gs_app_new (gs_plugin_get_name (plugin));
+               tp = transaction_progress_new ();
+               tp->app = g_object_ref (progress_app);
+               tp->plugin = g_object_ref (plugin);
+
+               options = make_refresh_md_options_variant (FALSE /* force */);
+               if (!gs_rpmostree_os_call_refresh_md_sync (os_proxy,
+                                                          options,
+                                                          &transaction_address,
+                                                          cancellable,
+                                                          error)) {
+                       gs_rpmostree_error_convert (error);
+                       return FALSE;
+               }
+
+               if (!gs_rpmostree_transaction_get_response_sync (sysroot_proxy,
+                                                                transaction_address,
+                                                                tp,
+                                                                cancellable,
+                                                                error)) {
+                       gs_rpmostree_error_convert (error);
+                       return FALSE;
+               }
+       }
+
        if (cache_age == G_MAXUINT)
                return TRUE;
 
@@ -756,7 +905,7 @@ gs_plugin_refresh (GsPlugin *plugin,
                                                          FALSE,  /* no-pull-base */
                                                          FALSE,  /* dry-run */
                                                          FALSE); /* no-overrides */
-               if (!gs_rpmostree_os_call_upgrade_sync (priv->os_proxy,
+               if (!gs_rpmostree_os_call_upgrade_sync (os_proxy,
                                                        options,
                                                        NULL /* fd list */,
                                                        &transaction_address,
@@ -767,7 +916,7 @@ gs_plugin_refresh (GsPlugin *plugin,
                        return FALSE;
                }
 
-               if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
+               if (!gs_rpmostree_transaction_get_response_sync (sysroot_proxy,
                                                                 transaction_address,
                                                                 tp,
                                                                 cancellable,
@@ -791,7 +940,7 @@ gs_plugin_refresh (GsPlugin *plugin,
                g_variant_dict_insert (&dict, "mode", "s", "check");
                options = g_variant_ref_sink (g_variant_dict_end (&dict));
 
-               if (!gs_rpmostree_os_call_automatic_update_trigger_sync (priv->os_proxy,
+               if (!gs_rpmostree_os_call_automatic_update_trigger_sync (os_proxy,
                                                                         options,
                                                                         NULL,
                                                                         &transaction_address,
@@ -801,7 +950,7 @@ gs_plugin_refresh (GsPlugin *plugin,
                        return FALSE;
                }
 
-               if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
+               if (!gs_rpmostree_transaction_get_response_sync (sysroot_proxy,
                                                                 transaction_address,
                                                                 tp,
                                                                 cancellable,
@@ -823,20 +972,24 @@ gs_plugin_add_updates (GsPlugin *plugin,
                       GCancellable *cancellable,
                       GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
        g_autoptr(GVariant) cached_update = NULL;
        g_autoptr(GVariant) rpm_diff = NULL;
+       g_autoptr(GsRPMOSTreeOS) os_proxy = NULL;
+       g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
        const gchar *checksum = NULL;
        const gchar *version = NULL;
        g_auto(GVariantDict) cached_update_dict;
 
+       if (!gs_rpmostree_ref_proxies (plugin, &os_proxy, &sysroot_proxy, cancellable, error))
+               return FALSE;
+
        /* ensure D-Bus properties are updated before reading them */
-       if (!gs_rpmostree_sysroot_call_reload_sync (priv->sysroot_proxy, cancellable, error)) {
+       if (!gs_rpmostree_sysroot_call_reload_sync (sysroot_proxy, cancellable, error)) {
                gs_rpmostree_error_convert (error);
                return FALSE;
        }
 
-       cached_update = gs_rpmostree_os_dup_cached_update (priv->os_proxy);
+       cached_update = gs_rpmostree_os_dup_cached_update (os_proxy);
        g_variant_dict_init (&cached_update_dict, cached_update);
 
        if (!g_variant_dict_lookup (&cached_update_dict, "checksum", "&s", &checksum))
@@ -933,7 +1086,9 @@ gs_plugin_add_updates (GsPlugin *plugin,
 static gboolean
 trigger_rpmostree_update (GsPlugin *plugin,
                           GsApp *app,
-                          GCancellable *cancellable,
+                         GsRPMOSTreeOS *os_proxy,
+                         GsRPMOSTreeSysroot *sysroot_proxy,
+                         GCancellable *cancellable,
                           GError **error)
 {
        GsPluginData *priv = gs_plugin_get_data (plugin);
@@ -962,7 +1117,7 @@ trigger_rpmostree_update (GsPlugin *plugin,
                                                  FALSE,  /* no-pull-base */
                                                  FALSE,  /* dry-run */
                                                  FALSE); /* no-overrides */
-       if (!gs_rpmostree_os_call_upgrade_sync (priv->os_proxy,
+       if (!gs_rpmostree_os_call_upgrade_sync (os_proxy,
                                                options,
                                                NULL /* fd list */,
                                                &transaction_address,
@@ -973,7 +1128,7 @@ trigger_rpmostree_update (GsPlugin *plugin,
                return FALSE;
        }
 
-       if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
+       if (!gs_rpmostree_transaction_get_response_sync (sysroot_proxy,
                                                         transaction_address,
                                                         tp,
                                                         cancellable,
@@ -995,15 +1150,20 @@ gs_plugin_update_app (GsPlugin *plugin,
                       GError **error)
 {
        GsAppList *related = gs_app_get_related (app);
+       g_autoptr(GsRPMOSTreeOS) os_proxy = NULL;
+       g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
+
+       if (!gs_rpmostree_ref_proxies (plugin, &os_proxy, &sysroot_proxy, cancellable, error))
+               return FALSE;
 
        /* we don't currently don't put all updates in the OsUpdate proxy app */
        if (!gs_app_has_quirk (app, GS_APP_QUIRK_IS_PROXY))
-               return trigger_rpmostree_update (plugin, app, cancellable, error);
+               return trigger_rpmostree_update (plugin, app, os_proxy, sysroot_proxy, cancellable, error);
 
        /* try to trigger each related app */
        for (guint i = 0; i < gs_app_list_length (related); i++) {
                GsApp *app_tmp = gs_app_list_index (related, i);
-               if (!trigger_rpmostree_update (plugin, app_tmp, cancellable, error))
+               if (!trigger_rpmostree_update (plugin, app_tmp, os_proxy, sysroot_proxy, cancellable, error))
                        return FALSE;
        }
 
@@ -1017,12 +1177,13 @@ gs_plugin_app_upgrade_trigger (GsPlugin *plugin,
                                GCancellable *cancellable,
                                GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
        const char *packages[] = { NULL };
        g_autofree gchar *new_refspec = NULL;
        g_autofree gchar *transaction_address = NULL;
        g_autoptr(GVariant) options = NULL;
        g_autoptr(TransactionProgress) tp = transaction_progress_new ();
+       g_autoptr(GsRPMOSTreeOS) os_proxy = NULL;
+       g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
 
        /* only process this app if was created by this plugin */
        if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0)
@@ -1032,6 +1193,9 @@ gs_plugin_app_upgrade_trigger (GsPlugin *plugin,
        if (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM)
                return TRUE;
 
+       if (!gs_rpmostree_ref_proxies (plugin, &os_proxy, &sysroot_proxy, cancellable, error))
+               return FALSE;
+
        /* construct new refspec based on the distro version we're upgrading to */
        new_refspec = g_strdup_printf ("ostree://fedora/%s/x86_64/silverblue",
                                       gs_app_get_version (app));
@@ -1046,7 +1210,7 @@ gs_plugin_app_upgrade_trigger (GsPlugin *plugin,
                                                  FALSE,  /* dry-run */
                                                  FALSE); /* no-overrides */
 
-       if (!gs_rpmostree_os_call_rebase_sync (priv->os_proxy,
+       if (!gs_rpmostree_os_call_rebase_sync (os_proxy,
                                               options,
                                               new_refspec,
                                               packages,
@@ -1059,7 +1223,7 @@ gs_plugin_app_upgrade_trigger (GsPlugin *plugin,
                return FALSE;
        }
 
-       if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
+       if (!gs_rpmostree_transaction_get_response_sync (sysroot_proxy,
                                                         transaction_address,
                                                         tp,
                                                         cancellable,
@@ -1080,13 +1244,14 @@ gs_plugin_app_upgrade_trigger (GsPlugin *plugin,
 }
 
 static gboolean
-gs_plugin_repo_enable (GsPlugin *plugin,
-                       GsApp *app,
-                       gboolean enable,
-                       GCancellable *cancellable,
-                       GError **error)
+gs_rpmostree_repo_enable (GsPlugin *plugin,
+                         GsApp *app,
+                         gboolean enable,
+                         GsRPMOSTreeOS *os_proxy,
+                         GsRPMOSTreeSysroot *sysroot_proxy,
+                         GCancellable *cancellable,
+                         GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
        g_autofree gchar *transaction_address = NULL;
        g_autoptr(GVariantBuilder) options_builder = NULL;
        g_autoptr(TransactionProgress) tp = NULL;
@@ -1098,7 +1263,7 @@ gs_plugin_repo_enable (GsPlugin *plugin,
 
        options_builder = g_variant_builder_new (G_VARIANT_TYPE ("a{ss}"));
        g_variant_builder_add (options_builder, "{ss}", "enabled", enable ? "1" : "0");
-       if (!gs_rpmostree_os_call_modify_yum_repo_sync (priv->os_proxy,
+       if (!gs_rpmostree_os_call_modify_yum_repo_sync (os_proxy,
                                                        gs_app_get_id (app),
                                                        g_variant_builder_end (options_builder),
                                                        &transaction_address,
@@ -1112,7 +1277,7 @@ gs_plugin_repo_enable (GsPlugin *plugin,
 
        tp = transaction_progress_new ();
        tp->app = g_object_ref (app);
-       if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
+       if (!gs_rpmostree_transaction_get_response_sync (sysroot_proxy,
                                                         transaction_address,
                                                         tp,
                                                         cancellable,
@@ -1141,20 +1306,25 @@ gs_plugin_app_install (GsPlugin *plugin,
                        GCancellable *cancellable,
                        GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
        const gchar *install_package = NULL;
        g_autofree gchar *local_filename = NULL;
        g_autofree gchar *transaction_address = NULL;
        g_autoptr(GVariant) options = NULL;
        g_autoptr(TransactionProgress) tp = transaction_progress_new ();
+       g_autoptr(GMutexLocker) locker = NULL;
+       g_autoptr(GsRPMOSTreeOS) os_proxy = NULL;
+       g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
 
        /* only process this app if was created by this plugin */
        if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0)
                return TRUE;
 
+       if (!gs_rpmostree_ref_proxies (plugin, &os_proxy, &sysroot_proxy, cancellable, error))
+               return FALSE;
+
        /* enable repo */
        if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
-               return gs_plugin_repo_enable (plugin, app, TRUE, cancellable, error);
+               return gs_rpmostree_repo_enable (plugin, app, TRUE, os_proxy, sysroot_proxy, cancellable, 
error);
 
        switch (gs_app_get_state (app)) {
        case GS_APP_STATE_AVAILABLE:
@@ -1200,7 +1370,7 @@ gs_plugin_app_install (GsPlugin *plugin,
                                                  FALSE,  /* dry-run */
                                                  FALSE); /* no-overrides */
 
-       if (!rpmostree_update_deployment (priv->os_proxy,
+       if (!rpmostree_update_deployment (os_proxy,
                                          install_package,
                                          NULL /* remove package */,
                                          local_filename,
@@ -1213,7 +1383,7 @@ gs_plugin_app_install (GsPlugin *plugin,
                return FALSE;
        }
 
-       if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
+       if (!gs_rpmostree_transaction_get_response_sync (sysroot_proxy,
                                                         transaction_address,
                                                         tp,
                                                         cancellable,
@@ -1242,18 +1412,22 @@ gs_plugin_app_remove (GsPlugin *plugin,
                       GCancellable *cancellable,
                       GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
        g_autofree gchar *transaction_address = NULL;
        g_autoptr(GVariant) options = NULL;
        g_autoptr(TransactionProgress) tp = transaction_progress_new ();
+       g_autoptr(GsRPMOSTreeOS) os_proxy = NULL;
+       g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
 
        /* only process this app if was created by this plugin */
        if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0)
                return TRUE;
 
+       if (!gs_rpmostree_ref_proxies (plugin, &os_proxy, &sysroot_proxy, cancellable, error))
+               return FALSE;
+
        /* disable repo */
        if (gs_app_get_kind (app) == AS_COMPONENT_KIND_REPOSITORY)
-               return gs_plugin_repo_enable (plugin, app, FALSE, cancellable, error);
+               return gs_rpmostree_repo_enable (plugin, app, FALSE, os_proxy, sysroot_proxy, cancellable, 
error);
 
        gs_app_set_state (app, GS_APP_STATE_REMOVING);
        tp->app = g_object_ref (app);
@@ -1267,7 +1441,7 @@ gs_plugin_app_remove (GsPlugin *plugin,
                                                  FALSE,  /* dry-run */
                                                  FALSE); /* no-overrides */
 
-       if (!rpmostree_update_deployment (priv->os_proxy,
+       if (!rpmostree_update_deployment (os_proxy,
                                          NULL /* install package */,
                                          gs_app_get_source_default (app),
                                          NULL /* install local package */,
@@ -1280,7 +1454,7 @@ gs_plugin_app_remove (GsPlugin *plugin,
                return FALSE;
        }
 
-       if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
+       if (!gs_rpmostree_transaction_get_response_sync (sysroot_proxy,
                                                         transaction_address,
                                                         tp,
                                                         cancellable,
@@ -1472,19 +1646,33 @@ gs_plugin_refine (GsPlugin *plugin,
        g_autoptr(GMutexLocker) locker = NULL;
        g_autoptr(GPtrArray) pkglist = NULL;
        g_autoptr(GVariant) default_deployment = NULL;
+       g_autoptr(GsRPMOSTreeOS) os_proxy = NULL;
+       g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
+       g_autoptr(DnfContext) dnf_context = NULL;
+       g_autoptr(OstreeRepo) ot_repo = NULL;
        g_auto(GStrv) layered_packages = NULL;
        g_auto(GStrv) layered_local_packages = NULL;
        g_autofree gchar *checksum = NULL;
 
        locker = g_mutex_locker_new (&priv->mutex);
 
+       if (!gs_rpmostree_ref_dnf_context_locked (plugin, &os_proxy, &sysroot_proxy, &dnf_context, 
cancellable, error))
+               return FALSE;
+
+       ot_repo = g_object_ref (priv->ot_repo);
+
+       if (!dnf_context)
+               return FALSE;
+
+       g_clear_pointer (&locker, g_mutex_locker_free);
+
        /* ensure D-Bus properties are updated before reading them */
-       if (!gs_rpmostree_sysroot_call_reload_sync (priv->sysroot_proxy, cancellable, error)) {
+       if (!gs_rpmostree_sysroot_call_reload_sync (sysroot_proxy, cancellable, error)) {
                gs_rpmostree_error_convert (error);
                return FALSE;
        }
 
-       default_deployment = gs_rpmostree_os_dup_default_deployment (priv->os_proxy);
+       default_deployment = gs_rpmostree_os_dup_default_deployment (os_proxy);
        g_assert (g_variant_lookup (default_deployment,
                                    "packages", "^as",
                                    &layered_packages));
@@ -1495,7 +1683,7 @@ gs_plugin_refine (GsPlugin *plugin,
                                    "checksum", "s",
                                    &checksum));
 
-       pkglist = rpm_ostree_db_query_all (priv->ot_repo, checksum, cancellable, error);
+       pkglist = rpm_ostree_db_query_all (ot_repo, checksum, cancellable, error);
        if (pkglist == NULL) {
                gs_rpmostree_error_convert (error);
                return FALSE;
@@ -1533,8 +1721,8 @@ gs_plugin_refine (GsPlugin *plugin,
                found = resolve_installed_packages_app (plugin, pkglist, layered_packages, 
layered_local_packages, app);
 
                /* if we didn't find anything, try resolving from available packages */
-               if (!found && priv->dnf_context != NULL)
-                       found = resolve_available_packages_app (plugin, dnf_context_get_sack 
(priv->dnf_context), app);
+               if (!found && dnf_context != NULL)
+                       found = resolve_available_packages_app (plugin, dnf_context_get_sack (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 */
@@ -1551,12 +1739,13 @@ gs_plugin_app_upgrade_download (GsPlugin *plugin,
                                 GCancellable *cancellable,
                                 GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
        const char *packages[] = { NULL };
        g_autofree gchar *new_refspec = NULL;
        g_autofree gchar *transaction_address = NULL;
        g_autoptr(GVariant) options = NULL;
        g_autoptr(TransactionProgress) tp = transaction_progress_new ();
+       g_autoptr(GsRPMOSTreeOS) os_proxy = NULL;
+       g_autoptr(GsRPMOSTreeSysroot) sysroot_proxy = NULL;
 
        /* only process this app if was created by this plugin */
        if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0)
@@ -1566,6 +1755,9 @@ gs_plugin_app_upgrade_download (GsPlugin *plugin,
        if (gs_app_get_kind (app) != AS_COMPONENT_KIND_OPERATING_SYSTEM)
                return TRUE;
 
+       if (!gs_rpmostree_ref_proxies (plugin, &os_proxy, &sysroot_proxy, cancellable, error))
+               return FALSE;
+
        /* construct new refspec based on the distro version we're upgrading to */
        new_refspec = g_strdup_printf ("ostree://fedora/%s/x86_64/silverblue",
                                       gs_app_get_version (app));
@@ -1582,7 +1774,7 @@ gs_plugin_app_upgrade_download (GsPlugin *plugin,
        gs_app_set_state (app, GS_APP_STATE_INSTALLING);
        tp->app = g_object_ref (app);
 
-       if (!gs_rpmostree_os_call_rebase_sync (priv->os_proxy,
+       if (!gs_rpmostree_os_call_rebase_sync (os_proxy,
                                               options,
                                               new_refspec,
                                               packages,
@@ -1596,7 +1788,7 @@ gs_plugin_app_upgrade_download (GsPlugin *plugin,
                return FALSE;
        }
 
-       if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy,
+       if (!gs_rpmostree_transaction_get_response_sync (sysroot_proxy,
                                                         transaction_address,
                                                         tp,
                                                         cancellable,
@@ -1787,15 +1979,18 @@ gs_plugin_add_search_what_provides (GsPlugin *plugin,
        GsPluginData *priv = gs_plugin_get_data (plugin);
        g_autoptr(GMutexLocker) locker = NULL;
        g_autoptr(GPtrArray) pkglist = NULL;
+       g_autoptr(DnfContext) dnf_context = NULL;
        g_auto(GStrv) provides = NULL;
 
        locker = g_mutex_locker_new (&priv->mutex);
 
-       if (priv->dnf_context == NULL)
-               return TRUE;
+       if (!gs_rpmostree_ref_dnf_context_locked (plugin, NULL, NULL, &dnf_context, cancellable, error))
+               return FALSE;
+
+       g_clear_pointer (&locker, g_mutex_locker_free);
 
        provides = what_provides_decompose (search);
-       pkglist = find_packages_by_provides (dnf_context_get_sack (priv->dnf_context), provides);
+       pkglist = find_packages_by_provides (dnf_context_get_sack (dnf_context), provides);
        for (guint i = 0; i < pkglist->len; i++) {
                DnfPackage *pkg = g_ptr_array_index (pkglist, i);
                g_autoptr(GsApp) app = NULL;
@@ -1830,18 +2025,12 @@ gs_plugin_add_sources (GsPlugin *plugin,
                       GCancellable *cancellable,
                       GError **error)
 {
-       GsPluginData *priv = gs_plugin_get_data (plugin);
-       g_autoptr(GMutexLocker) locker = NULL;
        g_autoptr(DnfContext) dnf_context = NULL;
        GPtrArray *repos;
 
-       locker = g_mutex_locker_new (&priv->mutex);
-
-       dnf_context = create_bare_rpmostree_dnf_context (cancellable, error);
-       if (!dnf_context) {
-               gs_rpmostree_error_convert (error);
+       dnf_context = gs_rpmostree_create_bare_dnf_context (cancellable, error);
+       if (!dnf_context)
                return FALSE;
-       }
 
        repos = dnf_context_get_repos (dnf_context);
        if (repos == NULL)


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