From: Adam King Date: Thu, 10 Nov 2022 20:01:33 +0000 (-0500) Subject: python-common/service_spec: introduce mon spec with new crush_locations field X-Git-Tag: v17.2.7~370^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=65de1889d515baec424987087d075f91479f6acc;p=ceph.git python-common/service_spec: introduce mon spec with new crush_locations field In order to allow having cephadm set the crush locations for the mons. For helping with setting up stretch mode with a cephadm cluster Signed-off-by: Adam King (cherry picked from commit 416da86b04b6a35fdeae9105728c99020a0ce6df) --- diff --git a/src/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index dbf42ef961f1..ca81c58f5aae 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -509,6 +509,7 @@ class ServiceSpec(object): from ceph.deployment.drive_group import DriveGroupSpec ret = { + 'mon': MONSpec, 'rgw': RGWSpec, 'nfs': NFSServiceSpec, 'osd': DriveGroupSpec, @@ -1509,6 +1510,52 @@ class MDSSpec(ServiceSpec): yaml.add_representer(MDSSpec, ServiceSpec.yaml_representer) +class MONSpec(ServiceSpec): + def __init__(self, + service_type: str, + service_id: Optional[str] = None, + placement: Optional[PlacementSpec] = None, + count: Optional[int] = None, + config: Optional[Dict[str, str]] = None, + unmanaged: bool = False, + preview_only: bool = False, + networks: Optional[List[str]] = None, + extra_container_args: Optional[List[str]] = None, + custom_configs: Optional[List[CustomConfig]] = None, + crush_locations: Optional[Dict[str, List[str]]] = None, + ): + assert service_type == 'mon' + super(MONSpec, self).__init__('mon', service_id=service_id, + placement=placement, + count=count, + config=config, + unmanaged=unmanaged, + preview_only=preview_only, + networks=networks, + extra_container_args=extra_container_args, + custom_configs=custom_configs) + + self.crush_locations = crush_locations + self.validate() + + def validate(self) -> None: + if self.crush_locations: + for host, crush_locs in self.crush_locations.items(): + try: + assert_valid_host(host) + except SpecValidationError as e: + err_str = f'Invalid hostname found in spec crush locations: {e}' + raise SpecValidationError(err_str) + for cloc in crush_locs: + if '=' not in cloc or len(cloc.split('=')) != 2: + err_str = ('Crush locations must be of form =. ' + f'Found crush location: {cloc}') + raise SpecValidationError(err_str) + + +yaml.add_representer(MONSpec, ServiceSpec.yaml_representer) + + class TunedProfileSpec(): def __init__(self, profile_name: str,