raise make_ex(ret, "Ioctx.read(%s): failed to read %s" % (self.name, key))
return ctypes.string_at(ret_buf, ret)
+ @requires(('key', str_type), ('cls', str_type), ('method', str_type), ('data', bytes))
+ def execute(self, key, cls, method, data, length=8192):
+ """
+ Execute an OSD class method on an object.
+
+ :param key: name of the object
+ :type key: str
+ :param cls: name of the object class
+ :type cls: str
+ :param method: name of the method
+ :type method: str
+ :param data: input data
+ :type data: bytes
+ :param length: size of output buffer in bytes (default=8291)
+ :type length: int
+
+ :raises: :class:`TypeError`
+ :raises: :class:`Error`
+ :returns: (ret, method output)
+ """
+ self.require_ioctx_open()
+ ret_buf = create_string_buffer(length)
+ ret = run_in_thread(self.librados.rados_exec,
+ (self.io, cstr(key), cstr(cls), cstr(method),
+ c_char_p(data), c_size_t(len(data)), ret_buf,
+ c_size_t(length)))
+ if ret < 0:
+ raise make_ex(ret, "Ioctx.exec(%s): failed to exec %s:%s on %s" %
+ (self.name, cls, method, key))
+ return ret, ctypes.string_at(ret_buf, min(ret, length))
+
def get_stats(self):
"""
Get pool usage statistics
assert_raises(ObjectNotFound, self.ioctx.unlock, "foo", "lock", "locker1")
assert_raises(ObjectNotFound, self.ioctx.unlock, "foo", "lock", "locker2")
+ def test_execute(self):
+ self.ioctx.write("foo", "") # ensure object exists
+
+ ret, buf = self.ioctx.execute("foo", "hello", "say_hello", "")
+ eq(buf, "Hello, world!")
+
+ ret, buf = self.ioctx.execute("foo", "hello", "say_hello", "nose")
+ eq(buf, "Hello, nose!")
class TestObject(object):