From 6e2da200999720b9855c434aa9e3350f54d78a41 Mon Sep 17 00:00:00 2001 From: Michael Fritch Date: Wed, 22 Jul 2020 17:43:05 -0600 Subject: [PATCH] mgr/orch: add errno to OrchestratorError add errno to OrchestratorError and ServiceSpecValidationError exceptions Signed-off-by: Michael Fritch (cherry picked from commit 60b99dcdc767d5520f4dddafe124de4404ee7459) --- qa/tasks/mgr/test_orchestrator_cli.py | 6 ++++-- src/pybind/mgr/orchestrator/_interface.py | 12 +++++++++--- src/pybind/mgr/test_orchestrator/module.py | 4 +++- src/python-common/ceph/deployment/service_spec.py | 7 +++++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/qa/tasks/mgr/test_orchestrator_cli.py b/qa/tasks/mgr/test_orchestrator_cli.py index db922632374ea..ed0c52feae683 100644 --- a/qa/tasks/mgr/test_orchestrator_cli.py +++ b/qa/tasks/mgr/test_orchestrator_cli.py @@ -163,8 +163,10 @@ data_devices: self._orch_cmd("apply", "nfs", "service_name", "2") def test_error(self): - ret = self._orch_cmd_result("host", "add", "raise_no_support") - self.assertEqual(ret, errno.ENOENT) + ret = self._orch_cmd_result("host", "add", "raise_validation_error") + self.assertEqual(ret, errno.EINVAL) + ret = self._orch_cmd_result("host", "add", "raise_error") + self.assertEqual(ret, errno.EINVAL) ret = self._orch_cmd_result("host", "add", "raise_bug") self.assertEqual(ret, errno.EINVAL) ret = self._orch_cmd_result("host", "add", "raise_not_implemented") diff --git a/src/pybind/mgr/orchestrator/_interface.py b/src/pybind/mgr/orchestrator/_interface.py index d7230b320613e..5b054a6dcbc2a 100644 --- a/src/pybind/mgr/orchestrator/_interface.py +++ b/src/pybind/mgr/orchestrator/_interface.py @@ -48,8 +48,12 @@ class OrchestratorError(Exception): It's not intended for programming errors or orchestrator internal errors. """ - def __init__(self, msg, event_kind_subject: Optional[Tuple[str, str]]=None): + def __init__(self, + msg: str, + errno: int = -errno.EINVAL, + event_kind_subject: Optional[Tuple[str, str]] = None): super(Exception, self).__init__(msg) + self.errno = errno # See OrchestratorEvent.subject self.event_subject = event_kind_subject @@ -59,7 +63,7 @@ class NoOrchestrator(OrchestratorError): No orchestrator in configured. """ def __init__(self, msg="No orchestrator configured (try `ceph orch set backend`)"): - super(NoOrchestrator, self).__init__(msg) + super(NoOrchestrator, self).__init__(msg, errno=-errno.ENOENT) class OrchestratorValidationError(OrchestratorError): @@ -83,8 +87,10 @@ def handle_exception(prefix, cmd_args, desc, perm, func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) - except (OrchestratorError, ImportError, ServiceSpecValidationError) as e: + except (OrchestratorError, ServiceSpecValidationError) as e: # Do not print Traceback for expected errors. + return HandleCommandResult(e.errno, stderr=str(e)) + except ImportError as e: return HandleCommandResult(-errno.ENOENT, stderr=str(e)) except NotImplementedError: msg = 'This Orchestrator does not support `{}`'.format(prefix) diff --git a/src/pybind/mgr/test_orchestrator/module.py b/src/pybind/mgr/test_orchestrator/module.py index 83100ab9a11b0..f2eabdc5bf0fe 100644 --- a/src/pybind/mgr/test_orchestrator/module.py +++ b/src/pybind/mgr/test_orchestrator/module.py @@ -355,8 +355,10 @@ class TestOrchestrator(MgrModule, orchestrator.Orchestrator): def add_host(self, spec): # type: (orchestrator.HostSpec) -> None host = spec.hostname - if host == 'raise_no_support': + if host == 'raise_validation_error': raise orchestrator.OrchestratorValidationError("MON count must be either 1, 3 or 5") + if host == 'raise_error': + raise orchestrator.OrchestratorError("host address is empty") if host == 'raise_bug': raise ZeroDivisionError() if host == 'raise_not_implemented': diff --git a/src/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index 6b7ec380e0b4d..4508430b31920 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -1,3 +1,4 @@ +import errno import fnmatch import re from collections import namedtuple, OrderedDict @@ -15,9 +16,11 @@ class ServiceSpecValidationError(Exception): Defining an exception here is a bit problematic, cause you cannot properly catch it, if it was raised in a different mgr module. """ - - def __init__(self, msg): + def __init__(self, + msg: str, + errno: int = -errno.EINVAL): super(ServiceSpecValidationError, self).__init__(msg) + self.errno = errno def assert_valid_host(name): -- 2.39.5