From 7d72a4b94158ad9a149f0efdbc66758cdf734838 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 26 Sep 2013 14:00:36 -0400 Subject: [PATCH] pull: Also fetch detached commitmeta files These will contain GPG signatures and the like in the future, so we should fetch them now. --- src/libostree/ostree-repo-pull.c | 149 ++++++++++++++++++++--------- src/ostree/ot-builtin-pull-local.c | 17 ++++ tests/pull-test.sh | 8 ++ tests/test-basic.sh | 8 ++ 4 files changed, 139 insertions(+), 43 deletions(-) diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 306bfe99..b52e19d2 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -56,6 +56,7 @@ #include "config.h" #include "ostree.h" +#include "ostree-core-private.h" #include "ostree-repo-private.h" #include "ostree-fetcher.h" #include "otutil.h" @@ -65,6 +66,7 @@ typedef struct { PULL_MSG_SCAN_IDLE, PULL_MSG_MAIN_IDLE, PULL_MSG_FETCH, + PULL_MSG_FETCH_DETACHED_METADATA, PULL_MSG_SCAN, PULL_MSG_QUIT } t; @@ -121,6 +123,7 @@ typedef struct { OtPullData *pull_data; GVariant *object; GFile *temp_path; + gboolean is_detached_meta; } FetchObjectData; static SoupURI * @@ -232,6 +235,7 @@ pull_worker_message_new (int msgtype, gpointer data) break; case PULL_MSG_SCAN: case PULL_MSG_FETCH: + case PULL_MSG_FETCH_DETACHED_METADATA: msg->d.item = data; break; case PULL_MSG_QUIT: @@ -653,6 +657,11 @@ on_metadata_writed (GObject *object, check_outstanding_requests_handle_error (pull_data, local_error); } +static void +enqueue_one_object_request (OtPullData *pull_data, + GVariant *object_name, + gboolean is_detached_meta); + static void meta_fetch_on_complete (GObject *object, GAsyncResult *result, @@ -666,23 +675,47 @@ meta_fetch_on_complete (GObject *object, GError *local_error = NULL; GError **error = &local_error; - fetch_data->temp_path = ostree_fetcher_request_uri_with_partial_finish ((OstreeFetcher*)object, result, error); - if (!fetch_data->temp_path) - goto out; - ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype); - g_debug ("fetch of %s complete", ostree_object_to_string (checksum, objtype)); - if (!ot_util_variant_map (fetch_data->temp_path, ostree_metadata_variant_type (objtype), - FALSE, &metadata, error)) - goto out; + fetch_data->temp_path = ostree_fetcher_request_uri_with_partial_finish ((OstreeFetcher*)object, result, error); + if (!fetch_data->temp_path) + { + if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + goto out; + else if (fetch_data->is_detached_meta) + { + /* There isn't any detached metadata, just fetch the commit */ + g_clear_error (&local_error); + enqueue_one_object_request (pull_data, fetch_data->object, FALSE); + } - ostree_repo_write_metadata_async (pull_data->repo, objtype, checksum, metadata, - pull_data->cancellable, - on_metadata_writed, fetch_data); + goto out; + } + + if (fetch_data->is_detached_meta) + { + if (!ot_util_variant_map (fetch_data->temp_path, G_VARIANT_TYPE ("a{sv}"), + FALSE, &metadata, error)) + goto out; + if (!ostree_repo_write_commit_detached_metadata (pull_data->repo, checksum, metadata, + pull_data->cancellable, error)) + goto out; + + enqueue_one_object_request (pull_data, fetch_data->object, FALSE); + } + else + { + if (!ot_util_variant_map (fetch_data->temp_path, ostree_metadata_variant_type (objtype), + FALSE, &metadata, error)) + goto out; + + ostree_repo_write_metadata_async (pull_data->repo, objtype, checksum, metadata, + pull_data->cancellable, + on_metadata_writed, fetch_data); + pull_data->n_outstanding_metadata_write_requests++; + } - pull_data->n_outstanding_metadata_write_requests++; out: pull_data->n_outstanding_metadata_fetches--; pull_data->n_fetched_metadata++; @@ -769,9 +802,14 @@ scan_one_metadata_object (OtPullData *pull_data, char *duped_checksum = g_strdup (tmp_checksum); g_hash_table_insert (pull_data->requested_metadata, duped_checksum, duped_checksum); - ot_waitable_queue_push (pull_data->metadata_objects_to_fetch, - pull_worker_message_new (PULL_MSG_FETCH, - g_variant_ref (object))); + if (objtype == OSTREE_OBJECT_TYPE_COMMIT) + ot_waitable_queue_push (pull_data->metadata_objects_to_fetch, + pull_worker_message_new (PULL_MSG_FETCH_DETACHED_METADATA, + g_variant_ref (object))); + else + ot_waitable_queue_push (pull_data->metadata_objects_to_fetch, + pull_worker_message_new (PULL_MSG_FETCH, + g_variant_ref (object))); } else if (is_stored) { @@ -918,6 +956,53 @@ metadata_thread_main (gpointer user_data) return NULL; } +static void +enqueue_one_object_request (OtPullData *pull_data, + GVariant *object_name, + gboolean is_detached_meta) +{ + const char *checksum; + OstreeObjectType objtype; + SoupURI *obj_uri = NULL; + gboolean is_meta; + FetchObjectData *fetch_data; + gs_free char *objpath = NULL; + + ostree_object_name_deserialize (object_name, &checksum, &objtype); + + if (is_detached_meta) + { + char buf[_OSTREE_LOOSE_PATH_MAX]; + _ostree_loose_path_with_suffix (buf, checksum, OSTREE_OBJECT_TYPE_COMMIT, + pull_data->remote_mode, "meta"); + obj_uri = suburi_new (pull_data->base_uri, "objects", buf, NULL); + } + else + { + objpath = ostree_get_relative_object_path (checksum, objtype, TRUE); + obj_uri = suburi_new (pull_data->base_uri, objpath, NULL); + } + + is_meta = OSTREE_OBJECT_TYPE_IS_META (objtype); + if (is_meta) + { + pull_data->n_outstanding_metadata_fetches++; + pull_data->n_requested_metadata++; + } + else + { + pull_data->n_outstanding_content_fetches++; + pull_data->n_requested_content++; + } + fetch_data = g_new (FetchObjectData, 1); + fetch_data->pull_data = pull_data; + fetch_data->object = g_variant_ref (object_name); + fetch_data->is_detached_meta = is_detached_meta; + ostree_fetcher_request_uri_with_partial_async (pull_data->fetcher, obj_uri, pull_data->cancellable, + is_meta ? meta_fetch_on_complete : content_fetch_on_complete, fetch_data); + soup_uri_free (obj_uri); +} + static gboolean on_metadata_objects_to_fetch_ready (gint fd, GIOCondition condition, @@ -948,36 +1033,14 @@ on_metadata_objects_to_fetch_ready (gint fd, pull_worker_message_new (PULL_MSG_MAIN_IDLE, GUINT_TO_POINTER (pull_data->idle_serial))); } } - else if (msg->t == PULL_MSG_FETCH) + else if (msg->t == PULL_MSG_FETCH || msg->t == PULL_MSG_FETCH_DETACHED_METADATA) { - const char *checksum; - gs_free char *objpath = NULL; - OstreeObjectType objtype; - SoupURI *obj_uri = NULL; - gboolean is_meta; - FetchObjectData *fetch_data; - - ostree_object_name_deserialize (msg->d.item, &checksum, &objtype); - objpath = ostree_get_relative_object_path (checksum, objtype, TRUE); - obj_uri = suburi_new (pull_data->base_uri, objpath, NULL); + gboolean is_detached_meta; + + is_detached_meta = msg->t == PULL_MSG_FETCH_DETACHED_METADATA; + + enqueue_one_object_request (pull_data, msg->d.item, is_detached_meta); - is_meta = OSTREE_OBJECT_TYPE_IS_META (objtype); - if (is_meta) - { - pull_data->n_outstanding_metadata_fetches++; - pull_data->n_requested_metadata++; - } - else - { - pull_data->n_outstanding_content_fetches++; - pull_data->n_requested_content++; - } - fetch_data = g_new (FetchObjectData, 1); - fetch_data->pull_data = pull_data; - fetch_data->object = g_variant_ref (msg->d.item); - ostree_fetcher_request_uri_with_partial_async (pull_data->fetcher, obj_uri, pull_data->cancellable, - is_meta ? meta_fetch_on_complete : content_fetch_on_complete, fetch_data); - soup_uri_free (obj_uri); g_variant_unref (msg->d.item); } else diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c index f051d6a5..6058b0e6 100644 --- a/src/ostree/ot-builtin-pull-local.c +++ b/src/ostree/ot-builtin-pull-local.c @@ -78,6 +78,23 @@ import_one_object (OtLocalCloneData *data, } else { + if (objtype == OSTREE_OBJECT_TYPE_COMMIT) + { + gs_unref_variant GVariant *detached_meta = NULL; + + if (!ostree_repo_read_commit_detached_metadata (data->src_repo, + checksum, &detached_meta, + cancellable, error)) + goto out; + + if (detached_meta) + { + if (!ostree_repo_write_commit_detached_metadata (data->src_repo, + checksum, detached_meta, + cancellable, error)) + goto out; + } + } if (!ostree_repo_write_metadata_stream_trusted (data->dest_repo, objtype, checksum, object, length, cancellable, error)) diff --git a/tests/pull-test.sh b/tests/pull-test.sh index a049dd77..dd93b88d 100755 --- a/tests/pull-test.sh +++ b/tests/pull-test.sh @@ -31,3 +31,11 @@ cd checkout-origin-main assert_file_has_content firstfile '^first$' assert_file_has_content baz/cow '^moo$' echo "ok pull contents" + +cd ${test_tmpdir} +ostree --repo=ostree-srv/gnomerepo commit -b main -s "Metadata string" --add-detached-metadata-string=SIGNATURE=HANCOCK --tree=ref=main +${CMD_PREFIX} ostree --repo=repo pull origin main +${CMD_PREFIX} ostree --repo=repo fsck +$OSTREE show --print-detached-metadata-key=SIGNATURE main > main-meta +assert_file_has_content main-meta "HANCOCK" +echo "ok pull detached metadata" diff --git a/tests/test-basic.sh b/tests/test-basic.sh index d5b9e5a4..4c7e056d 100755 --- a/tests/test-basic.sh +++ b/tests/test-basic.sh @@ -291,3 +291,11 @@ assert_file_has_content test2-meta "CUTE" $OSTREE show --print-detached-metadata-key=SIGNATURE test2 > test2-meta assert_file_has_content test2-meta "HANCOCK" echo "ok metadata commit with strings" + +cd ${test_tmpdir} +rm repo2 -rf +mkdir repo2 +${CMD_PREFIX} ostree --repo=repo2 init +${CMD_PREFIX} ostree --repo=repo2 pull-local repo +echo "ok pull-local after commit metadata" +