+import enum
import errno
import json
from typing import List, Set, Optional, Iterator, cast, Dict, Any, Union
return '-'
-def to_format(what, format: str, many: bool, cls):
+class Format(enum.Enum):
+ plain = 'plain'
+ json = 'json'
+ json_pretty = 'json-pretty'
+ yaml = 'yaml'
+
+
+class ServiceType(enum.Enum):
+ mon = 'mon'
+ mgr = 'mgr'
+ rbd_mirror = 'rbd-mirror'
+ crash = 'crash'
+ alertmanager = 'alertmanager'
+ grafana = 'grafana'
+ node_exporter = 'node-exporter'
+ prometheus = 'prometheus'
+ mds = 'mds'
+ rgw = 'rgw'
+ nfs = 'nfs'
+ iscsi = 'iscsi'
+ cephadm_exporter = 'cephadm-exporter'
+
+
+class ServiceAction(enum.Enum):
+ start = 'start'
+ stop = 'stop'
+ restart = 'restart'
+ redeploy = 'redeploy'
+ reconfig = 'reconfig'
+
+
+class DaemonAction(enum.Enum):
+ start = 'start'
+ stop = 'stop'
+ restart = 'restart'
+ reconfig = 'reconfig'
+
+
+def to_format(what, format: Format, many: bool, cls):
def to_json_1(obj):
if hasattr(obj, 'to_json'):
return obj.to_json()
to_json = to_json_n if many else to_json_1
- if format == 'json':
+ if format == Format.json:
return json.dumps(to_json(what), sort_keys=True)
- elif format == 'json-pretty':
+ elif format == Format.json_pretty:
return json.dumps(to_json(what), indent=2, sort_keys=True)
- elif format == 'yaml':
+ elif format == Format.yaml:
# fun with subinterpreters again. pyyaml depends on object identity.
# as what originates from a different subinterpreter we have to copy things here.
if cls:
locs = [d['location'] for d in self.get('devices')['devices'] if d['devid'] == dev_id]
return [DeviceLightLoc(**l) for l in sum(locs, [])]
- @_cli_read_command(
- prefix='device ls-lights',
- desc='List currently active device indicator lights')
+ @_cli_read_command(prefix='device ls-lights')
def _device_ls(self):
+ """List currently active device indicator lights"""
return HandleCommandResult(
stdout=json.dumps({
'ident': list(self.ident),
self._refresh_health()
raise
- @_cli_write_command(
- prefix='device light',
- cmd_args='name=enable,type=CephChoices,strings=on|off '
- 'name=devid,type=CephString '
- 'name=light_type,type=CephChoices,strings=ident|fault,req=false '
- 'name=force,type=CephBool,req=false',
- desc='Enable or disable the device light. Default type is `ident`\n'
- 'Usage: device light (on|off) <devid> [ident|fault] [--force]')
- def _device_light(self, enable, devid, light_type=None, force=False):
- # type: (str, str, Optional[str], bool) -> HandleCommandResult
- light_type = light_type or 'ident'
- on = enable == 'on'
- if on:
- return self.light_on(light_type, devid)
+ class DeviceLightEnable(enum.Enum):
+ on = 'on'
+ off = 'off'
+
+ class DeviceLightType(enum.Enum):
+ ident = 'ident'
+ fault = 'fault'
+
+ @_cli_write_command(prefix='device light')
+ def _device_light(self,
+ enable: DeviceLightEnable,
+ devid: str,
+ light_type: DeviceLightType = DeviceLightType.ident,
+ force: bool = False) -> HandleCommandResult:
+ """
+ Enable or disable the device light. Default type is `ident`
+ 'Usage: device light (on|off) <devid> [ident|fault] [--force]'
+ """""
+ if enable == self.DeviceLightEnable.on:
+ return self.light_on(light_type.value, devid)
else:
- return self.light_off(light_type, devid, force)
+ return self.light_off(light_type.value, devid, force)
def _select_orchestrator(self):
return self.get_module_option("orchestrator")
- @_cli_write_command(
- 'orch host add',
- 'name=hostname,type=CephString,req=true '
- 'name=addr,type=CephString,req=false '
- 'name=labels,type=CephString,n=N,req=false',
- 'Add a host')
+ @_cli_write_command('orch host add')
def _add_host(self, hostname: str, addr: Optional[str] = None, labels: Optional[List[str]] = None):
+ """Add a host"""
s = HostSpec(hostname=hostname, addr=addr, labels=labels)
completion = self.add_host(s)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch host rm',
- "name=hostname,type=CephString,req=true",
- 'Remove a host')
- def _remove_host(self, hostname):
+ @_cli_write_command('orch host rm')
+ def _remove_host(self, hostname: str):
+ """Remove a host"""
completion = self.remove_host(hostname)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch host set-addr',
- 'name=hostname,type=CephString '
- 'name=addr,type=CephString',
- 'Update a host address')
- def _update_set_addr(self, hostname, addr):
+ @_cli_write_command('orch host set-addr')
+ def _update_set_addr(self, hostname: str, addr: str):
+ """Update a host address"""
completion = self.update_host_addr(hostname, addr)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_read_command(
- 'orch host ls',
- 'name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false',
- 'List hosts')
- def _get_hosts(self, format='plain'):
+ @_cli_read_command('orch host ls')
+ def _get_hosts(self, format: Format = Format.plain):
+ """List hosts"""
completion = self.get_hosts()
self._orchestrator_wait([completion])
raise_if_exception(completion)
- if format != 'plain':
+ if format != Format.plain:
output = to_format(completion.result, format, many=True, cls=HostSpec)
else:
table = PrettyTable(
output = table.get_string()
return HandleCommandResult(stdout=output)
- @_cli_write_command(
- 'orch host label add',
- 'name=hostname,type=CephString '
- 'name=label,type=CephString',
- 'Add a host label')
- def _host_label_add(self, hostname, label):
+ @_cli_write_command('orch host label add')
+ def _host_label_add(self, hostname: str, label: str):
+ """Add a host label"""
completion = self.add_host_label(hostname, label)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch host label rm',
- 'name=hostname,type=CephString '
- 'name=label,type=CephString',
- 'Remove a host label')
- def _host_label_rm(self, hostname, label):
+ @_cli_write_command('orch host label rm')
+ def _host_label_rm(self, hostname: str, label: str):
+ """Remove a host label"""
completion = self.remove_host_label(hostname, label)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch host ok-to-stop',
- 'name=hostname,type=CephString',
- desc='Check if the specified host can be safely stopped without reducing availability')
+ @_cli_write_command('orch host ok-to-stop')
def _host_ok_to_stop(self, hostname: str):
+ """Check if the specified host can be safely stopped without reducing availability"""""
completion = self.host_ok_to_stop(hostname)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
@_cli_write_command(
- 'orch host maintenance enter',
- 'name=hostname,type=CephString',
- desc='Prepare a host for maintenance by shutting down and disabling all Ceph daemons (cephadm only)')
+ 'orch host maintenance enter')
def _host_maintenance_enter(self, hostname: str):
+ """
+ Prepare a host for maintenance by shutting down and disabling all Ceph daemons (cephadm only)
+ """
completion = self.enter_host_maintenance(hostname)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
@_cli_write_command(
- 'orch host maintenance exit',
- 'name=hostname,type=CephString',
- desc='Return a host from maintenance, restarting all Ceph daemons (cephadm only)')
+ 'orch host maintenance exit')
def _host_maintenance_exit(self, hostname: str):
+ """
+ Return a host from maintenance, restarting all Ceph daemons (cephadm only)
+ """
completion = self.exit_host_maintenance(hostname)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_read_command(
- 'orch device ls',
- "name=hostname,type=CephString,n=N,req=false "
- "name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false "
- "name=refresh,type=CephBool,req=false "
- "name=wide,type=CephBool,req=false",
- 'List devices on a host')
- def _list_devices(self, hostname=None, format='plain', refresh=False, wide=False):
- # type: (Optional[List[str]], str, bool, bool) -> HandleCommandResult
+ @_cli_read_command('orch device ls')
+ def _list_devices(self,
+ hostname: Optional[List[str]] = None,
+ format: Format = Format.plain,
+ refresh: bool = False,
+ wide: bool = False) -> HandleCommandResult:
"""
- Provide information about storage devices present in cluster hosts
-
- Note: this does not have to be completely synchronous. Slightly out of
- date hardware inventory is fine as long as hardware ultimately appears
- in the output of this command.
+ List devices on a host
"""
+ # Provide information about storage devices present in cluster hosts
+ #
+ # Note: this does not have to be completely synchronous. Slightly out of
+ # date hardware inventory is fine as long as hardware ultimately appears
+ # in the output of this command.
nf = InventoryFilter(hosts=hostname) if hostname else None
completion = self.get_inventory(host_filter=nf, refresh=refresh)
self._orchestrator_wait([completion])
raise_if_exception(completion)
- if format != 'plain':
- return HandleCommandResult(stdout=to_format(completion.result, format, many=True, cls=InventoryHost))
+ if format != Format.plain:
+ return HandleCommandResult(stdout=to_format(completion.result,
+ format,
+ many=True,
+ cls=InventoryHost))
else:
display_map = {
"Unsupported": "N/A",
out.append(table.get_string())
return HandleCommandResult(stdout='\n'.join(out))
- @_cli_write_command(
- 'orch device zap',
- 'name=hostname,type=CephString '
- 'name=path,type=CephString '
- 'name=force,type=CephBool,req=false',
- 'Zap (erase!) a device so it can be re-used')
- def _zap_device(self, hostname, path, force=False):
+ @_cli_write_command('orch device zap')
+ def _zap_device(self, hostname: str, path: str, force: bool = False):
+ """
+ Zap (erase!) a device so it can be re-used
+ """
if not force:
raise OrchestratorError('must pass --force to PERMANENTLY ERASE DEVICE DATA')
completion = self.zap_device(hostname, path)
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_read_command(
- 'orch ls',
- "name=service_type,type=CephString,req=false "
- "name=service_name,type=CephString,req=false "
- "name=export,type=CephBool,req=false "
- "name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false "
- "name=refresh,type=CephBool,req=false",
- 'List services known to orchestrator')
- def _list_services(self, host=None, service_type=None, service_name=None, export=False, format='plain', refresh=False):
-
- if export and format == 'plain':
- format = 'yaml'
+ @_cli_read_command('orch ls')
+ def _list_services(self,
+ host: Optional[str] = None,
+ service_type: Optional[str] = None,
+ service_name: Optional[str] = None,
+ export: bool = False,
+ format: Format = Format.plain,
+ refresh: bool = False):
+ """
+ List services known to orchestrator
+ """
+ if export and format == Format.plain:
+ format = Format.yaml
completion = self.describe_service(service_type,
service_name,
if len(services) == 0:
return HandleCommandResult(stdout="No services reported")
- elif format != 'plain':
+ elif format != Format.plain:
if export:
data = [s.spec for s in services]
return HandleCommandResult(stdout=to_format(data, format, many=True, cls=ServiceSpec))
return HandleCommandResult(stdout=table.get_string())
- @_cli_read_command(
- 'orch ps',
- "name=hostname,type=CephString,req=false "
- "name=service_name,type=CephString,req=false "
- "name=daemon_type,type=CephString,req=false "
- "name=daemon_id,type=CephString,req=false "
- "name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false "
- "name=refresh,type=CephBool,req=false",
- 'List daemons known to orchestrator')
- def _list_daemons(self, hostname=None, service_name=None, daemon_type=None, daemon_id=None, format='plain', refresh=False):
+ @_cli_read_command('orch ps')
+ def _list_daemons(self,
+ hostname: Optional[str] = None,
+ service_name: Optional[str] = None,
+ daemon_type: Optional[str] = None,
+ daemon_id: Optional[str] = None,
+ format: Format = Format.plain,
+ refresh: bool = False):
+ """
+ List daemons known to orchestrator
+ """
completion = self.list_daemons(service_name,
daemon_type,
daemon_id=daemon_id,
# Sort the list for display
daemons.sort(key=lambda s: (ukn(s.daemon_type), ukn(s.hostname), ukn(s.daemon_id)))
- if format != 'plain':
+ if format != Format.plain:
return HandleCommandResult(stdout=to_format(daemons, format, many=True, cls=DaemonDescription))
else:
if len(daemons) == 0:
return HandleCommandResult(stdout=table.get_string())
- @_cli_write_command(
- 'orch apply osd',
- 'name=all_available_devices,type=CephBool,req=false '
- 'name=dry_run,type=CephBool,req=false '
- 'name=unmanaged,type=CephBool,req=false '
- "name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false",
- 'Create OSD daemon(s) using a drive group spec')
+ @_cli_write_command('orch apply osd')
def _apply_osd(self,
all_available_devices: bool = False,
- format: str = 'plain',
- unmanaged=None,
- dry_run=None,
+ format: Format = Format.plain,
+ unmanaged: Optional[bool] = None,
+ dry_run: bool = False,
inbuf: Optional[str] = None) -> HandleCommandResult:
- """Apply DriveGroupSpecs to create OSDs"""
+ """
+ Create OSD daemon(s) using a drive group spec
+ """
+ # Apply DriveGroupSpecs to create OSDs
usage = """
usage:
ceph orch apply osd -i <json_file/yaml_file> [--dry-run]
self._orchestrator_wait([completion])
raise_if_exception(completion)
data = completion.result
- if format == 'plain':
+ if format == Format.plain:
out = generate_preview_tables(data, True)
else:
out = to_format(data, format, many=True, cls=None)
completion = self.plan(dg_specs)
self._orchestrator_wait([completion])
data = completion.result
- if format == 'plain':
+ if format == Format.plain:
out = generate_preview_tables(data, True)
else:
out = to_format(data, format, many=True, cls=None)
return HandleCommandResult(-errno.EINVAL, stderr=usage)
- @_cli_write_command(
- 'orch daemon add osd',
- "name=svc_arg,type=CephString,req=false",
- 'Create an OSD service. Either --svc_arg=host:drives')
- def _daemon_add_osd(self, svc_arg=None):
- # type: (Optional[str]) -> HandleCommandResult
- """Create one or more OSDs"""
+ @_cli_write_command('orch daemon add osd')
+ def _daemon_add_osd(self, svc_arg: Optional[str] = None) -> HandleCommandResult:
+ """Create an OSD service. Either --svc_arg=host:drives"""
+ # Create one or more OSDs"""
usage = """
Usage:
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch osd rm',
- "name=svc_id,type=CephString,n=N "
- "name=replace,type=CephBool,req=false "
- "name=force,type=CephBool,req=false",
- 'Remove OSD services')
+ @_cli_write_command('orch osd rm')
def _osd_rm_start(self,
svc_id: List[str],
replace: bool = False,
force: bool = False) -> HandleCommandResult:
+ """Remove OSD services"""
completion = self.remove_osds(svc_id, replace=replace, force=force)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch osd rm stop',
- "name=svc_id,type=CephString,n=N",
- 'Remove OSD services')
+ @_cli_write_command('orch osd rm stop')
def _osd_rm_stop(self, svc_id: List[str]) -> HandleCommandResult:
+ """Remove OSD services"""
completion = self.stop_remove_osds(svc_id)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch osd rm status',
- "name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false",
- desc='status of OSD removal operation')
- def _osd_rm_status(self, format='plain') -> HandleCommandResult:
+ @_cli_write_command('orch osd rm status')
+ def _osd_rm_status(self, format: Format = Format.plain) -> HandleCommandResult:
+ """status of OSD removal operation"""
completion = self.remove_osds_status()
self._orchestrator_wait([completion])
raise_if_exception(completion)
if not report:
return HandleCommandResult(stdout="No OSD remove/replace operations reported")
- if format != 'plain':
+ if format != Format.plain:
out = to_format(report, format, many=True, cls=None)
else:
table = PrettyTable(
return HandleCommandResult(stdout=out)
- @_cli_write_command(
- 'orch daemon add',
- 'name=daemon_type,type=CephChoices,strings=mon|mgr|rbd-mirror|crash|alertmanager|grafana|node-exporter|prometheus|cephadm-exporter,req=false '
- 'name=placement,type=CephString,req=false',
- 'Add daemon(s)')
+ @_cli_write_command('orch daemon add')
def _daemon_add_misc(self,
- daemon_type: Optional[str] = None,
+ daemon_type: Optional[ServiceType] = None,
placement: Optional[str] = None,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Add daemon(s)"""
usage = f"""Usage:
ceph orch daemon add -i <json_file>
ceph orch daemon add {daemon_type or '<daemon_type>'} <placement>"""
else:
spec = PlacementSpec.from_string(placement)
assert daemon_type
- spec = ServiceSpec(daemon_type, placement=spec)
-
- daemon_type = spec.service_type
+ spec = ServiceSpec(daemon_type.value, placement=spec)
- if daemon_type == 'mon':
+ if daemon_type == ServiceType.mon:
completion = self.add_mon(spec)
- elif daemon_type == 'mgr':
+ elif daemon_type == ServiceType.mgr:
completion = self.add_mgr(spec)
- elif daemon_type == 'rbd-mirror':
+ elif daemon_type == ServiceType.rbd_mirror:
completion = self.add_rbd_mirror(spec)
- elif daemon_type == 'crash':
+ elif daemon_type == ServiceType.crash:
completion = self.add_crash(spec)
- elif daemon_type == 'alertmanager':
+ elif daemon_type == ServiceType.alertmanager:
completion = self.add_alertmanager(spec)
- elif daemon_type == 'grafana':
+ elif daemon_type == ServiceType.grafana:
completion = self.add_grafana(spec)
- elif daemon_type == 'node-exporter':
+ elif daemon_type == ServiceType.node_exporter:
completion = self.add_node_exporter(spec)
- elif daemon_type == 'prometheus':
+ elif daemon_type == ServiceType.prometheus:
completion = self.add_prometheus(spec)
- elif daemon_type == 'mds':
+ elif daemon_type == ServiceType.mds:
completion = self.add_mds(spec)
- elif daemon_type == 'rgw':
+ elif daemon_type == ServiceType.rgw:
completion = self.add_rgw(spec)
- elif daemon_type == 'nfs':
+ elif daemon_type == ServiceType.nfs:
completion = self.add_nfs(spec)
- elif daemon_type == 'iscsi':
+ elif daemon_type == ServiceType.iscsi:
completion = self.add_iscsi(spec)
- elif daemon_type == 'cephadm-exporter':
+ elif daemon_type == ServiceType.cephadm_exporter:
completion = self.add_cephadm_exporter(spec)
else:
- raise OrchestratorValidationError(f'unknown daemon type `{daemon_type}`')
+ tp = type(daemon_type)
+ raise OrchestratorValidationError(f'unknown daemon type `{tp}`')
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch daemon add mds',
- 'name=fs_name,type=CephString '
- 'name=placement,type=CephString,req=false',
- 'Start MDS daemon(s)')
+ @_cli_write_command('orch daemon add mds')
def _mds_add(self,
fs_name: str,
placement: Optional[str] = None,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Start MDS daemon(s)"""
if inbuf:
raise OrchestratorValidationError('unrecognized command -i; -h or --help for usage')
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch daemon add rgw',
- 'name=realm_name,type=CephString '
- 'name=zone_name,type=CephString '
- 'name=subcluster,type=CephString,req=false '
- 'name=port,type=CephInt,req=false '
- 'name=ssl,type=CephBool,req=false '
- 'name=placement,type=CephString,req=false',
- 'Start RGW daemon(s)')
+ @_cli_write_command('orch daemon add rgw')
def _rgw_add(self,
realm_name: str,
zone_name: str,
ssl: bool = False,
placement: Optional[str] = None,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Start RGW daemon(s)"""
if inbuf:
raise OrchestratorValidationError('unrecognized command -i; -h or --help for usage')
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch daemon add nfs',
- "name=svc_id,type=CephString "
- "name=pool,type=CephString "
- "name=namespace,type=CephString,req=false "
- 'name=placement,type=CephString,req=false',
- 'Start NFS daemon(s)')
+ @_cli_write_command('orch daemon add nfs')
def _nfs_add(self,
svc_id: str,
pool: str,
namespace: Optional[str] = None,
placement: Optional[str] = None,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Start NFS daemon(s)"""
if inbuf:
raise OrchestratorValidationError('unrecognized command -i; -h or --help for usage')
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch daemon add iscsi',
- 'name=pool,type=CephString '
- 'name=api_user,type=CephString '
- 'name=api_password,type=CephString '
- 'name=trusted_ip_list,type=CephString,req=false '
- 'name=placement,type=CephString,req=false',
- 'Start iscsi daemon(s)')
+ @_cli_write_command('orch daemon add iscsi')
def _iscsi_add(self,
pool: str,
api_user: str,
trusted_ip_list: Optional[str] = None,
placement: Optional[str] = None,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Start iscsi daemon(s)"""
if inbuf:
raise OrchestratorValidationError('unrecognized command -i; -h or --help for usage')
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch',
- "name=action,type=CephChoices,strings=start|stop|restart|redeploy|reconfig "
- "name=service_name,type=CephString",
- 'Start, stop, restart, redeploy, or reconfig an entire service (i.e. all daemons)')
- def _service_action(self, action, service_name):
- completion = self.service_action(action, service_name)
+ @_cli_write_command('orch')
+ def _service_action(self, action: ServiceAction, service_name: str):
+ """Start, stop, restart, redeploy, or reconfig an entire service (i.e. all daemons)"""
+ completion = self.service_action(action.value, service_name)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch daemon',
- "name=action,type=CephChoices,strings=start|stop|restart|reconfig "
- "name=name,type=CephString",
- 'Start, stop, restart, (redeploy,) or reconfig a specific daemon')
- def _daemon_action(self, action, name):
+ @_cli_write_command('orch daemon')
+ def _daemon_action(self, action: DaemonAction, name: str):
+ """Start, stop, restart, (redeploy,) or reconfig a specific daemon"""
if '.' not in name:
raise OrchestratorError('%s is not a valid daemon name' % name)
- completion = self.daemon_action(action, name)
+ completion = self.daemon_action(action.value, name)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch daemon redeploy',
- "name=name,type=CephString "
- "name=image,type=CephString,req=false",
- 'Redeploy a daemon (with a specifc image)')
+ @_cli_write_command('orch daemon redeploy')
def _daemon_action_redeploy(self, name: str, image: Optional[str] = None) -> HandleCommandResult:
+ """Redeploy a daemon (with a specifc image)"""
if '.' not in name:
raise OrchestratorError('%s is not a valid daemon name' % name)
completion = self.daemon_action("redeploy", name, image=image)
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch daemon rm',
- "name=names,type=CephString,n=N "
- 'name=force,type=CephBool,req=false',
- 'Remove specific daemon(s)')
- def _daemon_rm(self, names, force=False):
+ @_cli_write_command('orch daemon rm')
+ def _daemon_rm(self,
+ names: List[str],
+ force: Optional[bool] = False):
+ """Remove specific daemon(s)"""
for name in names:
if '.' not in name:
raise OrchestratorError('%s is not a valid daemon name' % name)
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch rm',
- 'name=service_name,type=CephString '
- 'name=force,type=CephBool,req=false',
- 'Remove a service')
- def _service_rm(self, service_name, force=False):
+ @_cli_write_command('orch rm')
+ def _service_rm(self,
+ service_name: str,
+ force: bool = False):
+ """Remove a service"""
if service_name in ['mon', 'mgr'] and not force:
raise OrchestratorError('The mon and mgr services cannot be removed')
completion = self.remove_service(service_name)
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch apply',
- 'name=service_type,type=CephChoices,strings=mon|mgr|rbd-mirror|crash|alertmanager|grafana|node-exporter|prometheus|cephadm-exporter,req=false '
- 'name=placement,type=CephString,req=false '
- 'name=dry_run,type=CephBool,req=false '
- 'name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false '
- 'name=unmanaged,type=CephBool,req=false',
- 'Update the size or placement for a service or apply a large yaml spec')
+ @_cli_write_command('orch apply')
def _apply_misc(self,
- service_type: Optional[str] = None,
+ service_type: Optional[ServiceType] = None,
placement: Optional[str] = None,
dry_run: bool = False,
- format: str = 'plain',
+ format: Format = Format.plain,
unmanaged: bool = False,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Update the size or placement for a service or apply a large yaml spec"""
usage = """Usage:
ceph orch apply -i <yaml spec> [--dry-run]
ceph orch apply <service_type> [--placement=<placement_string>] [--unmanaged]
else:
placementspec = PlacementSpec.from_string(placement)
assert service_type
- specs = [ServiceSpec(service_type, placement=placementspec,
+ specs = [ServiceSpec(service_type.value, placement=placementspec,
unmanaged=unmanaged, preview_only=dry_run)]
completion = self.apply(specs)
self._orchestrator_wait([completion])
raise_if_exception(completion)
data = completion.result
- if format == 'plain':
+ if format == Format.plain:
out = generate_preview_tables(data)
else:
out = to_format(data, format, many=True, cls=None)
return HandleCommandResult(stdout=out)
- @_cli_write_command(
- 'orch apply mds',
- 'name=fs_name,type=CephString '
- 'name=placement,type=CephString,req=false '
- 'name=dry_run,type=CephBool,req=false '
- 'name=unmanaged,type=CephBool,req=false '
- 'name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false',
- 'Update the number of MDS instances for the given fs_name')
+ @_cli_write_command('orch apply mds')
def _apply_mds(self,
fs_name: str,
placement: Optional[str] = None,
dry_run: bool = False,
unmanaged: bool = False,
- format: str = 'plain',
+ format: Format = Format.plain,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Update the number of MDS instances for the given fs_name"""
if inbuf:
raise OrchestratorValidationError('unrecognized command -i; -h or --help for usage')
self._orchestrator_wait([completion_plan])
raise_if_exception(completion_plan)
data = completion_plan.result
- if format == 'plain':
+ if format == Format.plain:
out = preview_table_services(data)
else:
out = to_format(data, format, many=True, cls=None)
return HandleCommandResult(stdout=out)
- @_cli_write_command(
- 'orch apply rgw',
- 'name=realm_name,type=CephString '
- 'name=zone_name,type=CephString '
- 'name=subcluster,type=CephString,req=false '
- 'name=port,type=CephInt,req=false '
- 'name=ssl,type=CephBool,req=false '
- 'name=placement,type=CephString,req=false '
- 'name=dry_run,type=CephBool,req=false '
- 'name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false '
- 'name=unmanaged,type=CephBool,req=false',
- 'Update the number of RGW instances for the given zone')
+ @_cli_write_command('orch apply rgw')
def _apply_rgw(self,
realm_name: str,
zone_name: str,
ssl: bool = False,
placement: Optional[str] = None,
dry_run: bool = False,
- format: str = 'plain',
+ format: Format = Format.plain,
unmanaged: bool = False,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Update the number of RGW instances for the given zone"""
if inbuf:
raise OrchestratorValidationError('unrecognized command -i; -h or --help for usage')
self._orchestrator_wait([completion_plan])
raise_if_exception(completion_plan)
data = completion_plan.result
- if format == 'plain':
+ if format == Format.plain:
out = preview_table_services(data)
else:
out = to_format(data, format, many=True, cls=None)
return HandleCommandResult(stdout=out)
- @_cli_write_command(
- 'orch apply nfs',
- 'name=svc_id,type=CephString '
- 'name=pool,type=CephString '
- 'name=namespace,type=CephString,req=false '
- 'name=placement,type=CephString,req=false '
- 'name=dry_run,type=CephBool,req=false '
- 'name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false '
- 'name=unmanaged,type=CephBool,req=false',
- 'Scale an NFS service')
+ @_cli_write_command('orch apply nfs')
def _apply_nfs(self,
svc_id: str,
pool: str,
namespace: Optional[str] = None,
placement: Optional[str] = None,
- format: str = 'plain',
+ format: Format = Format.plain,
dry_run: bool = False,
unmanaged: bool = False,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Scale an NFS service"""
if inbuf:
raise OrchestratorValidationError('unrecognized command -i; -h or --help for usage')
self._orchestrator_wait([completion_plan])
raise_if_exception(completion_plan)
data = completion_plan.result
- if format == 'plain':
+ if format == Format.plain:
out = preview_table_services(data)
else:
out = to_format(data, format, many=True, cls=None)
return HandleCommandResult(stdout=out)
- @_cli_write_command(
- 'orch apply iscsi',
- 'name=pool,type=CephString '
- 'name=api_user,type=CephString '
- 'name=api_password,type=CephString '
- 'name=trusted_ip_list,type=CephString,req=false '
- 'name=placement,type=CephString,req=false '
- 'name=dry_run,type=CephBool,req=false '
- 'name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false '
- 'name=unmanaged,type=CephBool,req=false',
- 'Scale an iSCSI service')
+ @_cli_write_command('orch apply iscsi')
def _apply_iscsi(self,
pool: str,
api_user: str,
placement: Optional[str] = None,
unmanaged: bool = False,
dry_run: bool = False,
- format: str = 'plain',
+ format: Format = Format.plain,
inbuf: Optional[str] = None) -> HandleCommandResult:
+ """Scale an iSCSI service"""
if inbuf:
raise OrchestratorValidationError('unrecognized command -i; -h or --help for usage')
self._orchestrator_wait([completion_plan])
raise_if_exception(completion_plan)
data = completion_plan.result
- if format == 'plain':
+ if format == Format.plain:
out = preview_table_services(data)
else:
out = to_format(data, format, many=True, cls=None)
return HandleCommandResult(stdout=out)
- @_cli_write_command(
- 'orch set backend',
- "name=module_name,type=CephString,req=true",
- 'Select orchestrator module backend')
- def _set_backend(self, module_name):
+ @_cli_write_command('orch set backend')
+ def _set_backend(self, module_name: Optional[str] = None):
"""
- We implement a setter command instead of just having the user
- modify the setting directly, so that we can validate they're setting
- it to a module that really exists and is enabled.
-
- There isn't a mechanism for ensuring they don't *disable* the module
- later, but this is better than nothing.
+ Select orchestrator module backend
"""
+ # We implement a setter command instead of just having the user
+ # modify the setting directly, so that we can validate they're setting
+ # it to a module that really exists and is enabled.
+
+ # There isn't a mechanism for ensuring they don't *disable* the module
+ # later, but this is better than nothing.
mgr_map = self.get("mgr_map")
if module_name is None or module_name == "":
return HandleCommandResult(-errno.EINVAL, stderr="Module '{0}' not found".format(module_name))
- @_cli_write_command(
- 'orch pause',
- desc='Pause orchestrator background work')
+ @_cli_write_command('orch pause')
def _pause(self):
+ """Pause orchestrator background work"""
self.pause()
return HandleCommandResult()
- @_cli_write_command(
- 'orch resume',
- desc='Resume orchestrator background work (if paused)')
+ @_cli_write_command('orch resume')
def _resume(self):
+ """Resume orchestrator background work (if paused)"""
self.resume()
return HandleCommandResult()
- @_cli_write_command(
- 'orch cancel',
- desc='cancels ongoing operations')
+ @_cli_write_command('orch cancel')
def _cancel(self):
"""
+ cancels ongoing operations
+
ProgressReferences might get stuck. Let's unstuck them.
"""
self.cancel_completions()
return HandleCommandResult()
- @_cli_read_command(
- 'orch status',
- 'name=format,type=CephChoices,strings=plain|json|json-pretty|yaml,req=false',
- desc='Report configured backend and its status')
- def _status(self, format='plain'):
+ @_cli_read_command('orch status')
+ def _status(self, format: Format = Format.plain):
+ """Report configured backend and its status"""
o = self._select_orchestrator()
if o is None:
raise NoOrchestrator()
if not avail:
result['reason'] = why
- if format != 'plain':
+ if format != Format.plain:
output = to_format(result, format, many=False, cls=None)
else:
output = "Backend: {0}".format(result['backend'])
f" Maybe you meant `--ceph-version {ver}`?"
raise OrchestratorValidationError(s)
- @_cli_write_command(
- 'orch upgrade check',
- 'name=image,type=CephString,req=false '
- 'name=ceph_version,type=CephString,req=false',
- desc='Check service versions vs available and target containers')
- def _upgrade_check(self, image=None, ceph_version=None):
+ @_cli_write_command('orch upgrade check')
+ def _upgrade_check(self,
+ image: Optional[str] = None,
+ ceph_version: Optional[str] = None):
+ """Check service versions vs available and target containers"""
self._upgrade_check_image_name(image, ceph_version)
completion = self.upgrade_check(image=image, version=ceph_version)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch upgrade status',
- desc='Check service versions vs available and target containers')
+ @_cli_write_command('orch upgrade status')
def _upgrade_status(self):
+ """Check service versions vs available and target containers"""
completion = self.upgrade_status()
self._orchestrator_wait([completion])
raise_if_exception(completion)
out = json.dumps(r, indent=4)
return HandleCommandResult(stdout=out)
- @_cli_write_command(
- 'orch upgrade start',
- 'name=image,type=CephString,req=false '
- 'name=ceph_version,type=CephString,req=false',
- desc='Initiate upgrade')
- def _upgrade_start(self, image=None, ceph_version=None):
+ @_cli_write_command('orch upgrade start')
+ def _upgrade_start(self,
+ image: Optional[str] = None,
+ ceph_version: Optional[str] = None):
+ """Initiate upgrade"""
self._upgrade_check_image_name(image, ceph_version)
completion = self.upgrade_start(image, ceph_version)
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch upgrade pause',
- desc='Pause an in-progress upgrade')
+ @_cli_write_command('orch upgrade pause')
def _upgrade_pause(self):
+ """Pause an in-progress upgrade"""
completion = self.upgrade_pause()
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch upgrade resume',
- desc='Resume paused upgrade')
+ @_cli_write_command('orch upgrade resume')
def _upgrade_resume(self):
+ """Resume paused upgrade"""
completion = self.upgrade_resume()
self._orchestrator_wait([completion])
raise_if_exception(completion)
return HandleCommandResult(stdout=completion.result_str())
- @_cli_write_command(
- 'orch upgrade stop',
- desc='Stop an in-progress upgrade')
+ @_cli_write_command('orch upgrade stop')
def _upgrade_stop(self):
+ """Stop an in-progress upgrade"""
completion = self.upgrade_stop()
self._orchestrator_wait([completion])
raise_if_exception(completion)