[ostree/wip/delta-continuation: 7/7] wip



commit af1e4708072e5ef9e2527997550ed4bb3236b9cf
Author: Colin Walters <walters verbum org>
Date:   Sun Apr 13 02:15:01 2014 -0400

    wip

 src/libostree/ostree-core-private.h |    4 +
 src/libostree/ostree-core.c         |   25 +++++
 src/libostree/ostree-repo.c         |  204 +++++++++++++++++++++++++----------
 src/libostree/ostree-repo.h         |    8 ++
 4 files changed, 185 insertions(+), 56 deletions(-)
---
diff --git a/src/libostree/ostree-core-private.h b/src/libostree/ostree-core-private.h
index 0a0bc06..96902b6 100644
--- a/src/libostree/ostree-core-private.h
+++ b/src/libostree/ostree-core-private.h
@@ -118,5 +118,9 @@ _ostree_loose_path_with_suffix (char              *buf,
                                 OstreeRepoMode     repo_mode,
                                 const char        *suffix);
 
+GVariant *
+_ostree_detached_metadata_append_gpg_sig (GVariant   *existing_metadata,
+                                          GBytes     *signature_bytes);
+
 G_END_DECLS
 
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index 5d2388a..2a50ad6 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -1770,3 +1770,28 @@ ostree_commit_get_timestamp (GVariant  *commit_variant)
   g_variant_get_child (commit_variant, 5, "t", &ret);
   return GUINT64_FROM_BE (ret);
 }
+
+GVariant *
+_ostree_detached_metadata_append_gpg_sig (GVariant   *existing_metadata,
+                                          GBytes     *signature_bytes)
+{
+  if (existing_metadata)
+    {
+      builder = ot_util_variant_builder_from_variant (existing_metadata, G_VARIANT_TYPE ("a{sv}"));
+      signaturedata = g_variant_lookup_value (existing_metadata, "ostree.gpgsigs", G_VARIANT_TYPE ("aay"));
+      if (signaturedata)
+        signature_builder = ot_util_variant_builder_from_variant (signaturedata, G_VARIANT_TYPE ("aay"));
+    }
+  if (!builder)
+    builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+  if (!signature_builder)
+    signature_builder = g_variant_builder_new (G_VARIANT_TYPE ("aay"));
+
+  g_variant_builder_add (signature_builder, "@ay", ot_gvariant_new_ay_bytes (signature_bytes));
+
+  g_variant_builder_add (builder, "{sv}", "ostree.gpgsigs", g_variant_builder_end (signature_builder));
+  
+  metadata = g_variant_builder_end (builder);
+  return g_variant_ref_sink (metadata);
+}
+
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 392fe6f..c954f44 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -1518,6 +1518,7 @@ ostree_repo_append_gpg_signature (OstreeRepo     *self,
 {
   gboolean ret = FALSE;
   gs_unref_variant GVariant *metadata = NULL;
+  gs_unref_variant GVariant *new_metadata = NULL;
   gs_unref_variant_builder GVariantBuilder *builder = NULL;
   gs_unref_variant_builder GVariantBuilder *signature_builder = NULL;
   gs_unref_variant GVariant *signaturedata = NULL;
@@ -1533,27 +1534,11 @@ ostree_repo_append_gpg_signature (OstreeRepo     *self,
       goto out;
     }
 
-  if (metadata)
-    {
-      builder = ot_util_variant_builder_from_variant (metadata, G_VARIANT_TYPE ("a{sv}"));
-      signaturedata = g_variant_lookup_value (metadata, "ostree.gpgsigs", G_VARIANT_TYPE ("aay"));
-      if (signaturedata)
-        signature_builder = ot_util_variant_builder_from_variant (signaturedata, G_VARIANT_TYPE ("aay"));
-    }
-  if (!builder)
-    builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
-  if (!signature_builder)
-    signature_builder = g_variant_builder_new (G_VARIANT_TYPE ("aay"));
-
-  g_variant_builder_add (signature_builder, "@ay", ot_gvariant_new_ay_bytes (signature_bytes));
-
-  g_variant_builder_add (builder, "{sv}", "ostree.gpgsigs", g_variant_builder_end (signature_builder));
-  
-  metadata = g_variant_builder_end (builder);
+  new_metadata = _ostree_detached_metadata_append_gpg_sig (metadata, signature_bytes);
 
   if (!ostree_repo_write_commit_detached_metadata (self,
                                                    commit_checksum,
-                                                   metadata,
+                                                   new_metadata,
                                                    cancellable,
                                                    error))
     {
@@ -1567,33 +1552,20 @@ ostree_repo_append_gpg_signature (OstreeRepo     *self,
   return ret;
 }
 
-/**
- * ostree_repo_sign_commit:
- * @self: Self
- * @commit_checksum: SHA256 of given commit to sign
- * @key_id: Use this GPG key id
- * @homedir: (allow-none): GPG home directory, or %NULL
- * @cancellable: A #GCancellable
- * @error: a #GError
- *
- * Add a GPG signature to a commit.
- */
-gboolean
-ostree_repo_sign_commit (OstreeRepo     *self,
-                         const gchar    *commit_checksum,
-                         const gchar    *key_id,
-                         const gchar    *homedir,
-                         GCancellable   *cancellable,
-                         GError        **error)
+static gboolean
+sign_data (OstreeRepo     *self,
+           GBytes         *input_data,
+           const gchar    *key_id,
+           const gchar    *homedir,
+           GBytes        **out_signature,
+           GCancellable   *cancellable,
+           GError        **error)
 {
 #ifdef HAVE_GPGME
   gboolean ret = FALSE;
-  gs_unref_object GFile *commit_path = NULL;
-  gs_free gchar *commit_filename = NULL;
   gs_unref_object GFile *tmp_signature_file = NULL;
   gs_unref_object GOutputStream *tmp_signature_output = NULL;
-  gs_unref_variant GVariant *commit_variant = NULL;
-  gs_unref_bytes GBytes *signature_bytes = NULL;
+  gs_unref_bytes GBytes *ret_signature = NULL;
   gpgme_ctx_t context;
   gpgme_engine_info_t info;
   gpgme_error_t err;
@@ -1603,10 +1575,6 @@ ostree_repo_sign_commit (OstreeRepo     *self,
   int signature_fd = -1;
   GMappedFile *signature_file = NULL;
   
-  if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT,
-                                 commit_checksum, &commit_variant, error))
-    goto out;
-  
   if (!gs_file_open_in_tmpdir (self->tmp_dir, 0644,
                                &tmp_signature_file, &tmp_signature_output,
                                cancellable, error))
@@ -1661,13 +1629,16 @@ ostree_repo_sign_commit (OstreeRepo     *self,
       goto out;
     }
   
-  if ((err = gpgme_data_new_from_mem (&commit_buffer, g_variant_get_data (commit_variant),
-                                      g_variant_get_size (commit_variant), FALSE)) != GPG_ERR_NO_ERROR)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Failed to create buffer from commit file");
-      goto out;
-    }
+  {
+    gsize len;
+    const char *buf = g_bytes_get_data (input_data, &len);
+    if ((err = gpgme_data_new_from_mem (&commit_buffer, buf, len, FALSE)) != GPG_ERR_NO_ERROR)
+      {
+        g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                     "Failed to create buffer from commit file");
+        goto out;
+      }
+  }
   
   signature_fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)tmp_signature_output);
   if (signature_fd < 0)
@@ -1698,13 +1669,10 @@ ostree_repo_sign_commit (OstreeRepo     *self,
   signature_file = gs_file_map_noatime (tmp_signature_file, cancellable, error);
   if (!signature_file)
     goto out;
-  signature_bytes = g_mapped_file_get_bytes (signature_file);
+  ret_signature = g_mapped_file_get_bytes (signature_file);
   
-  if (!ostree_repo_append_gpg_signature (self, commit_checksum, signature_bytes,
-                                         cancellable, error))
-    goto out;
-
   ret = TRUE;
+  gs_transfer_out_value (out_signature, &ret_signature);
 out:
   if (commit_buffer)
     gpgme_data_release (commit_buffer);
@@ -1724,6 +1692,130 @@ out:
 #endif
 }
 
+/**
+ * ostree_repo_sign_commit:
+ * @self: Self
+ * @commit_checksum: SHA256 of given commit to sign
+ * @key_id: Use this GPG key id
+ * @homedir: (allow-none): GPG home directory, or %NULL
+ * @cancellable: A #GCancellable
+ * @error: a #GError
+ *
+ * Add a GPG signature to a commit.
+ */
+gboolean
+ostree_repo_sign_commit (OstreeRepo     *self,
+                         const gchar    *commit_checksum,
+                         const gchar    *key_id,
+                         const gchar    *homedir,
+                         GCancellable   *cancellable,
+                         GError        **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_bytes GBytes *commit_data = NULL;
+  gs_unref_bytes GBytes *signature_data = NULL;
+  gs_unref_variant GVariant *commit_variant = NULL;
+
+  if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT,
+                                 commit_checksum, &commit_variant, error))
+    goto out;
+
+  /* This has the same lifecycle as the variant, so we can just
+   * use static.
+   */
+  signature_data = g_bytes_new_static (g_variant_get_data (commit_variant),
+                                       g_variant_get_size (commit_variant));
+
+  if (!sign_data (self, signature_data, key_id, homedir,
+                  &signature_data,
+                  cancellable, error))
+    goto out;
+
+  if (!ostree_repo_append_gpg_signature (self, commit_checksum, signature_data,
+                                         cancellable, error))
+    goto out;
+
+  ret = TRUE;
+out:
+  return ret;
+}
+
+/**
+ * ostree_repo_sign_delta:
+ * @self: Self
+ * @from_commit: SHA256 of starting commit to sign
+ * @to_commit: SHA256 of target commit to sign
+ * @key_id: Use this GPG key id
+ * @homedir: (allow-none): GPG home directory, or %NULL
+ * @cancellable: A #GCancellable
+ * @error: a #GError
+ *
+ * Add a GPG signature to a static delta.
+ */
+gboolean
+ostree_repo_sign_delta (OstreeRepo     *self,
+                        const gchar    *from_commit,
+                        const gchar    *to_commit,
+                        const gchar    *key_id,
+                        const gchar    *homedir,
+                        GCancellable   *cancellable,
+                        GError        **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_bytes GBytes *delta_data = NULL;
+  gs_unref_bytes GBytes *signature_data = NULL;
+  gs_unref_variant GVariant *commit_variant = NULL;
+  gs_free char *delta_path = NULL;
+  gs_unref_object GFile *delta_file = NULL;
+  gs_unref_object char *detached_metadata_relpath = NULL;
+  gs_unref_object GFile *detached_metadata_path = NULL;
+  gs_unref_variant GVariant *existing_detached_metadata = NULL
+  GError *temp_error = NULL;
+
+  detached_metadata_relpath =
+    _ostree_get_relative_static_delta_detachedmeta_path (self, checksum);
+  detached_metadata_path = g_file_resolve_relative_path (self->repodir, detached_metadata_relpath);
+
+  delta_path = _ostree_get_relative_static_delta_path (from_commit, to_commit);
+  delta_file = g_file_resolve_relative_path (self->repodir, delta_path);
+  delta_data = gs_file_map_readonly (delta_file, cancellable, error);
+  if (!delta_data)
+    goto out;
+  gs_unref_variant GVariant *ret_metadata = NULL;
+  
+  if (!ot_util_variant_map (detached_metadata_path, G_VARIANT_TYPE ("a{sv}"),
+                            TRUE, &existing_detached_metadata, &temp_error))
+    {
+      if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+        {
+          g_clear_error (&temp_error);
+        }
+      else
+        {
+          g_propagate_error (error, temp_error);
+          goto out;
+        }
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value (out_metadata, &ret_metadata);
+ out:
+  return ret;
+
+  if (!sign_data (self, delta_data, key_id, homedir,
+                  &signature_data,
+                  cancellable, error))
+    goto out;
+
+  if (!ostree_repo_append_gpg_signature (self, commit_checksum, signature_data,
+                                         cancellable, error))
+    goto out;
+
+  ret = TRUE;
+out:
+  return ret;
+}
+
 gboolean
 _ostree_repo_gpg_verify_file_with_metadata (OstreeRepo          *self,
                                             GFile               *path,
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index f522fce..26aa6ae 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -521,6 +521,14 @@ gboolean ostree_repo_sign_commit (OstreeRepo     *self,
                                   GCancellable   *cancellable,
                                   GError        **error);
 
+gboolean ostree_repo_sign_delta (OstreeRepo     *self,
+                                 const gchar    *from_commit,
+                                 const gchar    *to_commit,
+                                 const gchar    *key_id,
+                                 const gchar    *homedir,
+                                 GCancellable   *cancellable,
+                                 GError        **error);
+
 gboolean ostree_repo_append_gpg_signature (OstreeRepo     *self,
                                            const gchar    *commit_checksum,
                                            GBytes         *signature_bytes,


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