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 <withnall@endlessm.com>
This commit is contained in:
Philip Withnall
2017-06-26 15:33:39 +01:00
committed by Alexander Larsson
parent b5860e8f2a
commit f3c898da05
10 changed files with 185 additions and 3 deletions

View File

@@ -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];

View File

@@ -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))

View File

@@ -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 doesnt 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 well use for the commit. This might
* be %NULL if the existing repo doesnt 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
* were 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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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.
<!-- FIXME: Uncomment this when enable-p2p is enabled unconditionally.
The collection ID set on
<arg choice="plain">DST-REPO</arg> (if set) will be used for the
newly created commits.
-->
</para>
<para>
This command is very useful when you want to maintain a branch

View File

@@ -63,6 +63,16 @@
subdirectories and the <filename>metadata</filename> file are included
in the commit, anything else is ignored.
</para>
<!-- FIXME: Uncomment this when enable-p2p is enabled unconditionally.
<para>
When exporting a flatpak to be published to the internet,
<option>-FIXME-collection-id=COLLECTION-ID</option> should be specified
as a globally unique reverse DNS value to identify the collection of
flatpaks this will be added to. Setting a globally unique collection
ID allows the apps in the repository to be shared over peer to peer
systems without needing further configuration.
</para>
-->
<para>
The build-update-repo command should be used to update repository
metadata whenever application builds are added to a repository.
@@ -102,6 +112,21 @@
</para></listitem>
</varlistentry>
<!-- FIXME: Uncomment this when enable-p2p is enabled unconditionally.
<varlistentry>
<term><option>-FIXME-collection-id=COLLECTION-ID</option></term>
<listitem><para>
Set as the collection ID of the repository. Setting a globally
unique collection ID allows the apps in the repository to be shared over
peer to peer systems without needing further configuration.
If exporting to an existing repository, the collection ID
must match the existing configured collection ID for that
repository.
</para></listitem>
</varlistentry>
-->
<varlistentry>
<term><option>--arch=ARCH</option></term>

View File

@@ -102,6 +102,21 @@
</para></listitem>
</varlistentry>
<!-- FIXME: Uncomment this when enable-p2p is enabled unconditionally.
<varlistentry>
<term><option>-FIXME-collection-id=COLLECTION-ID</option></term>
<listitem><para>
The globally unique identifier of the remote repository, to
allow mirrors to be grouped. This must be set to a globally
unique reverse DNS string if the repository is to be made
publicly available. If a collection ID is already set on an
existing repository, this will update it. If not specified,
the existing collection ID will be left unchanged.
</para></listitem>
</varlistentry>
-->
<varlistentry>
<term><option>--gpg-sign=KEYID</option></term>

View File

@@ -187,6 +187,19 @@
</para></listitem>
</varlistentry>
<!-- FIXME: Uncomment this when enable-p2p is enabled unconditionally.
<varlistentry>
<term><option>-FIXME-collection-id=COLLECTION-ID</option></term>
<listitem><para>
The globally unique identifier of the remote repository, to
allow mirrors to be grouped. This must only be set to the
collection ID provided by the remote, and must not be set if the
remote does not provide an collection ID.
</para></listitem>
</varlistentry>
-->
<varlistentry>
<term><option>--url=URL</option></term>

View File

@@ -80,6 +80,12 @@
<term><option>gpg-verify-summary</option> (boolean)</term>
<listitem><para>Whether to use GPG verification for the summary of this remote.</para></listitem>
</varlistentry>
<!-- FIXME: Uncomment this when enable-p2p is enabled unconditionally.
<varlistentry>
<term><option>collection-id</option> (string)</term>
<listitem><para>The globally unique identifier for the upstream collection repository, to allow mirrors to be grouped.</para></listitem>
</varlistentry>
-->
</variablelist>
<para>
All flatpak-specific keys have a xa. prefix: