diff options
author | Ricardo Dias <rdias@suse.com> | 2017-03-27 16:34:26 +0200 |
---|---|---|
committer | Ricardo Dias <rdias@suse.com> | 2017-04-11 13:09:41 +0200 |
commit | 6b542887936ac64b5624c39f99bc2382a57abd3d (patch) | |
tree | 40c6483a36021082b2026aa7b41439627ef8b5fb /src/pybind | |
parent | qa/workunits/rbd: cli testing of rbd trash commands (diff) | |
download | ceph-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.pyx | 147 |
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) + |