find-remotes: Add --finders option

It can be helpful to be able to choose which OstreeRepoFinder instances
to use when using the find-remotes command. For example, if the tests
need to run in an environment that can't have an Avahi daemon, this
allows you to disable the Avahi (LAN) finder. This commit adds the
--finders option for this purpose.

Closes: #1407
Approved by: cgwalters
This commit is contained in:
Matthew Leeds 2018-01-09 23:36:40 -08:00 committed by Atomic Bot
parent 3318db548e
commit 2c932d9721
1 changed files with 103 additions and 3 deletions

View File

@ -30,12 +30,14 @@
#include "ostree-remote-private.h" #include "ostree-remote-private.h"
static gchar *opt_cache_dir = NULL; static gchar *opt_cache_dir = NULL;
static gchar *opt_finders = NULL;
static gboolean opt_disable_fsync = FALSE; static gboolean opt_disable_fsync = FALSE;
static gboolean opt_pull = FALSE; static gboolean opt_pull = FALSE;
static GOptionEntry options[] = static GOptionEntry options[] =
{ {
{ "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL }, { "cache-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_cache_dir, "Use custom cache dir", NULL },
{ "finders", 0, 0, G_OPTION_ARG_STRING, &opt_finders, "Use the specified comma separated list of finders (e.g. config,lan,mount)", "FINDERS" },
{ "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL }, { "disable-fsync", 0, 0, G_OPTION_ARG_NONE, &opt_disable_fsync, "Do not invoke fsync()", NULL },
{ "pull", 0, 0, G_OPTION_ARG_NONE, &opt_pull, "Pull the updates after finding them", NULL }, { "pull", 0, 0, G_OPTION_ARG_NONE, &opt_pull, "Pull the updates after finding them", NULL },
{ NULL } { NULL }
@ -116,6 +118,52 @@ collection_ref_free0 (OstreeCollectionRef *ref)
ostree_collection_ref_free (ref); ostree_collection_ref_free (ref);
} }
static gboolean
validate_finders_list (char **finders,
GOptionContext *context,
GError **error)
{
typedef struct {
gchar *finder_name;
gboolean already_used;
} Finder;
Finder valid_finders[] = {
{.finder_name = "config", .already_used = FALSE},
{.finder_name = "lan", .already_used = FALSE},
{.finder_name = "mount", .already_used = FALSE}
};
if (finders == NULL || *finders == NULL)
{
ot_util_usage_error (context, "List of finders in --finders option must not be empty", error);
return FALSE;
}
for (char **iter = finders; iter && *iter; iter++)
{
gboolean is_valid_finder = FALSE;
for (int i = 0; i < 3; i++)
{
if (valid_finders[i].already_used == TRUE)
continue;
if (g_strcmp0 (*iter, valid_finders[i].finder_name) == 0)
{
is_valid_finder = TRUE;
valid_finders[i].already_used = TRUE;
}
}
if (!is_valid_finder)
{
g_autofree gchar *error_msg = NULL;
error_msg = g_strdup_printf ("Unknown or duplicate finder type given in --finders option: %s", *iter);
ot_util_usage_error (context, error_msg, error);
return FALSE;
}
}
return TRUE;
}
/* TODO: Add a man page. */ /* TODO: Add a man page. */
gboolean gboolean
ostree_builtin_find_remotes (int argc, ostree_builtin_find_remotes (int argc,
@ -127,12 +175,17 @@ ostree_builtin_find_remotes (int argc,
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
g_autoptr(OstreeRepo) repo = NULL; g_autoptr(OstreeRepo) repo = NULL;
g_autoptr(GPtrArray) refs = NULL; /* (element-type OstreeCollectionRef) */ g_autoptr(GPtrArray) refs = NULL; /* (element-type OstreeCollectionRef) */
g_autoptr(GPtrArray) finders = NULL; /* (element-type OstreeRepoFinder) */
g_autoptr(OstreeRepoFinder) finder_config = NULL;
g_autoptr(OstreeRepoFinder) finder_mount = NULL;
g_autoptr(OstreeRepoFinder) finder_avahi = NULL;
g_autoptr(OstreeAsyncProgress) progress = NULL; g_autoptr(OstreeAsyncProgress) progress = NULL;
gsize i; gsize i;
g_autoptr(GAsyncResult) find_result = NULL, pull_result = NULL; g_autoptr(GAsyncResult) find_result = NULL, pull_result = NULL;
g_auto(OstreeRepoFinderResultv) results = NULL; g_auto(OstreeRepoFinderResultv) results = NULL;
g_auto(GLnxConsoleRef) console = { 0, }; g_auto(GLnxConsoleRef) console = { 0, };
g_autoptr(GHashTable) refs_found = NULL; /* set (element-type OstreeCollectionRef) */ g_autoptr(GHashTable) refs_found = NULL; /* set (element-type OstreeCollectionRef) */
g_auto(GStrv) finders_strings = NULL;
context = g_option_context_new ("COLLECTION-ID REF [COLLECTION-ID REF...]"); context = g_option_context_new ("COLLECTION-ID REF [COLLECTION-ID REF...]");
@ -176,18 +229,65 @@ ostree_builtin_find_remotes (int argc,
g_ptr_array_add (refs, NULL); g_ptr_array_add (refs, NULL);
/* Build the array of OstreeRepoFinder instances */
if (opt_finders != NULL)
{
g_auto(GStrv) finders_strings = NULL;
finders_strings = g_strsplit (opt_finders, ",", 0);
if (!validate_finders_list (finders_strings, context, error))
return FALSE;
finders = g_ptr_array_new ();
for (char **iter =finders_strings; iter && *iter; iter++)
{
if (g_strcmp0 (*iter, "config") == 0)
{
finder_config = OSTREE_REPO_FINDER (ostree_repo_finder_config_new ());
g_ptr_array_add (finders, finder_config);
}
else if (g_strcmp0 (*iter, "mount") == 0)
{
finder_mount = OSTREE_REPO_FINDER (ostree_repo_finder_mount_new (NULL));
g_ptr_array_add (finders, finder_mount);
}
else if (g_strcmp0 (*iter, "lan") == 0)
{
#ifdef HAVE_AVAHI
GMainContext *main_context = g_main_context_get_thread_default ();
g_autoptr(GError) local_error = NULL;
finder_avahi = OSTREE_REPO_FINDER (ostree_repo_finder_avahi_new (main_context));
ostree_repo_finder_avahi_start (OSTREE_REPO_FINDER_AVAHI (finder_avahi), &local_error);
if (local_error != NULL)
{
g_warning ("Avahi finder failed; removing it: %s", local_error->message);
g_clear_object (&finder_avahi);
}
else
g_ptr_array_add (finders, finder_avahi);
#else
ot_util_usage_error (context, "LAN repo finder requested but ostree was compiled without Avahi support", error);
return FALSE;
#endif /* HAVE_AVAHI */
}
else
g_assert_not_reached ();
}
g_ptr_array_add (finders, NULL);
}
/* Run the operation. */ /* Run the operation. */
glnx_console_lock (&console); glnx_console_lock (&console);
if (console.is_tty) if (console.is_tty)
progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console); progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console);
/* FIXME: Eventually some command line options for customising the finders
* list would be good. */
ostree_repo_find_remotes_async (repo, ostree_repo_find_remotes_async (repo,
(const OstreeCollectionRef * const *) refs->pdata, (const OstreeCollectionRef * const *) refs->pdata,
NULL /* no options */, NULL /* no options */,
NULL /* default finders */, finders != NULL ? (OstreeRepoFinder **) finders->pdata : NULL,
progress, cancellable, progress, cancellable,
get_result_cb, &find_result); get_result_cb, &find_result);