]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Add Pool::list_objects
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Thu, 17 Feb 2011 14:46:08 +0000 (06:46 -0800)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Thu, 17 Feb 2011 14:46:08 +0000 (06:46 -0800)
Add a Pool::list_objects method. Add a test for this to pybind-test.py

Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
src/pybind/rados.py
src/test/pybind-test.py

index d711fb319d2dcc52db7b8622f7ccc908891c3886..d23c9fa06f1ce0eddcdfd928331efdb26fce8f5c 100755 (executable)
@@ -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)
index 1f3b6ce77ed9f7bf078d0ed9f0cbcabc6eeb3f14..42626cf4d9b6b040f120862e49b80e8f305a6dd9 100755 (executable)
@@ -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)