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:
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,
"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:
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"""
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)