Merge pull request #38695 from pcuzner/orch-status-changes

mgr/orchestrator: minor improvements to orch status

Reviewed-by: Alfonso Martínez <almartin@redhat.com>
Reviewed-by: Ernesto Puerta <epuertat@redhat.com>
Reviewed-by: Juan Miguel Olmo Martínez <jolmomar@redhat.com>
Reviewed-by: Michael Fritch <mfritch@suse.com>
Reviewed-by: Nizamudeen A <nia@redhat.com>
Reviewed-by: Sebastian Wagner <sebastian.wagner@suse.com>
This commit is contained in:
Sebastian Wagner 2021-02-08 11:15:19 +01:00 committed by GitHub
commit 4db6aebee0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 42 additions and 25 deletions

View File

@ -53,7 +53,7 @@ Status
::
ceph orch status
ceph orch status [--detail]
Show current orchestrator mode and high-level status (whether the orchestrator
plugin is available and operational)

View File

@ -675,16 +675,24 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule,
return False, "loading remoto library:{}".format(
remoto_import_error)
def available(self) -> Tuple[bool, str]:
def available(self) -> Tuple[bool, str, Dict[str, Any]]:
"""
The cephadm orchestrator is always available.
"""
ok, err = self.can_run()
if not ok:
return ok, err
return ok, err, {}
if not self.ssh_key or not self.ssh_pub:
return False, 'SSH keys not set. Use `ceph cephadm set-priv-key` and `ceph cephadm set-pub-key` or `ceph cephadm generate-key`'
return True, ''
return False, 'SSH keys not set. Use `ceph cephadm set-priv-key` and `ceph cephadm set-pub-key` or `ceph cephadm generate-key`', {}
# mypy is unable to determine type for _processes since it's private
worker_count: int = self._worker_pool._processes # type: ignore
ret = {
"workers": worker_count,
"paused": self.paused,
}
return True, err, ret
def process(self, completions: List[CephadmCompletion]) -> None: # type: ignore
"""

View File

@ -23,7 +23,7 @@ class OrchestratorAPI(OrchestratorClientMixin):
def status(self):
try:
status, message = super().available()
status, message, _module_details = super().available()
logger.info("is orchestrator available: %s, %s", status, message)
return dict(available=status, message=message)
except (RuntimeError, OrchestratorError, ImportError) as e:

View File

@ -703,7 +703,7 @@ class Orchestrator(object):
return True
@_hide_in_features
def available(self) -> Tuple[bool, str]:
def available(self) -> Tuple[bool, str, Dict[str, Any]]:
"""
Report whether we can talk to the orchestrator. This is the
place to give the user a meaningful message if the orchestrator
@ -724,7 +724,9 @@ class Orchestrator(object):
... if OrchestratorClientMixin().available()[0]: # wrong.
... OrchestratorClientMixin().get_hosts()
:return: two-tuple of boolean, string
:return: boolean representing whether the module is available/usable
:return: string describing any error
:return: dict containing any module specific information
"""
raise NotImplementedError()

View File

@ -1345,29 +1345,36 @@ Usage:
return HandleCommandResult()
@_cli_read_command('orch status')
def _status(self, format: Format = Format.plain) -> HandleCommandResult:
def _status(self,
detail: bool = False,
format: Format = Format.plain) -> HandleCommandResult:
"""Report configured backend and its status"""
o = self._select_orchestrator()
if o is None:
raise NoOrchestrator()
avail, why = self.available()
avail, why, module_details = self.available()
result: Dict[str, Any] = {
"backend": o
"available": avail,
"backend": o,
}
if avail is not None:
result['available'] = avail
if not avail:
result['reason'] = why
if avail:
result.update(module_details)
else:
result['reason'] = why
if format != Format.plain:
output = to_format(result, format, many=False, cls=None)
else:
output = "Backend: {0}".format(result['backend'])
if 'available' in result:
output += "\nAvailable: {0}".format(result['available'])
if 'reason' in result:
output += ' ({0})'.format(result['reason'])
output += f"\nAvailable: {'Yes' if result['available'] else 'No'}"
if 'reason' in result:
output += ' ({0})'.format(result['reason'])
if 'paused' in result:
output += f"\nPaused: {'Yes' if result['paused'] else 'No'}"
if 'workers' in result and detail:
output += f"\nHost Parallelism: {result['workers']}"
return HandleCommandResult(stdout=output)
def self_test(self) -> None:

View File

@ -125,18 +125,18 @@ class RookOrchestrator(MgrModule, orchestrator.Orchestrator):
return False, "Rook version unsupported."
return True, ''
def available(self) -> Tuple[bool, str]:
def available(self) -> Tuple[bool, str, Dict[str, Any]]:
if not kubernetes_imported:
return False, "`kubernetes` python module not found"
return False, "`kubernetes` python module not found", {}
elif not self._rook_env.has_namespace():
return False, "ceph-mgr not running in Rook cluster"
return False, "ceph-mgr not running in Rook cluster", {}
try:
self.k8s.list_namespaced_pod(self._rook_env.namespace)
except ApiException as e:
return False, "Cannot reach Kubernetes API: {}".format(e)
return False, "Cannot reach Kubernetes API: {}".format(e), {}
else:
return True, ""
return True, "", {}
def __init__(self, *args: Any, **kwargs: Any) -> None:
super(RookOrchestrator, self).__init__(*args, **kwargs)

View File

@ -90,7 +90,7 @@ class TestOrchestrator(MgrModule, orchestrator.Orchestrator):
return HandleCommandResult(retval=-errno.EINVAL, stderr=str(e))
def available(self):
return True, ""
return True, "", {}
def __init__(self, *args, **kwargs):
super(TestOrchestrator, self).__init__(*args, **kwargs)