From d8bcaac10a1a7cdc8689375f37f5d59d86148314 Mon Sep 17 00:00:00 2001 From: Sebastian Wagner Date: Tue, 16 Feb 2021 16:54:11 +0100 Subject: [PATCH] mgr/cephadm: remove spec from CephadmDaemonDeploySpec Signed-off-by: Sebastian Wagner --- src/pybind/mgr/cephadm/module.py | 18 ++++-- src/pybind/mgr/cephadm/serve.py | 22 ++------ .../mgr/cephadm/services/cephadmservice.py | 47 +++++++--------- src/pybind/mgr/cephadm/services/container.py | 22 ++------ src/pybind/mgr/cephadm/services/ha_rgw.py | 56 ++++--------------- src/pybind/mgr/cephadm/services/iscsi.py | 21 ++----- src/pybind/mgr/cephadm/services/monitoring.py | 36 +++++------- src/pybind/mgr/cephadm/services/nfs.py | 37 +++--------- src/pybind/mgr/cephadm/services/osd.py | 5 +- src/pybind/mgr/cephadm/tests/test_services.py | 8 ++- 10 files changed, 89 insertions(+), 183 deletions(-) diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index c2737505b3f..7e059de8a4b 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -27,7 +27,7 @@ from ceph.deployment.service_spec import \ HostPlacementSpec from ceph.utils import str_to_datetime, datetime_to_str, datetime_now from cephadm.serve import CephadmServe -from cephadm.services.cephadmservice import CephadmDaemonSpec +from cephadm.services.cephadmservice import CephadmDaemonDeploySpec from mgr_module import MgrModule, HandleCommandResult, Option from mgr_util import create_self_signed_cert @@ -1593,10 +1593,16 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule, ] def _daemon_action(self, daemon_type: str, daemon_id: str, host: str, action: str, image: Optional[str] = None) -> str: - daemon_spec: CephadmDaemonSpec = CephadmDaemonSpec( + dd = DaemonDescription( + hostname=host, + daemon_type=daemon_type, + daemon_id=daemon_id + ) + daemon_spec: CephadmDaemonDeploySpec = CephadmDaemonDeploySpec( host=host, daemon_id=daemon_id, daemon_type=daemon_type, + service_name=dd.service_name(), ) self._daemon_action_set_image(action, image, daemon_type, daemon_id) @@ -1895,7 +1901,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule, def _add_daemon(self, daemon_type: str, spec: ServiceSpec, - create_func: Callable[..., CephadmDaemonSpec]) -> List[str]: + create_func: Callable[..., CephadmDaemonDeploySpec]) -> List[str]: """ Add (and place) a daemon. Require explicit host placement. Do not schedule, and do not apply the related scheduling limitations. @@ -1920,7 +1926,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule, daemons: List[DaemonDescription], hosts: List[HostPlacementSpec], count: int, - create_func: Callable[..., CephadmDaemonSpec]) -> List[str]: + create_func: Callable[..., CephadmDaemonDeploySpec]) -> List[str]: if count > len(hosts): raise OrchestratorError('too few hosts: want %d, have %s' % ( count, hosts)) @@ -1928,7 +1934,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule, did_config = False service_type = daemon_type_to_service(daemon_type) - args = [] # type: List[CephadmDaemonSpec] + args = [] # type: List[CephadmDaemonDeploySpec] for host, network, name in hosts: daemon_id = self.get_unique_name(daemon_type, host, daemons, prefix=spec.service_id, @@ -1952,7 +1958,7 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule, ) daemons.append(sd) - @forall_hosts + @ forall_hosts def create_func_map(*args: Any) -> str: daemon_spec = create_func(*args) return CephadmServe(self)._create_daemon(daemon_spec) diff --git a/src/pybind/mgr/cephadm/serve.py b/src/pybind/mgr/cephadm/serve.py index a4cad1a4fee..8ffeeb53216 100644 --- a/src/pybind/mgr/cephadm/serve.py +++ b/src/pybind/mgr/cephadm/serve.py @@ -20,7 +20,7 @@ from ceph.utils import str_to_datetime, datetime_now import orchestrator from orchestrator import OrchestratorError, set_exception_subject, OrchestratorEvent -from cephadm.services.cephadmservice import CephadmDaemonSpec +from cephadm.services.cephadmservice import CephadmDaemonDeploySpec from cephadm.schedule import HostAssignment from cephadm.utils import forall_hosts, cephadmNoImage, is_repo_digest, \ CephadmNoImage, CEPH_UPGRADE_ORDER, ContainerInspectInfo @@ -734,7 +734,7 @@ class CephadmServe: return spec def _create_daemon(self, - daemon_spec: CephadmDaemonSpec, + daemon_spec: CephadmDaemonDeploySpec, reconfig: bool = False, osd_uuid_map: Optional[Dict[str, Any]] = None, ) -> str: @@ -751,18 +751,8 @@ class CephadmServe: ports: List[int] = daemon_spec.ports if daemon_spec.ports else [] if daemon_spec.daemon_type == 'container': - spec: Optional[CustomContainerSpec] = daemon_spec.spec - if spec is None: - # Exit here immediately because the required service - # spec to create a daemon is not provided. This is only - # provided when a service is applied via 'orch apply' - # command. - msg = "Failed to {} daemon {} on {}: Required " \ - "service specification not provided".format( - 'reconfigure' if reconfig else 'deploy', - daemon_spec.name(), daemon_spec.host) - self.log.info(msg) - return msg + spec = cast(CustomContainerSpec, + self.mgr.spec_store[daemon_spec.service_name].spec) image = spec.image if spec.ports: ports.extend(spec.ports) @@ -777,12 +767,12 @@ class CephadmServe: return msg if daemon_spec.daemon_type == 'haproxy': - haspec = cast(HA_RGWSpec, daemon_spec.spec) + haspec = cast(HA_RGWSpec, self.mgr.spec_store[daemon_spec.service_name].spec) if haspec.haproxy_container_image: image = haspec.haproxy_container_image if daemon_spec.daemon_type == 'keepalived': - haspec = cast(HA_RGWSpec, daemon_spec.spec) + haspec = cast(HA_RGWSpec, self.mgr.spec_store[daemon_spec.service_name].spec) if haspec.keepalived_container_image: image = haspec.keepalived_container_image diff --git a/src/pybind/mgr/cephadm/services/cephadmservice.py b/src/pybind/mgr/cephadm/services/cephadmservice.py index 8d35483c6d2..a676728ab5d 100644 --- a/src/pybind/mgr/cephadm/services/cephadmservice.py +++ b/src/pybind/mgr/cephadm/services/cephadmservice.py @@ -4,7 +4,7 @@ import re import logging import subprocess from abc import ABCMeta, abstractmethod -from typing import TYPE_CHECKING, List, Callable, TypeVar, Generic, \ +from typing import TYPE_CHECKING, List, Callable, TypeVar, \ Optional, Dict, Any, Tuple, NewType from mgr_module import HandleCommandResult, MonCommandFailed @@ -25,10 +25,10 @@ ServiceSpecs = TypeVar('ServiceSpecs', bound=ServiceSpec) AuthEntity = NewType('AuthEntity', str) -class CephadmDaemonSpec(Generic[ServiceSpecs]): +class CephadmDaemonDeploySpec: # typing.NamedTuple + Generic is broken in py36 def __init__(self, host: str, daemon_id: str, - spec: Optional[ServiceSpecs] = None, + service_name: str, network: Optional[str] = None, keyring: Optional[str] = None, extra_args: Optional[List[str]] = None, @@ -37,21 +37,15 @@ class CephadmDaemonSpec(Generic[ServiceSpecs]): daemon_type: Optional[str] = None, ports: Optional[List[int]] = None,): """ - Used for - * deploying new daemons. then everything is set - * redeploying existing daemons, then only the first three attrs are set. - - Would be great to have a consistent usage where all properties are set. + A data struction to encapsulate `cephadm deploy ... """ self.host: str = host self.daemon_id = daemon_id - daemon_type = daemon_type or (spec.service_type if spec else None) + self.service_name = service_name + daemon_type = daemon_type or (service_name.split('.')[0]) assert daemon_type is not None self.daemon_type: str = daemon_type - # would be great to have the spec always available: - self.spec: Optional[ServiceSpecs] = spec - # mons self.network = network @@ -109,19 +103,19 @@ class CephadmService(metaclass=ABCMeta): daemon_id: str, netowrk: str, spec: ServiceSpecs, - daemon_type: Optional[str] = None,) -> CephadmDaemonSpec: - return CephadmDaemonSpec( + daemon_type: Optional[str] = None,) -> CephadmDaemonDeploySpec: + return CephadmDaemonDeploySpec( host=host, daemon_id=daemon_id, - spec=spec, + service_name=spec.service_name(), network=netowrk, daemon_type=daemon_type ) - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: raise NotImplementedError() - def generate_config(self, daemon_spec: CephadmDaemonSpec) -> Tuple[Dict[str, Any], List[str]]: + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: raise NotImplementedError() def config(self, spec: ServiceSpec, daemon_id: str) -> None: @@ -298,7 +292,7 @@ class CephadmService(metaclass=ABCMeta): class CephService(CephadmService): - def generate_config(self, daemon_spec: CephadmDaemonSpec) -> Tuple[Dict[str, Any], List[str]]: + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: # Ceph.daemons (mon, mgr, mds, osd, etc) cephadm_config = self.get_config_and_keyring( daemon_spec.daemon_type, @@ -382,7 +376,7 @@ class CephService(CephadmService): class MonService(CephService): TYPE = 'mon' - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: """ Create a new monitor on the given host. """ @@ -473,7 +467,7 @@ class MonService(CephService): class MgrService(CephService): TYPE = 'mgr' - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: """ Create a new manager instance on a host. """ @@ -579,7 +573,7 @@ class MdsService(CephService): 'value': spec.service_id, }) - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type mds_id, _ = daemon_spec.daemon_id, daemon_spec.host @@ -684,7 +678,7 @@ class RgwService(CephService): spec.service_name(), spec.placement.pretty_str())) self.mgr.spec_store.save(spec) - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type rgw_id, _ = daemon_spec.daemon_id, daemon_spec.host @@ -838,7 +832,7 @@ class RgwService(CephService): class RbdMirrorService(CephService): TYPE = 'rbd-mirror' - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type daemon_id, _ = daemon_spec.daemon_id, daemon_spec.host @@ -859,7 +853,7 @@ class RbdMirrorService(CephService): class CrashService(CephService): TYPE = 'crash' - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type daemon_id, host = daemon_spec.daemon_id, daemon_spec.host @@ -960,7 +954,7 @@ class CephadmExporterConfig: class CephadmExporter(CephadmService): TYPE = 'cephadm-exporter' - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type cfg = CephadmExporterConfig(self.mgr) @@ -981,9 +975,8 @@ class CephadmExporter(CephadmService): return daemon_spec - def generate_config(self, daemon_spec: CephadmDaemonSpec) -> Tuple[Dict[str, Any], List[str]]: + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: assert self.TYPE == daemon_spec.daemon_type - assert daemon_spec.spec deps: List[str] = [] cfg = CephadmExporterConfig(self.mgr) diff --git a/src/pybind/mgr/cephadm/services/container.py b/src/pybind/mgr/cephadm/services/container.py index bd315779e52..b9cdfad5e76 100644 --- a/src/pybind/mgr/cephadm/services/container.py +++ b/src/pybind/mgr/cephadm/services/container.py @@ -1,11 +1,9 @@ import logging -from typing import List, Any, Tuple, Dict +from typing import List, Any, Tuple, Dict, cast from ceph.deployment.service_spec import CustomContainerSpec -from orchestrator import OrchestratorError - -from .cephadmservice import CephadmService, CephadmDaemonSpec +from .cephadmservice import CephadmService, CephadmDaemonDeploySpec logger = logging.getLogger(__name__) @@ -13,25 +11,17 @@ logger = logging.getLogger(__name__) class CustomContainerService(CephadmService): TYPE = 'container' - def prepare_create(self, daemon_spec: CephadmDaemonSpec[CustomContainerSpec]) \ - -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) \ + -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type - if daemon_spec.spec is None: - # Exit here immediately because the required service - # spec to create a daemon is not provided. This is only - # provided when a service is applied via 'orch apply' - # command. - msg = "Required service specification not provided" - raise OrchestratorError(msg) daemon_spec.final_config, daemon_spec.deps = self.generate_config(daemon_spec) return daemon_spec - def generate_config(self, daemon_spec: CephadmDaemonSpec[CustomContainerSpec]) \ + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) \ -> Tuple[Dict[str, Any], List[str]]: assert self.TYPE == daemon_spec.daemon_type - assert daemon_spec.spec deps: List[str] = [] - spec: CustomContainerSpec = daemon_spec.spec + spec = cast(CustomContainerSpec, self.mgr.spec_store[daemon_spec.service_name].spec) config: Dict[str, Any] = spec.config_json() logger.debug( 'Generated configuration for \'%s\' service: config-json=%s, dependencies=%s' % diff --git a/src/pybind/mgr/cephadm/services/ha_rgw.py b/src/pybind/mgr/cephadm/services/ha_rgw.py index 0a7bede49cd..9764c9b8184 100644 --- a/src/pybind/mgr/cephadm/services/ha_rgw.py +++ b/src/pybind/mgr/cephadm/services/ha_rgw.py @@ -3,7 +3,7 @@ from typing import List, cast, Tuple, Dict, Any from ceph.deployment.service_spec import HA_RGWSpec -from .cephadmservice import CephadmDaemonSpec, CephService +from .cephadmservice import CephadmDaemonDeploySpec, CephService from ..utils import resolve_ip logger = logging.getLogger(__name__) @@ -17,23 +17,14 @@ class HA_RGWService(CephService): self.name = hostname self.ip = address - def prepare_create(self, daemon_spec: CephadmDaemonSpec[HA_RGWSpec]) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert daemon_spec.daemon_type == 'haproxy' or daemon_spec.daemon_type == 'keepalived' - # if spec is not attached to daemon_spec it is likely a redeploy or reconfig and - # spec should be in spec store - if not daemon_spec.spec: - service_name: str = "ha-rgw." + daemon_spec.daemon_id.split('.')[0] - if service_name in self.mgr.spec_store: - daemon_spec.spec = cast( - HA_RGWSpec, self.mgr.spec_store[service_name].spec) - assert daemon_spec.spec - if daemon_spec.daemon_type == 'haproxy': return self.haproxy_prepare_create(daemon_spec) else: return self.keepalived_prepare_create(daemon_spec) - def generate_config(self, daemon_spec: CephadmDaemonSpec) -> Tuple[Dict[str, Any], List[str]]: + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: assert daemon_spec.daemon_type == 'haproxy' or daemon_spec.daemon_type == 'keepalived' if daemon_spec.daemon_type == 'haproxy': @@ -41,13 +32,12 @@ class HA_RGWService(CephService): else: return self.keepalived_generate_config(daemon_spec) - def haproxy_prepare_create(self, daemon_spec: CephadmDaemonSpec[HA_RGWSpec]) -> CephadmDaemonSpec: + def haproxy_prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert daemon_spec.daemon_type == 'haproxy' - assert daemon_spec.spec daemon_id = daemon_spec.daemon_id host = daemon_spec.host - spec = daemon_spec.spec + spec = cast(HA_RGWSpec, self.mgr.spec_store[daemon_spec.service_name].spec) logger.info('Create daemon %s on host %s with spec %s' % ( daemon_id, host, spec)) @@ -56,13 +46,12 @@ class HA_RGWService(CephService): return daemon_spec - def keepalived_prepare_create(self, daemon_spec: CephadmDaemonSpec[HA_RGWSpec]) -> CephadmDaemonSpec: + def keepalived_prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert daemon_spec.daemon_type == 'keepalived' - assert daemon_spec.spec daemon_id = daemon_spec.daemon_id host = daemon_spec.host - spec = daemon_spec.spec + spec = cast(HA_RGWSpec, self.mgr.spec_store[daemon_spec.service_name].spec) logger.info('Create daemon %s on host %s with spec %s' % ( daemon_id, host, spec)) @@ -71,20 +60,8 @@ class HA_RGWService(CephService): return daemon_spec - def haproxy_generate_config(self, daemon_spec: CephadmDaemonSpec) -> Tuple[Dict[str, Any], List[str]]: - daemon_id = daemon_spec.daemon_id - - service_name: str = "ha-rgw." + daemon_id.split('.')[0] - # if no service spec, return empty config - # TODO: fail, if we don't have any spec - if not daemon_spec.spec and service_name not in self.mgr.spec_store.all_specs: - config_files = {'files': {}} # type: Dict[str, Any] - return config_files, [] - elif daemon_spec.spec: - spec = daemon_spec.spec - else: - # service spec is not attached to daemon spec but is in spec store - spec = cast(HA_RGWSpec, self.mgr.spec_store.all_specs[service_name]) + def haproxy_generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: + spec = cast(HA_RGWSpec, self.mgr.spec_store[daemon_spec.service_name].spec) rgw_daemons = self.mgr.cache.get_daemons_by_type('rgw') rgw_servers = [] @@ -118,21 +95,10 @@ class HA_RGWService(CephService): return config_files, [] - def keepalived_generate_config(self, daemon_spec: CephadmDaemonSpec) -> Tuple[Dict[str, Any], List[str]]: - daemon_id = daemon_spec.daemon_id + def keepalived_generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: host = daemon_spec.host - service_name: str = "ha-rgw." + daemon_id.split('.')[0] - # if no service spec, return empty config - # TODO: In case of no spec, fail here - if not daemon_spec.spec and service_name not in self.mgr.spec_store.all_specs: - config_file = {'files': {}} # type: Dict[str, Any] - return config_file, [] - elif daemon_spec.spec: - spec = daemon_spec.spec - else: - # service spec is not attached to daemon spec but is in spec store - spec = cast(HA_RGWSpec, self.mgr.spec_store.all_specs[service_name]) + spec = cast(HA_RGWSpec, self.mgr.spec_store[daemon_spec.service_name].spec) all_hosts = [] for h, network, name in spec.definitive_host_list: diff --git a/src/pybind/mgr/cephadm/services/iscsi.py b/src/pybind/mgr/cephadm/services/iscsi.py index cf1e6932eb9..94e7741f884 100644 --- a/src/pybind/mgr/cephadm/services/iscsi.py +++ b/src/pybind/mgr/cephadm/services/iscsi.py @@ -5,7 +5,7 @@ from typing import List, cast from ceph.deployment.service_spec import IscsiServiceSpec from orchestrator import DaemonDescription -from .cephadmservice import CephadmDaemonSpec, CephService +from .cephadmservice import CephadmDaemonDeploySpec, CephService from .. import utils logger = logging.getLogger(__name__) @@ -19,23 +19,10 @@ class IscsiService(CephService): assert spec.pool self.mgr._check_pool_exists(spec.pool, spec.service_name()) - # TODO: remove this: - logger.info('Saving service %s spec with placement %s' % ( - spec.service_name(), spec.placement.pretty_str())) - self.mgr.spec_store.save(spec) - - def prepare_create(self, daemon_spec: CephadmDaemonSpec[IscsiServiceSpec]) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type - # if spec is not attached to daemon_spec it is likely a redeploy or reconfig and - # spec should be in spec store - if not daemon_spec.spec: - service_name: str = "iscsi." + daemon_spec.daemon_id.split('.')[0] - if service_name in self.mgr.spec_store: - daemon_spec.spec = cast( - IscsiServiceSpec, self.mgr.spec_store[service_name].spec) - assert daemon_spec.spec - - spec = daemon_spec.spec + + spec = cast(IscsiServiceSpec, self.mgr.spec_store[daemon_spec.service_name].spec) igw_id = daemon_spec.daemon_id ret, keyring, err = self.mgr.check_mon_command({ diff --git a/src/pybind/mgr/cephadm/services/monitoring.py b/src/pybind/mgr/cephadm/services/monitoring.py index 0dd8e58075a..aa18b04e13a 100644 --- a/src/pybind/mgr/cephadm/services/monitoring.py +++ b/src/pybind/mgr/cephadm/services/monitoring.py @@ -7,7 +7,7 @@ from mgr_module import HandleCommandResult from orchestrator import DaemonDescription from ceph.deployment.service_spec import AlertManagerSpec -from cephadm.services.cephadmservice import CephadmService, CephadmDaemonSpec +from cephadm.services.cephadmservice import CephadmService, CephadmDaemonDeploySpec from mgr_util import verify_tls, ServerConfigException, create_self_signed_cert logger = logging.getLogger(__name__) @@ -17,12 +17,12 @@ class GrafanaService(CephadmService): TYPE = 'grafana' DEFAULT_SERVICE_PORT = 3000 - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type daemon_spec.final_config, daemon_spec.deps = self.generate_config(daemon_spec) return daemon_spec - def generate_config(self, daemon_spec: CephadmDaemonSpec) -> Tuple[Dict[str, Any], List[str]]: + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: assert self.TYPE == daemon_spec.daemon_type deps = [] # type: List[str] @@ -95,29 +95,21 @@ class AlertmanagerService(CephadmService): TYPE = 'alertmanager' DEFAULT_SERVICE_PORT = 9093 - def prepare_create(self, daemon_spec: CephadmDaemonSpec[AlertManagerSpec]) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type - # if spec is not attached to daemon_spec it is likely a redeploy or reconfig and - # spec should be in spec store - if not daemon_spec.spec: - service_name: str = "alertmanager" - if service_name in self.mgr.spec_store: - daemon_spec.spec = cast( - AlertManagerSpec, self.mgr.spec_store[service_name].spec) - assert daemon_spec.spec daemon_spec.final_config, daemon_spec.deps = self.generate_config(daemon_spec) return daemon_spec - def generate_config(self, daemon_spec: CephadmDaemonSpec[AlertManagerSpec]) -> Tuple[Dict[str, Any], List[str]]: + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: assert self.TYPE == daemon_spec.daemon_type deps: List[str] = [] default_webhook_urls: List[str] = [] - if daemon_spec.spec: - user_data = daemon_spec.spec.user_data - if 'default_webhook_urls' in user_data and isinstance( - user_data['default_webhook_urls'], list): - default_webhook_urls.extend(user_data['default_webhook_urls']) + spec = cast(AlertManagerSpec, self.mgr.spec_store[daemon_spec.service_name].spec) + user_data = spec.user_data + if 'default_webhook_urls' in user_data and isinstance( + user_data['default_webhook_urls'], list): + default_webhook_urls.extend(user_data['default_webhook_urls']) # dashboard(s) dashboard_urls: List[str] = [] @@ -194,12 +186,12 @@ class PrometheusService(CephadmService): TYPE = 'prometheus' DEFAULT_SERVICE_PORT = 9095 - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type daemon_spec.final_config, daemon_spec.deps = self.generate_config(daemon_spec) return daemon_spec - def generate_config(self, daemon_spec: CephadmDaemonSpec) -> Tuple[Dict[str, Any], List[str]]: + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: assert self.TYPE == daemon_spec.daemon_type deps = [] # type: List[str] @@ -298,12 +290,12 @@ class PrometheusService(CephadmService): class NodeExporterService(CephadmService): TYPE = 'node-exporter' - def prepare_create(self, daemon_spec: CephadmDaemonSpec) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type daemon_spec.final_config, daemon_spec.deps = self.generate_config(daemon_spec) return daemon_spec - def generate_config(self, daemon_spec: CephadmDaemonSpec) -> Tuple[Dict[str, Any], List[str]]: + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: assert self.TYPE == daemon_spec.daemon_type return {}, [] diff --git a/src/pybind/mgr/cephadm/services/nfs.py b/src/pybind/mgr/cephadm/services/nfs.py index 9136b7ba918..b82c6e91277 100644 --- a/src/pybind/mgr/cephadm/services/nfs.py +++ b/src/pybind/mgr/cephadm/services/nfs.py @@ -6,7 +6,7 @@ import rados from orchestrator import DaemonDescription -from cephadm.services.cephadmservice import AuthEntity, CephadmDaemonSpec, CephService +from cephadm.services.cephadmservice import AuthEntity, CephadmDaemonDeploySpec, CephService logger = logging.getLogger(__name__) @@ -19,40 +19,18 @@ class NFSService(CephService): assert spec.pool self.mgr._check_pool_exists(spec.pool, spec.service_name()) - # TODO: Fail here, in case of no spec - logger.info('Saving service %s spec with placement %s' % ( - spec.service_name(), spec.placement.pretty_str())) - self.mgr.spec_store.save(spec) - - def prepare_create(self, daemon_spec: CephadmDaemonSpec[NFSServiceSpec]) -> CephadmDaemonSpec: + def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec: assert self.TYPE == daemon_spec.daemon_type - # if spec is not attached to daemon_spec it is likely a redeploy or reconfig and - # spec should be in spec store - if not daemon_spec.spec: - service_name: str = "nfs." + daemon_spec.daemon_id.split('.')[0] - if service_name in self.mgr.spec_store: - daemon_spec.spec = cast( - NFSServiceSpec, self.mgr.spec_store[service_name].spec) - assert daemon_spec.spec - - daemon_id = daemon_spec.daemon_id - host = daemon_spec.host - spec = daemon_spec.spec - daemon_spec.final_config, daemon_spec.deps = self.generate_config(daemon_spec) - - logger.info('Create daemon %s on host %s with spec %s' % ( - daemon_id, host, spec)) return daemon_spec - def generate_config(self, daemon_spec: CephadmDaemonSpec[NFSServiceSpec]) -> Tuple[Dict[str, Any], List[str]]: + def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: assert self.TYPE == daemon_spec.daemon_type - assert daemon_spec.spec daemon_type = daemon_spec.daemon_type daemon_id = daemon_spec.daemon_id host = daemon_spec.host - spec = daemon_spec.spec + spec = cast(NFSServiceSpec, self.mgr.spec_store[daemon_spec.service_name].spec) deps: List[str] = [] @@ -127,10 +105,9 @@ class NFSService(CephService): logger.info('Creating rados config object: %s' % obj) ioctx.write_full(obj, ''.encode('utf-8')) - def create_keyring(self, daemon_spec: CephadmDaemonSpec[NFSServiceSpec]) -> str: - assert daemon_spec.spec + def create_keyring(self, daemon_spec: CephadmDaemonDeploySpec) -> str: daemon_id = daemon_spec.daemon_id - spec = daemon_spec.spec + spec = cast(NFSServiceSpec, self.mgr.spec_store[daemon_spec.service_name].spec) entity: AuthEntity = self.get_auth_entity(daemon_id) osd_caps = 'allow rw pool=%s' % (spec.pool) @@ -147,7 +124,7 @@ class NFSService(CephService): return keyring - def create_rgw_keyring(self, daemon_spec: CephadmDaemonSpec[NFSServiceSpec]) -> str: + def create_rgw_keyring(self, daemon_spec: CephadmDaemonDeploySpec) -> str: daemon_id = daemon_spec.daemon_id entity: AuthEntity = self.get_auth_entity(f'{daemon_id}-rgw') diff --git a/src/pybind/mgr/cephadm/services/osd.py b/src/pybind/mgr/cephadm/services/osd.py index dc502243981..41b04febcd1 100644 --- a/src/pybind/mgr/cephadm/services/osd.py +++ b/src/pybind/mgr/cephadm/services/osd.py @@ -17,7 +17,7 @@ from ceph.utils import datetime_now from orchestrator import OrchestratorError from mgr_module import MonCommandFailed -from cephadm.services.cephadmservice import CephadmDaemonSpec, CephService +from cephadm.services.cephadmservice import CephadmDaemonDeploySpec, CephService if TYPE_CHECKING: from cephadm.module import CephadmOrchestrator @@ -121,7 +121,8 @@ class OSDService(CephService): continue created.append(osd_id) - daemon_spec: CephadmDaemonSpec = CephadmDaemonSpec( + daemon_spec: CephadmDaemonDeploySpec = CephadmDaemonDeploySpec( + service_name=drive_group.service_name(), daemon_id=osd_id, host=host, daemon_type='osd', diff --git a/src/pybind/mgr/cephadm/tests/test_services.py b/src/pybind/mgr/cephadm/tests/test_services.py index 06a34498c0b..916859b6385 100644 --- a/src/pybind/mgr/cephadm/tests/test_services.py +++ b/src/pybind/mgr/cephadm/tests/test_services.py @@ -3,7 +3,7 @@ import pytest from unittest.mock import MagicMock, call from cephadm.services.cephadmservice import MonService, MgrService, MdsService, RgwService, \ - RbdMirrorService, CrashService, CephadmExporter, CephadmDaemonSpec + RbdMirrorService, CrashService, CephadmExporter, CephadmDaemonDeploySpec from cephadm.services.iscsi import IscsiService from cephadm.services.nfs import NFSService from cephadm.services.osd import OSDService @@ -92,7 +92,11 @@ class TestCephadmService: iscsi_spec.spec.daemon_type = "iscsi" iscsi_spec.spec.ssl_cert = '' - iscsi_daemon_spec = CephadmDaemonSpec(host='host', daemon_id='a', spec=iscsi_spec) + mgr.spec_store = MagicMock() + mgr.spec_store.__getitem__.return_value = iscsi_spec + + iscsi_daemon_spec = CephadmDaemonDeploySpec( + host='host', daemon_id='a', service_name=iscsi_spec.service_name()) iscsi_service.prepare_create(iscsi_daemon_spec) -- 2.39.5