From 81492a352aba5709c8572c0c96c17cd6df1c5c8e Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Fri, 16 Dec 2016 19:17:28 +0000 Subject: [PATCH] Migrate flatpak-.c to flatpak_dir_get_system_list() We need to traverse now the full list of system directories, as defined in /etc/flatpak/installations.d, not just the default one. --- app/flatpak-transaction.c | 44 ++++++++++++-- common/flatpak-utils.c | 118 +++++++++++++++++++++++++++++--------- 2 files changed, 130 insertions(+), 32 deletions(-) diff --git a/app/flatpak-transaction.c b/app/flatpak-transaction.c index 1dc9d9155..83596b7ea 100644 --- a/app/flatpak-transaction.c +++ b/app/flatpak-transaction.c @@ -43,6 +43,7 @@ struct FlatpakTransactionOp { struct FlatpakTransaction { FlatpakDir *dir; GHashTable *refs; + GPtrArray *system_dirs; GList *ops; gboolean no_interaction; @@ -54,21 +55,40 @@ struct FlatpakTransaction { /* Check if the ref is in the dir, or in the system dir, in case its a - * user-dir. We want to avoid depending on user-installed things when - * installing to the system dir. + * user-dir or another system-wide installation. We want to avoid depending + * on user-installed things when installing to the system dir. */ static gboolean -ref_is_installed (FlatpakDir *dir, const char *ref) +ref_is_installed (FlatpakTransaction *self, + const char *ref, + GError **error) { g_autoptr(GFile) deploy_dir = NULL; + FlatpakDir *dir = self->dir; + int i; deploy_dir = flatpak_dir_get_if_deployed (dir, ref, NULL, NULL); if (deploy_dir != NULL) return TRUE; - if (flatpak_dir_is_user (dir)) + /* Don't try to fallback for the system's default directory. */ + if (!flatpak_dir_is_user (dir) && flatpak_dir_get_id (dir) == NULL) + return FALSE; + + /* Lazy initialization of this, once per transaction */ + if (self->system_dirs == NULL) { - g_autoptr(FlatpakDir) system_dir = flatpak_dir_get_system (); + self->system_dirs = flatpak_dir_get_system_list (NULL, error); + if (self->system_dirs == NULL) + return FALSE; + } + + for (i = 0; i < self->system_dirs->len; i++) + { + FlatpakDir *system_dir = g_ptr_array_index (self->system_dirs, i); + + if (g_strcmp0 (flatpak_dir_get_id (dir), flatpak_dir_get_id (system_dir)) == 0) + continue; deploy_dir = flatpak_dir_get_if_deployed (system_dir, ref, NULL, NULL); if (deploy_dir != NULL) @@ -149,6 +169,10 @@ flatpak_transaction_free (FlatpakTransaction *self) g_hash_table_unref (self->refs); g_list_free_full (self->ops, (GDestroyNotify)flatpak_transaction_operation_free); g_object_unref (self->dir); + + if (self->system_dirs != NULL) + g_ptr_array_free (self->system_dirs, TRUE); + g_free (self); } @@ -339,10 +363,18 @@ add_deps (FlatpakTransaction *self, if (!flatpak_transaction_contains_ref (self, full_runtime_ref)) { - if (!ref_is_installed (self->dir, full_runtime_ref)) + g_autoptr(GError) local_error = NULL; + + if (!ref_is_installed (self, full_runtime_ref, &local_error)) { g_auto(GStrv) remotes = NULL; + if (local_error != NULL) + { + g_propagate_error (error, g_steal_pointer (&local_error)); + return FALSE; + } + g_print (_("Required runtime for %s (%s) is not installed, searching...\n"), pref, runtime_ref); diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c index 560bfd1ba..0bb7e5c4d 100644 --- a/common/flatpak-utils.c +++ b/common/flatpak-utils.c @@ -933,24 +933,31 @@ flatpak_list_deployed_refs (const char *type, g_autoptr(GPtrArray) names = NULL; g_autoptr(GHashTable) hash = NULL; g_autoptr(FlatpakDir) user_dir = NULL; - g_autoptr(FlatpakDir) system_dir = NULL; + g_autoptr(GPtrArray) system_dirs = NULL; const char *key; GHashTableIter iter; + int i; hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); user_dir = flatpak_dir_get_user (); - system_dir = flatpak_dir_get_system_default (); + system_dirs = flatpak_dir_get_system_list (cancellable, error); + if (system_dirs == NULL) + goto out; if (!flatpak_dir_collect_deployed_refs (user_dir, type, name_prefix, branch, arch, hash, cancellable, error)) goto out; - if (!flatpak_dir_collect_deployed_refs (system_dir, type, name_prefix, - branch, arch, hash, cancellable, - error)) - goto out; + for (i = 0; i < system_dirs->len; i++) + { + FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i); + if (!flatpak_dir_collect_deployed_refs (system_dir, type, name_prefix, + branch, arch, hash, cancellable, + error)) + goto out; + } names = g_ptr_array_new (); g_hash_table_iter_init (&iter, hash); @@ -979,22 +986,41 @@ flatpak_list_unmaintained_refs (const char *name_prefix, g_autoptr(GPtrArray) names = NULL; g_autoptr(GHashTable) hash = NULL; g_autoptr(FlatpakDir) user_dir = NULL; - g_autoptr(FlatpakDir) system_dir = NULL; + g_autoptr(GError) my_error = NULL; const char *key; GHashTableIter iter; hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); user_dir = flatpak_dir_get_user (); - system_dir = flatpak_dir_get_system (); - if ((!flatpak_dir_collect_unmaintained_refs (user_dir, name_prefix, + if (!flatpak_dir_collect_unmaintained_refs (user_dir, name_prefix, branch, arch, hash, cancellable, - error)) && - (!flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix, - branch, arch, hash, cancellable, - error))) - goto out; + &my_error)) + { + g_autoptr(GPtrArray) system_dirs = NULL; + int i; + + system_dirs = flatpak_dir_get_system_list (cancellable, error); + if (system_dirs == NULL) + goto out; + + for (i = 0; i < system_dirs->len; i++) + { + FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i); + + g_clear_error (&my_error); + if (flatpak_dir_collect_unmaintained_refs (system_dir, name_prefix, + branch, arch, hash, cancellable, + &my_error)) + { + /* Reference found in at least one of the system installations */ + break; + } + + goto out; + } + } names = g_ptr_array_new (); g_hash_table_iter_init (&iter, hash); @@ -1007,6 +1033,9 @@ flatpak_list_unmaintained_refs (const char *name_prefix, ret = (char **) g_ptr_array_free (names, FALSE); names = NULL; + if (ret == NULL) + g_propagate_error (error, g_steal_pointer (&my_error)); + out: return ret; } @@ -1018,19 +1047,27 @@ flatpak_find_deploy_dir_for_ref (const char *ref, GError **error) { g_autoptr(FlatpakDir) user_dir = NULL; - g_autoptr(FlatpakDir) system_dir = NULL; + g_autoptr(GPtrArray) system_dirs = NULL; FlatpakDir *dir = NULL; g_autoptr(GFile) deploy = NULL; user_dir = flatpak_dir_get_user (); - system_dir = flatpak_dir_get_system_default (); + system_dirs = flatpak_dir_get_system_list (cancellable, error); + if (system_dirs == NULL) + return NULL; dir = user_dir; deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable); if (deploy == NULL) { - dir = system_dir; - deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable); + int i; + for (i = 0; deploy == NULL && i < system_dirs->len; i++) + { + dir = g_ptr_array_index (system_dirs, i); + deploy = flatpak_dir_get_if_deployed (dir, ref, NULL, cancellable); + if (deploy != NULL) + break; + } } if (deploy == NULL) @@ -1065,15 +1102,33 @@ flatpak_find_unmaintained_extension_dir_if_exists (const char *name, GCancellable *cancellable) { g_autoptr(FlatpakDir) user_dir = NULL; - g_autoptr(FlatpakDir) system_dir = NULL; g_autoptr(GFile) extension_dir = NULL; + g_autoptr(GError) local_error = NULL; user_dir = flatpak_dir_get_user (); - system_dir = flatpak_dir_get_system (); extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (user_dir, name, arch, branch, cancellable); if (extension_dir == NULL) - extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (system_dir, name, arch, branch, cancellable); + { + g_autoptr(GPtrArray) system_dirs = NULL; + int i; + + system_dirs = flatpak_dir_get_system_list (cancellable, &local_error); + if (system_dirs == NULL) + { + g_warning ("Could not get the system installations: %s", local_error->message); + return NULL; + } + + for (i = 0; i < system_dirs->len; i++) + { + FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i); + extension_dir = flatpak_dir_get_unmaintained_extension_dir_if_exists (system_dir, name, arch, branch, cancellable); + if (extension_dir != NULL) + break; + } + } + if (extension_dir == NULL) return NULL; @@ -1086,18 +1141,29 @@ flatpak_find_deploy_for_ref (const char *ref, GError **error) { g_autoptr(FlatpakDir) user_dir = NULL; - g_autoptr(FlatpakDir) system_dir = NULL; + g_autoptr(GPtrArray) system_dirs = NULL; g_autoptr(FlatpakDeploy) deploy = NULL; g_autoptr(GError) my_error = NULL; user_dir = flatpak_dir_get_user (); - system_dir = flatpak_dir_get_system_default (); + system_dirs = flatpak_dir_get_system_list (cancellable, error); + if (system_dirs == NULL) + return NULL; deploy = flatpak_dir_load_deployed (user_dir, ref, NULL, cancellable, &my_error); - if (deploy == NULL && g_error_matches (my_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED)) + if (deploy == NULL && + system_dirs->len > 0 && + g_error_matches (my_error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED)) { - g_clear_error (&my_error); - deploy = flatpak_dir_load_deployed (system_dir, ref, NULL, cancellable, &my_error); + int i; + + for (i = 0; deploy == NULL && i < system_dirs->len; i++) + { + FlatpakDir *system_dir = g_ptr_array_index (system_dirs, i); + + g_clear_error (&my_error); + deploy = flatpak_dir_load_deployed (system_dir, ref, NULL, cancellable, &my_error); + } } if (deploy == NULL) g_propagate_error (error, g_steal_pointer (&my_error));