lib/pull: Read mode and tombstone options from summary file if possible
authorPhilip Withnall <withnall@endlessm.com>
Mon, 10 Aug 2020 11:06:35 +0000 (12:06 +0100)
committerPhilip Withnall <pwithnall@endlessos.org>
Thu, 1 Oct 2020 10:06:56 +0000 (11:06 +0100)
Otherwise, fall back to downloading and reading them from the `config`
file. See the previous commit for details.

Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2165
src/libostree/ostree-repo-pull.c

index a6401907c1200ff30705270086b58c707b0447b6..f16ccec508399ac8f2f939104e54cbe5a8520f93 100644 (file)
@@ -2001,6 +2001,8 @@ start_fetch (OtPullData *pull_data,
                                       is_meta ? meta_fetch_on_complete : content_fetch_on_complete, fetch);
 }
 
+/* Deprecated: code should load options from the `summary` file rather than
+ * downloading the remote’s `config` file, to save on network round trips. */
 static gboolean
 load_remote_repo_config (OtPullData    *pull_data,
                          GKeyFile     **out_keyfile,
@@ -3757,30 +3759,6 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
       if (!ostree_repo_open (pull_data->remote_repo_local, cancellable, error))
         goto out;
     }
-  else
-    {
-      if (!load_remote_repo_config (pull_data, &remote_config, cancellable, error))
-        goto out;
-
-      if (!ot_keyfile_get_value_with_default (remote_config, "core", "mode", "bare",
-                                              &remote_mode_str, error))
-        goto out;
-
-      if (!ostree_repo_mode_from_string (remote_mode_str, &pull_data->remote_mode, error))
-        goto out;
-
-      if (!ot_keyfile_get_boolean_with_default (remote_config, "core", "tombstone-commits", FALSE,
-                                                &pull_data->has_tombstone_commits, error))
-        goto out;
-
-      if (pull_data->remote_mode != OSTREE_REPO_MODE_ARCHIVE)
-        {
-          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                       "Can't pull from archives with mode \"%s\"",
-                       remote_mode_str);
-          goto out;
-        }
-    }
   }
 
   /* Change some option defaults if we're actually pulling from a local
@@ -3854,6 +3832,8 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
     g_autoptr(GVariant) deltas = NULL;
     g_autoptr(GVariant) additional_metadata = NULL;
     gboolean summary_from_cache = FALSE;
+    gboolean remote_mode_loaded = FALSE;
+    gboolean tombstone_commits = FALSE;
 
     if (summary_sig_bytes_v)
       {
@@ -4167,6 +4147,46 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
                                  csum_data);
           }
       }
+
+    if (pull_data->summary &&
+        g_variant_lookup (additional_metadata, OSTREE_SUMMARY_MODE, "s", &remote_mode_str) &&
+        g_variant_lookup (additional_metadata, OSTREE_SUMMARY_TOMBSTONE_COMMITS, "b", &tombstone_commits))
+      {
+        if (!ostree_repo_mode_from_string (remote_mode_str, &pull_data->remote_mode, error))
+          goto out;
+        pull_data->has_tombstone_commits = tombstone_commits;
+        remote_mode_loaded = TRUE;
+      }
+    else if (pull_data->remote_repo_local == NULL)
+      {
+        /* Fall-back path which loads the necessary config from the remote’s
+         * `config` file. Doing so is deprecated since it means an
+         * additional round trip to the remote for each pull. No need to do
+         * it for local pulls. */
+        if (!load_remote_repo_config (pull_data, &remote_config, cancellable, error))
+          goto out;
+
+        if (!ot_keyfile_get_value_with_default (remote_config, "core", "mode", "bare",
+                                                &remote_mode_str, error))
+          goto out;
+
+        if (!ostree_repo_mode_from_string (remote_mode_str, &pull_data->remote_mode, error))
+          goto out;
+
+        if (!ot_keyfile_get_boolean_with_default (remote_config, "core", "tombstone-commits", FALSE,
+                                                  &pull_data->has_tombstone_commits, error))
+          goto out;
+
+        remote_mode_loaded = TRUE;
+      }
+
+    if (remote_mode_loaded && pull_data->remote_repo_local == NULL && pull_data->remote_mode != OSTREE_REPO_MODE_ARCHIVE)
+      {
+        g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                     "Can't pull from archives with mode \"%s\"",
+                     remote_mode_str);
+        goto out;
+      }
   }
 
   if (pull_data->is_mirror && !refs_to_fetch && !opt_collection_refs_set && !configured_branches)