system-helper: Support directly pulling local remotes

For a local (file:// uri) remote, do an (untrusted) direct pull instead
of pulling into the users cached repo first. This way we do less copies,
as well as guaranteeing the source of the data. The later means its
mostly safe to also allow this for non-gpg signed remotes.
tingping/wmclass
Alexander Larsson 2016-06-02 15:27:57 +02:00
parent d950ed338f
commit 13707f6b18
3 changed files with 82 additions and 3 deletions

View File

@ -2987,12 +2987,34 @@ flatpak_dir_install (FlatpakDir *self,
g_autofree char *child_repo_path = NULL;
FlatpakSystemHelper *system_helper;
FlatpakHelperDeployFlags helper_flags = 0;
g_autofree char *url = NULL;
system_helper = flatpak_dir_get_system_helper (self);
g_assert (system_helper != NULL);
if (!no_pull)
if (!ostree_repo_remote_get_url (self->repo,
remote_name,
&url,
error))
return FALSE;
if (no_pull)
{
/* Do nothing */
}
else if (g_str_has_prefix (url, "file:"))
{
/* In the local case we let the system-helper do all the work. That way we can trust its
reading from the right source, and its not doing any network i/o. */
helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL;
}
else
{
/* We're pulling from a remote source, we do the network mirroring pull as a
user and hand back the resulting data to the system-helper, that trusts us
due to the GPG signatures in the repo */
child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, error);
if (child_repo == NULL)
return FALSE;
@ -3061,6 +3083,7 @@ flatpak_dir_update (FlatpakDir *self,
FlatpakSystemHelper *system_helper;
g_autofree char *child_repo_path = NULL;
FlatpakHelperDeployFlags helper_flags = 0;
g_autofree char *url = NULL;
if (checksum_or_latest != NULL)
return flatpak_fail (error, "Can't update to a specific commit without root permissions");
@ -3068,13 +3091,32 @@ flatpak_dir_update (FlatpakDir *self,
system_helper = flatpak_dir_get_system_helper (self);
g_assert (system_helper != NULL);
if (!ostree_repo_remote_get_url (self->repo,
remote_name,
&url,
error))
return FALSE;
helper_flags = FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE;
if (no_pull)
{
if (!ostree_repo_resolve_rev (self->repo, ref, FALSE, &latest_checksum, error))
return FALSE;
}
else if (g_str_has_prefix (url, "file:"))
{
/* In the local case we let the system-helper do all the work. That way we can trust its
reading from the right source, and its not doing any network i/o. */
helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL;
}
else
{
/* We're pulling from a remote source, we do the network mirroring pull as a
user and hand back the resulting data to the system-helper, that trusts us
due to the GPG signatures in the repo */
child_repo = flatpak_dir_create_system_child_repo (self, &child_repo_lock, error);
if (child_repo == NULL)
return FALSE;
@ -3090,7 +3132,6 @@ flatpak_dir_update (FlatpakDir *self,
child_repo_path = g_file_get_path (ostree_repo_get_path (child_repo));
}
helper_flags = FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE;
if (no_deploy)
helper_flags |= FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY;

View File

@ -44,9 +44,10 @@ typedef enum {
FLATPAK_HELPER_DEPLOY_FLAGS_NONE = 0,
FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE = 1 << 0,
FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY = 1 << 1,
FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL = 1 << 2,
} FlatpakHelperDeployFlags;
#define FLATPAK_HELPER_DEPLOY_FLAGS_ALL (FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE|FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY)
#define FLATPAK_HELPER_DEPLOY_FLAGS_ALL (FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE|FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY|FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL)
typedef enum {
FLATPAK_HELPER_UNINSTALL_FLAGS_NONE = 0,

View File

@ -139,7 +139,9 @@ handle_deploy (FlatpakSystemHelper *object,
g_autoptr(GFile) deploy_dir = NULL;
gboolean is_update;
gboolean no_deploy;
gboolean local_pull;
g_autoptr(GMainContext) main_context = NULL;
g_autofree char *url = NULL;
g_debug ("Deploy %s %u %s %s", arg_repo_path, arg_flags, arg_ref, arg_origin);
@ -158,6 +160,7 @@ handle_deploy (FlatpakSystemHelper *object,
is_update = (arg_flags & FLATPAK_HELPER_DEPLOY_FLAGS_UPDATE) != 0;
no_deploy = (arg_flags & FLATPAK_HELPER_DEPLOY_FLAGS_NO_DEPLOY) != 0;
local_pull = (arg_flags & FLATPAK_HELPER_DEPLOY_FLAGS_LOCAL_PULL) != 0;
deploy_dir = flatpak_dir_get_if_deployed (system, arg_ref,
NULL, NULL);
@ -216,6 +219,40 @@ handle_deploy (FlatpakSystemHelper *object,
}
g_main_context_pop_thread_default (main_context);
}
else if (local_pull)
{
if (!ostree_repo_remote_get_url (flatpak_dir_get_repo (system),
arg_origin,
&url,
&error))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
"Error getting remote url: %s", error->message);
return TRUE;
}
if (!g_str_has_prefix (url, "file:"))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
"Local pull url doesn't start with file://");
return TRUE;
}
/* Work around ostree-pull spinning the default main context for the sync calls */
main_context = g_main_context_new ();
g_main_context_push_thread_default (main_context);
if (!flatpak_dir_pull (system, arg_origin, arg_ref, (char **)arg_subpaths, NULL,
OSTREE_REPO_PULL_FLAGS_UNTRUSTED, NULL,
NULL, &error))
{
g_main_context_pop_thread_default (main_context);
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
"Error pulling from repo: %s", error->message);
return TRUE;
}
g_main_context_pop_thread_default (main_context);
}
if (!no_deploy)
{