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



commit 193414b38b5411b778d25fee74412bbc547cb988
Author: Umang Jain <mailumangjain gmail com>
Date:   Mon Nov 11 23:38:26 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 update 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 #819.

 lib/gs-app.c                        | 50 +++++++++++++++++++++++++++++++++++++
 lib/gs-app.h                        |  3 +++
 plugins/flatpak/gs-plugin-flatpak.c | 17 +++++++++++++
 3 files changed, 70 insertions(+)
---
diff --git a/lib/gs-app.c b/lib/gs-app.c
index 3b556c94..69b33d73 100644
--- a/lib/gs-app.c
+++ b/lib/gs-app.c
@@ -115,6 +115,7 @@ typedef struct
        GCancellable            *cancellable;
        GsPluginAction           pending_action;
        GsAppPermissions         permissions;
+       gboolean                 is_update_downloaded;
 } GsAppPrivate;
 
 enum {
@@ -133,6 +134,7 @@ enum {
        PROP_QUIRK,
        PROP_PENDING_ACTION,
        PROP_KEY_COLORS,
+       PROP_IS_UPDATE_DOWNLOADED,
        PROP_LAST
 };
 
@@ -3573,6 +3575,42 @@ gs_app_remove_category (GsApp *app, const gchar *category)
        return FALSE;
 }
 
+/**
+ * gs_app_set_is_update_downloaded:
+ * @app: a #GsApp
+ * @is_update_downloaded: Whether a new update is already downloaded locally
+ *
+ * Sets if the new update is already downloaded for the app.
+ *
+ * Since: 3.36
+ **/
+void
+gs_app_set_is_update_downloaded (GsApp *app, gboolean is_update_downloaded)
+{
+       GsAppPrivate *priv = gs_app_get_instance_private (app);
+       g_return_if_fail (GS_IS_APP (app));
+       priv->is_update_downloaded = is_update_downloaded;
+}
+
+/**
+ * gs_app_get_is_update_downloaded:
+ * @app: a #GsApp
+ *
+ * Gets if the new update is already downloaded for the app and
+ * is locally available.
+ *
+ * Returns: (element-type gboolean): Whether a new update for the #GsApp is already downloaded.
+ *
+ * Since: 3.36
+ **/
+gboolean
+gs_app_get_is_update_downloaded (GsApp *app)
+{
+       GsAppPrivate *priv = gs_app_get_instance_private (app);
+       g_return_val_if_fail (GS_IS_APP (app), FALSE);
+       return priv->is_update_downloaded;
+}
+
 /**
  * gs_app_get_key_colors:
  * @app: a #GsApp
@@ -4053,6 +4091,9 @@ gs_app_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *
        case PROP_KEY_COLORS:
                g_value_set_boxed (value, priv->key_colors);
                break;
+       case PROP_IS_UPDATE_DOWNLOADED:
+               g_value_set_boolean (value, priv->is_update_downloaded);
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -4111,6 +4152,9 @@ gs_app_set_property (GObject *object, guint prop_id, const GValue *value, GParam
        case PROP_KEY_COLORS:
                gs_app_set_key_colors (app, g_value_get_boxed (value));
                break;
+       case PROP_IS_UPDATE_DOWNLOADED:
+               gs_app_set_is_update_downloaded (app, g_value_get_boolean (value));
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -4305,6 +4349,12 @@ gs_app_class_init (GsAppClass *klass)
        pspec = g_param_spec_boxed ("key-colors", NULL, NULL,
                                    G_TYPE_PTR_ARRAY, G_PARAM_READWRITE);
        g_object_class_install_property (object_class, PROP_KEY_COLORS, pspec);
+
+       pspec = g_param_spec_boolean ("is-update-downloaded", NULL, NULL,
+                                     FALSE,
+                                     G_PARAM_READWRITE);
+       g_object_class_install_property (object_class, PROP_IS_UPDATE_DOWNLOADED, pspec);
+
 }
 
 static void
diff --git a/lib/gs-app.h b/lib/gs-app.h
index 6a67dcd5..6f238966 100644
--- a/lib/gs-app.h
+++ b/lib/gs-app.h
@@ -340,6 +340,9 @@ void                 gs_app_set_key_colors          (GsApp          *app,
                                                 GPtrArray      *key_colors);
 void            gs_app_add_key_color           (GsApp          *app,
                                                 GdkRGBA        *key_color);
+void            gs_app_set_is_update_downloaded (GsApp         *app,
+                                                 gboolean       is_update_downloaded);
+gboolean        gs_app_get_is_update_downloaded (GsApp         *app);
 gboolean        gs_app_has_category            (GsApp          *app,
                                                 const gchar    *category);
 void            gs_app_add_category            (GsApp          *app,
diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c
index 628d2da2..faf52c96 100644
--- a/plugins/flatpak/gs-plugin-flatpak.c
+++ b/plugins/flatpak/gs-plugin-flatpak.c
@@ -526,6 +526,13 @@ gs_plugin_download (GsPlugin *plugin, GsAppList *list,
                        gs_flatpak_error_convert (error);
                        return FALSE;
                }
+
+               /* Traverse over the GsAppList again and set that the update has been already downloaded
+                * for the apps. */
+               for (guint i = 0; i < gs_app_list_length (list_tmp); i++) {
+                       GsApp *app = gs_app_list_index (list_tmp, i);
+                       gs_app_set_is_update_downloaded (app, TRUE);
+               }
        }
 
        return TRUE;
@@ -741,6 +748,7 @@ gs_plugin_flatpak_update (GsPlugin *plugin,
                          GError **error)
 {
        g_autoptr(FlatpakTransaction) transaction = NULL;
+       gboolean is_update_downloaded = TRUE;
 
        /* build and run transaction */
        transaction = _build_transaction (plugin, flatpak, cancellable, error);
@@ -764,7 +772,16 @@ gs_plugin_flatpak_update (GsPlugin *plugin,
        for (guint i = 0; i < gs_app_list_length (list_tmp); i++) {
                GsApp *app = gs_app_list_index (list_tmp, i);
                gs_app_set_state (app, AS_APP_STATE_INSTALLING);
+
+               /* If all apps' update are previously downloaded and available locally,
+                * FlatpakTransaction should run with no-pull flag. This is the case
+                * for apps' autoupdates. */
+               is_update_downloaded &= gs_app_get_is_update_downloaded (app);
        }
+
+       if (is_update_downloaded)
+               flatpak_transaction_set_no_pull (transaction, TRUE);
+
        if (!gs_flatpak_transaction_run (transaction, cancellable, error)) {
                for (guint i = 0; i < gs_app_list_length (list_tmp); i++) {
                        GsApp *app = gs_app_list_index (list_tmp, i);


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