[gnome-software/uajain/set-no-pull-autoupdate: 14/14] flatpak: Use --no-pull flag if update bits are downloaded already



commit 89ef19dbea4a7480a9493b7cf26e27635bcce405
Author: Umang Jain <umang endlessm com>
Date:   Fri Oct 4 12:40:15 2019 +0530

    flatpak: Use --no-pull flag if update bits are downloaded already
    
    Autoupdates code path is essentially a GS_PLUGIN_ACTION_DOWNLOAD
    followed by a GS_PLUGIN_ACTION_UPDATE action. The download action
    sets the --no-deploy flag on the transaction so that all the
    update gets downloaded to local cache but does not get deployed (yet).
    
    Hence, the follow-up upate action should just primarily execute the
    deployment phase for the downloads fetched via GS_PLUGIN_ACTION_DOWNLOAD.
    Flatpak-cli equivalent is : flatpak update --no-pull
    
    It was discovered that this wasn't the case in gnome-software.
    Without the --no-pull flag in autoupdates case, GS_PLUGIN_ACTION_UPDATE
    will try to fetch/query the outstanding updates again.
    Hence, mark the transaction with --no-pull if we already know
    that the update bits are already downloaded and available locally.
    
    The bug was noticed while investigating a larger problem in
    https://gitlab.gnome.org/GNOME/gnome-software/issues/819

 lib/gs-plugin-job-private.h         |  1 +
 lib/gs-plugin-job.c                 | 27 +++++++++++++++++++++++++++
 lib/gs-plugin-job.h                 |  2 ++
 lib/gs-plugin-loader.c              |  2 ++
 lib/gs-plugin-types.h               |  2 ++
 plugins/flatpak/gs-plugin-flatpak.c |  4 ++++
 src/gs-update-monitor.c             |  1 +
 7 files changed, 39 insertions(+)
---
diff --git a/lib/gs-plugin-job-private.h b/lib/gs-plugin-job-private.h
index 0fa0d2d0..3e291774 100644
--- a/lib/gs-plugin-job-private.h
+++ b/lib/gs-plugin-job-private.h
@@ -24,6 +24,7 @@ void                   gs_plugin_job_add_refine_flags         (GsPluginJob    *self,
 void                    gs_plugin_job_remove_refine_flags      (GsPluginJob    *self,
                                                                 GsPluginRefineFlags refine_flags);
 gboolean                gs_plugin_job_get_interactive          (GsPluginJob    *self);
+gboolean                gs_plugin_job_get_is_downloaded        (GsPluginJob    *self);
 guint                   gs_plugin_job_get_max_results          (GsPluginJob    *self);
 guint                   gs_plugin_job_get_timeout              (GsPluginJob    *self);
 guint64                         gs_plugin_job_get_age                  (GsPluginJob    *self);
diff --git a/lib/gs-plugin-job.c b/lib/gs-plugin-job.c
index 36dc6bea..8e42a30d 100644
--- a/lib/gs-plugin-job.c
+++ b/lib/gs-plugin-job.c
@@ -20,6 +20,7 @@ struct _GsPluginJob
        GsPluginRefineFlags      filter_flags;
        GsAppListFilterFlags     dedupe_flags;
        gboolean                 interactive;
+       gboolean                 is_downloaded;
        guint                    max_results;
        guint                    timeout;
        guint64                  age;
@@ -52,6 +53,7 @@ enum {
        PROP_REVIEW,
        PROP_MAX_RESULTS,
        PROP_TIMEOUT,
+       PROP_IS_DOWNLOADED,
        PROP_LAST
 };
 
@@ -76,6 +78,8 @@ gs_plugin_job_to_string (GsPluginJob *self)
        }
        if (self->interactive)
                g_string_append_printf (str, " with interactive=True");
+       if (self->is_downloaded)
+               g_string_append_printf (str, " with is-downloaded=True");
        if (self->timeout > 0)
                g_string_append_printf (str, " with timeout=%u", self->timeout);
        if (self->max_results > 0)
@@ -210,6 +214,20 @@ gs_plugin_job_get_interactive (GsPluginJob *self)
        return self->interactive;
 }
 
+void
+gs_plugin_job_set_is_downloaded (GsPluginJob *self, gboolean is_downloaded)
+{
+       g_return_if_fail (GS_IS_PLUGIN_JOB (self));
+       self->is_downloaded = is_downloaded;
+}
+
+gboolean
+gs_plugin_job_get_is_downloaded (GsPluginJob *self)
+{
+       g_return_val_if_fail (GS_IS_PLUGIN_JOB (self), FALSE);
+       return self->is_downloaded;
+}
+
 void
 gs_plugin_job_set_max_results (GsPluginJob *self, guint max_results)
 {
@@ -447,6 +465,9 @@ gs_plugin_job_get_property (GObject *obj, guint prop_id, GValue *value, GParamSp
        case PROP_TIMEOUT:
                g_value_set_uint (value, self->timeout);
                break;
+       case PROP_IS_DOWNLOADED:
+               g_value_set_boolean (value, self->is_downloaded);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
                break;
@@ -501,6 +522,9 @@ gs_plugin_job_set_property (GObject *obj, guint prop_id, const GValue *value, GP
        case PROP_TIMEOUT:
                gs_plugin_job_set_timeout (self, g_value_get_uint (value));
                break;
+       case PROP_IS_DOWNLOADED:
+               gs_plugin_job_set_is_downloaded (self, g_value_get_boolean (value));
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
                break;
@@ -601,6 +625,9 @@ gs_plugin_job_class_init (GsPluginJobClass *klass)
        pspec = g_param_spec_uint ("timeout", NULL, NULL,
                                   0, G_MAXUINT, 60,
                                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+       pspec = g_param_spec_boolean ("is-downloaded", NULL, NULL,
+                                     FALSE,
+                                     G_PARAM_READWRITE);
        g_object_class_install_property (object_class, PROP_TIMEOUT, pspec);
 }
 
diff --git a/lib/gs-plugin-job.h b/lib/gs-plugin-job.h
index 5100fdf0..efe5b0f3 100644
--- a/lib/gs-plugin-job.h
+++ b/lib/gs-plugin-job.h
@@ -27,6 +27,8 @@ void           gs_plugin_job_set_dedupe_flags         (GsPluginJob    *self,
                                                         GsAppListFilterFlags dedupe_flags);
 void            gs_plugin_job_set_interactive          (GsPluginJob    *self,
                                                         gboolean        interactive);
+void            gs_plugin_job_set_is_downloaded        (GsPluginJob    *self,
+                                                        gboolean        is_downloaded);
 void            gs_plugin_job_set_max_results          (GsPluginJob    *self,
                                                         guint           max_results);
 void            gs_plugin_job_set_timeout              (GsPluginJob    *self,
diff --git a/lib/gs-plugin-loader.c b/lib/gs-plugin-loader.c
index ebc05ba9..ce4be165 100644
--- a/lib/gs-plugin-loader.c
+++ b/lib/gs-plugin-loader.c
@@ -556,6 +556,8 @@ gs_plugin_loader_call_vfunc (GsPluginLoaderHelper *helper,
                }
                break;
        case GS_PLUGIN_ACTION_UPDATE:
+               if (gs_plugin_job_get_is_downloaded (helper->plugin_job))
+                       gs_plugin_add_flags (plugin, GS_PLUGIN_FLAGS_IS_DOWNLOADED);
                if (g_strcmp0 (helper->function_name, "gs_plugin_update_app") == 0) {
                        GsPluginActionFunc plugin_func = func;
                        ret = plugin_func (plugin, app, cancellable, &error_local);
diff --git a/lib/gs-plugin-types.h b/lib/gs-plugin-types.h
index d6d30d52..60d21322 100644
--- a/lib/gs-plugin-types.h
+++ b/lib/gs-plugin-types.h
@@ -41,11 +41,13 @@ typedef enum {
  * GsPluginFlags:
  * @GS_PLUGIN_FLAGS_NONE:              No flags set
  * @GS_PLUGIN_FLAGS_INTERACTIVE:       User initiated the job
+ * @GS_PLUGIN_FLAGS_IS_DOWNLOADED      Bits for updates are already downloaded.
  *
  * The flags for the plugin at this point in time.
  **/
 #define GS_PLUGIN_FLAGS_NONE           (0u)
 #define GS_PLUGIN_FLAGS_INTERACTIVE    (1u << 4)
+#define GS_PLUGIN_FLAGS_IS_DOWNLOADED  (1u << 8)
 typedef guint64 GsPluginFlags;
 
 /**
diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c
index 628d2da2..e393a287 100644
--- a/plugins/flatpak/gs-plugin-flatpak.c
+++ b/plugins/flatpak/gs-plugin-flatpak.c
@@ -741,6 +741,7 @@ gs_plugin_flatpak_update (GsPlugin *plugin,
                          GError **error)
 {
        g_autoptr(FlatpakTransaction) transaction = NULL;
+       gboolean is_downloaded = gs_plugin_has_flags (plugin, GS_PLUGIN_FLAGS_IS_DOWNLOADED);
 
        /* build and run transaction */
        transaction = _build_transaction (plugin, flatpak, cancellable, error);
@@ -749,6 +750,9 @@ gs_plugin_flatpak_update (GsPlugin *plugin,
                return FALSE;
        }
 
+       if (is_downloaded)
+               flatpak_transaction_set_no_pull (transaction, TRUE);
+
        for (guint i = 0; i < gs_app_list_length (list_tmp); i++) {
                GsApp *app = gs_app_list_index (list_tmp, i);
                g_autofree gchar *ref = NULL;
diff --git a/src/gs-update-monitor.c b/src/gs-update-monitor.c
index c55b1536..20769fa4 100644
--- a/src/gs-update-monitor.c
+++ b/src/gs-update-monitor.c
@@ -366,6 +366,7 @@ download_finished_cb (GObject *object, GAsyncResult *res, gpointer data)
                g_autoptr(GsPluginJob) plugin_job = NULL;
                plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_UPDATE,
                                                 "list", update_online,
+                                                "is-downloaded", TRUE,
                                                 NULL);
                gs_plugin_loader_job_process_async (monitor->plugin_loader,
                                                    plugin_job,


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