mirror of
https://github.com/flatpak/flatpak.git
synced 2026-05-19 22:39:08 -04:00
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.
This commit is contained in:
committed by
Alexander Larsson
parent
3ed522c057
commit
0d19e60ce3
@@ -1877,12 +1877,85 @@ _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)
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
FlatpakSystemHelper *system_helper;
|
||||
|
||||
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;
|
||||
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
if (!flatpak_dir_ensure_path (self, cancellable, &local_error))
|
||||
{
|
||||
if (allow_empty)
|
||||
return TRUE;
|
||||
|
||||
g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repodir = g_file_get_child (self->basedir, "repo");
|
||||
|
||||
if (use_helper)
|
||||
{
|
||||
g_autoptr(GFile) cache_dir = NULL;
|
||||
g_autofree char *cache_path = NULL;
|
||||
|
||||
repo = system_ostree_repo_new (repodir);
|
||||
|
||||
cache_dir = flatpak_ensure_user_cache_dir_location (error);
|
||||
if (cache_dir == NULL)
|
||||
return FALSE;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
if (!ostree_repo_create (repo, mode, cancellable, &my_error))
|
||||
{
|
||||
flatpak_rm_rf (repodir, cancellable, NULL);
|
||||
|
||||
if (allow_empty)
|
||||
return TRUE;
|
||||
|
||||
@@ -1890,91 +1963,49 @@ _flatpak_dir_ensure_repo (FlatpakDir *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
repodir = g_file_get_child (self->basedir, "repo");
|
||||
if (self->no_system_helper || self->user || getuid () == 0)
|
||||
/* Create .changes file early to avoid polling non-existing file in monitor */
|
||||
if (!flatpak_dir_mark_changed (self, &my_error))
|
||||
{
|
||||
repo = system_ostree_repo_new (repodir);
|
||||
g_warning ("Error marking directory as changed: %s", my_error->message);
|
||||
g_clear_error (&my_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_autoptr(GFile) cache_dir = NULL;
|
||||
g_autofree char *cache_path = NULL;
|
||||
|
||||
repo = system_ostree_repo_new (repodir);
|
||||
use_helper = TRUE;
|
||||
|
||||
cache_dir = flatpak_ensure_user_cache_dir_location (error);
|
||||
if (cache_dir == NULL)
|
||||
return FALSE;
|
||||
|
||||
cache_path = g_file_get_path (cache_dir);
|
||||
if (!ostree_repo_set_cache_dir (repo,
|
||||
AT_FDCWD, cache_path,
|
||||
cancellable, 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;
|
||||
|
||||
if (!ostree_repo_create (repo, mode, cancellable, &my_error))
|
||||
{
|
||||
flatpak_rm_rf (repodir, cancellable, NULL);
|
||||
|
||||
if (allow_empty)
|
||||
return TRUE;
|
||||
|
||||
g_propagate_error (error, g_steal_pointer (&my_error));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* 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))
|
||||
{
|
||||
g_autofree char *repopath = NULL;
|
||||
|
||||
repopath = g_file_get_path (repodir);
|
||||
g_prefix_error (error, _("While opening repository %s: "), repopath);
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ostree_repo_open (repo, cancellable, error))
|
||||
{
|
||||
g_autofree char *repopath = NULL;
|
||||
|
||||
repopath = g_file_get_path (repodir);
|
||||
g_prefix_error (error, _("While opening repository %s: "), repopath);
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user