From a62b5ac986235e074e261ad20b1ca4aefbc1b3cb Mon Sep 17 00:00:00 2001 From: Noah Watkins Date: Thu, 3 Dec 2015 18:17:20 -0800 Subject: [PATCH] pybind: support ioctx:exec Signed-off-by: Noah Watkins --- src/pybind/rados.py | 31 +++++++++++++++++++++++++++++++ src/test/pybind/test_rados.py | 8 ++++++++ 2 files changed, 39 insertions(+) diff --git a/src/pybind/rados.py b/src/pybind/rados.py index 515f19f431b81..4c7dabd3eb116 100644 --- a/src/pybind/rados.py +++ b/src/pybind/rados.py @@ -1667,6 +1667,37 @@ returned %d, but should return zero on success." % (self.name, ret)) 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 diff --git a/src/test/pybind/test_rados.py b/src/test/pybind/test_rados.py index 79cb0ff21d018..24ca2b46e9b79 100644 --- a/src/test/pybind/test_rados.py +++ b/src/test/pybind/test_rados.py @@ -583,6 +583,14 @@ class TestIoctx(object): 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): -- 2.39.5