From 02f106fb91512669d4a1c7c0a629f500d12f1c2d Mon Sep 17 00:00:00 2001 From: songweibin Date: Mon, 3 Sep 2018 15:09:46 +0800 Subject: [PATCH] pybind/rbd: new group snap rollback Python API Signed-off-by: songweibin --- src/pybind/rbd/rbd.pyx | 18 ++++++++++++++++++ src/test/pybind/test_rbd.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx index 33cf7f9ed96..3b2c37412a3 100644 --- a/src/pybind/rbd/rbd.pyx +++ b/src/pybind/rbd/rbd.pyx @@ -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 diff --git a/src/test/pybind/test_rbd.py b/src/test/pybind/test_rbd.py index ad6756050f5..2da63420ba4 100644 --- a/src/test/pybind/test_rbd.py +++ b/src/test/pybind/test_rbd.py @@ -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(): -- 2.39.5