diff --git a/apidoc/ostree-sections.txt b/apidoc/ostree-sections.txt index 440fe0c3..a91663ed 100644 --- a/apidoc/ostree-sections.txt +++ b/apidoc/ostree-sections.txt @@ -298,6 +298,7 @@ ostree_repo_get_mode ostree_repo_get_min_free_space_bytes ostree_repo_get_config ostree_repo_get_dfd +ostree_repo_get_repo_finders ostree_repo_hash ostree_repo_equal ostree_repo_copy_config diff --git a/man/ostree.repo-config.xml b/man/ostree.repo-config.xml index 8942a00b..49044b46 100644 --- a/man/ostree.repo-config.xml +++ b/man/ostree.repo-config.xml @@ -215,6 +215,20 @@ Boston, MA 02111-1307, USA. of -1 means block indefinitely. The default value is 30. + + + repo-finders + Semicolon separated default list of finders (sources + for refs) to use when pulling. This can be used to disable + pulling from mounted filesystems, peers on the local network, + or the Internet. However note that it only applies when a set + of finders isn't explicitly specified, either by a consumer of + libostree API or on the command line. Possible values: + config, lan, and + mount (or any combination thereof). If + unset, this defaults to config;lan;mount;. + + diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index 6d1fe934..80b04fd5 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -21,6 +21,7 @@ LIBOSTREE_2018.9 { ostree_mutable_tree_remove; ostree_repo_get_min_free_space_bytes; + ostree_repo_get_repo_finders; } LIBOSTREE_2018.7; /* Stub section for the stable release *after* this development one; don't diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index ad1269b3..40be7263 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -168,6 +168,7 @@ struct OstreeRepo { gint lock_timeout_seconds; guint64 payload_link_threshold; gint fs_support_reflink; /* The underlying filesystem has support for ioctl (FICLONE..) */ + gchar **repo_finders; OstreeRepo *parent_repo; }; diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index f5c52e4a..4a3adf2a 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -4999,45 +4999,55 @@ ostree_repo_find_remotes_async (OstreeRepo *self, /* Are we using #OstreeRepoFinders provided by the user, or the defaults? */ if (finders == NULL) { + guint finder_index = 0; #ifdef HAVE_AVAHI + guint avahi_index; GMainContext *context = g_main_context_get_thread_default (); g_autoptr(GError) local_error = NULL; #endif /* HAVE_AVAHI */ - finder_config = OSTREE_REPO_FINDER (ostree_repo_finder_config_new ()); - finder_mount = OSTREE_REPO_FINDER (ostree_repo_finder_mount_new (NULL)); + if (g_strv_contains ((const char * const *)self->repo_finders, "config")) + default_finders[finder_index++] = finder_config = OSTREE_REPO_FINDER (ostree_repo_finder_config_new ()); + + if (g_strv_contains ((const char * const *)self->repo_finders, "mount")) + default_finders[finder_index++] = finder_mount = OSTREE_REPO_FINDER (ostree_repo_finder_mount_new (NULL)); + #ifdef HAVE_AVAHI - finder_avahi = OSTREE_REPO_FINDER (ostree_repo_finder_avahi_new (context)); + if (g_strv_contains ((const char * const *)self->repo_finders, "lan")) + { + avahi_index = finder_index; + default_finders[finder_index++] = finder_avahi = OSTREE_REPO_FINDER (ostree_repo_finder_avahi_new (context)); + } #endif /* HAVE_AVAHI */ - default_finders[0] = finder_config; - default_finders[1] = finder_mount; - default_finders[2] = finder_avahi; - + g_assert (default_finders != NULL); finders = default_finders; #ifdef HAVE_AVAHI - ostree_repo_finder_avahi_start (OSTREE_REPO_FINDER_AVAHI (finder_avahi), - &local_error); - - if (local_error != NULL) + if (finder_avahi != NULL) { - /* See ostree-repo-finder-avahi.c:ostree_repo_finder_avahi_start, we - * intentionally throw this so as to distinguish between the Avahi - * finder failing because the Avahi daemon wasn't running and - * the Avahi finder failing because of some actual error. - * - * We need to distinguish between g_debug and g_warning here because - * unit tests that use this code may set G_DEBUG=fatal-warnings which - * would cause client code to abort if a warning were emitted. - */ - if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) - g_debug ("Avahi finder failed under normal operation; removing it: %s", local_error->message); - else - g_warning ("Avahi finder failed abnormally; removing it: %s", local_error->message); + ostree_repo_finder_avahi_start (OSTREE_REPO_FINDER_AVAHI (finder_avahi), + &local_error); - default_finders[2] = NULL; - g_clear_object (&finder_avahi); + if (local_error != NULL) + { + /* See ostree-repo-finder-avahi.c:ostree_repo_finder_avahi_start, we + * intentionally throw this so as to distinguish between the Avahi + * finder failing because the Avahi daemon wasn't running and + * the Avahi finder failing because of some actual error. + * + * We need to distinguish between g_debug and g_warning here because + * unit tests that use this code may set G_DEBUG=fatal-warnings which + * would cause client code to abort if a warning were emitted. + */ + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + g_debug ("Avahi finder failed under normal operation; removing it: %s", local_error->message); + else + g_warning ("Avahi finder failed abnormally; removing it: %s", local_error->message); + + default_finders[avahi_index] = NULL; + g_clear_object (&finder_avahi); + } } #endif /* HAVE_AVAHI */ } diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 857b2d4c..18fb7733 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -1035,6 +1035,7 @@ ostree_repo_finalize (GObject *object) g_mutex_clear (&self->cache_lock); g_mutex_clear (&self->txn_lock); g_free (self->collection_id); + g_strfreev (self->repo_finders); g_clear_pointer (&self->remotes, g_hash_table_destroy); g_mutex_clear (&self->remotes_lock); @@ -2938,6 +2939,40 @@ reload_core_config (OstreeRepo *self, self->payload_link_threshold = g_ascii_strtoull (payload_threshold, NULL, 10); } + { g_auto(GStrv) configured_finders = NULL; + g_autoptr(GError) local_error = NULL; + + configured_finders = g_key_file_get_string_list (self->config, "core", "repo-finders", + NULL, &local_error); + if (g_error_matches (local_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) + g_clear_error (&local_error); + else if (local_error != NULL) + { + g_propagate_error (error, g_steal_pointer (&local_error)); + return FALSE; + } + + if (configured_finders != NULL && *configured_finders == NULL) + return glnx_throw (error, "Invalid empty repo-finders configuration"); + + for (char **iter = configured_finders; iter && *iter; iter++) + { + const char *repo_finder = *iter; + + if (strcmp (repo_finder, "config") != 0 && + strcmp (repo_finder, "lan") != 0 && + strcmp (repo_finder, "mount") != 0) + return glnx_throw (error, "Invalid configured repo-finder '%s'", repo_finder); + } + + /* Fall back to a default set of finders */ + if (configured_finders == NULL) + configured_finders = g_strsplit ("config;lan;mount", ";", -1); + + g_clear_pointer (&self->repo_finders, g_strfreev); + self->repo_finders = g_steal_pointer (&configured_finders); + } + return TRUE; } @@ -5915,3 +5950,22 @@ ostree_repo_set_collection_id (OstreeRepo *self, return TRUE; } + +/** + * ostree_repo_get_repo_finders: + * @self: an #OstreeRepo + * + * Get the set of repo finders configured. See the documentation for + * the "core.repo-finders" config key. + * + * Returns: (array zero-terminated=1) (element-type utf8): + * %NULL-terminated array of strings. + * Since: 2018.9 + */ +const gchar * const * +ostree_repo_get_repo_finders (OstreeRepo *self) +{ + g_return_val_if_fail (OSTREE_IS_REPO (self), NULL); + + return (const gchar * const *)self->repo_finders; +} diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index eddbbf87..2f7abf6d 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -112,6 +112,9 @@ gboolean ostree_repo_set_collection_id (OstreeRepo *self, const gchar *collection_id, GError **error); +_OSTREE_PUBLIC +const gchar * const * ostree_repo_get_repo_finders (OstreeRepo *self); + _OSTREE_PUBLIC GFile * ostree_repo_get_path (OstreeRepo *self);