import six
import threading
try:
- from collections.abc import defaultdict
+ from collections.abc import defaultdict, namedtuple
except ImportError:
- from collections import defaultdict
+ from collections import defaultdict, namedtuple
import rados
PG_STATES = [
return self.r, self.outb, self.outs
+class HandleCommandResult(namedtuple('HandleCommandResult', ['retval', 'stdout', 'stderr'])):
+ def __new__(cls, retval=0, odata="", rs=""):
+ """
+ Tuple containing the result of `handle_command()`
+ :param retval: return code. E.g. 0 or -errno.EINVAL
+ :param odata: data of this result.
+ :param rs: Typically used for error or status messages.
+ """
+ return super(HandleCommandResult, cls).__new__(cls, retval, odata, rs)
+
+
class OSDMap(ceph_module.BasePyOSDMap):
def get_epoch(self):
return self._get_epoch()
output string. The output buffer is for data results,
the output string is for informative text.
- :param string inbuf: content of any "-i <file>" supplied to ceph cli
- :param dict cmd: from Ceph's cmdmap_t
+ :param inbuf: content of any "-i <file>" supplied to ceph cli
+ :type inbuf: str
+ :param cmd: from Ceph's cmdmap_t
+ :type cmd: dict
- :return: 3-tuple of (int, str, str)
+ :return: HandleCommandResult or a 3-tuple of (int, str, str)
"""
# Should never get called if they didn't declare
import errno
import time
-from mgr_module import MgrModule
+from mgr_module import MgrModule, HandleCommandResult
import orchestrator
d.id, d.type, d.size)
result += "\n"
- return 0, result, ""
+ return HandleCommandResult(odata=result)
def _list_services(self, cmd):
hostname = cmd.get('host', None)
services = completion.result
if len(services) == 0:
- return 0, "", "No services reported"
+ return HandleCommandResult(rs="No services reported")
else:
# Sort the list for display
services.sort(key = lambda s: (s.service_type, s.nodename, s.daemon_name))
s.nodename,
s.container_id))
- return 0, "\n".join(lines), ""
+ return HandleCommandResult(odata="\n".join(lines))
def _service_status(self, cmd):
svc_type = cmd['svc_type']
service_list = completion.result
if len(service_list) == 0:
- return 0, "", "No locations reported"
+ return HandleCommandResult(rs="No locations reported")
else:
lines = []
for l in service_list:
l.nodename,
l.container_id))
- return 0, "\n".join(lines), ""
+ return HandleCommandResult(odata="\n".join(lines))
def _service_add(self, cmd):
svc_type = cmd['svc_type']
try:
node_name, block_device = device_spec.split(":")
except TypeError:
- return -errno.EINVAL, "", "Invalid device spec, should be <node>:<device>"
+ return HandleCommandResult(-errno.EINVAL,
+ rs="Invalid device spec, should be <node>:<device>")
spec = orchestrator.OsdCreationSpec()
spec.node = node_name
completion = self._oremote("create_osds", spec)
self._wait([completion])
- return 0, "", "Success."
+ return HandleCommandResult(rs="Success.")
elif svc_type == "mds":
fs_name = cmd['svc_arg']
)
self._wait([completion])
- return 0, "", "Success."
+ return HandleCommandResult(rs="Success.")
elif svc_type == "rgw":
store_name = cmd['svc_arg']
)
self._wait([completion])
- return 0, "", "Success."
+ return HandleCommandResult(rs="Success.")
else:
raise NotImplementedError(svc_type)
if module_name == "":
self.set_config("orchestrator", None)
- return 0, "", ""
+ return HandleCommandResult()
for module in mgr_map['available_modules']:
if module['name'] != module_name:
enabled = module['name'] in mgr_map['modules']
if not enabled:
- return -errno.EINVAL, "", "Module '{0}' is not enabled".format(
- module_name
- )
+ return HandleCommandResult(-errno.EINVAL,
+ rs="Module '{0}' is not enabled".format(module_name))
try:
is_orchestrator = self.remote(module_name,
is_orchestrator = False
if not is_orchestrator:
- return -errno.EINVAL, "",\
- "'{0}' is not an orchestrator module".format(
- module_name)
+ return HandleCommandResult(-errno.EINVAL,
+ rs="'{0}' is not an orchestrator module".format(module_name))
self.set_config("orchestrator", module_name)
- return 0, "", ""
+ return HandleCommandResult()
- return -errno.ENOENT, "", "Module '{0}' not found".format(
- module_name
- )
+ return HandleCommandResult(-errno.EINVAL, rs="Module '{0}' not found".format(module_name))
def _status(self):
try:
avail, why = self._oremote("available")
except NoOrchestrator:
- return 0, "No orchestrator configured (try " \
- "`ceph orchestrator set backend`)", ""
+ return HandleCommandResult(odata="No orchestrator configured (try " \
+ "`ceph orchestrator set backend`)")
if avail is None:
# The module does not report its availability
- return 0, "Backend: {0}".format(
- self._select_orchestrator()), ""
+ return HandleCommandResult("Backend: {0}".format(self._select_orchestrator()))
else:
- return 0, "Backend: {0}\nAvailable: {1}{2}".format(
- self._select_orchestrator(),
- avail,
- " ({0})".format(why) if not avail else ""
- ), ""
+ return HandleCommandResult("Backend: {0}\nAvailable: {1}{2}".format(
+ self._select_orchestrator(),
+ avail,
+ " ({0})".format(why) if not avail else ""
+ ))
def handle_command(self, inbuf, cmd):
try:
return self._handle_command(inbuf, cmd)
except NoOrchestrator:
- return -errno.ENODEV, "", "No orchestrator configured"
+ return HandleCommandResult(-errno.ENODEV, rs="No orchestrator configured")
except ImportError as e:
- return -errno.ENOENT, "", str(e)
+ return HandleCommandResult(-errno.ENOENT, rs=str(e))
except NotImplementedError:
- return -errno.EINVAL, "", "Command not found"
+ return HandleCommandResult(-errno.EINVAL, rs="Command not found")
def _handle_command(self, _, cmd):
if cmd['prefix'] == "orchestrator device ls":