repo: Create metadata commit in ostree_repo_regenerate_metadata
authorDan Nicholson <nicholson@endlessm.com>
Tue, 15 Oct 2019 22:46:59 +0000 (16:46 -0600)
committerDan Nicholson <dbn@endlessos.org>
Tue, 7 Feb 2023 21:50:47 +0000 (14:50 -0700)
Rather than creating the `ostree-metadata` commit in the summary
builtin, do it in the new `ostree_repo_regenerate_metadata` API. The
commit contents are unchanged and the commit is generated before the
summary as before. To keep from triggering an extra summary update,
automatic summary updating is disabled in the transaction.

Since the summary builtin was already using the new API, it will
continue to generate the `ostree-metadata` commit when the repo has a
collection ID. However, the `ostree_repo_regenerate_summary` API will
still only generate the summary file as before.

src/libostree/ostree-repo-commit.c
src/libostree/ostree-repo-private.h
src/libostree/ostree-repo.c
src/ostree/ot-builtin-summary.c

index 51bfd46e943879f8b0a72b7a68ca68c29c575e7f..7f668b7da0603253464591d30060ffe0cc784348 100644 (file)
@@ -4871,3 +4871,72 @@ ostree_repo_transaction_stats_free (OstreeRepoTransactionStats *stats)
 G_DEFINE_BOXED_TYPE(OstreeRepoTransactionStats, ostree_repo_transaction_stats,
                     ostree_repo_transaction_stats_copy,
                     ostree_repo_transaction_stats_free);
+
+
+gboolean
+_ostree_repo_transaction_write_repo_metadata (OstreeRepo    *self,
+                                              GVariant      *additional_metadata,
+                                              char         **out_checksum,
+                                              GCancellable  *cancellable,
+                                              GError       **error)
+{
+  g_assert (self != NULL);
+  g_assert (OSTREE_IS_REPO (self));
+  g_assert (self->in_transaction == TRUE);
+
+  const char *collection_id = ostree_repo_get_collection_id (self);
+  if (collection_id == NULL)
+    return glnx_throw (error, "Repository must have collection ID to write repo metadata");
+
+  OstreeCollectionRef collection_ref = { (gchar *) collection_id,
+                                         (gchar *) OSTREE_REPO_METADATA_REF };
+  g_autofree char *old_checksum = NULL;
+  if (!ostree_repo_resolve_rev (self, OSTREE_REPO_METADATA_REF, TRUE,
+                                &old_checksum, error))
+    return FALSE;
+
+  /* Add bindings to the commit metadata. */
+  g_autoptr(GVariantDict) metadata_dict = g_variant_dict_new (additional_metadata);
+  g_variant_dict_insert (metadata_dict, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING,
+                         "s", collection_ref.collection_id);
+  g_variant_dict_insert_value (metadata_dict, OSTREE_COMMIT_META_KEY_REF_BINDING,
+                               g_variant_new_strv ((const gchar * const *) &collection_ref.ref_name, 1));
+  g_autoptr(GVariant) metadata = g_variant_dict_end (metadata_dict);
+
+  /* Set up an empty mtree. */
+  g_autoptr(OstreeMutableTree) mtree = ostree_mutable_tree_new ();
+
+  glnx_unref_object GFileInfo *fi = g_file_info_new ();
+  g_file_info_set_attribute_uint32 (fi, "unix::uid", 0);
+  g_file_info_set_attribute_uint32 (fi, "unix::gid", 0);
+  g_file_info_set_attribute_uint32 (fi, "unix::mode", (0755 | S_IFDIR));
+
+  g_autoptr(GVariant) dirmeta = ostree_create_directory_metadata (fi, NULL /* xattrs */);
+
+  g_autofree guchar *csum_raw = NULL;
+  if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_DIR_META, NULL,
+                                   dirmeta, &csum_raw, cancellable, error))
+    return FALSE;
+
+  g_autofree char *csum = ostree_checksum_from_bytes (csum_raw);
+  ostree_mutable_tree_set_metadata_checksum (mtree, csum);
+
+  g_autoptr(OstreeRepoFile) repo_file = NULL;
+  if (!ostree_repo_write_mtree (self, mtree, (GFile **) &repo_file, cancellable, error))
+    return FALSE;
+
+  g_autofree gchar *new_checksum = NULL;
+  if (!ostree_repo_write_commit (self, old_checksum,
+                                 NULL  /* subject */, NULL  /* body */,
+                                 metadata, repo_file,
+                                 &new_checksum,
+                                 cancellable, error))
+    return FALSE;
+
+  ostree_repo_transaction_set_collection_ref (self, &collection_ref, new_checksum);
+
+  if (out_checksum != NULL)
+    *out_checksum = g_steal_pointer (&new_checksum);
+
+  return TRUE;
+}
index 9a0ea2bedd058c3c0d00a5c9383cb2b191fab0c6..17993574efced12068058c09cfe50caea23d91ff 100644 (file)
@@ -523,6 +523,13 @@ ostree_repo_list_objects_set (OstreeRepo                  *self,
                               GCancellable                *cancellable,
                               GError                     **error);
 
+gboolean
+_ostree_repo_transaction_write_repo_metadata (OstreeRepo    *self,
+                                              GVariant      *additional_metadata,
+                                              char         **out_checksum,
+                                              GCancellable  *cancellable,
+                                              GError       **error);
+
 /**
  * OstreeRepoAutoTransaction:
  *
index b4e2be4f653b8ff1814329c1edb9113f7eb1c890..2816002e915602f64255d7e3f4ac627cc8794ed7 100644 (file)
@@ -6237,6 +6237,7 @@ summary_add_ref_entry (OstreeRepo       *self,
 
 static gboolean
 regenerate_metadata (OstreeRepo    *self,
+                     gboolean       do_metadata_commit,
                      GVariant      *additional_metadata,
                      GVariant      *options,
                      GCancellable  *cancellable,
@@ -6279,12 +6280,70 @@ regenerate_metadata (OstreeRepo    *self,
         }
     }
 
+  const gchar *main_collection_id = ostree_repo_get_collection_id (self);
+
+  /* Write out a new metadata commit for the repository when it has a collection ID. */
+  if (do_metadata_commit && main_collection_id != NULL)
+    {
+      g_autoptr(OstreeRepoAutoTransaction) txn =
+        _ostree_repo_auto_transaction_start (self, cancellable, error);
+      if (!txn)
+        return FALSE;
+
+      /* Disable automatic summary updating since we're already doing it */
+      self->txn.disable_auto_summary = TRUE;
+
+      g_autofree gchar *new_ostree_metadata_checksum = NULL;
+      if (!_ostree_repo_transaction_write_repo_metadata (self,
+                                                         additional_metadata,
+                                                         &new_ostree_metadata_checksum,
+                                                         cancellable,
+                                                         error))
+        return FALSE;
+
+      /* Sign the new commit. */
+      if (gpg_key_ids != NULL)
+        {
+          for (const char * const *iter = (const char * const *) gpg_key_ids;
+               iter != NULL && *iter != NULL; iter++)
+            {
+              const char *gpg_key_id = *iter;
+
+              if (!ostree_repo_sign_commit (self,
+                                            new_ostree_metadata_checksum,
+                                            gpg_key_id,
+                                            gpg_homedir,
+                                            cancellable,
+                                            error))
+                return FALSE;
+            }
+        }
+
+      if (sign_keys != NULL)
+        {
+          GVariantIter *iter;
+          GVariant *key;
+
+          g_variant_get (sign_keys, "av", &iter);
+          while (g_variant_iter_loop (iter, "v", &key))
+            {
+              if (!ostree_sign_set_sk (sign, key, error))
+                return FALSE;
+
+              if (!ostree_sign_commit (sign, self, new_ostree_metadata_checksum,
+                                       cancellable, error))
+                return FALSE;
+            }
+        }
+
+      if (!_ostree_repo_auto_transaction_commit (txn, NULL, cancellable, error))
+        return FALSE;
+    }
+
   g_auto(GVariantDict) additional_metadata_builder = OT_VARIANT_BUILDER_INITIALIZER;
   g_variant_dict_init (&additional_metadata_builder, additional_metadata);
   g_autoptr(GVariantBuilder) refs_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(s(taya{sv}))"));
 
-  const gchar *main_collection_id = ostree_repo_get_collection_id (self);
-
   {
     if (main_collection_id == NULL)
       {
@@ -6520,7 +6579,7 @@ ostree_repo_regenerate_summary (OstreeRepo     *self,
                                 GCancellable   *cancellable,
                                 GError        **error)
 {
-  return regenerate_metadata (self, additional_metadata, NULL, cancellable, error);
+  return regenerate_metadata (self, FALSE, additional_metadata, NULL, cancellable, error);
 }
 
 /**
@@ -6538,6 +6597,9 @@ ostree_repo_regenerate_summary (OstreeRepo     *self,
  * ostree_repo_regenerate_summary() and %OSTREE_SUMMARY_GVARIANT_FORMAT for
  * additional details on its contents.
  *
+ * Additionally, if the `core/collection-id` key is set in the configuration, a
+ * %OSTREE_REPO_METADATA_REF commit will be created.
+ *
  * The following @options are currently defined:
  *
  *   * `gpg-key-ids` (`as`): Array of GPG key IDs to sign the metadata with.
@@ -6558,7 +6620,7 @@ ostree_repo_regenerate_metadata (OstreeRepo    *self,
                                  GCancellable  *cancellable,
                                  GError       **error)
 {
-  return regenerate_metadata (self, additional_metadata, options, cancellable, error);
+  return regenerate_metadata (self, TRUE, additional_metadata, options, cancellable, error);
 }
 
 /* Regenerate the summary if `core/auto-update-summary` is set. We default to FALSE for
index 219af604ada16ed62bacf39605dcbf0d734a4f0a..fc590f8a37cbcb2571887083000318a154fb95cf 100644 (file)
@@ -122,107 +122,6 @@ ostree_builtin_summary (int argc, char **argv, OstreeCommandInvocation *invocati
             return FALSE;
         }
 
-      const char *collection_id = ostree_repo_get_collection_id (repo);
-
-      /* Write out a new metadata commit for the repository. */
-      if (collection_id != NULL)
-        {
-          OstreeCollectionRef collection_ref = { (gchar *) collection_id, (gchar *) OSTREE_REPO_METADATA_REF };
-          g_autofree char *old_ostree_metadata_checksum = NULL;
-          g_autofree gchar *new_ostree_metadata_checksum = NULL;
-          g_autoptr(OstreeMutableTree) mtree = NULL;
-          g_autoptr(OstreeRepoFile) repo_file = NULL;
-          g_autoptr(GVariantDict) new_summary_commit_dict = NULL;
-          g_autoptr(GVariant) new_summary_commit = NULL;
-
-          if (!ostree_repo_resolve_rev (repo, OSTREE_REPO_METADATA_REF,
-                                        TRUE, &old_ostree_metadata_checksum, error))
-            return FALSE;
-
-          /* Add bindings to the metadata. */
-          new_summary_commit_dict = g_variant_dict_new (additional_metadata);
-          g_variant_dict_insert (new_summary_commit_dict, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING,
-                                 "s", collection_ref.collection_id);
-          g_variant_dict_insert_value (new_summary_commit_dict, OSTREE_COMMIT_META_KEY_REF_BINDING,
-                                       g_variant_new_strv ((const gchar * const *) &collection_ref.ref_name, 1));
-          new_summary_commit = g_variant_dict_end (new_summary_commit_dict);
-
-          if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
-            return FALSE;
-
-          /* Set up an empty mtree. */
-          mtree = ostree_mutable_tree_new ();
-
-          glnx_unref_object GFileInfo *fi = g_file_info_new ();
-          g_file_info_set_attribute_uint32 (fi, "unix::uid", 0);
-          g_file_info_set_attribute_uint32 (fi, "unix::gid", 0);
-          g_file_info_set_attribute_uint32 (fi, "unix::mode", (0755 | S_IFDIR));
-
-          g_autofree guchar *csum_raw = NULL;
-          g_autofree char *csum = NULL;
-
-          g_autoptr(GVariant) dirmeta = ostree_create_directory_metadata (fi, NULL /* xattrs */);
-
-          if (!ostree_repo_write_metadata (repo, OSTREE_OBJECT_TYPE_DIR_META, NULL,
-                                           dirmeta, &csum_raw, cancellable, error))
-            return FALSE;
-
-          csum = ostree_checksum_from_bytes (csum_raw);
-          ostree_mutable_tree_set_metadata_checksum (mtree, csum);
-
-          if (!ostree_repo_write_mtree (repo, mtree, (GFile **) &repo_file, NULL, error))
-            return FALSE;
-
-          if (!ostree_repo_write_commit (repo, old_ostree_metadata_checksum,
-                                         NULL  /* subject */, NULL  /* body */,
-                                         new_summary_commit, repo_file, &new_ostree_metadata_checksum,
-                                         NULL, error))
-            return FALSE;
-          if (opt_gpg_key_ids != NULL)
-            {
-              for (const char * const *iter = (const char * const *) opt_gpg_key_ids;
-                   iter != NULL && *iter != NULL; iter++)
-                {
-                  const char *key_id = *iter;
-
-                  if (!ostree_repo_sign_commit (repo,
-                                                new_ostree_metadata_checksum,
-                                                key_id,
-                                                opt_gpg_homedir,
-                                                cancellable,
-                                                error))
-                    return FALSE;
-                }
-            }
-
-          if (opt_key_ids)
-            {
-              char **iter;
-              for (iter = opt_key_ids; iter && *iter; iter++)
-                {
-                  const char *keyid = *iter;
-                  g_autoptr (GVariant) secret_key = NULL;
-
-                  secret_key = g_variant_new_string (keyid);
-                  if (!ostree_sign_set_sk (sign, secret_key, error))
-                    return FALSE;
-
-                  if (!ostree_sign_commit (sign,
-                                           repo,
-                                           new_ostree_metadata_checksum,
-                                           cancellable,
-                                           error))
-                    return FALSE;
-                }
-            }
-
-          ostree_repo_transaction_set_collection_ref (repo, &collection_ref,
-                                                      new_ostree_metadata_checksum);
-
-          if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
-            return FALSE;
-        }
-
       /* Regenerate and sign the repo metadata. */
       g_auto(GVariantBuilder) metadata_opts_builder = G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT);
       g_autoptr(GVariant) metadata_opts = NULL;