import logging
from typing import Any, Optional
from mgr_module import MgrModule, NotifyType
-from ceph.deployment.service_spec import ServiceSpec
+from orchestrator._interface import MDSSpec, ServiceSpec
import orchestrator
import copy
return completion.result[0]
return None
- def update_daemon_count(self, spec: ServiceSpec, fs_name: str, abscount: int) -> ServiceSpec:
+ def update_daemon_count(self, spec: ServiceSpec, fs_name: str, abscount: int) -> MDSSpec:
ps = copy.deepcopy(spec.placement)
ps.count = abscount
- newspec = ServiceSpec(service_type=spec.service_type,
- service_id=spec.service_id,
- placement=ps)
+ newspec = MDSSpec(service_type=spec.service_type,
+ service_id=spec.service_id,
+ placement=ps)
return newspec
def get_required_standby_count(self, fs_map: dict, fs_name: str) -> int:
from ceph.deployment import inventory
from ceph.deployment.service_spec import ServiceSpec, NFSServiceSpec, RGWSpec, \
- IscsiServiceSpec, IngressSpec, SNMPGatewaySpec
+ IscsiServiceSpec, IngressSpec, SNMPGatewaySpec, MDSSpec
from ceph.deployment.drive_group import DriveGroupSpec
from ceph.deployment.hostspec import HostSpec, SpecValidationError
from ceph.utils import datetime_to_str, str_to_datetime
"""Update mgr cluster"""
raise NotImplementedError()
- def apply_mds(self, spec: ServiceSpec) -> OrchResult[str]:
+ def apply_mds(self, spec: MDSSpec) -> OrchResult[str]:
"""Update MDS cluster"""
raise NotImplementedError()
from ceph.deployment.inventory import Device
from ceph.deployment.drive_group import DriveGroupSpec, DeviceSelection, OSDMethod
-from ceph.deployment.service_spec import PlacementSpec, ServiceSpec, service_spec_allow_invalid_from_json, \
- SNMPGatewaySpec
+from ceph.deployment.service_spec import PlacementSpec, ServiceSpec, service_spec_allow_invalid_from_json
from ceph.deployment.hostspec import SpecValidationError
from ceph.utils import datetime_now
NoOrchestrator, OrchestratorValidationError, NFSServiceSpec, \
RGWSpec, InventoryFilter, InventoryHost, HostSpec, CLICommandMeta, \
ServiceDescription, DaemonDescription, IscsiServiceSpec, json_to_generic_spec, \
- GenericSpec, DaemonDescriptionStatus
+ GenericSpec, DaemonDescriptionStatus, SNMPGatewaySpec, MDSSpec
def nice_delta(now: datetime.datetime, t: Optional[datetime.datetime], suffix: str = '') -> str:
if inbuf:
raise OrchestratorValidationError('unrecognized command -i; -h or --help for usage')
- spec = ServiceSpec(
+ spec = MDSSpec(
service_type='mds',
service_id=fs_name,
placement=PlacementSpec.from_string(placement),
unmanaged=unmanaged,
preview_only=dry_run)
+
+ spec.validate() # force any validation exceptions to be caught correctly
+
return self._apply_misc([spec], dry_run, format, no_overwrite)
@_cli_write_command('orch apply rgw')
preview_only=dry_run
)
+ spec.validate() # force any validation exceptions to be caught correctly
+
return self._apply_misc([spec], dry_run, format, no_overwrite)
@_cli_write_command('orch apply nfs')
preview_only=dry_run
)
+ spec.validate() # force any validation exceptions to be caught correctly
+
return self._apply_misc([spec], dry_run, format, no_overwrite)
@_cli_write_command('orch apply iscsi')
preview_only=dry_run
)
+ spec.validate() # force any validation exceptions to be caught correctly
+
return self._apply_misc([spec], dry_run, format, no_overwrite)
@_cli_write_command('orch apply snmp-gateway')
'rgw': RGWSpec,
'nfs': NFSServiceSpec,
'osd': DriveGroupSpec,
+ 'mds': MDSSpec,
'iscsi': IscsiServiceSpec,
'alertmanager': AlertManagerSpec,
'ingress': IngressSpec,
f'Service of type \'{self.service_type}\' should not contain a service id')
if self.service_id:
- if not re.match('^[a-zA-Z0-9_.-]+$', self.service_id):
+ if not re.match('^[a-zA-Z0-9_.-]+$', str(self.service_id)):
raise SpecValidationError('Service id contains invalid characters, '
'only [a-zA-Z0-9_.-] allowed')
yaml.add_representer(SNMPGatewaySpec, ServiceSpec.yaml_representer)
+
+
+class MDSSpec(ServiceSpec):
+ def __init__(self,
+ service_type: str = 'mds',
+ service_id: Optional[str] = None,
+ placement: Optional[PlacementSpec] = None,
+ unmanaged: bool = False,
+ preview_only: bool = False,
+ ):
+ assert service_type == 'mds'
+ super(MDSSpec, self).__init__('mds', service_id=service_id,
+ placement=placement,
+ unmanaged=unmanaged,
+ preview_only=preview_only)
+
+ def validate(self) -> None:
+ super(MDSSpec, self).validate()
+
+ if str(self.service_id)[0].isdigit():
+ raise SpecValidationError('MDS service id cannot start with a numeric digit')
+
+
+yaml.add_representer(MDSSpec, ServiceSpec.yaml_representer)
@pytest.mark.parametrize(
's_type,s_id',
[
- ('mds', 's:id'),
+ ('mds', 's:id'), # MDS service_id cannot contain an invalid char ':'
+ ('mds', '1abc'), # MDS service_id cannot start with a numeric digit
+ ('mds', ''), # MDS service_id cannot be empty
('rgw', '*s_id'),
('nfs', 's/id'),
('iscsi', 's@id'),