diff --git a/Makefile-libostree-defines.am b/Makefile-libostree-defines.am index 1531cf8c..aff7e52b 100644 --- a/Makefile-libostree-defines.am +++ b/Makefile-libostree-defines.am @@ -38,6 +38,12 @@ libostree_public_headers = \ src/libostree/ostree-repo-deprecated.h \ $(NULL) +if ENABLE_EXPERIMENTAL_API +libostree_public_headers += \ + src/libostree/ostree-remote.h \ + $(NULL) +endif + # This one is generated via configure.ac, and the gtk-doc # code hence needs to look in the builddir. libostree_public_built_headers = src/libostree/ostree-version.h diff --git a/Makefile-libostree.am b/Makefile-libostree.am index 8d44b61c..86ba0414 100644 --- a/Makefile-libostree.am +++ b/Makefile-libostree.am @@ -94,6 +94,8 @@ libostree_1_la_SOURCES = \ src/libostree/ostree-linuxfsutil.c \ src/libostree/ostree-diff.c \ src/libostree/ostree-mutable-tree.c \ + src/libostree/ostree-remote.c \ + src/libostree/ostree-remote-private.h \ src/libostree/ostree-repo.c \ src/libostree/ostree-repo-checkout.c \ src/libostree/ostree-repo-commit.c \ @@ -146,6 +148,11 @@ libostree_1_la_SOURCES += \ src/libostree/ostree-tls-cert-interaction.h \ $(NULL) endif +if !ENABLE_EXPERIMENTAL_API +libostree_1_la_SOURCES += \ + src/libostree/ostree-remote.h \ + $(NULL) +endif libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(builddir)/src/libostree \ $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_LZMA_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) $(OT_DEP_OPENSSL_CFLAGS) \ diff --git a/apidoc/ostree-experimental-sections.txt b/apidoc/ostree-experimental-sections.txt index e69de29b..790feb33 100644 --- a/apidoc/ostree-experimental-sections.txt +++ b/apidoc/ostree-experimental-sections.txt @@ -0,0 +1,6 @@ +
+ostree-remote +OstreeRemote +ostree_remote_ref +ostree_remote_unref +
diff --git a/src/libostree/libostree-experimental.sym b/src/libostree/libostree-experimental.sym index 7ca23a15..e2ab4ea8 100644 --- a/src/libostree/libostree-experimental.sym +++ b/src/libostree/libostree-experimental.sym @@ -24,9 +24,8 @@ * --enable-experimental-api. They are not stable or officially supported, and * might disappear or change in future releases. */ -/* LIBOSTREE_2017.6_EXPERIMENTAL { global: - some_symbol; + ostree_remote_ref; + ostree_remote_unref; } LIBOSTREE_2017.6; -*/ diff --git a/src/libostree/ostree-autocleanups.h b/src/libostree/ostree-autocleanups.h index f030b50e..1fdb50ad 100644 --- a/src/libostree/ostree-autocleanups.h +++ b/src/libostree/ostree-autocleanups.h @@ -59,6 +59,10 @@ 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 (OstreeRemote, ostree_remote_unref) +#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ + #endif G_END_DECLS diff --git a/src/libostree/ostree-remote-private.h b/src/libostree/ostree-remote-private.h new file mode 100644 index 00000000..e207ed4c --- /dev/null +++ b/src/libostree/ostree-remote-private.h @@ -0,0 +1,59 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright © 2011 Colin Walters + * Copyright © 2015 Red Hat, Inc. + * 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: + * - Colin Walters + * - Philip Withnall + */ + +#pragma once + +#include +#include +#include + +#include "libglnx.h" +#include "ostree-remote.h" +#include "ostree-types.h" + +G_BEGIN_DECLS + +struct OstreeRemote { + volatile int ref_count; + char *name; + char *group; /* group name in options */ + char *keyring; /* keyring name (NAME.trustedkeys.gpg) */ + GFile *file; /* NULL if remote defined in repo/config */ + GKeyFile *options; +}; + +G_GNUC_INTERNAL +OstreeRemote *ostree_remote_new (void); + +G_GNUC_INTERNAL +OstreeRemote *ostree_remote_new_from_keyfile (GKeyFile *keyfile, + const gchar *group); + +#if (defined(OSTREE_COMPILATION) || GLIB_CHECK_VERSION(2, 44, 0)) && !defined(OSTREE_ENABLE_EXPERIMENTAL_API) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeRemote, ostree_remote_unref) +#endif + +G_END_DECLS diff --git a/src/libostree/ostree-remote.c b/src/libostree/ostree-remote.c new file mode 100644 index 00000000..d6298fba --- /dev/null +++ b/src/libostree/ostree-remote.c @@ -0,0 +1,144 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright © 2011 Colin Walters + * Copyright © 2015 Red Hat, Inc. + * 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: + * - Colin Walters + * - Philip Withnall + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "ostree-remote.h" +#include "ostree-remote-private.h" +#include "ot-keyfile-utils.h" + +/** + * SECTION:remote + * + * The #OstreeRemote structure represents the configuration for a single remote + * repository. Currently, all configuration is handled internally, and + * #OstreeRemote objects are represented by their textual name handle, or by an + * opaque pointer (which can be reference counted if needed). + * + * #OstreeRemote provides configuration for accessing a remote, but does not + * provide the results of accessing a remote, such as information about what + * refs are currently on a remote, or the commits they currently point to. Use + * #OstreeRepo in combination with an #OstreeRemote to query that information. + * + * Since: 2017.6 + */ + +OstreeRemote * +ostree_remote_new (void) +{ + OstreeRemote *remote; + + remote = g_slice_new0 (OstreeRemote); + remote->ref_count = 1; + remote->options = g_key_file_new (); + + return remote; +} + +OstreeRemote * +ostree_remote_new_from_keyfile (GKeyFile *keyfile, + const gchar *group) +{ + g_autoptr(GMatchInfo) match = NULL; + OstreeRemote *remote; + + static gsize regex_initialized; + static GRegex *regex; + + if (g_once_init_enter (®ex_initialized)) + { + regex = g_regex_new ("^remote \"(.+)\"$", 0, 0, NULL); + g_assert (regex); + g_once_init_leave (®ex_initialized, 1); + } + + /* Sanity check */ + g_return_val_if_fail (g_key_file_has_group (keyfile, group), NULL); + + /* If group name doesn't fit the pattern, fail. */ + if (!g_regex_match (regex, group, 0, &match)) + return NULL; + + remote = ostree_remote_new (); + remote->name = g_match_info_fetch (match, 1); + remote->group = g_strdup (group); + remote->keyring = g_strdup_printf ("%s.trustedkeys.gpg", remote->name); + + ot_keyfile_copy_group (keyfile, remote->options, group); + + return remote; +} + +/** + * ostree_remote_ref: + * @remote: an #OstreeRemote + * + * Increase the reference count on the given @remote. + * + * Returns: (transfer full): a copy of @remote, for convenience + * Since: 2017.6 + */ +OstreeRemote * +ostree_remote_ref (OstreeRemote *remote) +{ + gint refcount; + g_return_val_if_fail (remote != NULL, NULL); + refcount = g_atomic_int_add (&remote->ref_count, 1); + g_assert (refcount > 0); + return remote; +} + +/** + * ostree_remote_unref: + * @remote: (transfer full): an #OstreeRemote + * + * Decrease the reference count on the given @remote and free it if the + * reference count reaches 0. + * + * Since: 2017.6 + */ +void +ostree_remote_unref (OstreeRemote *remote) +{ + g_return_if_fail (remote != NULL); + g_return_if_fail (remote->ref_count > 0); + + if (g_atomic_int_dec_and_test (&remote->ref_count)) + { + g_clear_pointer (&remote->name, g_free); + g_clear_pointer (&remote->group, g_free); + g_clear_pointer (&remote->keyring, g_free); + g_clear_object (&remote->file); + g_clear_pointer (&remote->options, g_key_file_free); + g_slice_free (OstreeRemote, remote); + } +} diff --git a/src/libostree/ostree-remote.h b/src/libostree/ostree-remote.h new file mode 100644 index 00000000..bf62fd87 --- /dev/null +++ b/src/libostree/ostree-remote.h @@ -0,0 +1,56 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright © 2011 Colin Walters + * Copyright © 2015 Red Hat, Inc. + * 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: + * - Colin Walters + * - Philip Withnall + */ + +#pragma once + +#include +#include +#include + +#include "ostree-types.h" + +G_BEGIN_DECLS + +/** + * OstreeRemote: + * + * This represents the configuration for a single remote repository. Currently, + * remotes can only be passed around as (reference counted) opaque handles. In + * future, more API may be added to create and interrogate them. + * + * Since: 2016.7 + */ +#ifndef OSTREE_ENABLE_EXPERIMENTAL_API +/* This is in ostree-types.h otherwise */ +typedef struct OstreeRemote OstreeRemote; +#endif + +_OSTREE_PUBLIC +OstreeRemote *ostree_remote_ref (OstreeRemote *remote); +_OSTREE_PUBLIC +void ostree_remote_unref (OstreeRemote *remote); + +G_END_DECLS diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 87e67a23..2a518d4f 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -21,6 +21,7 @@ #pragma once #include "ostree-repo.h" +#include "ostree-remote-private.h" #include "libglnx.h" G_BEGIN_DECLS @@ -350,4 +351,16 @@ gboolean _ostree_repo_update_mtime (OstreeRepo *self, GError **error); +void +_ostree_repo_add_remote (OstreeRepo *self, + OstreeRemote *remote); +OstreeRemote * +_ostree_repo_get_remote (OstreeRepo *self, + const char *name, + GError **error); +OstreeRemote * +_ostree_repo_get_remote_inherited (OstreeRepo *self, + const char *name, + GError **error); + G_END_DECLS diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index fd7aa55d..76ae0d9b 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -32,6 +32,7 @@ #include #include "ostree-core-private.h" +#include "ostree-remote-private.h" #include "ostree-repo-private.h" #include "ostree-repo-file.h" #include "ostree-repo-file-enumerator.h" @@ -104,94 +105,10 @@ G_DEFINE_TYPE (OstreeRepo, ostree_repo, G_TYPE_OBJECT) #define SYSCONF_REMOTES SHORTENED_SYSCONFDIR "/ostree/remotes.d" -typedef struct { - volatile int ref_count; - char *name; - char *group; /* group name in options */ - char *keyring; /* keyring name (NAME.trustedkeys.gpg) */ - GFile *file; /* NULL if remote defined in repo/config */ - GKeyFile *options; -} OstreeRemote; - -static OstreeRemote * -ost_remote_new (void) -{ - OstreeRemote *remote; - - remote = g_slice_new0 (OstreeRemote); - remote->ref_count = 1; - remote->options = g_key_file_new (); - - return remote; -} - -static OstreeRemote * -ost_remote_new_from_keyfile (GKeyFile *keyfile, - const gchar *group) -{ - g_autoptr(GMatchInfo) match = NULL; - OstreeRemote *remote; - - static gsize regex_initialized; - static GRegex *regex; - - if (g_once_init_enter (®ex_initialized)) - { - regex = g_regex_new ("^remote \"(.+)\"$", 0, 0, NULL); - g_assert (regex); - g_once_init_leave (®ex_initialized, 1); - } - - /* Sanity check */ - g_return_val_if_fail (g_key_file_has_group (keyfile, group), NULL); - - /* If group name doesn't fit the pattern, fail. */ - if (!g_regex_match (regex, group, 0, &match)) - return NULL; - - remote = ost_remote_new (); - remote->name = g_match_info_fetch (match, 1); - remote->group = g_strdup (group); - remote->keyring = g_strdup_printf ("%s.trustedkeys.gpg", remote->name); - - ot_keyfile_copy_group (keyfile, remote->options, group); - - return remote; -} - -static OstreeRemote * -ost_remote_ref (OstreeRemote *remote) -{ - gint refcount; - g_return_val_if_fail (remote != NULL, NULL); - refcount = g_atomic_int_add (&remote->ref_count, 1); - g_assert (refcount > 0); - return remote; -} - -static void -ost_remote_unref (OstreeRemote *remote) -{ - g_return_if_fail (remote != NULL); - g_return_if_fail (remote->ref_count > 0); - - if (g_atomic_int_dec_and_test (&remote->ref_count)) - { - g_clear_pointer (&remote->name, g_free); - g_clear_pointer (&remote->group, g_free); - g_clear_pointer (&remote->keyring, g_free); - g_clear_object (&remote->file); - g_clear_pointer (&remote->options, g_key_file_free); - g_slice_free (OstreeRemote, remote); - } -} - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeRemote, ost_remote_unref) - -static OstreeRemote * -ost_repo_get_remote (OstreeRepo *self, - const char *name, - GError **error) +OstreeRemote * +_ostree_repo_get_remote (OstreeRepo *self, + const char *name, + GError **error) { OstreeRemote *remote = NULL; @@ -202,7 +119,7 @@ ost_repo_get_remote (OstreeRepo *self, remote = g_hash_table_lookup (self->remotes, name); if (remote != NULL) - ost_remote_ref (remote); + ostree_remote_ref (remote); else g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "Remote \"%s\" not found", name); @@ -212,19 +129,19 @@ ost_repo_get_remote (OstreeRepo *self, return remote; } -static OstreeRemote * -ost_repo_get_remote_inherited (OstreeRepo *self, - const char *name, - GError **error) +OstreeRemote * +_ostree_repo_get_remote_inherited (OstreeRepo *self, + const char *name, + GError **error) { g_autoptr(OstreeRemote) remote = NULL; g_autoptr(GError) temp_error = NULL; - remote = ost_repo_get_remote (self, name, &temp_error); + remote = _ostree_repo_get_remote (self, name, &temp_error); if (remote == NULL) { if (self->parent_repo != NULL) - return ost_repo_get_remote_inherited (self->parent_repo, name, error); + return _ostree_repo_get_remote_inherited (self->parent_repo, name, error); g_propagate_error (error, g_steal_pointer (&temp_error)); return NULL; @@ -233,9 +150,9 @@ ost_repo_get_remote_inherited (OstreeRepo *self, return g_steal_pointer (&remote); } -static void -ost_repo_add_remote (OstreeRepo *self, - OstreeRemote *remote) +void +_ostree_repo_add_remote (OstreeRepo *self, + OstreeRemote *remote) { g_return_if_fail (self != NULL); g_return_if_fail (remote != NULL); @@ -243,7 +160,7 @@ ost_repo_add_remote (OstreeRepo *self, g_mutex_lock (&self->remotes_lock); - g_hash_table_replace (self->remotes, remote->name, ost_remote_ref (remote)); + g_hash_table_replace (self->remotes, remote->name, ostree_remote_ref (remote)); g_mutex_unlock (&self->remotes_lock); } @@ -308,7 +225,7 @@ ostree_repo_get_remote_option (OstreeRepo *self, return TRUE; } - remote = ost_repo_get_remote (self, remote_name, &temp_error); + remote = _ostree_repo_get_remote (self, remote_name, &temp_error); if (remote != NULL) { value = g_key_file_get_string (remote->options, remote->group, option_name, &temp_error); @@ -385,7 +302,7 @@ ostree_repo_get_remote_list_option (OstreeRepo *self, return TRUE; } - remote = ost_repo_get_remote (self, remote_name, &temp_error); + remote = _ostree_repo_get_remote (self, remote_name, &temp_error); if (remote != NULL) { value = g_key_file_get_string_list (remote->options, @@ -461,7 +378,7 @@ ostree_repo_get_remote_boolean_option (OstreeRepo *self, return TRUE; } - remote = ost_repo_get_remote (self, remote_name, &temp_error); + remote = _ostree_repo_get_remote (self, remote_name, &temp_error); if (remote != NULL) { value = g_key_file_get_boolean (remote->options, remote->group, option_name, &temp_error); @@ -692,7 +609,7 @@ ostree_repo_init (OstreeRepo *self) self->remotes = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) NULL, - (GDestroyNotify) ost_remote_unref); + (GDestroyNotify) ostree_remote_unref); g_mutex_init (&self->remotes_lock); self->repo_dir_fd = -1; @@ -952,7 +869,7 @@ impl_repo_remote_add (OstreeRepo *self, if (strchr (name, '/') != NULL) return glnx_throw (error, "Invalid character '/' in remote name: %s", name); - g_autoptr(OstreeRemote) remote = ost_repo_get_remote (self, name, NULL); + g_autoptr(OstreeRemote) remote = _ostree_repo_get_remote (self, name, NULL); if (remote != NULL && if_not_exists) { /* Note early return */ @@ -965,7 +882,7 @@ impl_repo_remote_add (OstreeRepo *self, name, remote->file ? gs_file_get_path_cached (remote->file) : "(in config)"); } - remote = ost_remote_new (); + remote = ostree_remote_new (); remote->name = g_strdup (name); remote->group = g_strdup_printf ("remote \"%s\"", name); remote->keyring = g_strdup_printf ("%s.trustedkeys.gpg", name); @@ -1036,7 +953,7 @@ impl_repo_remote_add (OstreeRepo *self, return FALSE; } - ost_repo_add_remote (self, remote); + _ostree_repo_add_remote (self, remote); return TRUE; } @@ -1087,7 +1004,7 @@ impl_repo_remote_delete (OstreeRepo *self, g_autoptr(OstreeRemote) remote = NULL; if (if_exists) { - remote = ost_repo_get_remote (self, name, NULL); + remote = _ostree_repo_get_remote (self, name, NULL); if (!remote) { /* Note early return */ @@ -1095,7 +1012,7 @@ impl_repo_remote_delete (OstreeRepo *self, } } else - remote = ost_repo_get_remote (self, name, error); + remote = _ostree_repo_get_remote (self, name, error); if (remote == NULL) return FALSE; @@ -1412,7 +1329,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, /* First make sure the remote name is valid. */ - remote = ost_repo_get_remote_inherited (self, name, error); + remote = _ostree_repo_get_remote_inherited (self, name, error); if (remote == NULL) goto out; @@ -1624,7 +1541,7 @@ ostree_repo_remote_gpg_import (OstreeRepo *self, out: if (remote != NULL) - ost_remote_unref (remote); + ostree_remote_unref (remote); if (source_tmp_dir != NULL) (void) glnx_shutil_rm_rf_at (AT_FDCWD, source_tmp_dir, NULL, NULL); @@ -1857,7 +1774,7 @@ add_remotes_from_keyfile (OstreeRepo *self, { OstreeRemote *remote; - remote = ost_remote_new_from_keyfile (keyfile, groups[ii]); + remote = ostree_remote_new_from_keyfile (keyfile, groups[ii]); if (remote != NULL) { @@ -1888,7 +1805,7 @@ add_remotes_from_keyfile (OstreeRepo *self, out: while (!g_queue_is_empty (&queue)) - ost_remote_unref (g_queue_pop_head (&queue)); + ostree_remote_unref (g_queue_pop_head (&queue)); g_mutex_unlock (&self->remotes_lock); @@ -4213,7 +4130,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self, OstreeRemote *remote; g_autoptr(GFile) file = NULL; - remote = ost_repo_get_remote_inherited (self, remote_name, error); + remote = _ostree_repo_get_remote_inherited (self, remote_name, error); if (remote == NULL) return NULL; @@ -4232,7 +4149,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self, if (gpgkeypath) _ostree_gpg_verifier_add_key_ascii_file (verifier, gpgkeypath); - ost_remote_unref (remote); + ostree_remote_unref (remote); } if (add_global_keyring_dir) diff --git a/src/libostree/ostree-types.h b/src/libostree/ostree-types.h index f6aea0f0..61ac4283 100644 --- a/src/libostree/ostree-types.h +++ b/src/libostree/ostree-types.h @@ -38,4 +38,8 @@ typedef struct OstreeSysrootUpgrader OstreeSysrootUpgrader; typedef struct OstreeMutableTree OstreeMutableTree; typedef struct OstreeRepoFile OstreeRepoFile; +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API +typedef struct OstreeRemote OstreeRemote; +#endif + G_END_DECLS diff --git a/src/libostree/ostree.h b/src/libostree/ostree.h index eb4ed8d3..5d1ac1e1 100644 --- a/src/libostree/ostree.h +++ b/src/libostree/ostree.h @@ -24,6 +24,9 @@ #include #include #include +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API +#include +#endif #include #include #include