pull: add support for tombstone commits
authorGiuseppe Scrivano <gscrivan@redhat.com>
Wed, 28 Oct 2015 09:07:51 +0000 (10:07 +0100)
committerGiuseppe Scrivano <gscrivan@redhat.com>
Tue, 3 Nov 2015 08:53:38 +0000 (09:53 +0100)
Add a new object type: OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT that is
used when a commit was intentionally removed.

If the remote repository doesn't use tombstone commits, do not fail on
a missing commit (change 0b795785dd81cd1e8c2c5960f0959740bce72a51).

When the remote repository uses tombstones, if a commit cannot be
found, check if the tombstone file is present and fail if it is not
present.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
src/libostree/ostree-core.c
src/libostree/ostree-core.h
src/libostree/ostree-repo-pull.c

index 8fe9d765e5221fe149c4591ffac43eac966f2956..5f24e7c98b8d5fe82c167fd341f33033526feaa6 100644 (file)
@@ -975,6 +975,8 @@ ostree_object_type_to_string (OstreeObjectType objtype)
       return "dirmeta";
     case OSTREE_OBJECT_TYPE_COMMIT:
       return "commit";
+    case OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT:
+      return "tombstone-commit";
     default:
       g_assert_not_reached ();
       return NULL;
index 711c69947143568ba8ff4675c150f6beb7490cb3..637f81724f2e372ef7037c9eef7bad74d805e44f 100644 (file)
@@ -56,15 +56,17 @@ G_BEGIN_DECLS
  * @OSTREE_OBJECT_TYPE_DIR_TREE: List of children (trees or files), and metadata
  * @OSTREE_OBJECT_TYPE_DIR_META: Directory metadata
  * @OSTREE_OBJECT_TYPE_COMMIT: Toplevel object, refers to tree and dirmeta for root
+ * @OSTREE_OBJECT_TYPE_COMMIT_TOMBSTONE: Toplevel object, refers to a deleted commit
  *
  * Enumeration for core object types; %OSTREE_OBJECT_TYPE_FILE is for
  * content, the other types are metadata.
  */
 typedef enum {
-  OSTREE_OBJECT_TYPE_FILE = 1,      /* .file */
-  OSTREE_OBJECT_TYPE_DIR_TREE = 2,  /* .dirtree */
-  OSTREE_OBJECT_TYPE_DIR_META = 3,  /* .dirmeta */
-  OSTREE_OBJECT_TYPE_COMMIT = 4     /* .commit */
+  OSTREE_OBJECT_TYPE_FILE = 1,                /* .file */
+  OSTREE_OBJECT_TYPE_DIR_TREE = 2,            /* .dirtree */
+  OSTREE_OBJECT_TYPE_DIR_META = 3,            /* .dirmeta */
+  OSTREE_OBJECT_TYPE_COMMIT = 4,              /* .commit */
+  OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT = 5,    /* .commit-tombstone */
 } OstreeObjectType;
 
 /**
@@ -73,14 +75,14 @@ typedef enum {
  *
  * Returns: %TRUE if object type is metadata
  */
-#define OSTREE_OBJECT_TYPE_IS_META(t) (t >= 2 && t <= 4)
+#define OSTREE_OBJECT_TYPE_IS_META(t) (t >= 2 && t <= 5)
 
 /**
  * OSTREE_OBJECT_TYPE_LAST:
  *
  * Last valid object type; use this to validate ranges.
  */
-#define OSTREE_OBJECT_TYPE_LAST OSTREE_OBJECT_TYPE_COMMIT
+#define OSTREE_OBJECT_TYPE_LAST OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT
 
 /**
  * OSTREE_DIRMETA_GVARIANT_FORMAT:
index 41cc46b68a87919d0d235efc7a244e43d8f31964..7ba3ef6176ab9e59ad244ecd1cc2673cdc9edc51 100644 (file)
@@ -58,6 +58,7 @@ typedef struct {
   
   gboolean          gpg_verify;
   gboolean          gpg_verify_summary;
+  gboolean          has_tombstone_commits;
 
   GBytes           *summary_data;
   GBytes           *summary_data_sig;
@@ -795,12 +796,23 @@ meta_fetch_on_complete (GObject           *object,
                    pull_data->maxdepth != 0)
             {
               g_clear_error (&local_error);
+              /* If the remote repo supports tombstone commits, check if the commit was intentionally
+                 deleted.  */
+              if (pull_data->has_tombstone_commits)
+                {
+                  enqueue_one_object_request (pull_data, checksum, OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT,
+                                              FALSE, FALSE);
+                }
             }
         }
 
       goto out;
     }
 
+  /* Tombstone commits are always empty, so skip all processing here */
+  if (objtype == OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT)
+    goto out;
+
   fd = openat (pull_data->tmpdir_dfd, temp_path, O_RDONLY | O_CLOEXEC);
   if (fd == -1)
     {
@@ -1854,7 +1866,11 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
 
       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_Z2)
         {
           g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,