]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/rbd: new group snap rollback Python API
authorsongweibin <song.weibin@zte.com.cn>
Mon, 3 Sep 2018 07:09:46 +0000 (15:09 +0800)
committersongweibin <song.weibin@zte.com.cn>
Wed, 12 Sep 2018 15:42:15 +0000 (23:42 +0800)
Signed-off-by: songweibin <song.weibin@zte.com.cn>
src/pybind/rbd/rbd.pyx
src/test/pybind/test_rbd.py

index 33cf7f9ed96183526fc15bda5fd651212f232793..3b2c37412a36c0e6426ca10d37f1b30509f67351 100644 (file)
@@ -487,6 +487,8 @@ cdef extern from "rbd/librbd.h" nogil:
 
     void rbd_group_snap_list_cleanup(rbd_group_snap_info_t *snaps,
                                      size_t group_snap_info_size, size_t len)
+    int rbd_group_snap_rollback(rados_ioctx_t group_p, const char *group_name,
+                                const char *snap_name)
 
     int rbd_watchers_list(rbd_image_t image, rbd_image_watcher_t *watchers,
                           size_t *max_watchers)
@@ -1952,6 +1954,22 @@ cdef class Group(object):
         """
         return GroupSnapIterator(self)
 
+    def rollback_to_snap(self, name):
+        """
+        Rollback group to snapshot.
+
+        :param name: the group snapshot to rollback to
+        :type name: str
+        :raises: :class:`ObjectNotFound`
+        :raises: :class:`IOError`
+        """
+        name = cstr(name, 'name')
+        cdef char *_name = name
+        with nogil:
+            ret = rbd_group_snap_rollback(self._ioctx, self._name, _name)
+        if ret != 0:
+            raise make_ex(ret, 'error rolling back group to snapshot', group_errno_to_exception)
+
 cdef class Image(object):
     """
     This class represents an RBD image. It is used to perform I/O on
index ad6756050f51c4e0ed16a491d6433a55120c983a..2da63420ba4f152565c021a2bc045261583f227a 100644 (file)
@@ -1923,6 +1923,37 @@ class TestGroups(object):
         eq([snap_name], [snap['name'] for snap in self.group.list_snaps()])
         self.group.rename_snap(snap_name, new_snap_name)
         eq([new_snap_name], [snap['name'] for snap in self.group.list_snaps()])
+        self.group.remove_snap(new_snap_name)
+        eq([], list(self.group.list_snaps()))
+
+    def test_group_snap_rollback(self):
+        eq([], list(self.group.list_images()))
+        self.group.add_image(ioctx, image_name)
+        with Image(ioctx, image_name) as image:
+            image.write(b'\0' * 256, 0)
+            read = image.read(0, 256)
+            eq(read, b'\0' * 256)
+
+        global snap_name
+        eq([], list(self.group.list_snaps()))
+        self.group.create_snap(snap_name)
+        eq([snap_name], [snap['name'] for snap in self.group.list_snaps()])
+
+        with Image(ioctx, image_name) as image:
+            data = rand_data(256)
+            image.write(data, 0)
+            read = image.read(0, 256)
+            eq(read, data)
+
+        self.group.rollback_to_snap(snap_name)
+        with Image(ioctx, image_name) as image:
+            read = image.read(0, 256)
+            eq(read, b'\0' * 256)
+
+        self.group.remove_image(ioctx, image_name)
+        eq([], list(self.group.list_images()))
+        self.group.remove_snap(snap_name)
+        eq([], list(self.group.list_snaps()))
 
 @with_setup(create_image, remove_image)
 def test_rename():