summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <withnall@endlessm.com>2017-06-07 15:27:10 +0100
committerAtomic Bot <atomic-devel@projectatomic.io>2017-06-26 15:56:07 +0000
commit0a20e7d43c43c9d5793f0fdb5bf8422affa5d841 (patch)
tree3d9636d1489d1f7cf4f868777a98ddf4877c23c2
parentbf1f8eb0fa36204377127e335b01b4bb95666cb2 (diff)
downloadostree-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.am1
-rw-r--r--Makefile-libostree.am2
-rw-r--r--apidoc/ostree-experimental-sections.txt20
-rw-r--r--src/libostree/libostree-experimental.sym13
-rw-r--r--src/libostree/ostree-autocleanups.h2
-rw-r--r--src/libostree/ostree-core-private.h11
-rw-r--r--src/libostree/ostree-core.c32
-rw-r--r--src/libostree/ostree-core.h5
-rw-r--r--src/libostree/ostree-ref.c193
-rw-r--r--src/libostree/ostree-ref.h90
-rw-r--r--src/libostree/ostree-repo.h3
-rw-r--r--src/libostree/ostree.h4
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>