From 09ce71840372a9d293612bf4e7285d226cacd171 Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: Wed, 31 Jan 2018 15:27:06 +0100 Subject: [PATCH] lib: Make gnome-software work with an empty /var/lib/flatpak Similar to commit 6bb0196ffda1a80163f0c90172cb96f66594b962 that fixed https://github.com/flatpak/flatpak/issues/113 for the flatpak CLI, this fixes the library so that gnome-software works with an empty /var/lib/flatpak. Closes: #1368 Approved by: alexlarsson (cherry picked from commit a9b6e31121e0439e6076fe1f777d72050cae228d) --- lib/flatpak-installation.c | 204 +++++++++++++++++++++++++++++-------- lib/flatpak-remote.c | 8 +- 2 files changed, 166 insertions(+), 46 deletions(-) diff --git a/lib/flatpak-installation.c b/lib/flatpak-installation.c index 953f842f..3e2edc1f 100644 --- a/lib/flatpak-installation.c +++ b/lib/flatpak-installation.c @@ -144,7 +144,7 @@ flatpak_installation_new_for_dir (FlatpakDir *dir, FlatpakInstallation *self; FlatpakInstallationPrivate *priv; - if (!flatpak_dir_ensure_repo (dir, NULL, error)) + if (!flatpak_dir_maybe_ensure_repo (dir, NULL, error)) { g_object_unref (dir); return NULL; @@ -335,16 +335,41 @@ flatpak_installation_new_for_path (GFile *path, gboolean user, } static FlatpakDir * -flatpak_installation_get_dir (FlatpakInstallation *self) +_flatpak_installation_get_dir (FlatpakInstallation *self, gboolean ensure_repo, GError **error) { FlatpakInstallationPrivate *priv = flatpak_installation_get_instance_private (self); FlatpakDir *dir; + G_LOCK (dir); + + if (ensure_repo && flatpak_dir_get_repo (priv->dir_unlocked) == NULL) + { + if (!flatpak_dir_ensure_repo (priv->dir_unlocked, NULL, error)) + { + dir = NULL; + goto out; + } + } + dir = g_object_ref (priv->dir_unlocked); + +out: G_UNLOCK (dir); return dir; } +static FlatpakDir * +flatpak_installation_get_dir (FlatpakInstallation *self, GError **error) +{ + return _flatpak_installation_get_dir (self, TRUE, error); +} + +static FlatpakDir * +flatpak_installation_get_dir_maybe_no_repo (FlatpakInstallation *self) +{ + return _flatpak_installation_get_dir (self, FALSE, NULL); +} + /** * flatpak_installation_drop_caches: * @self: a #FlatpakInstallation @@ -370,7 +395,7 @@ flatpak_installation_drop_caches (FlatpakInstallation *self, old = priv->dir_unlocked; clone = flatpak_dir_clone (priv->dir_unlocked); - if (flatpak_dir_ensure_repo (clone, cancellable, error)) + if (flatpak_dir_maybe_ensure_repo (clone, cancellable, error)) { priv->dir_unlocked = clone; g_object_unref (old); @@ -393,7 +418,7 @@ flatpak_installation_drop_caches (FlatpakInstallation *self, gboolean flatpak_installation_get_is_user (FlatpakInstallation *self) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); return flatpak_dir_is_user (dir); } @@ -409,7 +434,7 @@ flatpak_installation_get_is_user (FlatpakInstallation *self) GFile * flatpak_installation_get_path (FlatpakInstallation *self) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); return g_object_ref (flatpak_dir_get_path (dir)); } @@ -427,7 +452,7 @@ flatpak_installation_get_path (FlatpakInstallation *self) const char * flatpak_installation_get_id (FlatpakInstallation *self) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); return flatpak_dir_get_id (dir); } @@ -445,7 +470,7 @@ flatpak_installation_get_id (FlatpakInstallation *self) const char * flatpak_installation_get_display_name (FlatpakInstallation *self) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); return flatpak_dir_get_display_name (dir); } @@ -463,7 +488,7 @@ flatpak_installation_get_display_name (FlatpakInstallation *self) gint flatpak_installation_get_priority (FlatpakInstallation *self) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); return flatpak_dir_get_priority (dir); } @@ -480,7 +505,7 @@ flatpak_installation_get_priority (FlatpakInstallation *self) */FlatpakStorageType flatpak_installation_get_storage_type (FlatpakInstallation *self) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); switch (flatpak_dir_get_storage_type (dir)) { @@ -527,10 +552,13 @@ flatpak_installation_launch (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; + g_autoptr(FlatpakDeploy) app_deploy = NULL; g_autofree char *app_ref = NULL; - g_autoptr(FlatpakDeploy) app_deploy = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; app_ref = flatpak_build_app_ref (name, branch, arch); @@ -633,11 +661,14 @@ flatpak_installation_get_installed_ref (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); - + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GFile) deploy = NULL; g_autofree char *ref = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + if (arch == NULL) arch = flatpak_get_arch (); @@ -678,12 +709,15 @@ flatpak_installation_get_current_installed_app (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); - + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GFile) deploy = NULL; - g_autofree char *current = - flatpak_dir_current_ref (dir, name, cancellable); + g_autofree char *current = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + + current = flatpak_dir_current_ref (dir, name, cancellable); if (current) deploy = flatpak_dir_get_if_deployed (dir, current, NULL, cancellable); @@ -714,7 +748,7 @@ flatpak_installation_list_installed_refs (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); g_auto(GStrv) raw_refs_app = NULL; g_auto(GStrv) raw_refs_runtime = NULL; g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref); @@ -773,7 +807,7 @@ flatpak_installation_list_installed_refs_by_kind (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); g_auto(GStrv) raw_refs = NULL; g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref); int i; @@ -989,7 +1023,7 @@ flatpak_installation_list_remotes (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); g_autoptr(FlatpakDir) dir_clone = NULL; g_auto(GStrv) remote_names = NULL; g_autoptr(GPtrArray) remotes = g_ptr_array_new_with_free_func (g_object_unref); @@ -1002,7 +1036,7 @@ flatpak_installation_list_remotes (FlatpakInstallation *self, /* We clone the dir here to make sure we re-read the latest ostree repo config, in case it has local changes */ dir_clone = flatpak_dir_clone (dir); - if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error)) + if (!flatpak_dir_maybe_ensure_repo (dir_clone, cancellable, error)) return NULL; for (i = 0; remote_names[i] != NULL; i++) @@ -1036,13 +1070,13 @@ flatpak_installation_modify_remote (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); g_autoptr(FlatpakDir) dir_clone = NULL; /* We clone the dir here to make sure we re-read the latest ostree repo config, in case it has local changes */ dir_clone = flatpak_dir_clone (dir); - if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error)) + if (!flatpak_dir_maybe_ensure_repo (dir_clone, cancellable, error)) return FALSE; if (!flatpak_remote_commit (remote, dir_clone, cancellable, error)) @@ -1071,9 +1105,13 @@ flatpak_installation_remove_remote (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(FlatpakDir) dir_clone = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; + /* We clone the dir here to make sure we re-read the latest ostree repo config, in case it has local changes */ dir_clone = flatpak_dir_clone (dir); @@ -1111,9 +1149,13 @@ flatpak_installation_set_config_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(FlatpakDir) dir_clone = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; + /* We clone the dir here to make sure we re-read the latest ostree repo config, in case it has local changes */ dir_clone = flatpak_dir_clone (dir); @@ -1147,7 +1189,11 @@ flatpak_installation_get_config (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; + + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; return flatpak_dir_get_config (dir, key, error); } @@ -1173,9 +1219,13 @@ flatpak_installation_update_remote_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(FlatpakDir) dir_clone = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; + /* We clone the dir here to make sure we re-read the latest ostree repo config, in case it has local changes */ dir_clone = flatpak_dir_clone (dir); @@ -1208,7 +1258,7 @@ flatpak_installation_get_remote_by_name (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); g_autoptr(FlatpakDir) dir_clone = NULL; g_auto(GStrv) remote_names = NULL; int i; @@ -1253,10 +1303,14 @@ flatpak_installation_load_app_overrides (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autofree char *metadata_contents = NULL; gsize metadata_size; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + metadata_contents = flatpak_dir_load_override (dir, app_id, &metadata_size, error); if (metadata_contents == NULL) return NULL; @@ -1286,12 +1340,16 @@ flatpak_installation_install_bundle (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(FlatpakDir) dir_clone = NULL; g_autofree char *ref = NULL; g_autofree char *remote = NULL; FlatpakInstalledRef *result = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + remote = flatpak_dir_ensure_bundle_remote (dir, file, NULL, &ref, NULL, NULL, cancellable, error); if (remote == NULL) return NULL; @@ -1341,10 +1399,14 @@ flatpak_installation_install_ref_file (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autofree char *remote = NULL; g_autofree char *ref = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + if (!flatpak_dir_create_remote_for_ref_file (dir, ref_file_data, NULL, &remote, &ref, error)) return NULL; @@ -1395,7 +1457,7 @@ flatpak_installation_install_full (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autofree char *ref = NULL; g_autoptr(FlatpakDir) dir_clone = NULL; g_autoptr(GMainContext) main_context = NULL; @@ -1403,6 +1465,10 @@ flatpak_installation_install_full (FlatpakInstallation *self, FlatpakInstalledRef *result = NULL; g_autoptr(GFile) deploy_dir = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + ref = flatpak_compose_ref (kind == FLATPAK_REF_KIND_APP, name, branch, arch, error); if (ref == NULL) return NULL; @@ -1539,7 +1605,7 @@ flatpak_installation_update_full (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autofree char *ref = NULL; g_autoptr(GFile) deploy_dir = NULL; g_autoptr(FlatpakDir) dir_clone = NULL; @@ -1550,6 +1616,10 @@ flatpak_installation_update_full (FlatpakInstallation *self, g_autofree char *target_commit = NULL; g_auto(OstreeRepoFinderResultv) check_results = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + ref = flatpak_compose_ref (kind == FLATPAK_REF_KIND_APP, name, branch, arch, error); if (ref == NULL) return NULL; @@ -1675,10 +1745,14 @@ flatpak_installation_uninstall (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autofree char *ref = NULL; g_autoptr(FlatpakDir) dir_clone = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; + ref = flatpak_compose_ref (kind == FLATPAK_REF_KIND_APP, name, branch, arch, error); if (ref == NULL) return FALSE; @@ -1724,9 +1798,13 @@ flatpak_installation_fetch_remote_size_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autofree char *full_ref = flatpak_ref_format_ref (ref); + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; + return flatpak_dir_fetch_ref_cache (dir, remote_name, full_ref, download_size, installed_size, NULL, @@ -1754,10 +1832,14 @@ flatpak_installation_fetch_remote_metadata_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autofree char *full_ref = flatpak_ref_format_ref (ref); char *res = NULL; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + if (!flatpak_dir_fetch_ref_cache (dir, remote_name, full_ref, NULL, NULL, &res, @@ -1785,13 +1867,17 @@ flatpak_installation_list_remote_refs_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref); g_autoptr(GHashTable) ht = NULL; GHashTableIter iter; gpointer key; gpointer value; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + if (!flatpak_dir_list_remote_refs (dir, remote_name, &ht, @@ -1840,7 +1926,7 @@ flatpak_installation_fetch_remote_ref_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GHashTable) ht = NULL; g_autofree char *ref = NULL; const char *checksum; @@ -1848,6 +1934,10 @@ flatpak_installation_fetch_remote_ref_sync (FlatpakInstallation *self, if (branch == NULL) branch = "master"; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + if (!flatpak_dir_list_remote_refs (dir, remote_name, &ht, @@ -1927,12 +2017,16 @@ flatpak_installation_update_appstream_full_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(FlatpakDir) dir_clone = NULL; g_autoptr(OstreeAsyncProgress) ostree_progress = NULL; g_autoptr(GMainContext) main_context = NULL; gboolean res; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; + /* Pull, prune, etc are not threadsafe, so we work on a copy */ dir_clone = flatpak_dir_clone (dir); if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error)) @@ -1981,7 +2075,7 @@ flatpak_installation_create_monitor (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir_maybe_no_repo (self); g_autoptr(GFile) path = NULL; path = flatpak_dir_get_changed_path (dir); @@ -2023,11 +2117,15 @@ flatpak_installation_list_remote_related_refs_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GPtrArray) related = NULL; g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref); int i; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + related = flatpak_dir_find_remote_related (dir, ref, remote_name, cancellable, error); if (related == NULL) @@ -2079,11 +2177,15 @@ flatpak_installation_list_installed_related_refs_sync (FlatpakInstallation *self GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GPtrArray) related = NULL; g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref); int i; + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return NULL; + related = flatpak_dir_find_local_related (dir, ref, remote_name, cancellable, error); if (related == NULL) @@ -2131,7 +2233,11 @@ flatpak_installation_remove_local_ref_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; + + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; return flatpak_dir_remove_ref (dir, remote_name, ref, cancellable, error); } @@ -2160,7 +2266,11 @@ flatpak_installation_cleanup_local_refs_sync (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; + + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; return flatpak_dir_cleanup_undeployed_refs (dir, cancellable, error); } @@ -2181,7 +2291,11 @@ flatpak_installation_prune_local_repo (FlatpakInstallation *self, GCancellable *cancellable, GError **error) { - g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir = NULL; + + dir = flatpak_installation_get_dir (self, error); + if (dir == NULL) + return FALSE; return flatpak_dir_prune (dir, cancellable, error); } diff --git a/lib/flatpak-remote.c b/lib/flatpak-remote.c index 03644266..fca0a831 100644 --- a/lib/flatpak-remote.c +++ b/lib/flatpak-remote.c @@ -790,6 +790,7 @@ flatpak_remote_commit (FlatpakRemote *self, GError **error) { FlatpakRemotePrivate *priv = flatpak_remote_get_instance_private (self); + OstreeRepo *repo; g_autofree char *url = NULL; g_autoptr(GKeyFile) config = NULL; g_autofree char *group = g_strdup_printf ("remote \"%s\"", priv->name); @@ -801,7 +802,12 @@ flatpak_remote_commit (FlatpakRemote *self, if (priv->type != FLATPAK_REMOTE_TYPE_STATIC) return flatpak_fail (error, "Dynamic remote cannot be committed"); - config = ostree_repo_copy_config (flatpak_dir_get_repo (dir)); + repo = flatpak_dir_get_repo (dir); + if (repo == NULL) + config = g_key_file_new (); + else + config = ostree_repo_copy_config (repo); + if (priv->local_url_set) g_key_file_set_string (config, group, "url", priv->local_url);