OCI: Use system helper to generate summary for OCI remotes

The OCI support relies on downloading a json index and converting it
to a ostree-style summary, which we the use in all sorts of operations
in the client code. Currently this happens in the user code, which means
that it will fail (due to permissions) in the system installation case.

We could do the conversion as the user, but when eventually installing
something the system-helper will anyway do this download and
conversion, so that would only double the work and risk things going out
of sync. Also, the OCI index is not gpg signed, so we can't realy on
downloads done as the user.

So, the solution done here is to add a GenerateOciSummary
system-helper call which we use instead of directly generating the
oci summary.

This fixes https://github.com/flatpak/flatpak/issues/2350

Closes: #2363
Approved by: matthiasclasen
This commit is contained in:
Alexander Larsson
2018-11-30 10:30:20 +01:00
committed by Atomic Bot
parent 5266600b5f
commit 0b6a66013c
4 changed files with 131 additions and 29 deletions

View File

@@ -735,6 +735,11 @@ FlatpakRemoteState * flatpak_dir_get_remote_state_for_summary (FlatpakDir *sel
GBytes *opt_summary_sig,
GCancellable *cancellable,
GError **error);
gboolean flatpak_dir_remote_make_oci_summary (FlatpakDir *self,
const char *remote,
GBytes **out_summary,
GCancellable *cancellable,
GError **error);
FlatpakRemoteState * flatpak_dir_get_remote_state_optional (FlatpakDir *self,
const char *remote,
GCancellable *cancellable,

View File

@@ -1430,6 +1430,22 @@ flatpak_dir_system_helper_call_update_summary (FlatpakDir *self,
return ret != NULL;
}
static gboolean
flatpak_dir_system_helper_call_generate_oci_summary (FlatpakDir *self,
const gchar *arg_origin,
const gchar *arg_installation,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GVariant) ret =
flatpak_dir_system_helper_call (self, "GenerateOciSummary",
g_variant_new ("(ss)",
arg_origin,
arg_installation),
cancellable, error);
return ret != NULL;
}
static OstreeRepo *
system_ostree_repo_new (GFile *repodir)
{
@@ -9238,7 +9254,7 @@ flatpak_dir_cache_summary (FlatpakDir *self,
G_UNLOCK (cache);
}
static gboolean
gboolean
flatpak_dir_remote_make_oci_summary (FlatpakDir *self,
const char *remote,
GBytes **out_summary,
@@ -9253,43 +9269,69 @@ flatpak_dir_remote_make_oci_summary (FlatpakDir *self,
g_autoptr(GError) local_error = NULL;
g_autoptr(GMappedFile) mfile = NULL;
g_autoptr(GBytes) cache_bytes = NULL;
g_autoptr(GBytes) summary_bytes = NULL;
self_name = flatpak_dir_get_name (self);
index_cache = flatpak_dir_update_oci_index (self, remote, &index_uri, cancellable, error);
if (index_cache == NULL)
return FALSE;
summary_cache = flatpak_dir_get_oci_summary_location (self, remote, error);
if (summary_cache == NULL)
return FALSE;
if (check_destination_mtime (index_cache, summary_cache, cancellable))
if (flatpak_dir_use_system_helper (self, NULL))
{
mfile = g_mapped_file_new (flatpak_file_get_path_cached (summary_cache), FALSE, NULL);
if (mfile)
const char *installation = flatpak_dir_get_id (self);
if (!flatpak_dir_system_helper_call_generate_oci_summary (self, remote,
installation ? installation : "",
cancellable, error))
return FALSE;
summary_cache = flatpak_dir_get_oci_summary_location (self, remote, error);
if (summary_cache == NULL)
return FALSE;
}
else
{
self_name = flatpak_dir_get_name (self);
index_cache = flatpak_dir_update_oci_index (self, remote, &index_uri, cancellable, error);
if (index_cache == NULL)
return FALSE;
summary_cache = flatpak_dir_get_oci_summary_location (self, remote, error);
if (summary_cache == NULL)
return FALSE;
if (!check_destination_mtime (index_cache, summary_cache, cancellable))
{
cache_bytes = g_mapped_file_get_bytes (mfile);
*out_summary = g_steal_pointer (&cache_bytes);
summary = flatpak_oci_index_make_summary (index_cache, index_uri, cancellable, &local_error);
if (summary == NULL)
{
g_propagate_error (error, g_steal_pointer (&local_error));
return FALSE;
}
summary_bytes = g_variant_get_data_as_bytes (summary);
if (!g_file_replace_contents (summary_cache,
g_bytes_get_data (summary_bytes, NULL),
g_bytes_get_size (summary_bytes),
NULL, FALSE, 0, NULL, cancellable, error))
{
g_prefix_error (error, _("Failed to write summary cache: "));
return FALSE;
}
if (out_summary)
*out_summary = g_steal_pointer (&summary_bytes);
return TRUE;
}
}
summary = flatpak_oci_index_make_summary (index_cache, index_uri, cancellable, &local_error);
if (summary == NULL)
if (out_summary)
{
g_propagate_error (error, g_steal_pointer (&local_error));
return FALSE;
mfile = g_mapped_file_new (flatpak_file_get_path_cached (summary_cache), FALSE, error);
if (mfile == NULL)
return FALSE;
cache_bytes = g_mapped_file_get_bytes (mfile);
*out_summary = g_steal_pointer (&cache_bytes);
}
*out_summary = g_variant_get_data_as_bytes (summary);
if (!g_file_replace_contents (summary_cache,
g_bytes_get_data (*out_summary, NULL),
g_bytes_get_size (*out_summary),
NULL, FALSE, 0, NULL, cancellable, NULL))
g_warning ("Failed to write summary cache");
return TRUE;
}

View File

@@ -144,6 +144,11 @@
<arg type='s' name='installation' direction='in'/>
</method>
<method name="GenerateOciSummary">
<arg type='s' name='origin' direction='in'/>
<arg type='s' name='installation' direction='in'/>
</method>
</interface>
</node>

View File

@@ -1189,6 +1189,54 @@ handle_update_summary (FlatpakSystemHelper *object,
return TRUE;
}
static gboolean
handle_generate_oci_summary (FlatpakSystemHelper *object,
GDBusMethodInvocation *invocation,
const gchar *arg_origin,
const gchar *arg_installation)
{
g_autoptr(FlatpakDir) system = NULL;
g_autoptr(GError) error = NULL;
gboolean is_oci;
g_debug ("GenerateOciSummary %s %s", arg_origin, 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_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
"Can't open system repo %s", error->message);
return TRUE;
}
is_oci = flatpak_dir_get_remote_oci (system, arg_origin);
if (!is_oci)
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
"%s is not a OCI remote", arg_origin);
return TRUE;
}
if (!flatpak_dir_remote_make_oci_summary (system, arg_origin, NULL, NULL, &error))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
"Failed to update OCI summary: %s", error->message);
return TRUE;
}
flatpak_system_helper_complete_generate_oci_summary (object, invocation);
return TRUE;
}
static gboolean
flatpak_authorize_method_handler (GDBusInterfaceSkeleton *interface,
GDBusMethodInvocation *invocation,
@@ -1326,7 +1374,8 @@ flatpak_authorize_method_handler (GDBusInterfaceSkeleton *interface,
g_strcmp0 (method_name, "PruneLocalRepo") == 0 ||
g_strcmp0 (method_name, "EnsureRepo") == 0 ||
g_strcmp0 (method_name, "RunTriggers") == 0 ||
g_strcmp0 (method_name, "UpdateSummary") == 0)
g_strcmp0 (method_name, "UpdateSummary") == 0 ||
g_strcmp0 (method_name, "GenerateOciSummary") == 0)
{
action = "org.freedesktop.Flatpak.modify-repo";
}
@@ -1391,6 +1440,7 @@ on_bus_acquired (GDBusConnection *connection,
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, "handle-update-summary", G_CALLBACK (handle_update_summary), NULL);
g_signal_connect (helper, "handle-generate-oci-summary", G_CALLBACK (handle_generate_oci_summary), NULL);
g_signal_connect (helper, "g-authorize-method",
G_CALLBACK (flatpak_authorize_method_handler),