diff options
author | Philip Withnall <withnall@endlessm.com> | 2017-06-07 15:27:10 +0100 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2017-06-26 15:56:07 +0000 |
commit | 0a20e7d43c43c9d5793f0fdb5bf8422affa5d841 (patch) | |
tree | 3d9636d1489d1f7cf4f868777a98ddf4877c23c2 | |
parent | bf1f8eb0fa36204377127e335b01b4bb95666cb2 (diff) | |
download | ostree-0a20e7d43c43c9d5793f0fdb5bf8422affa5d841.tar.gz |
lib/ref: Add OstreeCollectionRef type for globally unique refs
This is a type representing the tuple (collection ID, ref name), which is
guaranteed to be globally unique. It will be used in upcoming commits.
It introduces the concept of a ‘collection’ which is a unique, curated
set of refs which lie in the same trust domain (i.e. all signed by the
same key and validated by the same developer). Flathub might be a
collection, for example; or the set of OS refs coming from a particular
OS vendor.
It includes a function for validating collection IDs.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #924
Approved by: cgwalters
-rw-r--r-- | Makefile-libostree-defines.am | 1 | ||||
-rw-r--r-- | Makefile-libostree.am | 2 | ||||
-rw-r--r-- | apidoc/ostree-experimental-sections.txt | 20 | ||||
-rw-r--r-- | src/libostree/libostree-experimental.sym | 13 | ||||
-rw-r--r-- | src/libostree/ostree-autocleanups.h | 2 | ||||
-rw-r--r-- | src/libostree/ostree-core-private.h | 11 | ||||
-rw-r--r-- | src/libostree/ostree-core.c | 32 | ||||
-rw-r--r-- | src/libostree/ostree-core.h | 5 | ||||
-rw-r--r-- | src/libostree/ostree-ref.c | 193 | ||||
-rw-r--r-- | src/libostree/ostree-ref.h | 90 | ||||
-rw-r--r-- | src/libostree/ostree-repo.h | 3 | ||||
-rw-r--r-- | src/libostree/ostree.h | 4 |
12 files changed, 375 insertions, 1 deletions
diff --git a/Makefile-libostree-defines.am b/Makefile-libostree-defines.am index aff7e52b..44b6cd0a 100644 --- a/Makefile-libostree-defines.am +++ b/Makefile-libostree-defines.am @@ -40,6 +40,7 @@ libostree_public_headers = \ if ENABLE_EXPERIMENTAL_API libostree_public_headers += \ + src/libostree/ostree-ref.h \ src/libostree/ostree-remote.h \ $(NULL) endif diff --git a/Makefile-libostree.am b/Makefile-libostree.am index 61ad1f4a..a9c392c1 100644 --- a/Makefile-libostree.am +++ b/Makefile-libostree.am @@ -94,6 +94,7 @@ libostree_1_la_SOURCES = \ src/libostree/ostree-linuxfsutil.c \ src/libostree/ostree-diff.c \ src/libostree/ostree-mutable-tree.c \ + src/libostree/ostree-ref.c \ src/libostree/ostree-remote.c \ src/libostree/ostree-remote-private.h \ src/libostree/ostree-repo.c \ @@ -151,6 +152,7 @@ libostree_1_la_SOURCES += \ endif if !ENABLE_EXPERIMENTAL_API libostree_1_la_SOURCES += \ + src/libostree/ostree-ref.h \ src/libostree/ostree-remote.h \ $(NULL) endif diff --git a/apidoc/ostree-experimental-sections.txt b/apidoc/ostree-experimental-sections.txt index 998a4f9c..30355967 100644 --- a/apidoc/ostree-experimental-sections.txt +++ b/apidoc/ostree-experimental-sections.txt @@ -1,7 +1,27 @@ <SECTION> +<FILE>ostree-ref</FILE> +OstreeCollectionRef +ostree_collection_ref_new +ostree_collection_ref_dup +ostree_collection_ref_free +ostree_collection_ref_hash +ostree_collection_ref_equal +OstreeCollectionRefv +ostree_collection_ref_dupv +ostree_collection_ref_freev +<SUBSECTION Standard> +ostree_collection_ref_get_type +</SECTION> + +<SECTION> <FILE>ostree-remote</FILE> OstreeRemote ostree_remote_ref ostree_remote_unref ostree_remote_get_name </SECTION> + +<SECTION> +<FILE>ostree-misc-experimental</FILE> +ostree_validate_collection_id +</SECTION> diff --git a/src/libostree/libostree-experimental.sym b/src/libostree/libostree-experimental.sym index 9ccca958..0dabd591 100644 --- a/src/libostree/libostree-experimental.sym +++ b/src/libostree/libostree-experimental.sym @@ -34,3 +34,16 @@ LIBOSTREE_2017.7_EXPERIMENTAL { global: ostree_remote_get_name; } LIBOSTREE_2017.6_EXPERIMENTAL; + +LIBOSTREE_2017.8_EXPERIMENTAL { +global: + ostree_collection_ref_dup; + ostree_collection_ref_dupv; + ostree_collection_ref_equal; + ostree_collection_ref_free; + ostree_collection_ref_freev; + ostree_collection_ref_get_type; + ostree_collection_ref_hash; + ostree_collection_ref_new; + ostree_validate_collection_id; +} LIBOSTREE_2017.7_EXPERIMENTAL; diff --git a/src/libostree/ostree-autocleanups.h b/src/libostree/ostree-autocleanups.h index 1fdb50ad..f683c2e3 100644 --- a/src/libostree/ostree-autocleanups.h +++ b/src/libostree/ostree-autocleanups.h @@ -60,6 +60,8 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeSysrootUpgrader, g_object_unref) G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (OstreeRepoCommitTraverseIter, ostree_repo_commit_traverse_iter_clear) #ifdef OSTREE_ENABLE_EXPERIMENTAL_API +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeCollectionRef, ostree_collection_ref_free) +G_DEFINE_AUTO_CLEANUP_FREE_FUNC (OstreeCollectionRefv, ostree_collection_ref_freev, NULL) G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRemote, ostree_remote_unref) #endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ diff --git a/src/libostree/ostree-core-private.h b/src/libostree/ostree-core-private.h index 72b88aba..a4a31034 100644 --- a/src/libostree/ostree-core-private.h +++ b/src/libostree/ostree-core-private.h @@ -173,6 +173,15 @@ _ostree_raw_file_to_archive_stream (GInputStream *input, GCancellable *cancellable, GError **error); - +#ifndef OSTREE_ENABLE_EXPERIMENTAL_API +gboolean ostree_validate_collection_id (const char *collection_id, GError **error); +#endif /* !OSTREE_ENABLE_EXPERIMENTAL_API */ + +#if (defined(OSTREE_COMPILATION) || GLIB_CHECK_VERSION(2, 44, 0)) && !defined(OSTREE_ENABLE_EXPERIMENTAL_API) +#include <libglnx.h> +#include "ostree-ref.h" +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeCollectionRef, ostree_collection_ref_free) +G_DEFINE_AUTO_CLEANUP_FREE_FUNC (OstreeCollectionRefv, ostree_collection_ref_freev, NULL) +#endif G_END_DECLS diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 32516b7c..c0b7cbe3 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -210,6 +210,38 @@ ostree_validate_remote_name (const char *remote_name, return TRUE; } +/** + * ostree_validate_collection_id: + * @rev: (nullable): A collection ID + * @error: Error + * + * Check whether the given @collection_id is valid. Return an error if it is + * invalid or %NULL. + * + * Valid collection IDs are reverse DNS names: + * * They are composed of 1 or more elements separated by a period (`.`) character. + * All elements must contain at least one character. + * * Each element must only contain the ASCII characters `[A-Z][a-z][0-9]_` and must not + * begin with a digit. + * * They must contain at least one `.` (period) character (and thus at least two elements). + * * They must not begin with a `.` (period) character. + * * They must not exceed 255 characters in length. + * + * (This makes their format identical to D-Bus interface names, for consistency.) + * + * Returns: %TRUE if @collection_id is a valid collection ID, %FALSE if it is invalid + * or %NULL + */ +gboolean +ostree_validate_collection_id (const char *collection_id, GError **error) +{ + /* Abuse g_dbus_is_interface_name(), since collection IDs have the same format. */ + if (collection_id == NULL || !g_dbus_is_interface_name (collection_id)) + return glnx_throw (error, "Invalid collection ID %s", collection_id); + + return TRUE; +} + GVariant * _ostree_file_header_new (GFileInfo *file_info, GVariant *xattrs) diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h index dc64d89b..fa9e5e86 100644 --- a/src/libostree/ostree-core.h +++ b/src/libostree/ostree-core.h @@ -242,6 +242,11 @@ int ostree_cmp_checksum_bytes (const guchar *a, const guchar *b); _OSTREE_PUBLIC gboolean ostree_validate_rev (const char *rev, GError **error); +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API +_OSTREE_PUBLIC +gboolean ostree_validate_collection_id (const char *collection_id, GError **error); +#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ + _OSTREE_PUBLIC gboolean ostree_validate_remote_name (const char *remote_name, GError **error); diff --git a/src/libostree/ostree-ref.c b/src/libostree/ostree-ref.c new file mode 100644 index 00000000..8c84946c --- /dev/null +++ b/src/libostree/ostree-ref.c @@ -0,0 +1,193 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright © 2017 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: + * - Philip Withnall <withnall@endlessm.com> + */ + +#include "config.h" + +#include <gio/gio.h> +#include <glib.h> +#include <glib-object.h> +#include <libglnx.h> + +#include "ostree-autocleanups.h" +#include "ostree-core.h" +#include "ostree-core-private.h" +#include "ostree-ref.h" + +G_DEFINE_BOXED_TYPE (OstreeCollectionRef, ostree_collection_ref, + ostree_collection_ref_dup, ostree_collection_ref_free) + +/** + * ostree_collection_ref_new: + * @collection_id: (nullable): a collection ID, or %NULL for a plain ref + * @ref_name: a ref name + * + * Create a new #OstreeCollectionRef containing (@collection_id, @ref_name). If + * @collection_id is %NULL, this is equivalent to a plain ref name string (not a + * refspec; no remote name is included), which can be used for non-P2P + * operations. + * + * Returns: (transfer full): a new #OstreeCollectionRef + * Since: 2017.8 + */ +OstreeCollectionRef * +ostree_collection_ref_new (const gchar *collection_id, + const gchar *ref_name) +{ + g_autoptr(OstreeCollectionRef) collection_ref = NULL; + + g_return_val_if_fail (collection_id == NULL || + ostree_validate_collection_id (collection_id, NULL), NULL); + g_return_val_if_fail (ostree_validate_rev (ref_name, NULL), NULL); + + collection_ref = g_new0 (OstreeCollectionRef, 1); + collection_ref->collection_id = g_strdup (collection_id); + collection_ref->ref_name = g_strdup (ref_name); + + return g_steal_pointer (&collection_ref); +} + +/** + * ostree_collection_ref_dup: + * @ref: an #OstreeCollectionRef + * + * Create a copy of the given @ref. + * + * Returns: (transfer full): a newly allocated copy of @ref + * Since: 2017.8 + */ +OstreeCollectionRef * +ostree_collection_ref_dup (const OstreeCollectionRef *ref) +{ + g_return_val_if_fail (ref != NULL, NULL); + + return ostree_collection_ref_new (ref->collection_id, ref->ref_name); +} + +/** + * ostree_collection_ref_free: + * @ref: (transfer full): an #OstreeCollectionRef + * + * Free the given @ref. + * + * Since: 2017.8 + */ +void +ostree_collection_ref_free (OstreeCollectionRef *ref) +{ + g_return_if_fail (ref != NULL); + + g_free (ref->collection_id); + g_free (ref->ref_name); + g_free (ref); +} + +/** + * ostree_collection_ref_hash: + * @ref: an #OstreeCollectionRef + * + * Hash the given @ref. This function is suitable for use with #GHashTable. + * @ref must be non-%NULL. + * + * Returns: hash value for @ref + * Since: 2017.8 + */ +guint +ostree_collection_ref_hash (gconstpointer ref) +{ + const OstreeCollectionRef *_ref = ref; + + if (_ref->collection_id != NULL) + return g_str_hash (_ref->collection_id) ^ g_str_hash (_ref->ref_name); + else + return g_str_hash (_ref->ref_name); +} + +/** + * ostree_collection_ref_equal: + * @ref1: an #OstreeCollectionRef + * @ref2: another #OstreeCollectionRef + * + * Compare @ref1 and @ref2 and return %TRUE if they have the same collection ID and + * ref name, and %FALSE otherwise. Both @ref1 and @ref2 must be non-%NULL. + * + * Returns: %TRUE if @ref1 and @ref2 are equal, %FALSE otherwise + * Since: 2017.8 + */ +gboolean +ostree_collection_ref_equal (gconstpointer ref1, + gconstpointer ref2) +{ + const OstreeCollectionRef *_ref1 = ref1, *_ref2 = ref2; + + return (g_strcmp0 (_ref1->collection_id, _ref2->collection_id) == 0 && + g_strcmp0 (_ref1->ref_name, _ref2->ref_name) == 0); +} + +/** + * ostree_collection_ref_dupv: + * @refs: (array zero-terminated=1): %NULL-terminated array of #OstreeCollectionRefs + * + * Copy an array of #OstreeCollectionRefs, including deep copies of all its + * elements. @refs must be %NULL-terminated; it may be empty, but must not be + * %NULL. + * + * Returns: (transfer full) (array zero-terminated=1): a newly allocated copy of @refs + * Since: 2017.8 + */ +OstreeCollectionRef ** +ostree_collection_ref_dupv (const OstreeCollectionRef * const *refs) +{ + gsize i, n_refs = g_strv_length ((gchar **) refs); /* hack */ + g_auto(OstreeCollectionRefv) new_refs = NULL; + + g_return_val_if_fail (refs != NULL, NULL); + + new_refs = g_new0 (OstreeCollectionRef*, n_refs + 1); + + for (i = 0; i < n_refs; i++) + new_refs[i] = ostree_collection_ref_dup (refs[i]); + new_refs[i] = NULL; + + return g_steal_pointer (&new_refs); +} + +/** + * ostree_collection_ref_freev: + * @refs: (transfer full) (array zero-terminated=1): an array of #OstreeCollectionRefs + * + * Free the given array of @refs, including freeing all its elements. @refs + * must be %NULL-terminated; it may be empty, but must not be %NULL. + * + * Since: 2017.8 + */ +void +ostree_collection_ref_freev (OstreeCollectionRef **refs) +{ + gsize i; + + g_return_if_fail (refs != NULL); + + for (i = 0; refs[i] != NULL; i++) + ostree_collection_ref_free (refs[i]); + g_free (refs); +} diff --git a/src/libostree/ostree-ref.h b/src/libostree/ostree-ref.h new file mode 100644 index 00000000..4d43153c --- /dev/null +++ b/src/libostree/ostree-ref.h @@ -0,0 +1,90 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright © 2017 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: + * - Philip Withnall <withnall@endlessm.com> + */ + +#pragma once + +#include <gio/gio.h> +#include <glib.h> +#include <glib-object.h> + +#include "ostree-types.h" + +G_BEGIN_DECLS + +/** + * OstreeCollectionRef: + * @collection_id: (nullable): collection ID which provided the ref, or %NULL if there + * is no associated collection + * @ref_name: ref name + * + * A structure which globally uniquely identifies a ref as the tuple + * (@collection_id, @ref_name). For backwards compatibility, @collection_id may be %NULL, + * indicating a ref name which is not globally unique. + * + * Since: 2017.8 + */ +typedef struct +{ + gchar *collection_id; /* (nullable) */ + gchar *ref_name; /* (not nullable) */ +} OstreeCollectionRef; + +#ifndef __GI_SCANNER__ +_OSTREE_PUBLIC +GType ostree_collection_ref_get_type (void); +#endif + +_OSTREE_PUBLIC +OstreeCollectionRef *ostree_collection_ref_new (const gchar *collection_id, + const gchar *ref_name); +_OSTREE_PUBLIC +OstreeCollectionRef *ostree_collection_ref_dup (const OstreeCollectionRef *ref); +_OSTREE_PUBLIC +void ostree_collection_ref_free (OstreeCollectionRef *ref); + +_OSTREE_PUBLIC +guint ostree_collection_ref_hash (gconstpointer ref); +_OSTREE_PUBLIC +gboolean ostree_collection_ref_equal (gconstpointer ref1, + gconstpointer ref2); + +_OSTREE_PUBLIC +OstreeCollectionRef **ostree_collection_ref_dupv (const OstreeCollectionRef * const *refs); +_OSTREE_PUBLIC +void ostree_collection_ref_freev (OstreeCollectionRef **refs); + +/** + * OstreeCollectionRefv: + * + * A %NULL-terminated array of #OstreeCollectionRef instances, designed to + * be used with g_auto(): + * + * |[<!-- language="C" --> + * g_auto(OstreeCollectionRefv) refs = NULL; + * ]| + * + * Since: 2017.8 + */ +typedef OstreeCollectionRef** OstreeCollectionRefv; + +G_END_DECLS diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index ed73d4a2..04294f33 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -25,6 +25,9 @@ #include "ostree-core.h" #include "ostree-types.h" #include "ostree-async-progress.h" +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API +#include "ostree-ref.h" +#endif #include "ostree-sepolicy.h" #include "ostree-gpg-verify-result.h" diff --git a/src/libostree/ostree.h b/src/libostree/ostree.h index 5d1ac1e1..c9c3bb75 100644 --- a/src/libostree/ostree.h +++ b/src/libostree/ostree.h @@ -35,5 +35,9 @@ #include <ostree-diff.h> #include <ostree-gpg-verify-result.h> +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API +#include <ostree-ref.h> +#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ + #include <ostree-autocleanups.h> #include <ostree-version.h> |