[ostree] Change pull-local to just be a wrapper for pull with file:///



commit 9cc98041953090160dde48afa69b97c936541cdb
Author: Colin Walters <walters verbum org>
Date:   Sun Feb 8 04:30:52 2015 -0500

    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

 src/libostree/ostree-repo-private.h |    3 +
 src/libostree/ostree-repo-pull.c    |   61 ++++++---
 src/libostree/ostree-repo.c         |   24 ++++
 src/ostree/ot-builtin-pull-local.c  |  237 ++++++++---------------------------
 4 files changed, 122 insertions(+), 203 deletions(-)
---
diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h
index f3f1cfe..fa963d1 100644
--- a/src/libostree/ostree-repo-private.h
+++ b/src/libostree/ostree-repo-private.h
@@ -163,6 +163,9 @@ _ostree_repo_commit_modifier_apply (OstreeRepo               *self,
                                     GFileInfo               **out_modified_info);
 
 gboolean
+_ostree_repo_remote_name_is_file (const char *remote_name);
+
+gboolean
 _ostree_repo_get_remote_option (OstreeRepo  *self,
                                 const char  *remote_name,
                                 const char  *option_name,
diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c
index f79c46c..c424914 100644
--- a/src/libostree/ostree-repo-pull.c
+++ b/src/libostree/ostree-repo-pull.c
@@ -1603,7 +1603,7 @@ ostree_repo_pull_one_dir (OstreeRepo               *self,
 /* Documented in ostree-repo.c */
 gboolean
 ostree_repo_pull_with_options (OstreeRepo             *self,
-                               const char             *remote_name,
+                               const char             *remote_name_or_baseurl,
                                GVariant               *options,
                                OstreeAsyncProgress    *progress,
                                GCancellable           *cancellable,
@@ -1642,6 +1642,7 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
       /* Reduce risk of issues if enum happens to be 64 bit for some reason */
       flags = flags_i;
       (void) g_variant_lookup (options, "subdir", "&s", &dir_to_pull);
+      (void) g_variant_lookup (options, "override-remote-name", "s", &pull_data->remote_name);
       (void) g_variant_lookup (options, "depth", "i", &pull_data->maxdepth);
     }
 
@@ -1676,21 +1677,32 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
 
   pull_data->start_time = g_get_monotonic_time ();
 
-  pull_data->remote_name = g_strdup (remote_name);
+  if (_ostree_repo_remote_name_is_file (remote_name_or_baseurl))
+    {
+      baseurl = g_strdup (remote_name_or_baseurl);
+      /* For compatibility with pull-local, don't gpg verify local
+       * pulls.
+       */
+      pull_data->gpg_verify = FALSE;
+    }
+  else
+    {
+      pull_data->remote_name = g_strdup (remote_name_or_baseurl);
 
 #ifdef HAVE_GPGME
-  if (!_ostree_repo_get_remote_boolean_option (self,
-                                               pull_data->remote_name, "gpg-verify",
-                                               TRUE, &pull_data->gpg_verify, error))
-    goto out;
+      if (!_ostree_repo_get_remote_boolean_option (self,
+                                                   remote_name_or_baseurl, "gpg-verify",
+                                                   TRUE, &pull_data->gpg_verify, error))
+        goto out;
 #else
-  pull_data->gpg_verify = FALSE;
+      pull_data->gpg_verify = FALSE;
 #endif
+    }
 
   pull_data->phase = OSTREE_PULL_PHASE_FETCHING_REFS;
 
   if (!_ostree_repo_get_remote_boolean_option (self,
-                                               pull_data->remote_name, "tls-permissive",
+                                               remote_name_or_baseurl, "tls-permissive",
                                                FALSE, &tls_permissive, error))
     goto out;
   if (tls_permissive)
@@ -1706,11 +1718,11 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
     gs_free char *tls_client_key_path = NULL;
 
     if (!_ostree_repo_get_remote_option (self,
-                                         pull_data->remote_name, "tls-client-cert-path",
+                                         remote_name_or_baseurl, "tls-client-cert-path",
                                          NULL, &tls_client_cert_path, error))
       goto out;
     if (!_ostree_repo_get_remote_option (self,
-                                         pull_data->remote_name, "tls-client-key-path",
+                                         remote_name_or_baseurl, "tls-client-key-path",
                                          NULL, &tls_client_key_path, error))
       goto out;
 
@@ -1718,7 +1730,7 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
       {
         g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                      "remote \"%s\" must specify both \"tls-client-cert-path\" and \"tls-client-key-path\"",
-                     pull_data->remote_name);
+                     remote_name_or_baseurl);
         goto out;
       }
     else if (tls_client_cert_path)
@@ -1742,7 +1754,7 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
     gs_unref_object GTlsDatabase *db = NULL;
 
     if (!_ostree_repo_get_remote_option (self,
-                                         pull_data->remote_name, "tls-ca-path",
+                                         remote_name_or_baseurl, "tls-ca-path",
                                          NULL, &tls_ca_path, error))
       goto out;
 
@@ -1760,7 +1772,7 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
     gs_free char *http_proxy = NULL;
 
     if (!_ostree_repo_get_remote_option (self,
-                                         pull_data->remote_name, "proxy",
+                                         remote_name_or_baseurl, "proxy",
                                          NULL, &http_proxy, error))
       goto out;
 
@@ -1769,20 +1781,23 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
   }
 
   if (!_ostree_repo_get_remote_option (self,
-                                       pull_data->remote_name, "metalink",
+                                       remote_name_or_baseurl, "metalink",
                                        NULL, &metalink_url_str, error))
     goto out;
 
   if (!metalink_url_str)
     {
-      if (!repo_get_remote_option_inherit (self, pull_data->remote_name, "url", &baseurl, error))
-        goto out;
+      if (baseurl == NULL)
+        {
+          if (!repo_get_remote_option_inherit (self, remote_name_or_baseurl, "url", &baseurl, error))
+            goto out;
+        }
 
       if (baseurl == NULL)
         {
           g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
                        "No \"url\" option in remote \"%s\"",
-                       pull_data->remote_name);
+                       remote_name_or_baseurl);
           goto out;
         }
 
@@ -1841,7 +1856,7 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
     }
 
   if (!_ostree_repo_get_remote_list_option (self,
-                                            pull_data->remote_name, "branches",
+                                            remote_name_or_baseurl, "branches",
                                             &configured_branches, error))
     goto out;
 
@@ -1944,7 +1959,7 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
       if (!(branches_iter && *branches_iter))
         {
           g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                       "No configured branches for remote %s", pull_data->remote_name);
+                       "No configured branches for remote %s", remote_name_or_baseurl);
           goto out;
         }
       for (;branches_iter && *branches_iter; branches_iter++)
@@ -2077,7 +2092,10 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
       gs_free char *remote_ref = NULL;
       gs_free char *original_rev = NULL;
           
-      remote_ref = g_strdup_printf ("%s/%s", pull_data->remote_name, ref);
+      if (pull_data->remote_name)
+        remote_ref = g_strdup_printf ("%s/%s", pull_data->remote_name, ref);
+      else
+        remote_ref = g_strdup (ref);
 
       if (!ostree_repo_resolve_rev (pull_data->repo, remote_ref, TRUE, &original_rev, error))
         goto out;
@@ -2087,7 +2105,8 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
         }
       else
         {
-          ostree_repo_transaction_set_ref (pull_data->repo, pull_data->is_mirror ? NULL : 
pull_data->remote_name, ref, checksum);
+          ostree_repo_transaction_set_ref (pull_data->repo, pull_data->is_mirror ? NULL : 
pull_data->remote_name,
+                                          ref, checksum);
         }
     }
 
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index accb011..49ccbd8 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -232,6 +232,12 @@ ost_repo_remove_remote (OstreeRepo   *self,
 }
 
 gboolean
+_ostree_repo_remote_name_is_file (const char *remote_name)
+{
+  return g_str_has_prefix (remote_name, "file://");
+}
+
+gboolean
 _ostree_repo_get_remote_option (OstreeRepo  *self,
                                 const char  *remote_name,
                                 const char  *option_name,
@@ -242,6 +248,12 @@ _ostree_repo_get_remote_option (OstreeRepo  *self,
   local_cleanup_remote OstreeRemote *remote = NULL;
   gboolean ret = FALSE;
 
+  if (_ostree_repo_remote_name_is_file (remote_name))
+    {
+      *out_value = g_strdup (default_value);
+      return TRUE;
+    }
+
   remote = ost_repo_get_remote (self, remote_name, error);
 
   if (remote != NULL)
@@ -267,6 +279,12 @@ _ostree_repo_get_remote_list_option (OstreeRepo   *self,
   local_cleanup_remote OstreeRemote *remote = NULL;
   gboolean ret = FALSE;
 
+  if (_ostree_repo_remote_name_is_file (remote_name))
+    {
+      *out_value = NULL;
+      return TRUE;
+    }
+
   remote = ost_repo_get_remote (self, remote_name, error);
 
   if (remote != NULL)
@@ -304,6 +322,12 @@ _ostree_repo_get_remote_boolean_option (OstreeRepo  *self,
   local_cleanup_remote OstreeRemote *remote = NULL;
   gboolean ret = FALSE;
 
+  if (_ostree_repo_remote_name_is_file (remote_name))
+    {
+      *out_value = default_value;
+      return TRUE;
+    }
+  
   remote = ost_repo_get_remote (self, remote_name, error);
 
   if (remote != NULL)
diff --git a/src/ostree/ot-builtin-pull-local.c b/src/ostree/ot-builtin-pull-local.c
index c49ad0f..acad43b 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)


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