From ae702b3e9a3929bac235ecbe308bfb8ca08c4d7d Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Thu, 17 Feb 2011 06:46:08 -0800 Subject: [PATCH] Add Pool::list_objects Add a Pool::list_objects method. Add a test for this to pybind-test.py Signed-off-by: Colin McCabe --- src/pybind/rados.py | 118 +++++++++++++++++++++++++--------------- src/test/pybind-test.py | 12 ++++ 2 files changed, 87 insertions(+), 43 deletions(-) diff --git a/src/pybind/rados.py b/src/pybind/rados.py index d711fb319d2dc..d23c9fa06f1ce 100755 --- a/src/pybind/rados.py +++ b/src/pybind/rados.py @@ -90,26 +90,67 @@ class Rados(object): raise make_ex(ret, "error opening pool '%s'" % pool_name) return Pool(pool_name, self.librados, pool) +class ObjectIterator(object): + def __init__(self, pool): + self.pool = pool + self.ctx = c_void_p() + ret = self.pool.librados.\ + rados_list_objects_open(self.pool.pool_id, byref(self.ctx)) + if ret < 0: + raise make_ex(ret, "error iterating over the objects in pool '%s'" \ + % self.pool.pool_name) + + def __iter__(self): + return self + + def next(self): + key = c_char_p() + ret = self.pool.librados.rados_list_objects_next(self.ctx, byref(key)) + if ret < 0: + raise StopIteration() + return Object(self.pool, key) + + def __del__(self): + self.pool.librados.rados_list_objects_close(self.ctx) + class Pool(object): """Pool object""" - def __init__(self, name, librados, pool): + def __init__(self, name, librados, pool_id): self.name = name self.librados = librados - self.pool = pool + self.pool_id = pool_id self.state = "open" - def check_pool_state(self): + def __del__(self): + if (self.state == "open"): + self.close() + + def require_pool_open(self): if self.state != "open": raise PoolStateError("The pool is %s" % self.state) + def delete(self): + self.require_pool_open() + ret = self.librados.rados_delete_pool(self.pool_id) + if ret < 0: + raise make_ex(ret, "error deleting pool '%s'" % pool_name) + self.state = "deleted" + + def close(self): + self.require_pool_open() + ret = self.librados.rados_close_pool(self.pool_id) + if ret < 0: + raise make_ex(ret, "error closing pool '%s'" % self.pool_id) + self.state = "closed" + def get_object(self, key): - self.check_pool_state() + self.require_pool_open() return Object(self, key) def write(self, key, string_to_write, offset = 0): - self.check_pool_state() + self.require_pool_open() length = len(string_to_write) - ret = self.librados.rados_write(self.pool, c_char_p(key), + ret = self.librados.rados_write(self.pool_id, c_char_p(key), c_size_t(offset), c_char_p(string_to_write), c_size_t(length)) if ret == length: @@ -125,18 +166,18 @@ returned %d, but %d was the maximum number of bytes it could have \ written." % (self.name, ret, length)) def read(self, key, offset = 0, length = 8192): - self.check_pool_state() + self.require_pool_open() ret_buf = create_string_buffer(length) - ret = self.librados.rados_read(self.pool, c_char_p(key), c_size_t(offset), + ret = self.librados.rados_read(self.pool_id, c_char_p(key), c_size_t(offset), ret_buf, c_size_t(length)) if ret < 0: raise make_ex("Pool.read(%s): failed to read %s" % (self.name, key)) return ret_buf.value def get_stats(self): - self.check_pool_state() + self.require_pool_open() stats = rados_pool_stat_t() - ret = self.librados.rados_stat_pool(self.pool, byref(stats)) + ret = self.librados.rados_stat_pool(self.pool_id, byref(stats)) if ret < 0: raise make_ex(ret, "Pool.get_stats(%s): get_stats failed" % self.name) return {'num_bytes': stats.num_bytes, @@ -153,37 +194,37 @@ written." % (self.name, ret, length)) "num_wr_kb": stats.num_wr_kb } def remove_object(self, key): - self.check_pool_state() - ret = self.librados.rados_remove(self.pool, c_char_p(key)) + self.require_pool_open() + ret = self.librados.rados_remove(self.pool_id, c_char_p(key)) if ret < 0: raise make_ex(ret, "Failed to remove '%s'" % key) return True def stat(self, key): - self.check_pool_state() + self.require_pool_open() """Stat object, returns, size/timestamp""" psize = c_uint64() pmtime = c_uint64() - ret = self.librados.rados_stat(self.pool, c_char_p(key), pointer(psize), + ret = self.librados.rados_stat(self.pool_id, c_char_p(key), pointer(psize), pointer(pmtime)) if ret < 0: raise make_ex(ret, "Failed to stat %r" % key) return psize.value, time.localtime(pmtime.value) def get_xattr(self, key, xattr_name): - self.check_pool_state() + self.require_pool_open() ret_length = 4096 ret_buf = create_string_buffer(ret_length) - ret = self.librados.rados_getxattr(self.pool, c_char_p(key), + ret = self.librados.rados_getxattr(self.pool_id, c_char_p(key), c_char_p(xattr_name), ret_buf, c_size_t(ret_length)) if ret < 0: raise make_ex(ret, "Failed to get xattr %r" % xattr_name) return ret_buf.value def set_xattr(self, key, xattr_name, xattr_value): - self.check_pool_state() - ret = self.librados.rados_setxattr(self.pool, c_char_p(key), + self.require_pool_open() + ret = self.librados.rados_setxattr(self.pool_id, c_char_p(key), c_char_p(xattr_name), c_char_p(xattr_value), c_size_t(len(xattr_value))) if ret < 0: @@ -191,27 +232,15 @@ written." % (self.name, ret, length)) return True def rm_xattr(self, key, xattr_name): - self.check_pool_state() - ret = self.librados.rados_rmxattr(self.pool, c_char_p(key), c_char_p(xattr_name)) + self.require_pool_open() + ret = self.librados.rados_rmxattr(self.pool_id, c_char_p(key), c_char_p(xattr_name)) if ret < 0: raise make_ex(ret, "Failed to delete key %r xattr %r" % (key, xattr_name)) return True - def delete(self): - self.check_pool_state() - ret = self.librados.rados_delete_pool(self.pool) - if ret < 0: - raise make_ex(ret, "error deleting pool '%s'" % pool_name) - self.state = "deleted" - - def close(self, pool): - self.check_pool_state() - ret = self.librados.rados_close_pool(pool) - if ret < 0: - raise make_ex(ret, "error closing pool '%s'" % pool) - self.state = "closed" - + def list_objects(self): + return ObjectIterator(self) class Object(object): """Rados object wrapper, makes the object look like a file""" @@ -221,43 +250,46 @@ class Object(object): self.offset = 0 self.state = "exists" - def check_object_state(self): + def __str__(self): + return "rados.Object(pool=%s,key=%s)" % (str(self.pool), self.key.value) + + def require_object_exists(self): if self.state != "exists": raise ObjectStateError("The object is %s" % self.state) def read(self, length = 1024*1024): - self.check_object_state() + self.require_object_exists() ret = self.pool.read(self.key, self.offset, length) self.offset += len(ret) return ret def write(self, string_to_write): - self.check_object_state() + self.require_object_exists() ret = self.pool.write(self.key, string_to_write, self.offset) self.offset += ret return ret def remove(self): - self.check_object_state() + self.require_object_exists() self.pool.remove_object(self.key) self.state = "removed" def stat(self): - self.check_object_state() + self.require_object_exists() return self.pool.stat(self.key) def seek(self, position): - self.check_object_state() + self.require_object_exists() self.offset = position def get_xattr(self, xattr_name): - self.check_object_state() + self.require_object_exists() return self.pool.get_xattr(self.key, xattr_name) def set_xattr(self, xattr_name, xattr_value): - self.check_object_state() + self.require_object_exists() return self.pool.set_xattr(self.key, xattr_name, xattr_value) def rm_xattr(self, xattr_name): - self.check_object_state() + self.require_object_exists() return self.pool.rm_xattr(self.key, xattr_name) diff --git a/src/test/pybind-test.py b/src/test/pybind-test.py index 1f3b6ce77ed9f..42626cf4d9b6b 100755 --- a/src/test/pybind-test.py +++ b/src/test/pybind-test.py @@ -2,6 +2,7 @@ import rados +# Create and destroy a pool r = rados.Rados() try: r.create_pool("foo2") @@ -13,3 +14,14 @@ print "opening pool foo2" foo2_pool = r.open_pool("foo2") print "deleting pool foo2" foo2_pool.delete() + +# create a pool and some objects +try: + r.create_pool("foo3") +except rados.ObjectExists: + pass +foo3_pool = r.open_pool("foo3") +foo3_pool.write("abc", "abc") +foo3_pool.write("def", "def") +for obj in foo3_pool.list_objects(): + print str(obj) -- 2.39.5