From 54598331cc9640c414e3d2cbfbf9a7582e2d967b Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Tue, 11 Oct 2016 15:31:50 +0100 Subject: [PATCH 1/9] Wait until a remote has been added before incorporating its extra metadata We can't fetch the extra metadata from a repository's summary file before having added it locally, since ostree_repo_remote_fetch_summary() will fetch data by remote's name, and for that it needs to be added first. --- app/flatpak-builtins-add-remote.c | 48 ++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/app/flatpak-builtins-add-remote.c b/app/flatpak-builtins-add-remote.c index 9f687304..172a62c8 100644 --- a/app/flatpak-builtins-add-remote.c +++ b/app/flatpak-builtins-add-remote.c @@ -259,6 +259,35 @@ load_options (char *filename, } } +static gboolean +update_remote_with_extra_metadata (FlatpakDir* dir, + const char *remote, + GBytes *gpg_data, + GCancellable *cancellable, + GError **error) +{ + g_autofree char *title = NULL; + g_autoptr(GKeyFile) config = NULL; + + if (opt_title == NULL) + { + title = flatpak_dir_fetch_remote_title (dir, + remote, + NULL, + NULL); + if (title) + opt_title = title; + } + + if (title != NULL) + { + config = get_config_from_opts (dir, remote); + return flatpak_dir_modify_remote (dir, remote, config, gpg_data, cancellable, error); + } + + return TRUE; +} + gboolean flatpak_builtin_add_remote (int argc, char **argv, GCancellable *cancellable, GError **error) @@ -267,7 +296,6 @@ flatpak_builtin_add_remote (int argc, char **argv, g_autoptr(FlatpakDir) dir = NULL; g_autoptr(GFile) file = NULL; g_auto(GStrv) remotes = NULL; - g_autofree char *title = NULL; g_autofree char *remote_url = NULL; const char *remote_name; const char *url_or_path = NULL; @@ -323,17 +351,6 @@ flatpak_builtin_add_remote (int argc, char **argv, if (!opt_no_gpg_verify) opt_do_gpg_verify = TRUE; - - if (opt_title == NULL) - { - title = flatpak_dir_fetch_remote_title (dir, - remote_name, - NULL, - NULL); - if (title) - opt_title = title; - } - config = get_config_from_opts (dir, remote_name); if (opt_gpg_import != NULL) @@ -343,7 +360,12 @@ flatpak_builtin_add_remote (int argc, char **argv, return FALSE; } - return flatpak_dir_modify_remote (dir, remote_name, config, gpg_data, cancellable, error); + if (!flatpak_dir_modify_remote (dir, remote_name, config, gpg_data, cancellable, error)) + return FALSE; + + /* We can't retrieve the extra metadata until the remote has been added locally, since + ostree_repo_remote_fetch_summary() works with the repository's name, not its URL. */ + return update_remote_with_extra_metadata (dir, remote_name, gpg_data, cancellable, error); } gboolean From c492def9a71ecbed129d2c7277f0487f1a2f55e6 Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Tue, 11 Oct 2016 15:53:08 +0100 Subject: [PATCH 2/9] Fetch the default branch when adding a remote from its repo's summary file Just like we do with the title, fetch the default-branch from the repository's summary file and use that information when adding a remote reference from the command line. https://github.com/flatpak/flatpak/issues/221 --- app/flatpak-builtins-add-remote.c | 13 +++++++- common/flatpak-dir.c | 49 +++++++++++++++++++++++++++++++ common/flatpak-dir.h | 4 +++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/app/flatpak-builtins-add-remote.c b/app/flatpak-builtins-add-remote.c index 172a62c8..38b28e9a 100644 --- a/app/flatpak-builtins-add-remote.c +++ b/app/flatpak-builtins-add-remote.c @@ -267,6 +267,7 @@ update_remote_with_extra_metadata (FlatpakDir* dir, GError **error) { g_autofree char *title = NULL; + g_autofree char *default_branch = NULL; g_autoptr(GKeyFile) config = NULL; if (opt_title == NULL) @@ -279,7 +280,17 @@ update_remote_with_extra_metadata (FlatpakDir* dir, opt_title = title; } - if (title != NULL) + if (opt_default_branch == NULL) + { + default_branch = flatpak_dir_fetch_remote_default_branch (dir, + remote, + NULL, + NULL); + if (default_branch) + opt_default_branch = default_branch; + } + + if (title != NULL || default_branch != NULL) { config = get_config_from_opts (dir, remote); return flatpak_dir_modify_remote (dir, remote, config, gpg_data, cancellable, error); diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index a1e3cadc..2e244ae4 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -5260,6 +5260,55 @@ flatpak_dir_fetch_remote_title (FlatpakDir *self, return g_steal_pointer (&title); } +char * +flatpak_dir_fetch_remote_default_branch (FlatpakDir *self, + const char *remote, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GError) my_error = NULL; + g_autoptr(GBytes) summary_bytes = NULL; + g_autoptr(GVariant) summary = NULL; + g_autoptr(GVariant) extensions = NULL; + GVariantDict dict; + g_autofree char *default_branch = NULL; + + if (error == NULL) + error = &my_error; + + if (!flatpak_dir_ensure_repo (self, cancellable, error)) + return NULL; + + if (!flatpak_dir_remote_fetch_summary (self, remote, + &summary_bytes, + cancellable, error)) + return FALSE; + + if (summary_bytes == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, + _("Remote default-branch not available; server has no summary file")); + return FALSE; + } + + summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, + summary_bytes, FALSE)); + extensions = g_variant_get_child_value (summary, 1); + + g_variant_dict_init (&dict, extensions); + g_variant_dict_lookup (&dict, "xa.default-branch", "s", &default_branch); + g_variant_dict_end (&dict); + + if (default_branch == NULL) + { + g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + _("Remote default-branch not set")); + return FALSE; + } + + return g_steal_pointer (&default_branch); +} + static gboolean flatpak_dir_parse_summary_for_ref (FlatpakDir *self, GVariant *summary, diff --git a/common/flatpak-dir.h b/common/flatpak-dir.h index 9d74fcf4..6c372fbf 100644 --- a/common/flatpak-dir.h +++ b/common/flatpak-dir.h @@ -424,6 +424,10 @@ char * flatpak_dir_fetch_remote_title (FlatpakDir *self, const char *remote, GCancellable *cancellable, GError **error); +char * flatpak_dir_fetch_remote_default_branch (FlatpakDir *self, + const char *remote, + GCancellable *cancellable, + GError **error); gboolean flatpak_dir_fetch_ref_cache (FlatpakDir *self, const char *remote_name, const char *ref, From 7ed464834fa5dac01a7bec91cb3bca5c7e892acc Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Tue, 11 Oct 2016 16:16:22 +0100 Subject: [PATCH 3/9] Refactor code for fetching the remote's title and the default branch --- common/flatpak-dir.c | 64 +++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 2e244ae4..61a4f341 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -5211,18 +5211,14 @@ flatpak_dir_list_remote_refs (FlatpakDir *self, return TRUE; } -char * -flatpak_dir_fetch_remote_title (FlatpakDir *self, - const char *remote, - GCancellable *cancellable, - GError **error) +static GVariant * +fetch_remote_summary_file (FlatpakDir *self, + const char *remote, + GCancellable *cancellable, + GError **error) { g_autoptr(GError) my_error = NULL; g_autoptr(GBytes) summary_bytes = NULL; - g_autoptr(GVariant) summary = NULL; - g_autoptr(GVariant) extensions = NULL; - GVariantDict dict; - g_autofree char *title = NULL; if (error == NULL) error = &my_error; @@ -5233,17 +5229,35 @@ flatpak_dir_fetch_remote_title (FlatpakDir *self, if (!flatpak_dir_remote_fetch_summary (self, remote, &summary_bytes, cancellable, error)) - return FALSE; + return NULL; if (summary_bytes == NULL) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - _("Remote title not available; server has no summary file")); - return FALSE; + _("Remote extra metadata not available; server has no summary file")); + return NULL; } - summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, - summary_bytes, FALSE)); + return g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, + summary_bytes, FALSE)); +} + + +char * +flatpak_dir_fetch_remote_title (FlatpakDir *self, + const char *remote, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GVariant) summary = NULL; + g_autoptr(GVariant) extensions = NULL; + GVariantDict dict; + g_autofree char *title = NULL; + + summary = fetch_remote_summary_file (self, remote, cancellable, error); + if (summary == NULL) + return NULL; + extensions = g_variant_get_child_value (summary, 1); g_variant_dict_init (&dict, extensions); @@ -5266,33 +5280,15 @@ flatpak_dir_fetch_remote_default_branch (FlatpakDir *self, GCancellable *cancellable, GError **error) { - g_autoptr(GError) my_error = NULL; - g_autoptr(GBytes) summary_bytes = NULL; g_autoptr(GVariant) summary = NULL; g_autoptr(GVariant) extensions = NULL; GVariantDict dict; g_autofree char *default_branch = NULL; - if (error == NULL) - error = &my_error; - - if (!flatpak_dir_ensure_repo (self, cancellable, error)) + summary = fetch_remote_summary_file (self, remote, cancellable, error); + if (summary == NULL) return NULL; - if (!flatpak_dir_remote_fetch_summary (self, remote, - &summary_bytes, - cancellable, error)) - return FALSE; - - if (summary_bytes == NULL) - { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, - _("Remote default-branch not available; server has no summary file")); - return FALSE; - } - - summary = g_variant_ref_sink (g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, - summary_bytes, FALSE)); extensions = g_variant_get_child_value (summary, 1); g_variant_dict_init (&dict, extensions); From 69831c60ca122f80d146dda1392bc96d3651be75 Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Tue, 11 Oct 2016 15:15:32 +0100 Subject: [PATCH 4/9] Check flatpak_remote_get_default_branch() in test-lib.c --- lib/test-lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/test-lib.c b/lib/test-lib.c index 6df516c1..206fc0c1 100644 --- a/lib/test-lib.c +++ b/lib/test-lib.c @@ -357,11 +357,12 @@ main (int argc, char *argv[]) { FlatpakRemote *remote = g_ptr_array_index (remotes, i); g_autoptr(GPtrArray) refs = NULL; - g_print ("\nRemote: %s %d %s %s %d %d %s\n", + g_print ("\nRemote: %s %d %s %s %s %d %d %s\n", flatpak_remote_get_name (remote), flatpak_remote_get_prio (remote), flatpak_remote_get_url (remote), flatpak_remote_get_title (remote), + flatpak_remote_get_default_branch (remote), flatpak_remote_get_gpg_verify (remote), flatpak_remote_get_noenumerate (remote), g_file_get_path (flatpak_remote_get_appstream_dir (remote, NULL))); From 81d1bef4a0d421991a99221a1af66758962d5563 Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Tue, 11 Oct 2016 14:16:42 +0100 Subject: [PATCH 5/9] Support --default-branch when updating the repository summary file Add support for this flag in build-update-repo, so that we can define a default branch in the server side, to be picked by the clients. https://github.com/flatpak/flatpak/issues/221 --- app/flatpak-builtins-repo-update.c | 6 ++++++ common/flatpak-utils.c | 30 +++++++++++++++++++++++++++++- common/flatpak-utils.h | 3 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/app/flatpak-builtins-repo-update.c b/app/flatpak-builtins-repo-update.c index 25c7886e..e5656326 100644 --- a/app/flatpak-builtins-repo-update.c +++ b/app/flatpak-builtins-repo-update.c @@ -33,6 +33,7 @@ #include "flatpak-utils.h" static char *opt_title; +static char *opt_default_branch; static char *opt_gpg_homedir; static char **opt_gpg_key_ids; static gboolean opt_prune; @@ -41,6 +42,7 @@ static gint opt_prune_depth = -1; static GOptionEntry options[] = { { "title", 0, 0, G_OPTION_ARG_STRING, &opt_title, N_("A nice name to use for this repository"), N_("TITLE") }, + { "default-branch", 0, 0, G_OPTION_ARG_STRING, &opt_default_branch, N_("Default branch to use for this repository"), N_("BRANCH") }, { "gpg-sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_gpg_key_ids, N_("GPG Key ID to sign the summary with"), N_("KEY-ID") }, { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, N_("GPG Homedir to use when looking for keyrings"), N_("HOMEDIR") }, { "generate-static-deltas", 0, 0, G_OPTION_ARG_NONE, &opt_generate_deltas, N_("Generate delta files"), NULL }, @@ -376,6 +378,10 @@ flatpak_builtin_build_update_repo (int argc, char **argv, !flatpak_repo_set_title (repo, opt_title, error)) return FALSE; + if (opt_default_branch && + !flatpak_repo_set_default_branch (repo, opt_default_branch, error)) + return FALSE; + g_print (_("Updating appstream branch\n")); if (!flatpak_repo_generate_appstream (repo, (const char **) opt_gpg_key_ids, opt_gpg_homedir, cancellable, error)) return FALSE; diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c index 5ef07e6f..30ed6b1c 100644 --- a/common/flatpak-utils.c +++ b/common/flatpak-utils.c @@ -2179,6 +2179,27 @@ flatpak_repo_set_title (OstreeRepo *repo, return TRUE; } + +gboolean +flatpak_repo_set_default_branch (OstreeRepo *repo, + const char *branch, + GError **error) +{ + g_autoptr(GKeyFile) config = NULL; + + config = ostree_repo_copy_config (repo); + + if (branch) + g_key_file_set_string (config, "flatpak", "default-branch", branch); + else + g_key_file_remove_key (config, "flatpak", "default-branch", NULL); + + if (!ostree_repo_write_config (repo, config, error)) + return FALSE; + + return TRUE; +} + #define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \ "unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev") @@ -2299,6 +2320,7 @@ flatpak_repo_update (OstreeRepo *repo, GVariantBuilder ref_data_builder; GKeyFile *config; g_autofree char *title = NULL; + g_autofree char *default_branch = NULL; g_autoptr(GVariant) old_summary = NULL; g_autoptr(GHashTable) refs = NULL; const char *prefixes[] = { "appstream", "app", "runtime", NULL }; @@ -2312,12 +2334,18 @@ flatpak_repo_update (OstreeRepo *repo, config = ostree_repo_get_config (repo); if (config) - title = g_key_file_get_string (config, "flatpak", "title", NULL); + { + title = g_key_file_get_string (config, "flatpak", "title", NULL); + default_branch = g_key_file_get_string (config, "flatpak", "default-branch", NULL); + } if (title) g_variant_builder_add (&builder, "{sv}", "xa.title", g_variant_new_string (title)); + if (default_branch) + g_variant_builder_add (&builder, "{sv}", "xa.default-branch", + g_variant_new_string (default_branch)); g_variant_builder_init (&ref_data_builder, G_VARIANT_TYPE ("a{s(tts)}")); diff --git a/common/flatpak-utils.h b/common/flatpak-utils.h index 71006f0d..3b9bebe7 100644 --- a/common/flatpak-utils.h +++ b/common/flatpak-utils.h @@ -229,6 +229,9 @@ void flatpak_table_printer_print (FlatpakTablePrinter *printer); gboolean flatpak_repo_set_title (OstreeRepo *repo, const char *title, GError **error); +gboolean flatpak_repo_set_default_branch (OstreeRepo *repo, + const char *branch, + GError **error); gboolean flatpak_repo_update (OstreeRepo *repo, const char **gpg_key_ids, const char *gpg_homedir, From 44dcc77a1851438c3096b2493703e9b610772db7 Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Tue, 11 Oct 2016 14:44:25 +0100 Subject: [PATCH 6/9] Check and use the remote's default branch when installing flatpaks If no branch is explicitly stated when installing a flatpak, and several options (branches) are available for the same ID, we now check the remote's default branch and use that one, if it's defined and available for the app. https://github.com/flatpak/flatpak/issues/221 --- app/flatpak-builtins-install.c | 7 +++--- common/flatpak-dir.c | 44 ++++++++++++++++++++++------------ common/flatpak-dir.h | 1 + 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/app/flatpak-builtins-install.c b/app/flatpak-builtins-install.c index 89a0bd26..ce559bca 100644 --- a/app/flatpak-builtins-install.c +++ b/app/flatpak-builtins-install.c @@ -293,7 +293,7 @@ flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro const char *repository; char **prefs = NULL; int i, n_prefs; - const char *default_branch = NULL; + g_autofree char *default_branch = NULL; FlatpakKinds kinds; g_autoptr(GPtrArray) refs = NULL; @@ -322,7 +322,7 @@ flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro /* Backwards compat for old "REPOSITORY NAME [BRANCH]" argument version */ if (argc == 4 && looks_like_branch (argv[3])) { - default_branch = argv[3]; + default_branch = g_strdup (argv[3]); n_prefs = 1; } @@ -343,7 +343,8 @@ flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro &matched_kinds, &id, &arch, &branch, error)) return FALSE; - ref = flatpak_dir_find_remote_ref (dir, repository, id, branch, arch, + default_branch = flatpak_dir_get_remote_default_branch (dir, repository); + ref = flatpak_dir_find_remote_ref (dir, repository, id, branch, default_branch, arch, matched_kinds, &kind, cancellable, error); if (ref == NULL) return FALSE; diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 61a4f341..441da409 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -4362,6 +4362,7 @@ static char * find_matching_ref (GHashTable *refs, const char *name, const char *opt_branch, + const char *opt_default_branch, const char *opt_arch, FlatpakKinds kinds, GError **error) @@ -4377,6 +4378,7 @@ find_matching_ref (GHashTable *refs, for (i = 0; arches[i] != NULL; i++) { g_autoptr(GPtrArray) matched_refs = NULL; + int j; matched_refs = find_matching_refs (refs, name, opt_branch, arches[i], kinds, error); @@ -4386,25 +4388,36 @@ find_matching_ref (GHashTable *refs, if (matched_refs->len == 0) continue; - if (matched_refs->len > 1) + if (matched_refs->len == 1) + return g_strdup (g_ptr_array_index (matched_refs, 0)); + + /* Multiple refs found, see if some belongs to the default branch, if passed */ + if (opt_default_branch != NULL) { - int i; - g_autoptr(GString) err = g_string_new (""); - g_string_printf (err, "Multiple branches available for %s, you must specify one of: ", name); - for (i = 0; i < matched_refs->len; i++) + for (j = 0; j < matched_refs->len; j++) { - g_auto(GStrv) parts = flatpak_decompose_ref (g_ptr_array_index (matched_refs, i), NULL); - if (i != 0) - g_string_append (err, ", "); + char *current_ref = g_ptr_array_index (matched_refs, j); + g_auto(GStrv) parts = flatpak_decompose_ref (current_ref, NULL); - g_string_append (err, parts[3]); + if (g_strcmp0 (opt_default_branch, parts[3]) == 0) + return g_strdup (current_ref); } - - flatpak_fail (error, err->str); - return NULL; } - return g_strdup (g_ptr_array_index (matched_refs, 0)); + /* Nothing to do other than reporting the different choices */ + g_autoptr(GString) err = g_string_new (""); + g_string_printf (err, "Multiple branches available for %s, you must specify one of: ", name); + for (j = 0; j < matched_refs->len; j++) + { + g_auto(GStrv) parts = flatpak_decompose_ref (g_ptr_array_index (matched_refs, j), NULL); + if (j != 0) + g_string_append (err, ", "); + + g_string_append (err, parts[3]); + } + + flatpak_fail (error, err->str); + return NULL; } g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, @@ -4446,6 +4459,7 @@ flatpak_dir_find_remote_ref (FlatpakDir *self, const char *remote, const char *name, const char *opt_branch, + const char *opt_default_branch, const char *opt_arch, FlatpakKinds kinds, FlatpakKinds *out_kind, @@ -4463,7 +4477,7 @@ flatpak_dir_find_remote_ref (FlatpakDir *self, &remote_refs, cancellable, error)) return NULL; - remote_ref = find_matching_ref (remote_refs, name, opt_branch, + remote_ref = find_matching_ref (remote_refs, name, opt_branch, opt_default_branch, opt_arch, kinds, &my_error); if (remote_ref == NULL) { @@ -4580,7 +4594,7 @@ flatpak_dir_find_installed_ref (FlatpakDir *self, if (local_refs == NULL) return NULL; - local_ref = find_matching_ref (local_refs, opt_name, opt_branch, + local_ref = find_matching_ref (local_refs, opt_name, opt_branch, NULL, opt_arch, kinds, &my_error); if (local_ref == NULL) { diff --git a/common/flatpak-dir.h b/common/flatpak-dir.h index 6c372fbf..34561e8f 100644 --- a/common/flatpak-dir.h +++ b/common/flatpak-dir.h @@ -157,6 +157,7 @@ char * flatpak_dir_find_remote_ref (FlatpakDir *self, const char *remote, const char *name, const char *opt_branch, + const char *opt_default_branch, const char *opt_arch, FlatpakKinds kinds, FlatpakKinds *out_kind, From 7e5f2580a6ba9756a2b3458a60df9d0d5483bef6 Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Thu, 13 Oct 2016 17:48:07 +0100 Subject: [PATCH 7/9] New internal API to update configuration of remotes from their summary file The new function flatpak_dir_update_remote_configuration() can be called to fetch the contents of the summary file from the remote's source location and update the local configuration in the installation directory accordingly. For now, only the xa.title and xa.default-branch configuration parameters are supported, since those seem to be the only relevant ones at the moment. --- common/flatpak-dir.c | 78 ++++++++++++++++++++++++++++++++++++++++++++ common/flatpak-dir.h | 4 +++ 2 files changed, 82 insertions(+) diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 441da409..24f7bd46 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -5319,6 +5319,84 @@ flatpak_dir_fetch_remote_default_branch (FlatpakDir *self, return g_steal_pointer (&default_branch); } +gboolean +flatpak_dir_update_remote_configuration (FlatpakDir *self, + const char *remote, + GCancellable *cancellable, + GError **error) +{ + /* We only support those configuration parameters that can + be set in the server when building the repo (see the + flatpak_repo_set_* () family of functions) */ + static const char *const supported_params[] = { + "xa.title", + "xa.default-branch", NULL + }; + + g_autoptr(GVariant) summary = NULL; + g_autoptr(GVariant) extensions = NULL; + g_autoptr(GPtrArray) updated_params = g_ptr_array_new_with_free_func (g_free); + GVariantIter iter; + + summary = fetch_remote_summary_file (self, remote, cancellable, error); + if (summary == NULL) + return FALSE; + + extensions = g_variant_get_child_value (summary, 1); + + g_variant_iter_init (&iter, extensions); + if (g_variant_iter_n_children (&iter) > 0) + { + GVariant *value_var = NULL; + char *key = NULL; + + while (g_variant_iter_next (&iter, "{sv}", &key, &value_var)) + { + /* At the moment, every supported parameter are strings */ + if (g_strv_contains (supported_params, key) && + g_variant_get_type_string (value_var)) + { + const char *value = g_variant_get_string(value_var, NULL); + if (value != NULL && *value != 0) + { + g_ptr_array_add (updated_params, g_strdup (key)); + g_ptr_array_add (updated_params, g_strdup (value)); + } + } + + g_variant_unref (value_var); + g_free (key); + } + } + + if (updated_params->len > 0) + { + g_autoptr(GKeyFile) config = NULL; + g_autofree char *group = NULL; + int i; + + config = ostree_repo_copy_config (flatpak_dir_get_repo (self)); + group = g_strdup_printf ("remote \"%s\"", remote); + + i = 0; + while (i < (updated_params->len - 1)) + { + /* This array should have an even number of elements with + keys in the odd positions and values on even ones. */ + g_key_file_set_string (config, group, + g_ptr_array_index (updated_params, i), + g_ptr_array_index (updated_params, i+1)); + i += 2; + } + + /* Update the local remote configuration with the updated info. */ + if (!flatpak_dir_modify_remote (self, remote, config, NULL, cancellable, error)) + return FALSE; + } + + return TRUE; +} + static gboolean flatpak_dir_parse_summary_for_ref (FlatpakDir *self, GVariant *summary, diff --git a/common/flatpak-dir.h b/common/flatpak-dir.h index 34561e8f..273c0dd4 100644 --- a/common/flatpak-dir.h +++ b/common/flatpak-dir.h @@ -429,6 +429,10 @@ char * flatpak_dir_fetch_remote_default_branch (FlatpakDir *self, const char *remote, GCancellable *cancellable, GError **error); +gboolean flatpak_dir_update_remote_configuration (FlatpakDir *self, + const char *remote, + GCancellable *cancellable, + GError **error); gboolean flatpak_dir_fetch_ref_cache (FlatpakDir *self, const char *remote_name, const char *ref, From 2cbb1da9357861244716fafce6a9788b67547be1 Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Fri, 14 Oct 2016 10:22:21 +0100 Subject: [PATCH 8/9] Added new parameter for the remote-modify built-in command: --update This new command relies on flatpak_dir_update_remote_configuration() and allows updating the local configuration for the remotes based on the extra metadata present in the OSTree repo's summary file. This parameter can still be combined with --title and --default-branch, which take precedence when combined with --update. --- app/flatpak-builtins-add-remote.c | 14 ++++++++++++++ doc/flatpak-remote-modify.xml | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/app/flatpak-builtins-add-remote.c b/app/flatpak-builtins-add-remote.c index 38b28e9a..3d823818 100644 --- a/app/flatpak-builtins-add-remote.c +++ b/app/flatpak-builtins-add-remote.c @@ -47,6 +47,7 @@ static gboolean opt_do_enumerate; static gboolean opt_no_enumerate; static gboolean opt_if_not_exists; static gboolean opt_enable; +static gboolean opt_update_metadata; static gboolean opt_disable; static int opt_prio = -1; static char *opt_title; @@ -67,6 +68,7 @@ static GOptionEntry modify_options[] = { { "enumerate", 0, 0, G_OPTION_ARG_NONE, &opt_do_enumerate, N_("Mark the remote as enumerate"), NULL }, { "url", 0, 0, G_OPTION_ARG_STRING, &opt_url, N_("Set a new url"), N_("URL") }, { "enable", 0, 0, G_OPTION_ARG_NONE, &opt_enable, N_("Enable the remote"), NULL }, + { "update-metadata", 0, 0, G_OPTION_ARG_NONE, &opt_update_metadata, N_("Update extra metadata from the summary file"), NULL }, { NULL } }; @@ -430,6 +432,18 @@ flatpak_builtin_modify_remote (int argc, char **argv, GCancellable *cancellable, if (!ostree_repo_remote_get_url (flatpak_dir_get_repo (dir), remote_name, NULL, NULL)) return flatpak_fail (error, _("No remote %s"), remote_name); + if (opt_update_metadata) + { + g_autoptr(GError) local_error = NULL; + + g_print (_("Updating extra metadata from remote summary for %s\n"), remote_name); + if (!flatpak_dir_update_remote_configuration (dir, remote_name, cancellable, &local_error)) + { + g_printerr (_("Error updating extra metadata for '%s': %s\n"), remote_name, local_error->message); + return flatpak_fail (error, _("Could not update extra metadata for %s"), remote_name); + } + } + config = get_config_from_opts (dir, remote_name); if (opt_gpg_import != NULL) diff --git a/doc/flatpak-remote-modify.xml b/doc/flatpak-remote-modify.xml index a2743389..92c162af 100644 --- a/doc/flatpak-remote-modify.xml +++ b/doc/flatpak-remote-modify.xml @@ -158,6 +158,18 @@ + + + + + A default branch to for the remote, mainly for use in a UI. + + + Update the remote's extra metadata from the OSTree repository's summary + file. Only xa.title and xa.default-branch are supported at the moment. + + + From 8decac7d7ff38196167cca507193b13e348b0787 Mon Sep 17 00:00:00 2001 From: Mario Sanchez Prada Date: Thu, 13 Oct 2016 18:12:36 +0100 Subject: [PATCH 9/9] Added new public API: flatpak_installation_update_remote_sync() Provides access to the functionality offered by the new internal API flatpak_dir_update_remote_configuration(), in a similar way to what can be done via the command 'flatpak remote-modify --update-metadata'. --- doc/reference/flatpak-sections.txt | 1 + lib/flatpak-installation.c | 39 ++++++++++++++++++++++++++++++ lib/flatpak-installation.h | 4 +++ 3 files changed, 44 insertions(+) diff --git a/doc/reference/flatpak-sections.txt b/doc/reference/flatpak-sections.txt index 0f117e35..7c32306e 100644 --- a/doc/reference/flatpak-sections.txt +++ b/doc/reference/flatpak-sections.txt @@ -29,6 +29,7 @@ flatpak_installation_install_bundle flatpak_installation_drop_caches flatpak_installation_modify_remote flatpak_installation_remove_remote +flatpak_installation_update_remote_sync flatpak_get_default_arch FlatpakProgressCallback FlatpakUpdateFlags diff --git a/lib/flatpak-installation.c b/lib/flatpak-installation.c index 4ab6e6b5..0e473ced 100644 --- a/lib/flatpak-installation.c +++ b/lib/flatpak-installation.c @@ -798,6 +798,45 @@ flatpak_installation_remove_remote (FlatpakInstallation *self, return TRUE; } +/** + * flatpak_installation_update_remote_sync: + * @self: a #FlatpakInstallation + * @name: the name of the remote to update + * @cancellable: (nullable): a #GCancellable + * @error: return location for a #GError + * + * Updates the local configuration of a remote repository by fetching + * the related information from the summary file in the remote OSTree + * repository and committing the changes to the local installation. + * + * Returns: %TRUE if the remote has been updated successfully + * + * Since: 0.6.13 + */ +gboolean +flatpak_installation_update_remote_sync (FlatpakInstallation *self, + const char *name, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(FlatpakDir) dir = flatpak_installation_get_dir (self); + g_autoptr(FlatpakDir) dir_clone = NULL; + + /* We clone the dir here to make sure we re-read the latest ostree repo config, in case + it has local changes */ + dir_clone = flatpak_dir_clone (dir); + if (!flatpak_dir_ensure_repo (dir_clone, cancellable, error)) + return FALSE; + + if (!flatpak_dir_update_remote_configuration (dir, name, cancellable, error)) + return FALSE; + + /* Make sure we pick up the new config */ + flatpak_installation_drop_caches (self, NULL, NULL); + + return TRUE; +} + /** * flatpak_installation_get_remote_by_name: * @self: a #FlatpakInstallation diff --git a/lib/flatpak-installation.h b/lib/flatpak-installation.h index bdaeb52d..1b059e41 100644 --- a/lib/flatpak-installation.h +++ b/lib/flatpak-installation.h @@ -158,6 +158,10 @@ FLATPAK_EXTERN gboolean flatpak_installation_remove_remote (Flatpak const char *name, GCancellable *cancellable, GError **error); +FLATPAK_EXTERN gboolean flatpak_installation_update_remote_sync (FlatpakInstallation *self, + const char *name, + GCancellable *cancellable, + GError **error); FLATPAK_EXTERN char * flatpak_installation_load_app_overrides (FlatpakInstallation *self, const char *app_id, GCancellable *cancellable,