Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a --finders option to find-remotes #1407

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 103 additions & 3 deletions src/ostree/ot-builtin-find-remotes.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@
#include "ostree-remote-private.h"

static gchar *opt_cache_dir = NULL;
static gchar *opt_finders = NULL;
static gboolean opt_disable_fsync = FALSE;
static gboolean opt_pull = FALSE;

static GOptionEntry options[] =
{
{ "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 },
{ "pull", 0, 0, G_OPTION_ARG_NONE, &opt_pull, "Pull the updates after finding them", NULL },
{ NULL }
Expand Down Expand Up @@ -116,6 +118,52 @@ collection_ref_free0 (OstreeCollectionRef *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. */
gboolean
ostree_builtin_find_remotes (int argc,
Expand All @@ -127,12 +175,17 @@ ostree_builtin_find_remotes (int argc,
g_autoptr(GOptionContext) context = NULL;
g_autoptr(OstreeRepo) repo = NULL;
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;
gsize i;
g_autoptr(GAsyncResult) find_result = NULL, pull_result = NULL;
g_auto(OstreeRepoFinderResultv) results = NULL;
g_auto(GLnxConsoleRef) console = { 0, };
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...]");

Expand Down Expand Up @@ -176,18 +229,65 @@ ostree_builtin_find_remotes (int argc,

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. */
glnx_console_lock (&console);

if (console.is_tty)
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,
(const OstreeCollectionRef * const *) refs->pdata,
NULL /* no options */,
NULL /* default finders */,
finders != NULL ? (OstreeRepoFinder **) finders->pdata : NULL,
progress, cancellable,
get_result_cb, &find_result);

Expand Down
28 changes: 14 additions & 14 deletions tests/test-find-remotes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,15 @@ assert_file_has_content local-mirror/refs/mirrors/org.example.OsCollection/os/am

for repo in local local-mirror; do
# Try finding an update for an existing branch.
${CMD_PREFIX} ostree --repo=$repo find-remotes org.example.AppsCollection app1 > find
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config org.example.AppsCollection app1 > find
assert_file_has_content find "^Result [0-9]\+: file://$(pwd)/apps-collection$"
assert_file_has_content find "^ - Keyring: apps-remote.trustedkeys.gpg$"
assert_file_has_content find "^ - (org.example.AppsCollection, app1) = $(cat app1-checksum)$"
assert_file_has_content find "^1/1 refs were found.$"
assert_not_file_has_content find "^No results.$"

# Find several updates for several existing branches.
${CMD_PREFIX} ostree --repo=$repo find-remotes org.example.AppsCollection app1 org.example.OsCollection os/amd64/master > find
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config org.example.AppsCollection app1 org.example.OsCollection os/amd64/master > find
assert_file_has_content find "^Result [0-9]\+: file://$(pwd)/apps-collection$"
assert_file_has_content find "^ - Keyring: apps-remote.trustedkeys.gpg$"
assert_file_has_content find "^ - (org.example.AppsCollection, app1) = $(cat app1-checksum)$"
Expand All @@ -105,7 +105,7 @@ for repo in local local-mirror; do
assert_not_file_has_content find "^No results.$"

# Find some updates and a new branch.
${CMD_PREFIX} ostree --repo=$repo find-remotes org.example.AppsCollection app1 org.example.AppsCollection app2 org.example.OsCollection os/amd64/master > find
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config org.example.AppsCollection app1 org.example.AppsCollection app2 org.example.OsCollection os/amd64/master > find
assert_file_has_content find "^Result [0-9]\+: file://$(pwd)/apps-collection$"
assert_file_has_content find "^ - Keyring: apps-remote.trustedkeys.gpg$"
assert_file_has_content find "^ - (org.example.AppsCollection, app1) = $(cat app1-checksum)$"
Expand All @@ -117,7 +117,7 @@ for repo in local local-mirror; do
assert_not_file_has_content find "^No results.$"

# Find an update and a non-existent branch.
${CMD_PREFIX} ostree --repo=$repo find-remotes org.example.AppsCollection app1 org.example.AppsCollection not-an-app > find
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config org.example.AppsCollection app1 org.example.AppsCollection not-an-app > find
assert_file_has_content find "^Result [0-9]\+: file://$(pwd)/apps-collection$"
assert_file_has_content find "^ - Keyring: apps-remote.trustedkeys.gpg$"
assert_file_has_content find "^ - (org.example.AppsCollection, not-an-app) = (not found)$"
Expand All @@ -128,28 +128,28 @@ for repo in local local-mirror; do
assert_not_file_has_content find "^No results.$"

# Do all the above, but pull this time.
${CMD_PREFIX} ostree --repo=$repo find-remotes --pull org.example.AppsCollection app1 > pull || true
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config --pull org.example.AppsCollection app1 > pull || true
assert_file_has_content pull "^1/1 refs were found.$"
assert_file_has_content pull "^Pulled 1/1 refs successfully.$"
assert_not_file_has_content pull "Failed to pull some refs from the remotes"
assert_ref $repo app1 $(cat app1-checksum)

${CMD_PREFIX} ostree --repo=$repo find-remotes --pull org.example.AppsCollection app1 org.example.OsCollection os/amd64/master > pull
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config --pull org.example.AppsCollection app1 org.example.OsCollection os/amd64/master > pull
assert_file_has_content pull "^2/2 refs were found.$"
assert_file_has_content pull "^Pulled 2/2 refs successfully.$"
assert_not_file_has_content pull "Failed to pull some refs from the remotes"
assert_ref $repo app1 $(cat app1-checksum)
assert_ref $repo os/amd64/master $(cat os-checksum)

${CMD_PREFIX} ostree --repo=$repo find-remotes --pull org.example.AppsCollection app1 org.example.AppsCollection app2 org.example.OsCollection os/amd64/master > pull
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config --pull org.example.AppsCollection app1 org.example.AppsCollection app2 org.example.OsCollection os/amd64/master > pull
assert_file_has_content pull "^3/3 refs were found.$"
assert_file_has_content pull "^Pulled 3/3 refs successfully.$"
assert_not_file_has_content pull "Failed to pull some refs from the remotes"
assert_ref $repo app1 $(cat app1-checksum)
assert_ref $repo app2 $(cat app2-checksum)
assert_ref $repo os/amd64/master $(cat os-checksum)

${CMD_PREFIX} ostree --repo=$repo find-remotes --pull org.example.AppsCollection app1 org.example.AppsCollection not-an-app > pull
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config --pull org.example.AppsCollection app1 org.example.AppsCollection not-an-app > pull
assert_file_has_content pull "^1/2 refs were found.$"
assert_not_file_has_content pull "Failed to pull some refs from the remotes"
assert_ref $repo app1 $(cat app1-checksum)
Expand All @@ -164,15 +164,15 @@ ${CMD_PREFIX} ostree --repo=os-collection summary --update --gpg-homedir=${TEST_

for repo in local-mirror; do
# Try finding an update for that branch.
${CMD_PREFIX} ostree --repo=$repo find-remotes org.example.OsCollection os/amd64/master > find
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config org.example.OsCollection os/amd64/master > find
assert_file_has_content find "^Result [0-9]\+: file://$(pwd)/os-collection$"
assert_file_has_content find "^ - Keyring: os-remote.trustedkeys.gpg$"
assert_file_has_content find "^ - (org.example.OsCollection, os/amd64/master) = $(cat os-checksum-2)$"
assert_file_has_content find "^1/1 refs were found.$"
assert_not_file_has_content find "^No results.$"

# Pull it.
${CMD_PREFIX} ostree --repo=$repo find-remotes --pull org.example.OsCollection os/amd64/master > pull || true
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config --pull org.example.OsCollection os/amd64/master > pull || true
assert_file_has_content pull "^1/1 refs were found.$"
assert_file_has_content pull "^Pulled 1/1 refs successfully.$"
assert_not_file_has_content pull "Failed to pull some refs from the remotes"
Expand All @@ -191,7 +191,7 @@ ${CMD_PREFIX} ostree --repo=local remote add os-remote-local-mirror file://$(pwd

for repo in local; do
# Try finding an update for that branch.
${CMD_PREFIX} ostree --repo=$repo find-remotes org.example.OsCollection os/amd64/master > find
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config org.example.OsCollection os/amd64/master > find
assert_file_has_content find "^Result [0-9]\+: file://$(pwd)/os-collection$"
assert_file_has_content find "^ - Keyring: os-remote.trustedkeys.gpg$"
assert_file_has_content find "^ - (org.example.OsCollection, os/amd64/master) = $(cat os-checksum-2)$"
Expand All @@ -202,7 +202,7 @@ for repo in local; do
assert_not_file_has_content find "^No results.$"

# Pull it.
${CMD_PREFIX} ostree --repo=$repo find-remotes --pull org.example.OsCollection os/amd64/master > pull || true
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config --pull org.example.OsCollection os/amd64/master > pull || true
assert_file_has_content pull "^1/1 refs were found.$"
assert_file_has_content pull "^Pulled 1/1 refs successfully.$"
assert_not_file_has_content pull "Failed to pull some refs from the remotes"
Expand All @@ -218,15 +218,15 @@ ${CMD_PREFIX} ostree --repo=os-collection summary --update --gpg-homedir=${TEST_

for repo in local; do
# Try finding an update for that branch.
${CMD_PREFIX} ostree --repo=$repo find-remotes org.example.OsCollection os/amd64/master > find
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config org.example.OsCollection os/amd64/master > find
assert_file_has_content find "^Result [0-9]\+: file://$(pwd)/os-collection$"
assert_file_has_content find "^ - Keyring: os-remote.trustedkeys.gpg$"
assert_file_has_content find "^ - (org.example.OsCollection, os/amd64/master) = $(cat os-checksum-3)$"
assert_file_has_content find "^1/1 refs were found.$"
assert_not_file_has_content find "^No results.$"

# Pull it.
${CMD_PREFIX} ostree --repo=$repo find-remotes --pull org.example.OsCollection os/amd64/master > pull || true
${CMD_PREFIX} ostree --repo=$repo find-remotes --finders=config --pull org.example.OsCollection os/amd64/master > pull || true
assert_file_has_content pull "^1/1 refs were found.$"
assert_file_has_content pull "^Pulled 1/1 refs successfully.$"
assert_not_file_has_content pull "Failed to pull some refs from the remotes"
Expand Down
4 changes: 2 additions & 2 deletions tests/test-repo-finder-mount-integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ for fs_type in ext4 vfat; do
ostree_repo_init peer-repo_$fs_type
${CMD_PREFIX} ostree --repo=peer-repo_$fs_type remote add remote1 file://just-here-for-the-keyring --collection-id org.example.Collection1 --gpg-import="${test_tmpdir}/gpghome/key1.asc"

${CMD_PREFIX} ostree --repo=peer-repo_$fs_type find-remotes org.example.Collection1 test-1 > find-results
${CMD_PREFIX} ostree --repo=peer-repo_$fs_type find-remotes --finders=mount org.example.Collection1 test-1 > find-results
assert_not_file_has_content find-results "^No results.$"
assert_file_has_content find-results "^Result 0: file://${usb_mount}"
assert_file_has_content find-results "(org.example.Collection1, test-1) = $(cat ref1-checksum)$"

${CMD_PREFIX} ostree --repo=peer-repo_$fs_type find-remotes --pull org.example.Collection1 test-1 > pull-results
${CMD_PREFIX} ostree --repo=peer-repo_$fs_type find-remotes --finders=mount --pull org.example.Collection1 test-1 > pull-results
assert_file_has_content pull-results "^Pulled 1/1 refs successfully.$"

${CMD_PREFIX} ostree --repo=peer-repo_$fs_type refs --collections > refs
Expand Down