1
0
mirror of https://github.com/ceph/ceph synced 2024-12-24 12:24:19 +00:00

Merge pull request from Songweibin/wip-init-image-id

pybind/rbd: support open the image by image_id

Reviewed-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2017-12-14 22:17:43 -05:00 committed by GitHub
commit 182c25f3e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 7 deletions
src
pybind/rbd
test/pybind

View File

@ -227,8 +227,12 @@ cdef extern from "rbd/librbd.h" nogil:
int rbd_open(rados_ioctx_t io, const char *name,
rbd_image_t *image, const char *snap_name)
int rbd_open_by_id(rados_ioctx_t io, const char *image_id,
rbd_image_t *image, const char *snap_name)
int rbd_open_read_only(rados_ioctx_t io, const char *name,
rbd_image_t *image, const char *snap_name)
int rbd_open_by_id_read_only(rados_ioctx_t io, const char *image_id,
rbd_image_t *image, const char *snap_name)
int rbd_close(rbd_image_t image)
int rbd_resize(rbd_image_t image, uint64_t size)
int rbd_stat(rbd_image_t image, rbd_image_info_t *info, size_t infosize)
@ -1372,9 +1376,12 @@ cdef class Image(object):
cdef object ioctx
cdef rados_ioctx_t _ioctx
def __init__(self, ioctx, name, snapshot=None, read_only=False):
def __init__(self, ioctx, name=None, snapshot=None,
read_only=False, image_id=None):
"""
Open the image at the given snapshot.
Specify either name or id, otherwise :class:`InvalidArgument` is raised.
If a snapshot is specified, the image will be read-only, unless
:func:`Image.set_snap` is called later.
@ -1394,25 +1401,42 @@ cdef class Image(object):
:type snaphshot: str
:param read_only: whether to open the image in read-only mode
:type read_only: bool
:param image_id: the id of the image
:type image_id: str
"""
name = cstr(name, 'name')
name = cstr(name, 'name', opt=True)
image_id = cstr(image_id, 'image_id', opt=True)
snapshot = cstr(snapshot, 'snapshot', opt=True)
self.closed = True
self.name = name
if name is not None and image_id is not None:
raise InvalidArgument("only need to specify image name or image id")
elif name is None and image_id is None:
raise InvalidArgument("image name or image id was not specified")
elif name is not None:
self.name = name
else:
self.name = image_id
# Keep around a reference to the ioctx, so it won't get deleted
self.ioctx = ioctx
cdef:
rados_ioctx_t _ioctx = convert_ioctx(ioctx)
char *_name = name
char *_name = opt_str(name)
char *_image_id = opt_str(image_id)
char *_snapshot = opt_str(snapshot)
if read_only:
with nogil:
ret = rbd_open_read_only(_ioctx, _name, &self.image, _snapshot)
if name is not None:
ret = rbd_open_read_only(_ioctx, _name, &self.image, _snapshot)
else:
ret = rbd_open_by_id_read_only(_ioctx, _image_id, &self.image, _snapshot)
else:
with nogil:
ret = rbd_open(_ioctx, _name, &self.image, _snapshot)
if name is not None:
ret = rbd_open(_ioctx, _name, &self.image, _snapshot)
else:
ret = rbd_open_by_id(_ioctx, _image_id, &self.image, _snapshot)
if ret != 0:
raise make_ex(ret, 'error opening image %s at snapshot %s' % (name, snapshot))
raise make_ex(ret, 'error opening image %s at snapshot %s' % (self.name, snapshot))
self.closed = False
def __enter__(self):

View File

@ -884,6 +884,35 @@ class TestImage(object):
# watcher.
eq(len(watchers), 1)
class TestImageId(object):
def setUp(self):
self.rbd = RBD()
create_image()
self.image = Image(ioctx, image_name)
self.image2 = Image(ioctx, None, None, False, self.image.id())
def tearDown(self):
self.image.close()
self.image2.close()
remove_image()
self.image = None
self.image2 = None
def test_read(self):
data = self.image2.read(0, 20)
eq(data, b'\0' * 20)
def test_write(self):
data = rand_data(256)
self.image2.write(data, 0)
def test_resize(self):
new_size = IMG_SIZE * 2
self.image2.resize(new_size)
info = self.image2.stat()
check_stat(info, new_size, IMG_ORDER)
def check_diff(image, offset, length, from_snapshot, expected):
extents = []
def cb(offset, length, exists):