[ostree/wip/soup-hard-dep] Rebase pull-local reusing 'pull'
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree/wip/soup-hard-dep] Rebase pull-local reusing 'pull'
- Date: Sat, 17 Nov 2012 04:43:54 +0000 (UTC)
commit 7e31d0f6fc05cab5335f82086fcd658e843a9cd0
Author: Colin Walters <walters verbum org>
Date: Thu Nov 1 13:24:49 2012 -0400
Rebase pull-local reusing 'pull'
This gets us async scanning and commit, progress bar, etc.
src/ostree/ostree-fetcher.c | 12 ++-
src/ostree/ostree-pull.c | 139 +++++++++++++++++++------
src/ostree/ot-builtin-pull-local.c | 198 ++++--------------------------------
3 files changed, 135 insertions(+), 214 deletions(-)
---
diff --git a/src/ostree/ostree-fetcher.c b/src/ostree/ostree-fetcher.c
index 6d4b5db..96c2dae 100644
--- a/src/ostree/ostree-fetcher.c
+++ b/src/ostree/ostree-fetcher.c
@@ -193,7 +193,8 @@ on_request_sent (GObject *object,
pending->request_body = soup_request_send_finish ((SoupRequest*) object,
result, &local_error);
- msg = soup_request_http_get_message ((SoupRequestHTTP*) object);
+ if (SOUP_IS_REQUEST_HTTP (object))
+ msg = soup_request_http_get_message ((SoupRequestHTTP*) object);
if (!pending->request_body)
{
@@ -201,7 +202,7 @@ on_request_sent (GObject *object,
g_simple_async_result_take_error (pending->result, local_error);
g_simple_async_result_complete (pending->result);
}
- else if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
+ else if (msg && !SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
{
g_set_error (&local_error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Server returned status %u: %s",
@@ -255,9 +256,10 @@ ostree_fetcher_request_uri_async (OstreeFetcher *self,
g_assert_no_error (local_error);
pending->refcount++;
- g_hash_table_insert (self->message_to_request,
- soup_request_http_get_message ((SoupRequestHTTP*)pending->request),
- pending);
+ if (SOUP_IS_REQUEST_HTTP (pending->request))
+ g_hash_table_insert (self->message_to_request,
+ soup_request_http_get_message ((SoupRequestHTTP*)pending->request),
+ pending);
pending->result = g_simple_async_result_new ((GObject*) self,
callback, user_data,
diff --git a/src/ostree/ostree-pull.c b/src/ostree/ostree-pull.c
index 4c0e2dd..0f01d85 100644
--- a/src/ostree/ostree-pull.c
+++ b/src/ostree/ostree-pull.c
@@ -86,6 +86,8 @@ static GOptionEntry options[] = {
typedef struct {
OstreeRepo *repo;
char *remote_name;
+ OstreeRepo *remote_repo_on_local_fs;
+ gboolean remote_on_local_fs;
OstreeRepoMode remote_mode;
OstreeFetcher *fetcher;
SoupURI *base_uri;
@@ -560,18 +562,51 @@ process_one_file_request (OtFetchOneContentItemData *data)
gboolean compressed = pull_data->remote_mode == OSTREE_REPO_MODE_ARCHIVE_Z2;
ot_lfree char *objpath = NULL;
SoupURI *obj_uri = NULL;
+ GError *local_error = NULL;
+ GError **error = &local_error;
+
+ if (pull_data->remote_repo_on_local_fs)
+ {
+ guint64 length;
+ ot_lobj GInputStream *object_input = NULL;
+ ot_lobj GInputStream *input = NULL;
+ ot_lobj GFileInfo *file_info = NULL;
+ ot_lvariant GVariant *xattrs = NULL;
- objpath = ostree_get_relative_object_path (checksum, OSTREE_OBJECT_TYPE_FILE, compressed);
- obj_uri = suburi_new (pull_data->base_uri, objpath, NULL);
+ if (!ostree_repo_load_file (pull_data->remote_repo_on_local_fs,
+ checksum, &input, &file_info, &xattrs,
+ pull_data->cancellable, error))
+ goto out;
+
+ if (!ostree_raw_file_to_content_stream (input, file_info, xattrs,
+ &object_input, &length,
+ pull_data->cancellable, error))
+ goto out;
+
+ data->pull_data->outstanding_content_stage_requests++;
+ ostree_repo_stage_content_async (data->pull_data->repo, checksum,
+ object_input, length,
+ pull_data->cancellable,
+ content_fetch_on_stage_complete, data);
+ }
+ else
+ {
+ objpath = ostree_get_relative_object_path (checksum, OSTREE_OBJECT_TYPE_FILE, compressed);
+ obj_uri = suburi_new (pull_data->base_uri, objpath, NULL);
- ostree_fetcher_request_uri_async (pull_data->fetcher, obj_uri, pull_data->cancellable,
- content_fetch_on_complete, data);
- soup_uri_free (obj_uri);
+ ostree_fetcher_request_uri_async (pull_data->fetcher, obj_uri, pull_data->cancellable,
+ content_fetch_on_complete, data);
+ soup_uri_free (obj_uri);
- if (compressed)
- pull_data->outstanding_filecontent_requests++;
- else
- pull_data->outstanding_filemeta_requests++;
+ if (compressed)
+ pull_data->outstanding_filecontent_requests++;
+ else
+ pull_data->outstanding_filemeta_requests++;
+
+ }
+
+ out:
+ check_outstanding_requests_handle_error (data->pull_data, local_error);
}
static void
@@ -719,6 +754,9 @@ idle_queue_content_request (gpointer user_data)
{
g_queue_push_tail (&pull_data->queued_filemeta, data);
}
+ else if (pull_data->remote_on_local_fs)
+ {
+ }
else
{
process_one_file_request (data);
@@ -762,9 +800,9 @@ meta_fetch_on_complete (GObject *object,
{
IdleFetchMetadataObjectData *fetch_data = user_data;
OtPullData *pull_data = fetch_data->pull_data;
- ot_lvariant GVariant *metadata = NULL;
const char *checksum;
OstreeObjectType objtype;
+ ot_lvariant GVariant *metadata = NULL;
GError *local_error = NULL;
GError **error = &local_error;
@@ -800,18 +838,36 @@ idle_fetch_metadata_object (gpointer data)
const char *checksum;
OstreeObjectType objtype;
SoupURI *obj_uri = NULL;
- gboolean compressed;
-
- compressed = pull_data->remote_mode == OSTREE_REPO_MODE_ARCHIVE_Z2;
+ GError *local_error = NULL;
+ GError **error = &local_error;
ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype);
- objpath = ostree_get_relative_object_path (checksum, objtype, compressed);
- obj_uri = suburi_new (pull_data->base_uri, objpath, NULL);
+ if (pull_data->remote_on_local_fs)
+ {
+ ot_lvariant GVariant *metadata = NULL;
+ if (!ostree_repo_load_variant (pull_data->remote_repo_on_local_fs, objtype,
+ checksum, &metadata, error))
+ goto out;
+ ostree_repo_stage_metadata_async (pull_data->repo, objtype, checksum, metadata,
+ pull_data->cancellable,
+ on_metadata_staged, fetch_data);
+ }
+ else
+ {
+ gboolean compressed;
+
+ compressed = pull_data->remote_mode == OSTREE_REPO_MODE_ARCHIVE_Z2;
+ objpath = ostree_get_relative_object_path (checksum, objtype, compressed);
- ostree_fetcher_request_uri_async (pull_data->fetcher, obj_uri, pull_data->cancellable,
- meta_fetch_on_complete, fetch_data);
- soup_uri_free (obj_uri);
+ obj_uri = suburi_new (pull_data->base_uri, objpath, NULL);
+ ostree_fetcher_request_uri_async (pull_data->fetcher, obj_uri, pull_data->cancellable,
+ meta_fetch_on_complete, fetch_data);
+ soup_uri_free (obj_uri);
+ }
+
+ out:
+ check_outstanding_requests_handle_error (pull_data, local_error);
return FALSE;
}
@@ -1229,10 +1285,23 @@ ostree_builtin_pull (int argc, char **argv, GFile *repo_path, GError **error)
pull_data->fetcher = ostree_fetcher_new (ostree_repo_get_tmpdir (pull_data->repo));
config = ostree_repo_get_config (repo);
- remote_key = g_strdup_printf ("remote \"%s\"", pull_data->remote_name);
- if (!repo_get_string_key_inherit (repo, remote_key, "url", &baseurl, error))
- goto out;
- pull_data->base_uri = soup_uri_new (baseurl);
+ if (g_str_has_prefix (pull_data->remote_name, "file://"))
+ {
+ ot_lobj GFile *raw_path = g_file_new_for_path (pull_data->remote_name + strlen ("file://"));
+ pull_data->remote_repo_on_local_fs = ostree_repo_new (raw_path);
+ if (!ostree_repo_check (pull_data->remote_repo_on_local_fs, error))
+ goto out;
+ pull_data->base_uri = soup_uri_new (pull_data->remote_name);
+ pull_data->remote_on_local_fs = TRUE;
+ }
+ else
+ {
+ remote_key = g_strdup_printf ("remote \"%s\"", pull_data->remote_name);
+ if (!repo_get_string_key_inherit (repo, remote_key, "url", &baseurl, error))
+ goto out;
+ pull_data->base_uri = soup_uri_new (baseurl);
+ pull_data->remote_on_local_fs = FALSE;
+ }
if (!pull_data->base_uri)
{
@@ -1251,15 +1320,18 @@ ostree_builtin_pull (int argc, char **argv, GFile *repo_path, GError **error)
if (!ostree_repo_mode_from_string (remote_mode_str, &pull_data->remote_mode, error))
goto out;
- switch (pull_data->remote_mode)
+ if (!pull_data->remote_on_local_fs)
{
- case OSTREE_REPO_MODE_ARCHIVE:
- case OSTREE_REPO_MODE_ARCHIVE_Z2:
- break;
- default:
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Can't pull from archives with mode \"%s\"",
- remote_mode_str);
+ switch (pull_data->remote_mode)
+ {
+ case OSTREE_REPO_MODE_ARCHIVE:
+ case OSTREE_REPO_MODE_ARCHIVE_Z2:
+ break;
+ default:
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Can't pull from archives with mode \"%s\"",
+ remote_mode_str);
+ }
}
requested_refs_to_fetch = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
@@ -1293,7 +1365,8 @@ ostree_builtin_pull (int argc, char **argv, GFile *repo_path, GError **error)
GError *temp_error = NULL;
gboolean fetch_all_refs;
- configured_branches = g_key_file_get_string_list (config, remote_key, "branches", NULL, &temp_error);
+ if (remote_key)
+ configured_branches = g_key_file_get_string_list (config, remote_key, "branches", NULL, &temp_error);
if (configured_branches == NULL && temp_error != NULL)
{
if (g_error_matches (temp_error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND))
@@ -1443,7 +1516,9 @@ ostree_builtin_pull (int argc, char **argv, GFile *repo_path, GError **error)
g_free (pull_data->remote_name);
if (pull_data->base_uri)
soup_uri_free (pull_data->base_uri);
- g_clear_pointer (&pull_data->metadata_objects_to_scan, (GDestroyNotify) ot_worker_queue_unref);
+ if (pull_data->metadata_objects_to_scan)
+ ot_worker_queue_unref (pull_data->metadata_objects_to_scan);
+ g_clear_object (&pull_data->remote_repo_on_local_fs);
g_clear_pointer (&pull_data->scanned_metadata, (GDestroyNotify) g_hash_table_unref);
g_clear_pointer (&pull_data->requested_content, (GDestroyNotify) g_hash_table_unref);
g_clear_pointer (&remote_config, (GDestroyNotify) g_key_file_unref);
diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c
index 94f0b88..6a7de53 100644
--- a/src/ostree/ot-builtin-pull-local.c
+++ b/src/ostree/ot-builtin-pull-local.c
@@ -32,207 +32,51 @@ static GOptionEntry options[] = {
{ NULL }
};
-typedef struct {
- OstreeRepo *src_repo;
- OstreeRepo *dest_repo;
-} OtLocalCloneData;
-
-static gboolean
-import_one_object (OtLocalCloneData *data,
- const char *checksum,
- OstreeObjectType objtype,
- GCancellable *cancellable,
- GError **error)
-{
- gboolean ret = FALSE;
- ot_lobj GFile *content_path = NULL;
- ot_lobj GFileInfo *archive_info = NULL;
-
- if (objtype == OSTREE_OBJECT_TYPE_FILE)
- {
- guint64 length;
- ot_lobj GInputStream *file_object = NULL;
- ot_lobj GInputStream *input = NULL;
- ot_lobj GFileInfo *file_info = NULL;
- ot_lvariant GVariant *xattrs = NULL;
-
- if (!ostree_repo_load_file (data->src_repo, checksum,
- &input, &file_info, &xattrs,
- cancellable, error))
- goto out;
-
- if (!ostree_raw_file_to_content_stream (input, file_info, xattrs,
- &file_object, &length,
- cancellable, error))
- goto out;
-
- if (!ostree_repo_stage_content_trusted (data->dest_repo, checksum,
- file_object, length,
- cancellable, error))
- goto out;
- }
- else
- {
- ot_lvariant GVariant *metadata = NULL;
-
- if (!ostree_repo_load_variant (data->src_repo, objtype, checksum, &metadata,
- error))
- goto out;
-
- if (!ostree_repo_stage_metadata_trusted (data->dest_repo, objtype, checksum, metadata,
- cancellable, error))
- goto out;
- }
-
- ret = TRUE;
- out:
- return ret;
-}
-
gboolean
ostree_builtin_pull_local (int argc, char **argv, GFile *repo_path, GError **error)
{
- gboolean ret = FALSE;
- GCancellable *cancellable = NULL;
GOptionContext *context;
- const char *src_repo_path;
+ gboolean ret = FALSE;
+ GPtrArray *args = NULL;
int i;
- GHashTableIter hash_iter;
- gpointer key, value;
- ot_lhash GHashTable *objects = NULL;
- ot_lobj GFile *src_f = NULL;
- ot_lobj GFile *src_repo_dir = NULL;
- ot_lobj GFile *dest_repo_dir = NULL;
- ot_lobj GFile *src_dir = NULL;
- ot_lobj GFile *dest_dir = NULL;
- ot_lhash GHashTable *refs_to_clone = NULL;
- ot_lhash GHashTable *source_objects = NULL;
- ot_lhash GHashTable *objects_to_copy = NULL;
- OtLocalCloneData data;
+ gs_lfree char *file_uri = NULL;
+ gs_lfree char *repo_arg = NULL;
+ gs_lfree char *abspath = NULL;
context = g_option_context_new ("SRC_REPO [REFS...] - Copy data from SRC_REPO");
g_option_context_add_main_entries (context, options, NULL);
- memset (&data, 0, sizeof (data));
-
if (!g_option_context_parse (context, &argc, &argv, error))
goto out;
- data.dest_repo = ostree_repo_new (repo_path);
- if (!ostree_repo_check (data.dest_repo, error))
- goto out;
-
- if (argc < 2)
- {
- gchar *help = g_option_context_get_help (context, TRUE, NULL);
- g_printerr ("%s\n", help);
- g_free (help);
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "DESTINATION must be specified");
- goto out;
- }
-
- src_repo_path = argv[1];
- src_f = g_file_new_for_path (src_repo_path);
-
- data.src_repo = ostree_repo_new (src_f);
- if (!ostree_repo_check (data.src_repo, error))
- goto out;
-
- 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));
-
- if (argc == 2)
+ if (!g_path_is_absolute (argv[1]))
{
- if (!ostree_repo_list_all_refs (data.src_repo, &refs_to_clone, cancellable, error))
- goto out;
+ gs_lfree char *cwd = g_get_current_dir ();;
+ abspath = g_build_filename (cwd, argv[1], NULL);
}
else
- {
- refs_to_clone = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- for (i = 2; i < argc; i++)
- {
- const char *ref = argv[i];
- char *rev;
-
- 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);
- }
- }
+ abspath = g_strdup (argv[1]);
- g_print ("Enumerating objects...\n");
-
- source_objects = ostree_traverse_new_reachable ();
-
- 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_traverse_commit (data.src_repo, checksum, 0, source_objects, cancellable, error))
- goto out;
- }
-
- objects_to_copy = ostree_traverse_new_reachable ();
- g_hash_table_iter_init (&hash_iter, source_objects);
- while (g_hash_table_iter_next (&hash_iter, &key, &value))
- {
- GVariant *serialized_key = key;
- gboolean has_object;
- const char *checksum;
- OstreeObjectType objtype;
+ file_uri = g_strconcat ("file://", abspath, NULL);
+ repo_arg = g_strconcat ("--repo=", ot_gfile_get_path_cached (repo_path), NULL);
- ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
-
- if (!ostree_repo_has_object (data.dest_repo, objtype, checksum, &has_object,
- cancellable, error))
- goto out;
- if (!has_object)
- g_hash_table_insert (objects_to_copy, g_variant_ref (serialized_key), serialized_key);
- }
-
- g_print ("%u objects to copy\n", g_hash_table_size (objects_to_copy));
-
- if (!ostree_repo_prepare_transaction (data.dest_repo, FALSE, cancellable, error))
- goto out;
+ args = g_ptr_array_new ();
+ ot_ptrarray_add_many (args, "ostree", "pull", repo_arg, file_uri, NULL);
- g_hash_table_iter_init (&hash_iter, objects_to_copy);
- while (g_hash_table_iter_next (&hash_iter, &key, &value))
- {
- GVariant *serialized_key = key;
- const char *checksum;
- OstreeObjectType objtype;
+ for (i = 2; i < argc; i++)
+ g_ptr_array_add (args, argv[i]);
- ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
+ g_ptr_array_add (args, NULL);
- if (!import_one_object (&data, checksum, objtype, cancellable, error))
- goto out;
- }
+ execvp ("ostree", (char**)args->pdata);
+ /* Shouldn't return */
- if (!ostree_repo_commit_transaction (data.dest_repo, NULL, error))
- goto out;
-
- 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;
-
- if (!ostree_repo_write_ref (data.dest_repo, NULL, name, checksum, error))
- goto out;
- }
+ ot_util_set_error_from_errno (error, errno);
+ goto out;
ret = TRUE;
out:
- if (data.src_repo)
- g_object_unref (data.src_repo);
- if (data.dest_repo)
- g_object_unref (data.dest_repo);
+ g_clear_pointer (&args, (GDestroyNotify)g_ptr_array_unref);
if (context)
g_option_context_free (context);
return ret;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]