"""librados Python ctypes wrapper
Copyright 2011, Hannu Valtonen <hannu.valtonen@ormod.com>
"""
-from ctypes import CDLL, c_char_p, c_size_t, c_void_p,\
+from ctypes import CDLL, c_char_p, c_size_t, c_void_p, c_int, \
create_string_buffer, byref, Structure, c_uint64, c_ubyte, c_byte, pointer
import ctypes
import datetime
self.shutdown()
def version(self):
- major = ctypes.c_int()
- minor = ctypes.c_int()
- extra = ctypes.c_int()
+ major = c_int(0)
+ minor = c_int(0)
+ extra = c_int(0)
self.librados.rados_version(byref(major), byref(minor), byref(extra))
return Version(major.value, minor.value, extra.value)
def __del__(self):
self.ioctx.librados.rados_objects_list_close(self.ctx)
+class XattrIterator(object):
+ """Extended attribute iterator"""
+ def __init__(self, ioctx, it, oid):
+ self.ioctx = ioctx
+ self.it = it
+ self.oid = oid
+ def __iter__(self):
+ return self
+ def next(self):
+ name_ = c_char_p(0)
+ val_ = c_char_p(0)
+ len_ = c_int(0)
+ ret = self.ioctx.librados.\
+ rados_getxattrs_next(self.it, byref(name_), byref(val_), byref(len_))
+ if (ret != 0):
+ raise make_ex(ret, "error iterating over the extended attributes \
+in '%s'" % self.oid)
+ if name_.value == None:
+ raise StopIteration()
+ name = ctypes.string_at(name_)
+ val = ctypes.string_at(val_, len_)
+ return (name, val)
+ def __del__(self):
+ self.ioctx.librados.rados_getxattrs_end(self.it)
+
class SnapIterator(object):
"""Snapshot iterator"""
def __init__(self, ioctx):
raise make_ex(ret, "Failed to get xattr %r" % xattr_name)
return ret_buf.value
+ def get_xattrs(self, oid):
+ self.require_ioctx_open()
+ it = c_void_p(0)
+ ret = self.librados.rados_getxattrs(self.io, oid, byref(it))
+ if ret != 0:
+ raise make_ex(ret, "Failed to get rados xattrs for object %r" % oids)
+ return XattrIterator(self, it, oid)
+
def set_xattr(self, key, xattr_name, xattr_value):
self.require_ioctx_open()
ret = self.librados.rados_setxattr(self.io, c_char_p(key),
self.require_object_exists()
return self.ioctx.get_xattr(self.key, xattr_name)
+ def get_xattrs(self, xattr_name):
+ self.require_object_exists()
+ return self.ioctx.get_xattrs(self.key, xattr_name)
+
def set_xattr(self, xattr_name, xattr_value):
self.require_object_exists()
return self.ioctx.set_xattr(self.key, xattr_name, xattr_value)
if (def_str != "d"):
raise RuntimeError("error reading object def: expected value d, \
got %s" % def_str)
-
for obj in foo3_ioctx.list_objects():
print str(obj)
+# do some things with extended attributes
+foo3_ioctx.set_xattr("abc", "a", "1")
+foo3_ioctx.set_xattr("def", "b", "2")
+foo3_ioctx.set_xattr("abc", "c", "3")
+ret = foo3_ioctx.get_xattr("abc", "a")
+if (ret != "1"):
+ raise RuntimeError("error: expected object abc to have a=1")
+ret = foo3_ioctx.get_xattr("def", "b")
+if (ret != "2"):
+ raise RuntimeError("error: expected object def to have b=2")
+ret = foo3_ioctx.get_xattr("abc", "c")
+if (ret != "3"):
+ raise RuntimeError("error: expected object abc to have c=3")
+found = {}
+for k,v in foo3_ioctx.get_xattrs("abc"):
+ found[k] = v
+if (len(found) != 2):
+ raise RuntimeError("error: expected two extended attributes on abc")
+if (found["a"] != "1"):
+ raise RuntimeError("error: expected object abc to have a=1")
+if (found["c"] != "3"):
+ raise RuntimeError("error: expected object abc to have c=3")
+
# create some snapshots and do stuff with them
print "creating snap bjork"
foo3_ioctx.create_snap("bjork")