summaryrefslogtreecommitdiff
path: root/src/ostree/ot-builtin-pull-local.c
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2015-02-08 04:30:52 -0500
committerColin Walters <walters@verbum.org>2015-02-08 04:43:06 -0500
commit9cc98041953090160dde48afa69b97c936541cdb (patch)
tree1d13dacb86b0e3eb8f9be6608f863ab0b8adf9b0 /src/ostree/ot-builtin-pull-local.c
parentab3bf493dd9fa5cd6abba299d9eea182d9d17d96 (diff)
downloadostree-9cc98041953090160dde48afa69b97c936541cdb.tar.gz
Change pull-local to just be a wrapper for pull with file:///
This follows up from the previous commit; now that pull knows how to do the efficient link() or copy for local files, we can just have pull-local call into ostree_repo_pull(). As part of this: - pull() can also accept a file:/// URI instead of a remote name (since pull local supports anonymous pulls) - pull() knows an "override-remote-name" option, since pull-local supported writing a ref out even if there wasn't a remote with that name
Diffstat (limited to 'src/ostree/ot-builtin-pull-local.c')
-rw-r--r--src/ostree/ot-builtin-pull-local.c237
1 files changed, 55 insertions, 182 deletions
diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c
index c49ad0f6..acad43bc 100644
--- a/src/ostree/ot-builtin-pull-local.c
+++ b/src/ostree/ot-builtin-pull-local.c
@@ -39,99 +39,25 @@ static GOptionEntry options[] = {
{ NULL }
};
-typedef struct {
- OstreeRepo *src_repo;
- OstreeRepo *dest_repo;
- GThreadPool *threadpool;
- GMainLoop *loop;
- int n_objects_to_check;
- volatile int n_objects_checked;
- volatile int n_objects_copied;
- GSConsole *console;
-} OtLocalCloneData;
-
-static gboolean
-termination_condition (OtLocalCloneData *self)
-{
- return g_atomic_int_get (&self->n_objects_checked) == self->n_objects_to_check;
-}
-
-static void
-import_one_object_thread (gpointer object,
- gpointer user_data)
-{
- OtLocalCloneData *data = user_data;
- gs_unref_variant GVariant *serialized_key = object;
- GError *local_error = NULL;
- GError **error = &local_error;
- const char *checksum;
- OstreeObjectType objtype;
- GCancellable *cancellable = NULL;
-
- ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
-
- if (!ostree_repo_import_object_from (data->dest_repo, data->src_repo,
- objtype, checksum, cancellable, error))
- goto out;
-
- g_atomic_int_inc (&data->n_objects_copied);
-
- out:
- g_atomic_int_add (&data->n_objects_checked, 1);
- if (termination_condition (data))
- g_main_context_wakeup (NULL);
- if (local_error != NULL)
- {
- g_printerr ("%s\n", local_error->message);
- exit (EXIT_FAILURE);
- }
-}
-
-static gboolean
-idle_print_status (gpointer user_data)
-{
- OtLocalCloneData *data = user_data;
- gs_free char *str = NULL;
-
- str = g_strdup_printf ("pull: %d/%d scanned, %d objects copied",
- g_atomic_int_get (&data->n_objects_checked),
- data->n_objects_to_check,
- g_atomic_int_get (&data->n_objects_copied));
- if (data->console)
- gs_console_begin_status_line (data->console, str, NULL, NULL);
- else
- g_print ("%s\n", str);
-
- return TRUE;
-}
-
gboolean
ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GError **error)
{
gboolean ret = FALSE;
GOptionContext *context;
gs_unref_object OstreeRepo *repo = NULL;
- const char *src_repo_path;
int i;
- GHashTableIter hash_iter;
- gpointer key, value;
- gboolean transaction_resuming = FALSE;
- gs_unref_object GFile *src_f = NULL;
- gs_unref_object GFile *src_repo_dir = NULL;
- gs_unref_object GFile *dest_repo_dir = NULL;
- gs_unref_hashtable GHashTable *refs_to_clone = NULL;
- gs_unref_hashtable GHashTable *commits_to_clone = NULL;
+ const char *src_repo_arg;
+ GSConsole *console = NULL;
+ gs_free char *src_repo_uri = NULL;
+ gs_unref_object OstreeAsyncProgress *progress = NULL;
+ gs_unref_ptrarray GPtrArray *refs_to_fetch = NULL;
gs_unref_hashtable GHashTable *source_objects = NULL;
- OtLocalCloneData datav = { 0, };
- OtLocalCloneData *data = &datav;
context = g_option_context_new ("SRC_REPO [REFS...] - Copy data from SRC_REPO");
if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error))
goto out;
- data->dest_repo = g_object_ref (repo);
-
if (argc < 2)
{
gchar *help = g_option_context_get_help (context, TRUE, NULL);
@@ -142,133 +68,80 @@ ostree_builtin_pull_local (int argc, char **argv, GCancellable *cancellable, GEr
goto out;
}
- src_repo_path = argv[1];
- src_f = g_file_new_for_path (src_repo_path);
+ src_repo_arg = argv[1];
- data->src_repo = ostree_repo_new (src_f);
- if (!ostree_repo_open (data->src_repo, cancellable, error))
- goto out;
+ { gs_free char *cwd = g_get_current_dir ();
+ src_repo_uri = g_strconcat ("file://", cwd, "/", src_repo_arg, NULL);
+ }
if (opt_disable_fsync)
- ostree_repo_set_disable_fsync (data->dest_repo, TRUE);
-
- data->threadpool = ot_thread_pool_new_nproc (import_one_object_thread, data);
-
- src_repo_dir = g_object_ref (ostree_repo_get_path (data->src_repo));
- dest_repo_dir = g_object_ref (ostree_repo_get_path (data->dest_repo));
+ ostree_repo_set_disable_fsync (repo, TRUE);
if (argc == 2)
{
- if (!ostree_repo_list_refs (data->src_repo, NULL, &refs_to_clone,
+ gs_unref_object GFile *src_repo_path = g_file_new_for_path (src_repo_arg);
+ gs_unref_object OstreeRepo *src_repo = ostree_repo_new (src_repo_path);
+ gs_unref_hashtable GHashTable *refs_to_clone = NULL;
+
+ refs_to_fetch = g_ptr_array_new_with_free_func (g_free);
+
+ if (!ostree_repo_open (src_repo, cancellable, error))
+ goto out;
+
+ if (!ostree_repo_list_refs (src_repo, NULL, &refs_to_clone,
cancellable, error))
goto out;
+
+ { GHashTableIter hashiter;
+ gpointer hkey, hvalue;
+
+ g_hash_table_iter_init (&hashiter, refs_to_clone);
+ while (g_hash_table_iter_next (&hashiter, &hkey, &hvalue))
+ g_ptr_array_add (refs_to_fetch, g_strdup (hkey));
+ }
+ g_ptr_array_add (refs_to_fetch, NULL);
}
else
{
- refs_to_clone = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- commits_to_clone = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
+ refs_to_fetch = g_ptr_array_new ();
for (i = 2; i < argc; i++)
{
const char *ref = argv[i];
- char *rev;
- if (ostree_validate_checksum_string (ref, NULL))
- {
- g_hash_table_insert (commits_to_clone, (char*)ref, (char*) ref);
- }
- else
- {
- if (!ostree_repo_resolve_rev (data->src_repo, ref, FALSE, &rev, error))
- goto out;
-
- /* Transfer ownership of rev */
- g_hash_table_insert (refs_to_clone, g_strdup (ref), rev);
- }
+ g_ptr_array_add (refs_to_fetch, (char*)ref);
}
+ g_ptr_array_add (refs_to_fetch, NULL);
}
- if (!ostree_repo_prepare_transaction (data->dest_repo, &transaction_resuming,
- cancellable, error))
- goto out;
-
- g_print ("Enumerating objects...\n");
-
- source_objects = ostree_repo_traverse_new_reachable ();
-
- if (refs_to_clone)
- {
- g_hash_table_iter_init (&hash_iter, refs_to_clone);
- while (g_hash_table_iter_next (&hash_iter, &key, &value))
- {
- const char *checksum = value;
-
- if (!ostree_repo_traverse_commit_union (data->src_repo, checksum, 0, source_objects,
- cancellable, error))
- goto out;
- }
- }
-
- if (commits_to_clone)
- {
- g_hash_table_iter_init (&hash_iter, commits_to_clone);
- while (g_hash_table_iter_next (&hash_iter, &key, &value))
- {
- const char *checksum = key;
- gs_unref_hashtable GHashTable *tmp_source_objects = NULL;
-
- if (!ostree_repo_traverse_commit_union (data->src_repo, checksum, 0, source_objects,
- cancellable, error))
- goto out;
- }
- }
-
- data->n_objects_to_check = g_hash_table_size (source_objects);
- g_hash_table_iter_init (&hash_iter, source_objects);
- while (g_hash_table_iter_next (&hash_iter, &key, &value))
+ console = gs_console_get ();
+ if (console)
{
- GVariant *serialized_key = key;
- g_thread_pool_push (data->threadpool, g_variant_ref (serialized_key), NULL);
+ gs_console_begin_status_line (console, "", NULL, NULL);
+ progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, console);
}
- if (data->n_objects_to_check > 0)
- {
- data->console = gs_console_get ();
-
- if (data->console)
- gs_console_begin_status_line (data->console, "", NULL, NULL);
-
- g_timeout_add_seconds (1, idle_print_status, data);
- idle_print_status (data);
-
- while (!termination_condition (data))
- g_main_context_iteration (NULL, TRUE);
-
- idle_print_status (data);
- if (data->console)
- gs_console_end_status_line (data->console, NULL, NULL);
- }
-
- g_print ("Writing %u refs\n", g_hash_table_size (refs_to_clone));
-
- g_hash_table_iter_init (&hash_iter, refs_to_clone);
- while (g_hash_table_iter_next (&hash_iter, &key, &value))
- {
- const char *name = key;
- const char *checksum = value;
-
- ostree_repo_transaction_set_ref (data->dest_repo, opt_remote, name, checksum);
- }
-
- if (!ostree_repo_commit_transaction (data->dest_repo, NULL, NULL, error))
- goto out;
+ { GVariantBuilder builder;
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+
+ g_variant_builder_add (&builder, "{s@v}", "flags",
+ g_variant_new_variant (g_variant_new_int32 (OSTREE_REPO_PULL_FLAGS_NONE)));
+ g_variant_builder_add (&builder, "{s@v}", "refs",
+ g_variant_new_variant (g_variant_new_strv ((const char *const*) refs_to_fetch->pdata, -1)));
+ if (opt_remote)
+ g_variant_builder_add (&builder, "{s@v}", "override-remote-name",
+ g_variant_new_variant (g_variant_new_string (opt_remote)));
+
+ if (!ostree_repo_pull_with_options (repo, src_repo_uri,
+ g_variant_builder_end (&builder),
+ progress,
+ cancellable, error))
+ goto out;
+ }
ret = TRUE;
out:
- g_clear_pointer (&data->threadpool, (GDestroyNotify) g_thread_pool_free);
- if (data->src_repo)
- g_object_unref (data->src_repo);
- if (data->dest_repo)
- g_object_unref (data->dest_repo);
+ if (progress)
+ ostree_async_progress_finish (progress);
if (context)
g_option_context_free (context);
if (repo)