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;
+}
GCancellable *cancellable,
GError **error);
+gboolean
+_ostree_repo_transaction_write_repo_metadata (OstreeRepo *self,
+ GVariant *additional_metadata,
+ char **out_checksum,
+ GCancellable *cancellable,
+ GError **error);
+
/**
* OstreeRepoAutoTransaction:
*
static gboolean
regenerate_metadata (OstreeRepo *self,
+ gboolean do_metadata_commit,
GVariant *additional_metadata,
GVariant *options,
GCancellable *cancellable,
}
}
+ 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)
{
GCancellable *cancellable,
GError **error)
{
- return regenerate_metadata (self, additional_metadata, NULL, cancellable, error);
+ return regenerate_metadata (self, FALSE, additional_metadata, NULL, cancellable, error);
}
/**
* 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.
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
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;