[ostree/wip/metalinks] wip



commit 37e089b8135ce0a85551dd13b41f3291bfaeee12
Author: Colin Walters <walters verbum org>
Date:   Fri Aug 15 15:19:08 2014 -0400

    wip

 src/libostree/ostree-metalink.c  |  157 ++++++++++++++++++++++++++++++++++----
 src/libostree/ostree-metalink.h  |   15 +++-
 src/libostree/ostree-repo-pull.c |   29 +++++---
 3 files changed, 172 insertions(+), 29 deletions(-)
---
diff --git a/src/libostree/ostree-metalink.c b/src/libostree/ostree-metalink.c
index f217461..072c97e 100644
--- a/src/libostree/ostree-metalink.c
+++ b/src/libostree/ostree-metalink.c
@@ -45,6 +45,15 @@ struct OstreeMetalink
   GObject parent_instance;
 
   OstreeMetalink *fetcher;
+  char *requested_file;
+  guint64 max_size;
+};
+
+G_DEFINE_TYPE (OstreeMetalink, _ostree_metalink, G_TYPE_OBJECT)
+
+struct OstreeMetalinkRequest
+{
+  OstreeMetalink *metalink;
 
   guint passthrough_depth;
   OstreeMetalinkState passthrough_previous;
@@ -58,22 +67,20 @@ struct OstreeMetalink
   GPtrArray *urls;
 
   OstreeMetalinkState state;
-};
-
-G_DEFINE_TYPE (OstreeMetalink, _ostree_metalink, G_TYPE_OBJECT)
+}
 
 static void
-state_transition (OstreeMetalink       *self,
-                  OstreeMetalinkState   new_state)
+state_transition (OstreeMetalinkRequest  *self,
+                  OstreeMetalinkState     new_state)
 {
   g_assert (self->state != new_state);
   self->state = new_state;
 }
 
 static void
-unknown_element (OstreeMetalink         *self,
-                 const char             *element_name,
-                 GError                **error)
+unknown_element (OstreeMetalinkRequest         *self,
+                 const char                    *element_name,
+                 GError                       **error)
 {
   state_transition (self, OSTREE_METALINK_STATE_PASSTHROUGH);
   g_assert (self->passthrough_depth == 0);
@@ -87,7 +94,7 @@ metalink_parser_start (GMarkupParseContext  *context,
                        gpointer              user_data,
                        GError              **error)
 {
-  OstreeMetalink *self = user_data;
+  OstreeMetalinkRequest *self = user_data;
 
   switch (self->state)
     {
@@ -294,21 +301,139 @@ _ostree_metalink_new (OstreeFetcher  *fetcher,
                       SoupURI        *uri)
 {
   OstreeMetalink *self = (OstreeMetalink*)g_object_new (OSTREE_TYPE_METALINK, NULL);
+
+  self->requested_file = g_strdup (requested_file);
+  self->max_size = max_size;
  
   return self;
 }
 
+static void
+on_metalink_bytes_read (GObject           *src,
+                        GAsyncResult      *result,
+                        gpointer           user_data)
+{
+  GError *local_error = NULL;
+  GTask *task = user_data;
+  gs_unref_bytes GBytes *bytes = NULL;
+
+  bytes = g_input_stream_read_bytes_finish ((GInputStream*)src,
+                                            result, error);
+  if (!bytes)
+    goto out;
+
+  if (g_bytes_get_size (bytes) == 0)
+    {
+      g_
+    }
+  else
+    {
+      g_input_stream_read_bytes_async ((GInputStream*)src, 8192, G_PRIORITY_DEFAULT,
+                                       g_task_get_cancellable (task),
+                                       on_metalink_bytes_read, task);
+    }
+
+ out:
+  if (local_error)
+    g_task_return_error (task, local_error);
+}
+
+static void
+on_retrieved_metalink (GObject           *src,
+                       GAsyncResult      *result,
+                       gpointer           user_data)
+{
+  GError *local_error = NULL;
+  GTask *task = user_data;
+  gs_unref_object GInputStream *metalink_stream = NULL;
+
+  metalink_stream = ostree_fetcher_stream_uri_finish ((OstreeFetcher*)src, result, &local_error);
+  if (!metalink_stream)
+    goto out;
+
+  g_input_stream_read_bytes_async (metalink_stream, 8192, G_PRIORITY_DEFAULT,
+                                   g_task_get_cancellable (task),
+                                   on_metalink_bytes_read, task);
+
+ out:
+  if (local_error)
+    g_task_return_error (task, local_error);
+}
+
+static void
+ostree_metalink_request_unref (gpointer data)
+{
+  OstreeMetalinkRequest  *request = data;
+  g_object_unref (request->metalink);
+  g_free (request);
+}
+                               
+
 void
 _ostree_metalink_request_async (OstreeMetalink         *self,
-                                GCancellable          *cancellable,
-                                GAsyncReadyCallback    callback,
-                                gpointer               user_data)
+                                GCancellable           *cancellable,
+                                GAsyncReadyCallback     callback,
+                                gpointer                user_data)
 {
+  GTask *task = g_task_new (self, cancellable, callback, user_data);
+  OstreeMetalinkRequest *request = g_new0 (OstreeMetalinkRequest, 1);
+  request->metalink = g_object_ref (self);
+  g_task_set_task_data (task, request, ostree_metalink_request_unref);
+  _ostree_fetcher_stream_uri_async (self->fetcher, self->uri,
+                                    self->max_size, cancellable,
+                                    on_retrieved_metalink, task);
 }
 
-GFile *
-_ostree_metalink_request_finish (OstreeMetalink *self,
-                                 GAsyncResult   *result,
-                                 GError        **error)
+gboolean
+ostree_metalink_request_finish (OstreeMetalink         *self,
+                                GAsyncResult           *result,
+                                SoupURI               **out_target_uri,
+                                GFile                 **out_data,
+                                GError                **error)
 {
 }
+
+struct MetalinkSyncCallState
+{
+  gboolean                running;
+  gboolean                success;
+  SoupURI               **out_target_uri;
+  GFile                 **out_data;
+  GError                **error;
+}
+
+static void
+on_async_result (GObject          *src,
+                 GAsyncResult     *result,
+                 gpointer          user_data)
+{
+  MetalinkSyncCallState *state = user_data;
+
+  state->success = ostree_metalink_request_finish ((OstreeMetalink*)src, result,
+                                                   state->out_target_uri, state->out_data,
+                                                   state->error);
+  state->running = FALSE;
+}
+
+gboolean
+_ostree_metalink_request_sync (OstreeMetalink         *self,
+                               GCancellable           *cancellable,
+                               SoupURI               **out_target_uri,
+                               GFile                 **out_data,
+                               GError                **error)
+{
+  gboolean ret = FALSE;
+  GMainContext *sync_context = g_main_context_new ();
+  MetalinkSyncCallState state = { 0, };
+  
+  _ostree_metalink_request_async (self, cancellable, on_async_result, &state);
+  
+  while (state.running)
+    g_main_context_iteration (sync_context, TRUE);
+
+  ret = state.success;
+ out:
+  if (sync_context)
+    g_main_context_unref (sync_context);
+  return ret;
+}
diff --git a/src/libostree/ostree-metalink.h b/src/libostree/ostree-metalink.h
index bb81292..72bdfb5 100644
--- a/src/libostree/ostree-metalink.h
+++ b/src/libostree/ostree-metalink.h
@@ -48,14 +48,23 @@ OstreeMetalink *_ostree_metalink_new (OstreeFetcher  *fetcher,
                                       guint64         max_size,
                                       SoupURI        *uri);
 
+gboolean _ostree_metalink_request_sync (OstreeMetalink         *self,
+                                        SoupURI               **out_target_uri,
+                                        GFile                 **out_data,
+                                        GCancellable           *cancellable,
+                                        GError                **error);
+
+
 void _ostree_metalink_request_async (OstreeMetalink         *self,
                                      GCancellable          *cancellable,
                                      GAsyncReadyCallback    callback,
                                      gpointer               user_data);
 
-GFile *_ostree_metalink_request_finish (OstreeMetalink         *self,
-                                        GAsyncResult          *result,
-                                        GError               **error);
+gboolean_ostree_metalink_request_finish (OstreeMetalink         *self,
+                                         GAsyncResult           *result,
+                                         SoupURI               **out_target_uri,
+                                         GFile                 **out_data,
+                                         GError                **error);
 
 G_END_DECLS
 
diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c
index 9be8f32..7a0917b 100644
--- a/src/libostree/ostree-repo-pull.c
+++ b/src/libostree/ostree-repo-pull.c
@@ -1034,6 +1034,7 @@ ostree_repo_pull (OstreeRepo               *self,
   gs_unref_hashtable GHashTable *requested_refs_to_fetch = NULL;
   gs_unref_hashtable GHashTable *commits_to_fetch = NULL;
   gs_free char *remote_mode_str = NULL;
+  gs_unref_object OstreeMetalink *metalink = NULL;
   OtPullData pull_data_real = { 0, };
   OtPullData *pull_data = &pull_data_real;
   GKeyFile *config = NULL;
@@ -1072,26 +1073,34 @@ ostree_repo_pull (OstreeRepo               *self,
       goto out;
     }
 
-  if (!ot_keyfile_get_value_with_default (self, remote_key, "metalink", &metalink_url, error))
+  if (!repo_get_string_key_inherit (self, remote_key, "metalink", &metalink_url, error))
     goto out;
 
   if (!metalink_url)
     {
       if (!repo_get_string_key_inherit (self, remote_key, "url", &baseurl, error))
         goto out;
+
+      pull_data->base_uri = soup_uri_new (baseurl);
+
+      if (!pull_data->base_uri)
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       "Failed to parse url '%s'", baseurl);
+          goto out;
+        }
     }
   else
     {
-      FIXME - need to retrieve the metalink value, extract checksum for ref from it
-    }
+      gs_unref_object GFile *metalink_data = NULL;
+      SoupURI *metalink_uri = soup_uri_new (metalink_url);
+      metalink = _ostree_metalink_new (pull_data->fetcher, metalink_url, OSTREE_MAX_METADATA_SIZE, 
metalink_uri);
+      g_object_unref (metalink_uri);
 
-  pull_data->base_uri = soup_uri_new (baseurl);
-
-  if (!pull_data->base_uri)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Failed to parse url '%s'", baseurl);
-      goto out;
+      if (!_ostree_metalink_request_sync (metalink, &pull_data->base_uri,
+                                          &metalink_data,
+                                          cancellable, error))
+        goto out;
     }
 
 #ifdef HAVE_GPGME


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]