diff options
author | Alexander Larsson <alexl@redhat.com> | 2018-07-06 19:13:11 +0200 |
---|---|---|
committer | Alexander Larsson <alexander.larsson@gmail.com> | 2018-07-07 16:37:44 +0200 |
commit | 0d19e60ce3c562bc33aa59453bfe0a87e03d1d7a (patch) | |
tree | 0a300737e1d06ad591c3e57ef35a925f2f993205 | |
parent | 3ed522c05717efe2542ecceb233ead6d7c13a657 (diff) | |
download | flatpak-0d19e60ce3c562bc33aa59453bfe0a87e03d1d7a.tar.gz |
system-helper: Add EnsureRepo operation
This is used to create the /var/lib/flatpak repo if
needed so that other later operations work. We have
some partial support for it not working in various
operations (using the allow_empty argument) but
this is in no way complete. For example, this
can easily happen if you have a per-user installation
but no system one and then you run flatpak install
with no --user, then it will try to figure out
which one to use and die.
-rw-r--r-- | common/flatpak-dir.c | 175 | ||||
-rw-r--r-- | data/org.freedesktop.Flatpak.xml | 4 | ||||
-rw-r--r-- | system-helper/flatpak-system-helper.c | 31 |
3 files changed, 138 insertions, 72 deletions
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 6ccc78c4..78ff663f 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -1877,105 +1877,136 @@ _flatpak_dir_ensure_repo (FlatpakDir *self, g_autoptr(GFile) repodir = NULL; g_autoptr(OstreeRepo) repo = NULL; g_autoptr(GError) my_error = NULL; - gboolean use_helper = FALSE; + gboolean use_helper; - if (self->repo == NULL) + if (self->repo != NULL) + return TRUE; + + use_helper = + !self->no_system_helper && !self->user && getuid () != 0; + + if (!g_file_query_exists (self->basedir, cancellable)) { - if (!flatpak_dir_ensure_path (self, cancellable, &my_error)) + if (use_helper) { - if (allow_empty) - return TRUE; + g_autoptr(GError) local_error = NULL; + FlatpakSystemHelper *system_helper; - g_propagate_error (error, g_steal_pointer (&my_error)); - return FALSE; - } + system_helper = flatpak_dir_get_system_helper (self); + if (system_helper) + { + const char *installation = flatpak_dir_get_id (self); + if (!flatpak_system_helper_call_ensure_repo_sync (system_helper, + installation ? installation : "", + NULL, &local_error)) + { + if (allow_empty) + return TRUE; - repodir = g_file_get_child (self->basedir, "repo"); - if (self->no_system_helper || self->user || getuid () == 0) - { - repo = system_ostree_repo_new (repodir); + g_propagate_error (error, g_steal_pointer (&local_error)); + return FALSE; + } + } } else { - g_autoptr(GFile) cache_dir = NULL; - g_autofree char *cache_path = NULL; + g_autoptr(GError) local_error = NULL; + if (!flatpak_dir_ensure_path (self, cancellable, &local_error)) + { + if (allow_empty) + return TRUE; - repo = system_ostree_repo_new (repodir); - use_helper = TRUE; + g_propagate_error (error, g_steal_pointer (&local_error)); + return FALSE; + } + } + } - cache_dir = flatpak_ensure_user_cache_dir_location (error); - if (cache_dir == NULL) - return FALSE; + repodir = g_file_get_child (self->basedir, "repo"); - cache_path = g_file_get_path (cache_dir); - if (!ostree_repo_set_cache_dir (repo, - AT_FDCWD, cache_path, - cancellable, error)) - return FALSE; - } + if (use_helper) + { + g_autoptr(GFile) cache_dir = NULL; + g_autofree char *cache_path = NULL; - if (!g_file_query_exists (repodir, cancellable)) - { - /* We always use bare-user-only these days, except old installations - that still user bare-user */ - OstreeRepoMode mode = OSTREE_REPO_MODE_BARE_USER_ONLY; + repo = system_ostree_repo_new (repodir); - if (!ostree_repo_create (repo, mode, cancellable, &my_error)) - { - flatpak_rm_rf (repodir, cancellable, NULL); + cache_dir = flatpak_ensure_user_cache_dir_location (error); + if (cache_dir == NULL) + return FALSE; - if (allow_empty) - return TRUE; + cache_path = g_file_get_path (cache_dir); + if (!ostree_repo_set_cache_dir (repo, + AT_FDCWD, cache_path, + cancellable, error)) + return FALSE; + } + else if (self->user) + repo = ostree_repo_new (repodir); + else + repo = system_ostree_repo_new (repodir); - g_propagate_error (error, g_steal_pointer (&my_error)); - return FALSE; - } + if (!g_file_query_exists (repodir, cancellable)) + { + /* We always use bare-user-only these days, except old installations + that still user bare-user */ + OstreeRepoMode mode = OSTREE_REPO_MODE_BARE_USER_ONLY; - /* Create .changes file early to avoid polling non-existing file in monitor */ - if (!flatpak_dir_mark_changed (self, &my_error)) - { - g_warning ("Error marking directory as changed: %s", my_error->message); - g_clear_error (&my_error); - } - } - else + if (!ostree_repo_create (repo, mode, cancellable, &my_error)) { - if (!ostree_repo_open (repo, cancellable, error)) - { - g_autofree char *repopath = NULL; + flatpak_rm_rf (repodir, cancellable, NULL); - repopath = g_file_get_path (repodir); - g_prefix_error (error, _("While opening repository %s: "), repopath); - return FALSE; - } + if (allow_empty) + return TRUE; + + g_propagate_error (error, g_steal_pointer (&my_error)); + return FALSE; } - /* Reset min-free-space-percent to 0, this keeps being a problem for a lot of people */ - if (!use_helper) + /* Create .changes file early to avoid polling non-existing file in monitor */ + if (!flatpak_dir_mark_changed (self, &my_error)) + { + g_warning ("Error marking directory as changed: %s", my_error->message); + g_clear_error (&my_error); + } + } + else + { + if (!ostree_repo_open (repo, cancellable, error)) { - GKeyFile *orig_config = NULL; - g_autofree char *orig_min_free_space_percent = NULL; + g_autofree char *repopath = NULL; - orig_config = ostree_repo_get_config (repo); - orig_min_free_space_percent = g_key_file_get_value (orig_config, "core", "min-free-space-percent", NULL); - if (orig_min_free_space_percent == NULL) - { - g_autoptr(GKeyFile) config = ostree_repo_copy_config (repo); + repopath = g_file_get_path (repodir); + g_prefix_error (error, _("While opening repository %s: "), repopath); + return FALSE; + } + } - g_key_file_set_string (config, "core", "min-free-space-percent", "0"); - if (!ostree_repo_write_config (repo, config, error)) - return FALSE; + /* Reset min-free-space-percent to 0, this keeps being a problem for a lot of people */ + if (!use_helper) + { + GKeyFile *orig_config = NULL; + g_autofree char *orig_min_free_space_percent = NULL; - if (!ostree_repo_reload_config (repo, cancellable, error)) - return FALSE; - } - } + orig_config = ostree_repo_get_config (repo); + orig_min_free_space_percent = g_key_file_get_value (orig_config, "core", "min-free-space-percent", NULL); + if (orig_min_free_space_percent == NULL) + { + g_autoptr(GKeyFile) config = ostree_repo_copy_config (repo); - /* Make sure we didn't reenter weirdly */ - g_assert (self->repo == NULL); - self->repo = g_object_ref (repo); + g_key_file_set_string (config, "core", "min-free-space-percent", "0"); + if (!ostree_repo_write_config (repo, config, error)) + return FALSE; + + if (!ostree_repo_reload_config (repo, cancellable, error)) + return FALSE; + } } + /* Make sure we didn't reenter weirdly */ + g_assert (self->repo == NULL); + self->repo = g_object_ref (repo); + return TRUE; } diff --git a/data/org.freedesktop.Flatpak.xml b/data/org.freedesktop.Flatpak.xml index d2241d6e..713c3efa 100644 --- a/data/org.freedesktop.Flatpak.xml +++ b/data/org.freedesktop.Flatpak.xml @@ -136,6 +136,10 @@ <arg type='s' name='installation' direction='in'/> </method> + <method name="EnsureRepo"> + <arg type='s' name='installation' direction='in'/> + </method> + </interface> </node> diff --git a/system-helper/flatpak-system-helper.c b/system-helper/flatpak-system-helper.c index 55d8fdcf..97ab9b83 100644 --- a/system-helper/flatpak-system-helper.c +++ b/system-helper/flatpak-system-helper.c @@ -1013,6 +1013,35 @@ handle_prune_local_repo (FlatpakSystemHelper *object, return TRUE; } + +static gboolean +handle_ensure_repo (FlatpakSystemHelper *object, + GDBusMethodInvocation *invocation, + const gchar *arg_installation) +{ + g_autoptr(FlatpakDir) system = NULL; + g_autoptr(GError) error = NULL; + + g_debug ("EnsureRepo %s", arg_installation); + + system = dir_get_system (arg_installation, &error); + if (system == NULL) + { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; + } + + if (!flatpak_dir_ensure_repo (system, NULL, &error)) + { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; + } + + flatpak_system_helper_complete_ensure_repo (object, invocation); + + return TRUE; +} + static gboolean handle_run_triggers (FlatpakSystemHelper *object, GDBusMethodInvocation *invocation, @@ -1172,6 +1201,7 @@ flatpak_authorize_method_handler (GDBusInterfaceSkeleton *interface, } else if (g_strcmp0 (method_name, "RemoveLocalRef") == 0 || g_strcmp0 (method_name, "PruneLocalRepo") == 0 || + g_strcmp0 (method_name, "EnsureRepo") == 0 || g_strcmp0 (method_name, "RunTriggers") == 0) { const char *remote; @@ -1240,6 +1270,7 @@ on_bus_acquired (GDBusConnection *connection, g_signal_connect (helper, "handle-update-remote", G_CALLBACK (handle_update_remote), NULL); g_signal_connect (helper, "handle-remove-local-ref", G_CALLBACK (handle_remove_local_ref), NULL); g_signal_connect (helper, "handle-prune-local-repo", G_CALLBACK (handle_prune_local_repo), NULL); + g_signal_connect (helper, "handle-ensure-repo", G_CALLBACK (handle_ensure_repo), NULL); g_signal_connect (helper, "handle-run-triggers", G_CALLBACK (handle_run_triggers), NULL); g_signal_connect (helper, "g-authorize-method", |