summaryrefslogtreecommitdiffstats
path: root/src/pybind
diff options
context:
space:
mode:
authorRicardo Dias <rdias@suse.com>2017-03-27 16:34:26 +0200
committerRicardo Dias <rdias@suse.com>2017-04-11 13:09:41 +0200
commit6b542887936ac64b5624c39f99bc2382a57abd3d (patch)
tree40c6483a36021082b2026aa7b41439627ef8b5fb /src/pybind
parentqa/workunits/rbd: cli testing of rbd trash commands (diff)
downloadceph-6b542887936ac64b5624c39f99bc2382a57abd3d.tar.xz
ceph-6b542887936ac64b5624c39f99bc2382a57abd3d.zip
pybind: librbd: added trash API to python RBD binding
Signed-off-by: Ricardo Dias <rdias@suse.com>
Diffstat (limited to 'src/pybind')
-rw-r--r--src/pybind/rbd/rbd.pyx147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/pybind/rbd/rbd.pyx b/src/pybind/rbd/rbd.pyx
index 73ef177db9b..90f855e502e 100644
--- a/src/pybind/rbd/rbd.pyx
+++ b/src/pybind/rbd/rbd.pyx
@@ -137,6 +137,17 @@ cdef extern from "rbd/librbd.h" nogil:
_RBD_LOCK_MODE_EXCLUSIVE "RBD_LOCK_MODE_EXCLUSIVE"
_RBD_LOCK_MODE_SHARED "RBD_LOCK_MODE_SHARED"
+ ctypedef enum rbd_trash_image_source_t:
+ _RBD_TRASH_IMAGE_SOURCE_USER "RBD_TRASH_IMAGE_SOURCE_USER",
+ _RBD_TRASH_IMAGE_SOURCE_MIRRORING "RBD_TRASH_IMAGE_SOURCE_MIRRORING"
+
+ ctypedef struct rbd_trash_image_info_t:
+ char *id
+ char *name
+ rbd_trash_image_source_t source
+ time_t deletion_time
+ time_t deferment_end_time
+
ctypedef void (*rbd_callback_t)(rbd_completion_t cb, void *arg)
ctypedef int (*librbd_progress_fn_t)(uint64_t offset, uint64_t total, void* ptr)
@@ -168,6 +179,14 @@ cdef extern from "rbd/librbd.h" nogil:
int rbd_rename(rados_ioctx_t src_io_ctx, const char *srcname,
const char *destname)
+ int rbd_trash_move(rados_ioctx_t io, const char *name, uint64_t delay)
+ int rbd_trash_list(rados_ioctx_t io, rbd_trash_image_info_t *trash_entries,
+ size_t *num_entries)
+ void rbd_trash_list_cleanup(rbd_trash_image_info_t *trash_entries,
+ size_t num_entries)
+ int rbd_trash_remove(rados_ioctx_t io, const char *id, int force)
+ int rbd_trash_restore(rados_ioctx_t io, const char *id, const char *name)
+
int rbd_mirror_mode_get(rados_ioctx_t io, rbd_mirror_mode_t *mirror_mode)
int rbd_mirror_mode_set(rados_ioctx_t io, rbd_mirror_mode_t mirror_mode)
int rbd_mirror_peer_add(rados_ioctx_t io, char *uuid,
@@ -848,6 +867,81 @@ class RBD(object):
if ret != 0:
raise make_ex(ret, 'error renaming image')
+ def trash_move(self, ioctx, name, delay=0):
+ """
+ Moves an RBD image to the trash.
+ :param ioctx: determines which RADOS pool the image is in
+ :type ioctx: :class:`rados.Ioctx`
+ :param name: the name of the image to remove
+ :type name: str
+ :param delay: time delay in seconds before the image can be deleted
+ from trash
+ :type delay: int
+ :raises: :class:`ImageNotFound`
+ """
+ name = cstr(name, 'name')
+ cdef:
+ rados_ioctx_t _ioctx = convert_ioctx(ioctx)
+ char *_name = name
+ uint64_t _delay = delay
+ with nogil:
+ ret = rbd_trash_move(_ioctx, _name, _delay)
+ if ret != 0:
+ raise make_ex(ret, 'error moving image to trash')
+
+ def trash_remove(self, ioctx, image_id, force=False):
+ """
+ Deletes an RBD image from trash. If image deferment time has not
+ expired :class:`PermissionError` is raised.
+ :param ioctx: determines which RADOS pool the image is in
+ :type ioctx: :class:`rados.Ioctx`
+ :param image_id: the id of the image to remove
+ :type image_id: str
+ :param force: force remove even if deferment time has not expired
+ :type force: bool
+ :raises: :class:`ImageNotFound`, :class:`PermissionError`
+ """
+ image_id = cstr(image_id, 'image_id')
+ cdef:
+ rados_ioctx_t _ioctx = convert_ioctx(ioctx)
+ char *_image_id = image_id
+ int _force = force
+ with nogil:
+ ret = rbd_trash_remove(_ioctx, _image_id, _force)
+ if ret != 0:
+ raise make_ex(ret, 'error deleting image from trash')
+
+ def trash_list(self, ioctx):
+ """
+ Lists all entries from trash.
+ :param ioctx: determines which RADOS pool the image is in
+ :type ioctx: :class:`rados.Ioctx`
+ :returns: :class:`TrashIterator`
+ """
+ return TrashIterator(ioctx)
+
+ def trash_restore(self, ioctx, image_id, name):
+ """
+ Restores an RBD image from trash.
+ :param ioctx: determines which RADOS pool the image is in
+ :type ioctx: :class:`rados.Ioctx`
+ :param image_id: the id of the image to restore
+ :type image_id: str
+ :param name: the new name of the restored image
+ :type name: str
+ :raises: :class:`ImageNotFound`
+ """
+ image_id = cstr(image_id, 'image_id')
+ name = cstr(name, 'name')
+ cdef:
+ rados_ioctx_t _ioctx = convert_ioctx(ioctx)
+ char *_image_id = image_id
+ char *_name = name
+ with nogil:
+ ret = rbd_trash_restore(_ioctx, _image_id, _name)
+ if ret != 0:
+ raise make_ex(ret, 'error restoring image from trash')
+
def mirror_mode_get(self, ioctx):
"""
Get pool mirror mode.
@@ -2553,3 +2647,56 @@ cdef class SnapIterator(object):
if self.snaps:
rbd_snap_list_end(self.snaps)
free(self.snaps)
+
+cdef class TrashIterator(object):
+ """
+ Iterator over trash entries.
+
+ Yields a dictionary containing trash info of an image.
+
+ Keys are:
+
+ * `id` (str) - image id
+
+ * `name` (str) - image name
+
+ * `source` (str) - source of deletion
+
+ * `deletion_time` (datetime) - time of deletion
+
+ * `deferment_end_time` (datetime) - time that an image is allowed to be
+ removed from trash
+ """
+
+ cdef:
+ rados_ioctx_t ioctx
+ size_t num_entries
+ rbd_trash_image_info_t *entries
+
+ def __init__(self, ioctx):
+ self.ioctx = convert_ioctx(ioctx)
+ self.num_entries = 1024
+ self.entries = <rbd_trash_image_info_t *>realloc_chk(NULL,
+ sizeof(rbd_trash_image_info_t) * self.num_entries)
+ with nogil:
+ ret = rbd_trash_list(self.ioctx, self.entries, &self.num_entries)
+ if ret < 0:
+ raise make_ex(ret, 'error listing trash entries')
+
+ __source_string = ['USER', 'MIRRORING']
+
+ def __iter__(self):
+ for i in range(self.num_entries):
+ yield {
+ 'id' : decode_cstr(self.entries[i].id),
+ 'name' : decode_cstr(self.entries[i].name),
+ 'source' : TrashIterator.__source_string[self.entries[i].source],
+ 'deletion_time' : datetime.fromtimestamp(self.entries[i].deletion_time),
+ 'deferment_end_time' : datetime.fromtimestamp(self.entries[i].deferment_end_time)
+ }
+
+ def __dealloc__(self):
+ rbd_trash_list_cleanup(self.entries, self.num_entries)
+ if self.entries:
+ free(self.entries)
+