[gnome-software] Install the runtime as part of the application install phase



commit 16d2e24d3407e39ac72eff1ccc5632fe7837a072
Author: Richard Hughes <richard hughsie com>
Date:   Mon Jul 17 19:25:58 2017 +0100

    Install the runtime as part of the application install phase

 plugins/flatpak/gs-flatpak.c   |  202 ++++++++++++++++++----------------------
 plugins/flatpak/gs-self-test.c |   13 ++-
 2 files changed, 99 insertions(+), 116 deletions(-)
---
diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c
index 63d5d36..1997b8b 100644
--- a/plugins/flatpak/gs-flatpak.c
+++ b/plugins/flatpak/gs-flatpak.c
@@ -2344,10 +2344,74 @@ gs_flatpak_related_should_download (GsFlatpak *self, GsApp *app, FlatpakRelatedR
        return flatpak_related_ref_should_download (xref_related);
 }
 
+static gboolean
+gs_flatpak_refine_runtime_for_install (GsFlatpak *self,
+                                      GsApp *app,
+                                      GCancellable *cancellable,
+                                      GError **error)
+{
+       GsApp *runtime;
+
+       /* only required for ostree-based flatpak apps */
+       if (gs_flatpak_app_get_file_kind (app) == GS_FLATPAK_APP_FILE_KIND_BUNDLE) {
+               gsize len;
+               const gchar *str;
+               g_autoptr(GBytes) data = NULL;
+               g_autoptr(GsApp) runtime_new = NULL;
+
+               data = gs_flatpak_fetch_remote_metadata (self, app, cancellable, error);
+               if (data == NULL) {
+                       gs_utils_error_add_unique_id (error, app);
+                       return FALSE;
+               }
+
+               str = g_bytes_get_data (data, &len);
+               runtime_new = gs_flatpak_create_runtime_from_metadata (self, app,
+                                                                      str, len,
+                                                                      error);
+               if (runtime_new == NULL)
+                       return FALSE;
+               gs_app_set_update_runtime (app, runtime_new);
+       }
+
+       /* no runtime required */
+       runtime = gs_app_get_update_runtime (app);
+       if (runtime == NULL)
+               return TRUE;
+
+       /* the runtime could come from a different remote to the app */
+       if (!gs_refine_item_metadata (self, runtime, cancellable, error)) {
+               gs_utils_error_add_unique_id (error, runtime);
+               return FALSE;
+       }
+       if (!gs_plugin_refine_item_origin (self, runtime, cancellable, error)) {
+               gs_utils_error_add_unique_id (error, runtime);
+               return FALSE;
+       }
+       if (!gs_plugin_refine_item_state (self, runtime, cancellable, error)) {
+               gs_utils_error_add_unique_id (error, runtime);
+               return FALSE;
+       }
+       if (gs_app_get_state (runtime) == AS_APP_STATE_UNKNOWN) {
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_NOT_SUPPORTED,
+                            "Failed to find runtime %s",
+                            gs_app_get_source_default (runtime));
+               gs_utils_error_add_unique_id (error, runtime);
+               return FALSE;
+       }
+
+       gs_app_set_runtime (app, runtime);
+
+       return TRUE;
+}
+
 static GsAppList *
 gs_flatpak_get_list_for_install (GsFlatpak *self, GsApp *app,
                                 GCancellable *cancellable, GError **error)
 {
+       GsApp *runtime;
        g_autofree gchar *ref = NULL;
        g_autoptr(GPtrArray) related = NULL;
        g_autoptr(GPtrArray) xrefs_installed = NULL;
@@ -2369,6 +2433,24 @@ gs_flatpak_get_list_for_install (GsFlatpak *self, GsApp *app,
                                  flatpak_ref_format_ref (FLATPAK_REF (xref)));
        }
 
+       /* add runtime */
+       runtime = gs_app_get_runtime (app);
+       if (runtime != NULL) {
+               g_autofree gchar *ref_display = NULL;
+               if (!gs_flatpak_refine_runtime_for_install (self, app, cancellable, error))
+                       return FALSE;
+               ref_display = gs_flatpak_app_get_ref_display (runtime);
+               if (g_hash_table_contains (hash_installed, ref_display)) {
+                       g_debug ("%s is already installed, so skipping",
+                                gs_app_get_id (runtime));
+               } else {
+                       g_debug ("%s/%s is not already installed, so installing",
+                                gs_flatpak_app_get_ref_name (runtime),
+                                gs_flatpak_app_get_ref_branch (runtime));
+                       gs_app_list_add (list, runtime);
+               }
+       }
+
        /* lookup any related refs for this ref */
        ref = g_strdup_printf ("%s/%s/%s/%s",
                               gs_flatpak_app_get_ref_kind_as_str (app),
@@ -2497,98 +2579,6 @@ gs_flatpak_app_remove (GsFlatpak *self,
        return TRUE;
 }
 
-static gboolean
-install_runtime_for_app (GsFlatpak *self,
-                        GsApp *app,
-                        GCancellable *cancellable,
-                        GError **error)
-{
-       GsApp *runtime;
-
-       /* only required for ostree-based flatpak apps */
-       if (gs_flatpak_app_get_file_kind (app) == GS_FLATPAK_APP_FILE_KIND_BUNDLE) {
-               gsize len;
-               const gchar *str;
-               g_autoptr(GBytes) data = NULL;
-               g_autoptr(GsApp) runtime_new = NULL;
-
-               data = gs_flatpak_fetch_remote_metadata (self, app, cancellable, error);
-               if (data == NULL) {
-                       gs_utils_error_add_unique_id (error, app);
-                       return FALSE;
-               }
-
-               str = g_bytes_get_data (data, &len);
-               runtime_new = gs_flatpak_create_runtime_from_metadata (self, app,
-                                                                      str, len,
-                                                                      error);
-               if (runtime_new == NULL)
-                       return FALSE;
-               gs_app_set_update_runtime (app, runtime_new);
-       }
-
-       /* no runtime required */
-       runtime = gs_app_get_update_runtime (app);
-       if (runtime == NULL)
-               return TRUE;
-
-       /* the runtime could come from a different remote to the app */
-       if (!gs_refine_item_metadata (self, runtime, cancellable, error)) {
-               gs_utils_error_add_unique_id (error, runtime);
-               return FALSE;
-       }
-       if (!gs_plugin_refine_item_origin (self, runtime, cancellable, error)) {
-               gs_utils_error_add_unique_id (error, runtime);
-               return FALSE;
-       }
-       if (!gs_plugin_refine_item_state (self, runtime, cancellable, error)) {
-               gs_utils_error_add_unique_id (error, runtime);
-               return FALSE;
-       }
-       if (gs_app_get_state (runtime) == AS_APP_STATE_UNKNOWN) {
-               g_set_error (error,
-                            GS_PLUGIN_ERROR,
-                            GS_PLUGIN_ERROR_NOT_SUPPORTED,
-                            "Failed to find runtime %s",
-                            gs_app_get_source_default (runtime));
-               gs_utils_error_add_unique_id (error, runtime);
-               return FALSE;
-       }
-
-       /* not installed */
-       if (gs_app_get_state (runtime) != AS_APP_STATE_INSTALLED) {
-               g_autoptr(FlatpakInstalledRef) xref = NULL;
-               g_autoptr(GsFlatpakProgressHelper) phelper = NULL;
-
-               g_debug ("%s/%s is not already installed, so installing",
-                        gs_app_get_id (runtime),
-                        gs_flatpak_app_get_ref_branch (runtime));
-               gs_app_set_state (runtime, AS_APP_STATE_INSTALLING);
-               phelper = gs_flatpak_progress_helper_new (self->plugin, app);
-               xref = flatpak_installation_install (self->installation,
-                                                    gs_app_get_origin (runtime),
-                                                    gs_flatpak_app_get_ref_kind (runtime),
-                                                    gs_flatpak_app_get_ref_name (runtime),
-                                                    gs_flatpak_app_get_ref_arch (runtime),
-                                                    gs_flatpak_app_get_ref_branch (runtime),
-                                                    gs_flatpak_progress_cb, phelper,
-                                                    cancellable, error);
-               if (xref == NULL) {
-                       gs_flatpak_error_convert (error);
-                       gs_app_set_state_recover (runtime);
-                       return FALSE;
-               }
-               gs_app_set_state (runtime, AS_APP_STATE_INSTALLED);
-       } else {
-               g_debug ("%s is already installed, so skipping",
-                        gs_app_get_id (runtime));
-       }
-
-       gs_app_set_runtime (app, runtime);
-
-       return TRUE;
-}
-
 static GsApp *
 gs_flatpak_create_runtime_repo (GsFlatpak *self,
                                const gchar *uri,
@@ -2640,9 +2630,6 @@ gs_flatpak_app_install (GsFlatpak *self,
                                    cancellable, error))
                return FALSE;
 
-       /* install */
-       gs_app_set_state (app, AS_APP_STATE_INSTALLING);
-
        /* add a source */
        if (gs_app_get_kind (app) == AS_APP_KIND_SOURCE) {
                return gs_flatpak_app_install_source (self,
@@ -2728,6 +2715,7 @@ gs_flatpak_app_install (GsFlatpak *self,
 
                /* now install actual app */
                data = g_bytes_new (contents, len);
+               gs_app_set_state (app, AS_APP_STATE_INSTALLING);
                xref2 = flatpak_installation_install_ref_file (self->installation,
                                                              data,
                                                              cancellable,
@@ -2743,13 +2731,6 @@ gs_flatpak_app_install (GsFlatpak *self,
                        return FALSE;
        }
 
-       /* install required runtime if not already installed */
-       if (gs_app_get_kind (app) == AS_APP_KIND_DESKTOP &&
-           !install_runtime_for_app (self, app, cancellable, error)) {
-               gs_app_set_state_recover (app);
-               return FALSE;
-       }
-
        if (gs_flatpak_app_get_file_kind (app) == GS_FLATPAK_APP_FILE_KIND_BUNDLE) {
                g_autoptr(FlatpakInstalledRef) xref = NULL;
                g_autoptr(GsFlatpakProgressHelper) phelper = NULL;
@@ -2763,6 +2744,7 @@ gs_flatpak_app_install (GsFlatpak *self,
                }
                g_debug ("installing bundle %s", gs_app_get_unique_id (app));
                phelper = gs_flatpak_progress_helper_new (self->plugin, app);
+               gs_app_set_state (app, AS_APP_STATE_INSTALLING);
                xref = flatpak_installation_install_bundle (self->installation,
                                                            gs_app_get_local_file (app),
                                                            gs_flatpak_progress_cb,
@@ -2802,6 +2784,7 @@ gs_flatpak_app_install (GsFlatpak *self,
                        GsApp *app_tmp = gs_app_list_index (list, phelper->job_now);
                        g_autoptr(FlatpakInstalledRef) xref = NULL;
                        g_debug ("installing %s", gs_flatpak_app_get_ref_name (app_tmp));
+                       gs_app_set_state (app_tmp, AS_APP_STATE_INSTALLING);
                        xref = flatpak_installation_install (self->installation,
                                                             gs_app_get_origin (app_tmp),
                                                             gs_flatpak_app_get_ref_kind (app_tmp),
@@ -2812,15 +2795,15 @@ gs_flatpak_app_install (GsFlatpak *self,
                                                             cancellable, error);
                        if (xref == NULL) {
                                gs_flatpak_error_convert (error);
-                               gs_app_set_state_recover (app);
+                               gs_app_set_state_recover (app_tmp);
                                return FALSE;
                        }
+
+                       /* state is known */
+                       gs_app_set_state (app_tmp, AS_APP_STATE_INSTALLED);
                }
        }
 
-       /* state is known */
-       gs_app_set_state (app, AS_APP_STATE_INSTALLED);
-
        /* set new version */
        if (!gs_flatpak_refine_appstream (self, app, error))
                return FALSE;
@@ -2857,13 +2840,6 @@ gs_flatpak_update_app (GsFlatpak *self,
                                  flatpak_ref_format_ref (FLATPAK_REF (xref)));
        }
 
-       /* install required runtime if not already installed */
-       if (gs_app_get_kind (app) == AS_APP_KIND_DESKTOP &&
-           !install_runtime_for_app (self, app, cancellable, error)) {
-               gs_app_set_state_recover (app);
-               return FALSE;
-       }
-
        /* get the list of apps to process */
        list = gs_flatpak_get_list_for_install (self, app, cancellable, error);
        if (list == NULL) {
diff --git a/plugins/flatpak/gs-self-test.c b/plugins/flatpak/gs-self-test.c
index 52105eb..2c83059 100644
--- a/plugins/flatpak/gs-self-test.c
+++ b/plugins/flatpak/gs-self-test.c
@@ -301,6 +301,12 @@ gs_plugins_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
        g_assert_cmpstr (gs_app_get_update_details (app), ==, NULL);
        g_assert_cmpint (gs_app_get_update_urgency (app), ==, AS_URGENCY_KIND_UNKNOWN);
 
+       /* check runtime */
+       runtime = gs_app_get_runtime (app);
+       g_assert (runtime != NULL);
+       g_assert_cmpstr (gs_app_get_unique_id (runtime), ==, 
"user/flatpak/test/runtime/org.test.Runtime/master");
+       g_assert_cmpint (gs_app_get_state (runtime), ==, AS_APP_STATE_AVAILABLE);
+
        /* install, also installing runtime */
        g_object_unref (plugin_job);
        plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_INSTALL,
@@ -313,6 +319,7 @@ gs_plugins_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_INSTALLED);
        g_assert_cmpstr (gs_app_get_version (app), ==, "1.2.3");
        g_assert_cmpint (gs_app_get_progress (app), ==, 0);
+       g_assert_cmpint (gs_app_get_state (runtime), ==, AS_APP_STATE_INSTALLED);
 
        /* check the application exists in the right places */
        metadata_fn = g_build_filename (root,
@@ -361,6 +368,7 @@ gs_plugins_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
        g_assert_no_error (error);
        g_assert (ret);
        g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+       g_assert_cmpint (gs_app_get_state (runtime), ==, AS_APP_STATE_INSTALLED);
        g_assert (!g_file_test (metadata_fn, G_FILE_TEST_IS_REGULAR));
        g_assert (!g_file_test (desktop_fn, G_FILE_TEST_IS_REGULAR));
 
@@ -390,6 +398,7 @@ gs_plugins_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
        g_assert_no_error (error);
        g_assert (ret);
        g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+       g_assert_cmpint (gs_app_get_state (runtime), ==, AS_APP_STATE_INSTALLED);
        g_assert (!g_file_test (metadata_fn, G_FILE_TEST_IS_REGULAR));
        g_assert (!g_file_test (desktop_fn, G_FILE_TEST_IS_REGULAR));
 
@@ -407,9 +416,6 @@ gs_plugins_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
        g_assert_cmpint (gs_app_get_state (app_source), ==, AS_APP_STATE_INSTALLED);
 
        /* remove the runtime */
-       runtime = gs_app_get_runtime (app);
-       g_assert (runtime != NULL);
-       g_assert_cmpstr (gs_app_get_unique_id (runtime), ==, 
"user/flatpak/test/runtime/org.test.Runtime/master");
        g_object_unref (plugin_job);
        plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_REMOVE,
                                         "app", runtime,
@@ -418,6 +424,7 @@ gs_plugins_flatpak_app_with_runtime_func (GsPluginLoader *plugin_loader)
        gs_test_flush_main_context ();
        g_assert_no_error (error);
        g_assert (ret);
+       g_assert_cmpint (gs_app_get_state (runtime), ==, AS_APP_STATE_AVAILABLE);
 
        /* remove the remote */
        g_object_unref (plugin_job);


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