From f3c898da05a92d96841a962284a6924612552a7a Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 26 Jun 2017 15:33:39 +0100 Subject: [PATCH] app: Add support for collection IDs to built-in flatpak commands This sets the collection ID on remote configs and in commit metadata when building flatpaks. Signed-off-by: Philip Withnall --- app/flatpak-builtins-add-remote.c | 22 +++++++++ app/flatpak-builtins-build-commit-from.c | 30 +++++++++++- app/flatpak-builtins-build-export.c | 60 +++++++++++++++++++++++- app/flatpak-builtins-repo-update.c | 8 ++++ app/flatpak-builtins-repo.c | 4 ++ doc/flatpak-build-commit-from.xml | 5 ++ doc/flatpak-build-export.xml | 25 ++++++++++ doc/flatpak-build-update-repo.xml | 15 ++++++ doc/flatpak-remote-modify.xml | 13 +++++ doc/flatpak-remote.xml | 6 +++ 10 files changed, 185 insertions(+), 3 deletions(-) diff --git a/app/flatpak-builtins-add-remote.c b/app/flatpak-builtins-add-remote.c index 60651ec2..34f63717 100644 --- a/app/flatpak-builtins-add-remote.c +++ b/app/flatpak-builtins-add-remote.c @@ -48,6 +48,7 @@ static int opt_prio = -1; static char *opt_title; static char *opt_default_branch; static char *opt_url; +static char *opt_collection_id = NULL; static gboolean opt_from; static char **opt_gpg_import; @@ -75,6 +76,9 @@ static GOptionEntry common_options[] = { { "prio", 0, 0, G_OPTION_ARG_INT, &opt_prio, N_("Set priority (default 1, higher is more prioritized)"), N_("PRIORITY") }, { "title", 0, 0, G_OPTION_ARG_STRING, &opt_title, N_("A nice name to use for this remote"), N_("TITLE") }, { "default-branch", 0, 0, G_OPTION_ARG_STRING, &opt_default_branch, N_("Default branch to use for this remote"), N_("BRANCH") }, +#ifdef FLATPAK_ENABLE_P2P + { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, N_("Collection ID"), N_("COLLECTION-ID") }, +#endif /* FLATPAK_ENABLE_P2P */ { "gpg-import", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_gpg_import, N_("Import GPG key from FILE (- for stdin)"), N_("FILE") }, { "disable", 0, 0, G_OPTION_ARG_NONE, &opt_disable, N_("Disable the remote"), NULL }, { "oci", 0, 0, G_OPTION_ARG_NONE, &opt_oci, N_("Add OCI registry"), NULL }, @@ -111,6 +115,12 @@ get_config_from_opts (FlatpakDir *dir, const char *remote_name, gboolean *change *changed = TRUE; } + if (opt_collection_id) + { + g_key_file_set_string (config, group, "collection-id", opt_collection_id); + *changed = TRUE; + } + if (opt_title) { g_key_file_set_string (config, group, "xa.title", opt_title); @@ -237,6 +247,12 @@ load_options (const char *filename, if (str != NULL) opt_url = str; +#ifdef FLATPAK_ENABLE_P2P + str = g_key_file_get_string (keyfile, FLATPAK_REPO_GROUP, FLATPAK_REPO_COLLECTION_ID_KEY, NULL); + if (str != NULL) + opt_collection_id = str; +#endif /* FLATPAK_ENABLE_P2P */ + str = g_key_file_get_locale_string (keyfile, FLATPAK_REPO_GROUP, FLATPAK_REPO_TITLE_KEY, NULL, NULL); if (str != NULL) @@ -309,6 +325,12 @@ flatpak_builtin_add_remote (int argc, char **argv, if (argc > 3) return usage_error (context, _("Too many arguments"), error); +#ifdef FLATPAK_ENABLE_P2P + if (opt_collection_id != NULL && + !ostree_validate_collection_id (opt_collection_id, &local_error)) + return flatpak_fail (error, _("‘%s’ is not a valid collection ID: %s"), opt_collection_id, local_error->message); +#endif /* FLATPAK_ENABLE_P2P */ + remote_name = argv[1]; location = argv[2]; diff --git a/app/flatpak-builtins-build-commit-from.c b/app/flatpak-builtins-build-commit-from.c index 39c676b9..dde8c50e 100644 --- a/app/flatpak-builtins-build-commit-from.c +++ b/app/flatpak-builtins-build-commit-from.c @@ -232,6 +232,7 @@ flatpak_builtin_build_commit_from (int argc, char **argv, GCancellable *cancella g_autofree char *commit_checksum = NULL; GVariantBuilder metadata_builder; gint j; + const char *dst_collection_id = NULL; if (!ostree_repo_resolve_rev (dst_repo, dst_ref, TRUE, &dst_parent, error)) return FALSE; @@ -273,9 +274,22 @@ flatpak_builtin_build_commit_from (int argc, char **argv, GCancellable *cancella if (opt_body) body = (const char *)opt_body; +#ifdef FLATPAK_ENABLE_P2P + dst_collection_id = ostree_repo_get_collection_id (dst_repo); +#endif /* FLATPAK_ENABLE_P2P */ + /* Copy old metadata */ g_variant_builder_init (&metadata_builder, G_VARIANT_TYPE ("a{sv}")); + + /* Bindings. xa.ref is deprecated but added anyway for backwards compatibility. + * Add the bindings even if we are not built with P2P support, since other + * flatpak builds might be. */ + g_variant_builder_add (&metadata_builder, "{sv}", "ostree.collection-binding", + g_variant_new_string (dst_collection_id ? dst_collection_id : "")); + g_variant_builder_add (&metadata_builder, "{sv}", "ostree.ref-binding", + g_variant_new_strv (&dst_ref, 1)); g_variant_builder_add (&metadata_builder, "{sv}", "xa.ref", g_variant_new_string (dst_ref)); + /* Record the source commit. This is nice to have, but it also means the commit-from gets a different commit id, which avoids problems with e.g. sharing .commitmeta files @@ -289,7 +303,9 @@ flatpak_builtin_build_commit_from (int argc, char **argv, GCancellable *cancella const char *key = g_variant_get_string (keyv, NULL); if (strcmp (key, "xa.ref") == 0 || - strcmp (key, "xa.from_commit") == 0) + strcmp (key, "xa.from_commit") == 0 || + strcmp (key, "ostree.collection-binding") == 0 || + strcmp (key, "ostree.ref-binding") == 0) continue; g_variant_builder_add_value (&metadata_builder, child); @@ -330,7 +346,17 @@ flatpak_builtin_build_commit_from (int argc, char **argv, GCancellable *cancella } } - ostree_repo_transaction_set_ref (dst_repo, NULL, dst_ref, commit_checksum); +#ifdef FLATPAK_ENABLE_P2P + if (dst_collection_id != NULL) + { + OstreeCollectionRef ref = { (char *) dst_collection_id, (char *) dst_ref }; + ostree_repo_transaction_set_collection_ref (dst_repo, &ref, commit_checksum); + } + else +#endif /* FLATPAK_ENABLE_P2P */ + { + ostree_repo_transaction_set_ref (dst_repo, NULL, dst_ref, commit_checksum); + } } if (!ostree_repo_commit_transaction (dst_repo, NULL, cancellable, error)) diff --git a/app/flatpak-builtins-build-export.c b/app/flatpak-builtins-build-export.c index 788a074e..fd0c85c0 100644 --- a/app/flatpak-builtins-build-export.c +++ b/app/flatpak-builtins-build-export.c @@ -45,6 +45,9 @@ static char *opt_gpg_homedir; static char *opt_files; static char *opt_metadata; static char *opt_timestamp = NULL; +#ifdef FLATPAK_ENABLE_P2P +static char *opt_collection_id = NULL; +#endif /* FLATPAK_ENABLE_P2P */ static GOptionEntry options[] = { { "subject", 's', 0, G_OPTION_ARG_STRING, &opt_subject, N_("One line subject"), N_("SUBJECT") }, @@ -60,6 +63,9 @@ static GOptionEntry options[] = { { "include", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_include, N_("Excluded files to include"), N_("PATTERN") }, { "gpg-homedir", 0, 0, G_OPTION_ARG_STRING, &opt_gpg_homedir, N_("GPG Homedir to use when looking for keyrings"), N_("HOMEDIR") }, { "timestamp", 0, 0, G_OPTION_ARG_STRING, &opt_timestamp, N_("Override the timestamp of the commit"), N_("ISO-8601-TIMESTAMP") }, +#ifdef FLATPAK_ENABLE_P2P + { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, N_("Collection ID"), "COLLECTION-ID" }, +#endif /* FLATPAK_ENABLE_P2P */ { NULL } }; @@ -651,6 +657,7 @@ flatpak_builtin_build_export (int argc, char **argv, GCancellable *cancellable, gboolean is_extension = FALSE; guint64 installed_size = 0,download_size = 0; GTimeVal ts; + const char *collection_id; context = g_option_context_new (_("LOCATION DIRECTORY [BRANCH] - Create a repository from a build directory")); g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); @@ -678,6 +685,15 @@ flatpak_builtin_build_export (int argc, char **argv, GCancellable *cancellable, else branch = "master"; +#ifdef FLATPAK_ENABLE_P2P + if (opt_collection_id != NULL && + !ostree_validate_collection_id (opt_collection_id, &my_error)) + { + flatpak_fail (error, _("‘%s’ is not a valid collection ID: %s"), opt_collection_id, my_error->message); + goto out; + } +#endif /* FLATPAK_ENABLE_P2P */ + if (!flatpak_is_valid_branch (branch, &my_error)) { flatpak_fail (error, _("'%s' is not a valid branch name: %s"), branch, my_error->message); @@ -772,13 +788,37 @@ flatpak_builtin_build_export (int argc, char **argv, GCancellable *cancellable, if (!ostree_repo_resolve_rev (repo, full_branch, TRUE, &parent, error)) goto out; + +#ifdef FLATPAK_ENABLE_P2P + if (opt_collection_id != NULL && + g_strcmp0 (ostree_repo_get_collection_id (repo), opt_collection_id) != 0) + { + flatpak_fail (error, "Specified collection ID ‘%s’ doesn’t match collection ID in repository configuration ‘%s’.", + opt_collection_id, ostree_repo_get_collection_id (repo)); + goto out; + } +#endif /* FLATPAK_ENABLE_P2P */ } else { +#ifdef FLATPAK_ENABLE_P2P + if (opt_collection_id != NULL && + !ostree_repo_set_collection_id (repo, opt_collection_id, error)) + goto out; +#endif /* FLATPAK_ENABLE_P2P */ if (!ostree_repo_create (repo, OSTREE_REPO_MODE_ARCHIVE_Z2, cancellable, error)) goto out; } + /* Get the canonical collection ID which we’ll use for the commit. This might + * be %NULL if the existing repo doesn’t have one and none was specified on + * the command line. */ +#ifdef FLATPAK_ENABLE_P2P + collection_id = ostree_repo_get_collection_id (repo); +#else /* if !FLATPAK_ENABLE_P2P */ + collection_id = NULL; +#endif /* !FLATPAK_ENABLE_P2P */ + if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error)) goto out; @@ -836,7 +876,15 @@ flatpak_builtin_build_export (int argc, char **argv, GCancellable *cancellable, if (!flatpak_repo_collect_sizes (repo, root, &installed_size, &download_size, cancellable, error)) goto out; + /* Binding information. xa.ref is deprecated in favour of the OSTree keys, but + * keep it around for backwards compatibility. Write the bindings even if + * we’re compiled without P2P support, since other flatpak builds might be. */ + g_variant_dict_insert_value (&metadata_dict, "ostree.collection-binding", + g_variant_new_string ((collection_id != NULL) ? collection_id : "")); + g_variant_dict_insert_value (&metadata_dict, "ostree.ref-binding", + g_variant_new_strv ((const gchar * const *) &full_branch, 1)); g_variant_dict_insert_value (&metadata_dict, "xa.ref", g_variant_new_string (full_branch)); + g_variant_dict_insert_value (&metadata_dict, "xa.metadata", g_variant_new_string (metadata_contents)); g_variant_dict_insert_value (&metadata_dict, "xa.installed-size", g_variant_new_uint64 (GUINT64_TO_BE (installed_size))); g_variant_dict_insert_value (&metadata_dict, "xa.download-size", g_variant_new_uint64 (GUINT64_TO_BE (download_size))); @@ -889,7 +937,17 @@ flatpak_builtin_build_export (int argc, char **argv, GCancellable *cancellable, } } - ostree_repo_transaction_set_ref (repo, NULL, full_branch, commit_checksum); +#ifdef FLATPAK_ENABLE_P2P + if (collection_id != NULL) + { + OstreeCollectionRef ref = { (char *) collection_id, full_branch }; + ostree_repo_transaction_set_collection_ref (repo, &ref, commit_checksum); + } + else +#endif /* FLATPAK_ENABLE_P2P */ + { + ostree_repo_transaction_set_ref (repo, NULL, full_branch, commit_checksum); + } if (!ostree_repo_commit_transaction (repo, &stats, cancellable, error)) goto out; diff --git a/app/flatpak-builtins-repo-update.c b/app/flatpak-builtins-repo-update.c index b920926b..280958bb 100644 --- a/app/flatpak-builtins-repo-update.c +++ b/app/flatpak-builtins-repo-update.c @@ -36,6 +36,7 @@ static char *opt_title; static char *opt_redirect_url; static char *opt_default_branch; +static char *opt_collection_id = NULL; static char **opt_gpg_import; static char *opt_generate_delta_from; static char *opt_generate_delta_to; @@ -50,6 +51,9 @@ static GOptionEntry options[] = { { "redirect-url", 0, 0, G_OPTION_ARG_STRING, &opt_redirect_url, N_("Redirect this repo to a new URL"), N_("URL") }, { "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") }, +#ifdef FLATPAK_ENABLE_P2P + { "collection-id", 0, 0, G_OPTION_ARG_STRING, &opt_collection_id, N_("Collection ID"), N_("COLLECTION-ID") }, +#endif /* FLATPAK_ENABLE_P2P */ { "gpg-import", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_gpg_import, N_("Import new default GPG public key from FILE"), N_("FILE") }, { "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") }, @@ -435,6 +439,10 @@ flatpak_builtin_build_update_repo (int argc, char **argv, !flatpak_repo_set_default_branch (repo, opt_default_branch[0] ? opt_default_branch : NULL, error)) return FALSE; + if (opt_collection_id && + !flatpak_repo_set_collection_id (repo, opt_collection_id[0] ? opt_collection_id : NULL, error)) + return FALSE; + if (opt_gpg_import) { g_autoptr(GBytes) gpg_data = flatpak_load_gpg_keys (opt_gpg_import, cancellable, error); diff --git a/app/flatpak-builtins-repo.c b/app/flatpak-builtins-repo.c index 54de28f7..f4691e27 100644 --- a/app/flatpak-builtins-repo.c +++ b/app/flatpak-builtins-repo.c @@ -38,6 +38,7 @@ print_info (GVariant *meta) { g_autoptr(GVariant) cache = NULL; const char *title; + const char *collection_id; const char *default_branch; const char *redirect_url; g_autoptr(GVariant) gpg_keys = NULL; @@ -45,6 +46,9 @@ print_info (GVariant *meta) if (g_variant_lookup (meta, "xa.title", "&s", &title)) g_print ("Title: %s\n", title); + if (g_variant_lookup (meta, "collection-id", "&s", &collection_id)) + g_print ("Collection ID: %s\n", collection_id); + if (g_variant_lookup (meta, "xa.default-branch", "&s", &default_branch)) g_print ("Default branch: %s\n", default_branch); diff --git a/doc/flatpak-build-commit-from.xml b/doc/flatpak-build-commit-from.xml index 0ddf223e..52f39b0e 100644 --- a/doc/flatpak-build-commit-from.xml +++ b/doc/flatpak-build-commit-from.xml @@ -46,6 +46,11 @@ contents (and most of the metadata) taken from another branch, either from another repo, or from another branch in the same repository. + This command is very useful when you want to maintain a branch diff --git a/doc/flatpak-build-export.xml b/doc/flatpak-build-export.xml index 2d84cae9..ec3d077f 100644 --- a/doc/flatpak-build-export.xml +++ b/doc/flatpak-build-export.xml @@ -63,6 +63,16 @@ subdirectories and the metadata file are included in the commit, anything else is ignored. + The build-update-repo command should be used to update repository metadata whenever application builds are added to a repository. @@ -102,6 +112,21 @@ + + diff --git a/doc/flatpak-build-update-repo.xml b/doc/flatpak-build-update-repo.xml index b1369be0..953fd0e3 100644 --- a/doc/flatpak-build-update-repo.xml +++ b/doc/flatpak-build-update-repo.xml @@ -102,6 +102,21 @@ + + diff --git a/doc/flatpak-remote-modify.xml b/doc/flatpak-remote-modify.xml index f0c70bdd..3f5b58bc 100644 --- a/doc/flatpak-remote-modify.xml +++ b/doc/flatpak-remote-modify.xml @@ -187,6 +187,19 @@ + + diff --git a/doc/flatpak-remote.xml b/doc/flatpak-remote.xml index 1afa77ff..e263b8e1 100644 --- a/doc/flatpak-remote.xml +++ b/doc/flatpak-remote.xml @@ -80,6 +80,12 @@ (boolean) Whether to use GPG verification for the summary of this remote. + All flatpak-specific keys have a xa. prefix: