From 4de736fdfa6751139e7773eca09812d3b7ba5286 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 7 Jun 2017 12:38:59 +0100 Subject: [PATCH] lib/repo: Add collection ID support to OstreeRepo Add {get,set}_collection_id() methods to OstreeRepo and some documentation about the concept of a collection ID which globally identifies an upstream repository. See the documentation for more details. This will be used in future commits. For now, the new API is marked as experimental (--enable-experimental-api). Signed-off-by: Philip Withnall Closes: #924 Approved by: cgwalters --- apidoc/ostree-experimental-sections.txt | 2 + src/libostree/libostree-experimental.sym | 2 + src/libostree/ostree-repo-private.h | 11 ++++ src/libostree/ostree-repo.c | 83 ++++++++++++++++++++++++ src/libostree/ostree-repo.h | 11 ++++ 5 files changed, 109 insertions(+) diff --git a/apidoc/ostree-experimental-sections.txt b/apidoc/ostree-experimental-sections.txt index 30355967..16983ae8 100644 --- a/apidoc/ostree-experimental-sections.txt +++ b/apidoc/ostree-experimental-sections.txt @@ -23,5 +23,7 @@ ostree_remote_get_name
ostree-misc-experimental +ostree_repo_get_collection_id +ostree_repo_set_collection_id ostree_validate_collection_id
diff --git a/src/libostree/libostree-experimental.sym b/src/libostree/libostree-experimental.sym index 0dabd591..dad788b7 100644 --- a/src/libostree/libostree-experimental.sym +++ b/src/libostree/libostree-experimental.sym @@ -45,5 +45,7 @@ global: ostree_collection_ref_get_type; ostree_collection_ref_hash; ostree_collection_ref_new; + ostree_repo_get_collection_id; + ostree_repo_set_collection_id; ostree_validate_collection_id; } LIBOSTREE_2017.7_EXPERIMENTAL; diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 8f87b103..825c1ffc 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -20,6 +20,7 @@ #pragma once +#include "ostree-ref.h" #include "ostree-repo.h" #include "ostree-remote-private.h" #include "libglnx.h" @@ -129,6 +130,7 @@ struct OstreeRepo { gboolean enable_uncompressed_cache; gboolean generate_sizes; guint64 tmp_expiry_seconds; + gchar *collection_id; OstreeRepo *parent_repo; }; @@ -349,4 +351,13 @@ _ostree_repo_get_remote_inherited (OstreeRepo *self, const char *name, GError **error); +#ifndef OSTREE_ENABLE_EXPERIMENTAL_API + +const gchar * ostree_repo_get_collection_id (OstreeRepo *self); +gboolean ostree_repo_set_collection_id (OstreeRepo *self, + const gchar *collection_id, + GError **error); + +#endif /* !OSTREE_ENABLE_EXPERIMENTAL_API */ + G_END_DECLS diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index f2b7c21b..24e94e03 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -77,6 +77,25 @@ * Once the #OstreeMutableTree is complete, write all of its metadata * with ostree_repo_write_mtree(), and finally create a commit with * ostree_repo_write_commit(). + * + * ## Collection IDs + * + * A collection ID is a globally unique identifier which, if set, is used to + * identify refs from a repository which are mirrored elsewhere, such as in + * mirror repositories or peer to peer networks. + * + * This is separate from the `collection-id` configuration key for a remote, which + * is used to store the collection ID of the repository that remote points to. + * + * The collection ID should only be set on an #OstreeRepo if it is the canonical + * collection for some refs. + * + * A collection ID must be a reverse DNS name, where the domain name is under the + * control of the curator of the collection, so they can demonstrate ownership + * of the collection. The later elements in the reverse DNS name can be used to + * disambiguate between multiple collections from the same curator. For example, + * `org.exampleos.Main` and `org.exampleos.Apps`. For the complete format of + * collection IDs, see ostree_validate_collection_id(). */ typedef struct { GObjectClass parent_class; @@ -461,6 +480,7 @@ ostree_repo_finalize (GObject *object) g_clear_pointer (&self->dirmeta_cache, (GDestroyNotify) g_hash_table_unref); g_mutex_clear (&self->cache_lock); g_mutex_clear (&self->txn_stats_lock); + g_free (self->collection_id); g_clear_pointer (&self->remotes, g_hash_table_destroy); g_mutex_clear (&self->remotes_lock); @@ -1707,6 +1727,9 @@ ostree_repo_create (OstreeRepo *self, g_string_append_printf (config_data, "mode=%s\n", mode_str); + if (self->collection_id != NULL) + g_string_append_printf (config_data, "collection-id=%s\n", self->collection_id); + if (!glnx_file_replace_contents_at (dfd, "config", (guint8*)config_data->str, config_data->len, 0, cancellable, error)) @@ -1939,6 +1962,13 @@ reload_core_config (OstreeRepo *self, self->zlib_compression_level = OSTREE_ARCHIVE_DEFAULT_COMPRESSION_LEVEL; } + { + g_clear_pointer (&self->collection_id, g_free); + if (!ot_keyfile_get_value_with_default (self->config, "core", "collection-id", + NULL, &self->collection_id, NULL)) + return FALSE; + } + if (!ot_keyfile_get_value_with_default (self->config, "core", "parent", NULL, &parent_repo_path, error)) return FALSE; @@ -4827,3 +4857,56 @@ _ostree_repo_memory_cache_ref_destroy (OstreeRepoMemoryCacheRef *state) g_mutex_unlock (lock); g_object_unref (repo); } + +/** + * ostree_repo_get_collection_id: + * @self: an #OstreeRepo + * + * Get the collection ID of this repository. See [collection IDs][collection-ids]. + * + * Returns: (nullable): collection ID for the repository + * Since: 2017.8 + */ +const gchar * +ostree_repo_get_collection_id (OstreeRepo *self) +{ + g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); + + return self->collection_id; +} + +/** + * ostree_repo_set_collection_id: + * @self: an #OstreeRepo + * @collection_id: (nullable): new collection ID, or %NULL to unset it + * @error: return location for a #GError, or %NULL + * + * Set or clear the collection ID of this repository. See [collection IDs][collection-ids]. + * The update will be made in memory, but must be written out to the repository + * configuration on disk using ostree_repo_write_config(). + * + * Returns: %TRUE on success, %FALSE otherwise + * Since: 2017.8 + */ +gboolean +ostree_repo_set_collection_id (OstreeRepo *self, + const gchar *collection_id, + GError **error) +{ + if (collection_id != NULL && !ostree_validate_collection_id (collection_id, error)) + return FALSE; + + g_autofree gchar *new_collection_id = g_strdup (collection_id); + g_free (self->collection_id); + self->collection_id = g_steal_pointer (&new_collection_id); + + if (self->config != NULL) + { + if (collection_id != NULL) + g_key_file_set_string (self->config, "core", "collection-id", collection_id); + else + return g_key_file_remove_key (self->config, "core", "collection-id", error); + } + + return TRUE; +} diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 04294f33..566754d4 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -89,6 +89,17 @@ gboolean ostree_repo_create (OstreeRepo *self, GCancellable *cancellable, GError **error); +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API + +_OSTREE_PUBLIC +const gchar * ostree_repo_get_collection_id (OstreeRepo *self); +_OSTREE_PUBLIC +gboolean ostree_repo_set_collection_id (OstreeRepo *self, + const gchar *collection_id, + GError **error); + +#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ + _OSTREE_PUBLIC GFile * ostree_repo_get_path (OstreeRepo *self);