summaryrefslogtreecommitdiff
path: root/src/libostree
diff options
context:
space:
mode:
authorDan Nicholson <nicholson@endlessm.com>2019-10-15 16:46:59 -0600
committerDan Nicholson <dbn@endlessos.org>2023-02-07 14:50:47 -0700
commitb88948180129a8866a4c03699c16f21ce40f3b18 (patch)
treef0cf15124948545bd24e582a639d82cfbc104754 /src/libostree
parentb2f02337f86efe55f56ea2ad641a55059c2a2623 (diff)
downloadostree-b88948180129a8866a4c03699c16f21ce40f3b18.tar.gz
repo: Create metadata commit in ostree_repo_regenerate_metadata
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.
Diffstat (limited to 'src/libostree')
-rw-r--r--src/libostree/ostree-repo-commit.c69
-rw-r--r--src/libostree/ostree-repo-private.h7
-rw-r--r--src/libostree/ostree-repo.c70
3 files changed, 142 insertions, 4 deletions
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index 51bfd46e..7f668b7d 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -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;
+}
diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h
index 9a0ea2be..17993574 100644
--- a/src/libostree/ostree-repo-private.h
+++ b/src/libostree/ostree-repo-private.h
@@ -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:
*
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index b4e2be4f..2816002e 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -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