[gnome-software: 1/2] flatpak: Ignore FLATPAK_ERROR_ALREADY_INSTALLED when installing apps




commit c1a95c954a396a2d9d296143fb45b374e98835a1
Author: Philip Withnall <withnall endlessm com>
Date:   Wed Jul 3 15:32:10 2019 +0100

    flatpak: Ignore FLATPAK_ERROR_ALREADY_INSTALLED when installing apps
    
    Somehow, sometimes, it might be possible for the state in gnome-software
    to be out of date, and hence for g-s to start installing an app which is
    actually already installed.
    
    If that happens for an app, libflatpak will return
    `FLATPAK_ERROR_ALREADY_INSTALLED` from
    `flatpak_transaction_add_install()`. If it happens for a flatpakref or a
    bundle, libflatpak will return the error from
    `flatpak_transaction_run()` instead (since it needs to resolve the
    flatpakrefs and bundles to refs before it can determine whether they’re
    already installed).
    
    Handle both of those cases in the flatpak plugin, marking the app as
    installed if libflatpak returns that error code. The handling of it is
    not especially pretty, since it needs to still fall through and refresh
    the `GsApp` after marking it as installed.
    
    Based on a downstream commit by Joaquim Rocha <jrocha endlessm com>.
    
    Signed-off-by: Philip Withnall <withnall endlessm com>

 plugins/flatpak/gs-plugin-flatpak.c | 43 +++++++++++++++++++++++++++++--------
 1 file changed, 34 insertions(+), 9 deletions(-)
---
diff --git a/plugins/flatpak/gs-plugin-flatpak.c b/plugins/flatpak/gs-plugin-flatpak.c
index e3d7805e..20ca8380 100644
--- a/plugins/flatpak/gs-plugin-flatpak.c
+++ b/plugins/flatpak/gs-plugin-flatpak.c
@@ -816,6 +816,7 @@ gs_plugin_app_install (GsPlugin *plugin,
        g_autoptr(FlatpakTransaction) transaction = NULL;
        g_autoptr(GError) error_local = NULL;
        gpointer schedule_entry_handle = NULL;
+       gboolean already_installed = FALSE;
 
        /* queue for install if installation needs the network */
        if (!app_has_local_source (app) &&
@@ -905,9 +906,17 @@ gs_plugin_app_install (GsPlugin *plugin,
                g_autofree gchar *ref = gs_flatpak_app_get_ref_display (app);
                if (!flatpak_transaction_add_install (transaction,
                                                      gs_app_get_origin (app),
-                                                     ref, NULL, error)) {
-                       gs_flatpak_error_convert (error);
-                       return FALSE;
+                                                     ref, NULL, &error_local)) {
+                       /* Somehow, the app might already be installed. */
+                       if (g_error_matches (error_local, FLATPAK_ERROR,
+                                            FLATPAK_ERROR_ALREADY_INSTALLED)) {
+                               already_installed = TRUE;
+                               g_clear_error (&error_local);
+                       } else {
+                               g_propagate_error (error, g_steal_pointer (&error_local));
+                               gs_flatpak_error_convert (error);
+                               return FALSE;
+                       }
                }
        }
 
@@ -923,12 +932,28 @@ gs_plugin_app_install (GsPlugin *plugin,
        }
 
        /* run transaction */
-       gs_app_set_state (app, GS_APP_STATE_INSTALLING);
-       if (!gs_flatpak_transaction_run (transaction, cancellable, error)) {
-               gs_flatpak_error_convert (error);
-               gs_app_set_state_recover (app);
-               remove_schedule_entry (schedule_entry_handle);
-               return FALSE;
+       if (!already_installed) {
+               gs_app_set_state (app, GS_APP_STATE_INSTALLING);
+               if (!gs_flatpak_transaction_run (transaction, cancellable, &error_local)) {
+                       /* Somehow, the app might already be installed. */
+                       if (g_error_matches (error_local, FLATPAK_ERROR,
+                                            FLATPAK_ERROR_ALREADY_INSTALLED)) {
+                               already_installed = TRUE;
+                               g_clear_error (&error_local);
+                       } else {
+                               g_propagate_error (error, g_steal_pointer (&error_local));
+                               gs_flatpak_error_convert (error);
+                               gs_app_set_state_recover (app);
+                               remove_schedule_entry (schedule_entry_handle);
+                               return FALSE;
+                       }
+               }
+       }
+
+       if (already_installed) {
+               /* Set the app back to UNKNOWN so that refining it gets all the right details. */
+               g_debug ("App %s is already installed", gs_app_get_unique_id (app));
+               gs_app_set_state (app, GS_APP_STATE_UNKNOWN);
        }
 
        remove_schedule_entry (schedule_entry_handle);


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