From 9e4bb25b2c389263bc146f5393f62ad0e1348df2 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Wed, 11 May 2016 15:43:40 +0200 Subject: [PATCH] modify-remote: Move the actual config rewriting to FlatpakDir This is in preparation for doing this in the system helper. --- app/flatpak-builtins-add-remote.c | 40 +++++++++++---- common/flatpak-dir.c | 81 +++++++++++++++++++++++++++++++ common/flatpak-dir.h | 6 +++ 3 files changed, 118 insertions(+), 9 deletions(-) diff --git a/app/flatpak-builtins-add-remote.c b/app/flatpak-builtins-add-remote.c index fe6b7b8f2..5186f63ac 100644 --- a/app/flatpak-builtins-add-remote.c +++ b/app/flatpak-builtins-add-remote.c @@ -118,6 +118,29 @@ open_source_stream (GInputStream **out_source_stream, return TRUE; } +GBytes * +load_keys (GCancellable *cancellable, + GError **error) +{ + g_autoptr(GInputStream) input_stream = NULL; + g_autoptr(GOutputStream) output_stream = NULL; + gssize n_bytes_written; + + if (!open_source_stream (&input_stream, cancellable, error)) + return FALSE; + + output_stream = g_memory_output_stream_new_resizable (); + + n_bytes_written = g_output_stream_splice (output_stream, input_stream, + G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | + G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, + NULL, error); + if (n_bytes_written < 0) + return NULL; + + return g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (output_stream)); +} + gboolean import_keys (FlatpakDir *dir, const char *remote_name, @@ -270,6 +293,7 @@ flatpak_builtin_modify_remote (int argc, char **argv, GCancellable *cancellable, g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GVariantBuilder) optbuilder = NULL; g_autoptr(GKeyFile) config = NULL; + g_autoptr(GBytes) gpg_data = NULL; const char *remote_name; g_autofree char *group = NULL; @@ -329,14 +353,12 @@ flatpak_builtin_modify_remote (int argc, char **argv, GCancellable *cancellable, g_key_file_set_string (config, group, "xa.prio", prio_as_string); } - if (!ostree_repo_write_config (flatpak_dir_get_repo (dir), config, error)) - return FALSE; + if (opt_gpg_import != NULL) + { + gpg_data = load_keys (cancellable, error); + if (gpg_data == NULL) + return FALSE; + } - if (!import_keys (dir, remote_name, cancellable, error)) - return FALSE; - - if (!flatpak_dir_mark_changed (dir, error)) - return FALSE; - - return TRUE; + return flatpak_dir_modify_remove (dir, remote_name, config, gpg_data, cancellable, error); } diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index f97e12571..2c0e1f02b 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -3901,6 +3901,87 @@ flatpak_dir_list_remotes (FlatpakDir *self, return res; } +gboolean +flatpak_dir_modify_remove (FlatpakDir *self, + const char *remote_name, + GKeyFile *config, + GBytes *gpg_data, + GCancellable *cancellable, + GError **error) +{ + g_autofree char *group = g_strdup_printf ("remote \"%s\"", remote_name); + g_autofree char *url = NULL; + g_autofree char *metalink = NULL; + g_autoptr(GKeyFile) new_config = NULL; + g_auto(GStrv) keys = NULL; + int i; + + if (strchr (remote_name, '/') != NULL) + return flatpak_fail (error, "Invalid character '/' in remote name: %s", + remote_name); + + + if (!g_key_file_has_group (config, group)) + return flatpak_fail (error, "No configuration for remote %s specified", + remote_name); + + metalink = g_key_file_get_string (config, group, "metalink", NULL); + if (metalink != NULL && *metalink != 0) + url = g_strconcat ("metalink=", metalink, NULL); + else + url = g_key_file_get_string (config, group, "url", NULL); + + if (url == NULL || *url == 0) + return flatpak_fail (error, "No url for remote %s specified", + remote_name); + + /* Add it if its not there yet */ + if (!ostree_repo_remote_change (self->repo, NULL, + OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS, + remote_name, + url, NULL, cancellable, error)) + return FALSE; + + new_config = ostree_repo_copy_config (self->repo); + + g_key_file_remove_group (new_config, group, NULL); + + keys = g_key_file_get_keys (config, + group, + NULL, error); + if (keys == NULL) + return FALSE; + + for (i = 0; keys[i] != NULL; i++) + { + g_autofree gchar *value = g_key_file_get_value (config, group, keys[i], NULL); + if (value) + g_key_file_set_value (new_config, group, keys[i], value); + } + + if (!ostree_repo_write_config (self->repo, config, error)) + return FALSE; + + if (gpg_data != NULL) + { + g_autoptr(GInputStream) input_stream = g_memory_input_stream_new_from_bytes (gpg_data); + guint imported = 0; + + if (!ostree_repo_remote_gpg_import (self->repo, remote_name, input_stream, + NULL, &imported, cancellable, error)) + return FALSE; + + /* XXX If we ever add internationalization, use ngettext() here. */ + g_debug ("Imported %u GPG key%s to remote \"%s\"", + imported, (imported == 1) ? "" : "s", remote_name); + } + + if (!flatpak_dir_mark_changed (self, error)) + return FALSE; + + return TRUE; +} + static gboolean remove_unless_in_hash (gpointer key, gpointer value, diff --git a/common/flatpak-dir.h b/common/flatpak-dir.h index f40811fc2..7f76e2d1b 100644 --- a/common/flatpak-dir.h +++ b/common/flatpak-dir.h @@ -326,6 +326,12 @@ char *flatpak_dir_create_origin_remote (FlatpakDir *self, char **flatpak_dir_list_remotes (FlatpakDir *self, GCancellable *cancellable, GError **error); +gboolean flatpak_dir_modify_remove (FlatpakDir *self, + const char *remote_name, + GKeyFile *config, + GBytes *gpg_data, + GCancellable *cancellable, + GError **error); char *flatpak_dir_get_remote_title (FlatpakDir *self, const char *remote_name); int flatpak_dir_get_remote_prio (FlatpakDir *self,