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 <withnall@endlessm.com>

Closes: #924
Approved by: cgwalters
This commit is contained in:
Philip Withnall 2017-06-07 12:38:59 +01:00 committed by Atomic Bot
parent 0a20e7d43c
commit 4de736fdfa
5 changed files with 109 additions and 0 deletions

View File

@ -23,5 +23,7 @@ ostree_remote_get_name
<SECTION>
<FILE>ostree-misc-experimental</FILE>
ostree_repo_get_collection_id
ostree_repo_set_collection_id
ostree_validate_collection_id
</SECTION>

View File

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

View File

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

View File

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

View File

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