]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/cephfs: python bindings for new snapshot APIs
authorVenky Shankar <vshankar@redhat.com>
Tue, 20 Oct 2020 06:04:36 +0000 (02:04 -0400)
committerVenky Shankar <vshankar@redhat.com>
Thu, 17 Dec 2020 18:07:54 +0000 (13:07 -0500)
Signed-off-by: Venky Shankar <vshankar@redhat.com>
src/pybind/cephfs/c_cephfs.pxd
src/pybind/cephfs/cephfs.pyx
src/pybind/cephfs/mock_cephfs.pxi

index 4dfcb49d5894cde67c4272833120cb5023428b4b..b4b2c625144b84676323d5782f6c63a8aaa93453 100644 (file)
@@ -27,6 +27,15 @@ cdef extern from "cephfs/libcephfs.h" nogil:
     cdef struct ceph_dir_result:
         pass
 
+    cdef struct snap_metadata:
+        const char *key
+        const char *value
+
+    cdef struct snap_info:
+        uint64_t id
+        size_t nr_snap_metadata
+        snap_metadata *snap_metadata
+
     ctypedef void* rados_t
 
     const char *ceph_version(int *major, int *minor, int *patch)
@@ -88,6 +97,10 @@ cdef extern from "cephfs/libcephfs.h" nogil:
     int ceph_close(ceph_mount_info *cmount, int fd)
     int ceph_open(ceph_mount_info *cmount, const char *path, int flags, mode_t mode)
     int ceph_mkdir(ceph_mount_info *cmount, const char *path, mode_t mode)
+    int ceph_mksnap(ceph_mount_info *cmount, const char *path, const char *name, mode_t mode, snap_metadata *snap_metadata, size_t nr_snap_metadata)
+    int ceph_rmsnap(ceph_mount_info *cmount, const char *path, const char *name)
+    int ceph_get_snap_info(ceph_mount_info *cmount, const char *path, snap_info *snap_info)
+    void ceph_free_snap_info_buffer(snap_info *snap_info)
     int ceph_mkdirs(ceph_mount_info *cmount, const char *path, mode_t mode)
     int ceph_closedir(ceph_mount_info *cmount, ceph_dir_result *dirp)
     int ceph_opendir(ceph_mount_info *cmount, const char *name, ceph_dir_result **dirpp)
index c7342d70fef165c13885e453ec9b0d62ad1a268f..2771f1dee14404e8f07f3944a0cf93da0644ef05 100644 (file)
@@ -969,6 +969,96 @@ cdef class LibCephFS(object):
         if ret < 0:
             raise make_ex(ret, "error in mkdir {}".format(path.decode('utf-8')))
 
+    def mksnap(self, path, name, mode, metadata={}):
+        """
+        Create a snapshot.
+
+        :param path: path of the directory to snapshot.
+        :param name: snapshot name
+        :param mode: permission of the snapshot
+        :param metadata: metadata key/value to store with the snapshot
+
+        :raises: :class: `TypeError`
+        :raises: :class: `Error`
+        :returns: int: 0 on success
+        """
+
+        self.require_state("mounted")
+        path = cstr(path, 'path')
+        name = cstr(name, 'name')
+        if not isinstance(mode, int):
+            raise TypeError('mode must be an int')
+        if not isinstance(metadata, dict):
+            raise TypeError('metadata must be an dictionary')
+        md = {}
+        for key, value in metadata.items():
+            if not isinstance(key, str) or not isinstance(value, str):
+                raise TypeError('metadata key and values should be strings')
+            md[key.encode('utf-8')] = value.encode('utf-8')
+        cdef:
+            char* _path = path
+            char* _name = name
+            int _mode = mode
+            size_t nr = len(md)
+            snap_metadata *_snap_meta = <snap_metadata *>malloc(nr * sizeof(snap_metadata))
+        if nr and _snap_meta == NULL:
+            raise MemoryError("malloc failed")
+        i = 0
+        for key, value in md.items():
+            _snap_meta[i] = snap_metadata(<char*>key, <char*>value)
+            i += 1
+        with nogil:
+            ret = ceph_mksnap(self.cluster, _path, _name, _mode, _snap_meta, nr)
+        free(_snap_meta)
+        if ret < 0:
+            raise make_ex(ret, "mksnap error")
+        return 0
+
+    def rmsnap(self, path, name):
+        """
+        Remove a snapshot.
+
+        :param path: path of the directory for removing snapshot
+        :param name: snapshot name
+
+        :raises: :class: `Error`
+        :returns: int: 0 on success
+        """
+        self.require_state("mounted")
+        path = cstr(path, 'path')
+        name = cstr(name, 'name')
+        cdef:
+            char* _path = path
+            char* _name = name
+        ret = ceph_rmsnap(self.cluster, _path, _name)
+        if ret < 0:
+            raise make_ex(ret, "rmsnap error")
+        return 0
+
+    def snap_info(self, path):
+        """
+        Fetch sapshot info
+
+        :param path: snapshot path
+
+        :raises: :class: `Error`
+        :returns: dict: snapshot metadata
+        """
+        self.require_state("mounted")
+        path = cstr(path, 'path')
+        cdef:
+            char* _path = path
+            snap_info info
+        ret = ceph_get_snap_info(self.cluster, _path, &info)
+        if ret < 0:
+            raise make_ex(ret, "snap_info error")
+        md = {}
+        if info.nr_snap_metadata:
+            md = {snap_meta.key.decode('utf-8'): snap_meta.value.decode('utf-8') for snap_meta in
+                  info.snap_metadata[:info.nr_snap_metadata]}
+            ceph_free_snap_info_buffer(&info)
+        return {'id': info.id, 'metadata': md}
+
     def chmod(self, path, mode) :
         """
         Change directory mode.
index c1c93ac100a6fa4bc5c663a693e6cb2096e030cc..f4ff5b7360cd4c54750cff9eb90d25462aa57852 100644 (file)
@@ -30,6 +30,15 @@ cdef nogil:
     cdef struct ceph_dir_result:
         int dummy
 
+    cdef struct snap_metadata:
+        const char *key
+        const char *value
+
+    cdef struct snap_info:
+        uint64_t id
+        size_t nr_snap_metadata
+        snap_metadata *snap_metadata
+
     ctypedef void* rados_t
 
     const char *ceph_version(int *major, int *minor, int *patch):
@@ -138,6 +147,14 @@ cdef nogil:
         pass
     int ceph_mkdir(ceph_mount_info *cmount, const char *path, mode_t mode):
         pass
+    int ceph_mksnap(ceph_mount_info *cmount, const char *path, const char *name, mode_t mode, snap_metadata *snap_metadata, size_t nr_snap_metadata):
+        pass
+    int ceph_rmsnap(ceph_mount_info *cmount, const char *path, const char *name):
+        pass
+    int ceph_get_snap_info(ceph_mount_info *cmount, const char *path, snap_info *snap_info):
+        pass
+    void ceph_free_snap_info_buffer(snap_info *snap_info):
+        pass
     int ceph_mkdirs(ceph_mount_info *cmount, const char *path, mode_t mode):
         pass
     int ceph_closedir(ceph_mount_info *cmount, ceph_dir_result *dirp):