summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2018-07-06 19:13:11 +0200
committerAlexander Larsson <alexander.larsson@gmail.com>2018-07-07 16:37:44 +0200
commit0d19e60ce3c562bc33aa59453bfe0a87e03d1d7a (patch)
tree0a300737e1d06ad591c3e57ef35a925f2f993205
parent3ed522c05717efe2542ecceb233ead6d7c13a657 (diff)
downloadflatpak-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.c175
-rw-r--r--data/org.freedesktop.Flatpak.xml4
-rw-r--r--system-helper/flatpak-system-helper.c31
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",