]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm: remove spec from CephadmDaemonDeploySpec
authorSebastian Wagner <sebastian.wagner@suse.com>
Tue, 16 Feb 2021 15:54:11 +0000 (16:54 +0100)
committerSebastian Wagner <sebastian.wagner@suse.com>
Tue, 9 Mar 2021 09:18:50 +0000 (10:18 +0100)
Signed-off-by: Sebastian Wagner <sebastian.wagner@suse.com>
(cherry picked from commit d8bcaac10a1a7cdc8689375f37f5d59d86148314)

src/pybind/mgr/cephadm/module.py
src/pybind/mgr/cephadm/serve.py
src/pybind/mgr/cephadm/services/cephadmservice.py
src/pybind/mgr/cephadm/services/container.py
src/pybind/mgr/cephadm/services/ha_rgw.py
src/pybind/mgr/cephadm/services/iscsi.py
src/pybind/mgr/cephadm/services/monitoring.py
src/pybind/mgr/cephadm/services/nfs.py
src/pybind/mgr/cephadm/services/osd.py
src/pybind/mgr/cephadm/tests/test_services.py

index a48e237c994ee1afbfcb882d19a926c49dfe1069..4085f6542d934dfed27ce6c641994c40d1ba998a 100644 (file)
@@ -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
@@ -1599,10 +1599,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)
@@ -1901,7 +1907,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.
@@ -1926,7 +1932,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))
@@ -1934,7 +1940,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,
@@ -1958,7 +1964,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)
index 9fb9ffc324eedd2d5b8085284628f183aa84e36d..d253f5e67eabbd8ed1769b0d5ae00df3e0a27b1a 100644 (file)
@@ -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
@@ -730,7 +730,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:
@@ -747,18 +747,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)
@@ -773,12 +763,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
 
index 8d35483c6d26c68f0deade2e5f369ee25c2723e4..a676728ab5de2282c240f6f9555640196277c87e 100644 (file)
@@ -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)
index bd315779e52b9f1fd2b413c6236079006d88b55e..b9cdfad5e760e73f7e35d189ad778d900c80acb4 100644 (file)
@@ -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' %
index 0a7bede49cd7db0b50f5ff07673484f1f5253db3..9764c9b818461162d11ca36c68cd6787f7138f1c 100644 (file)
@@ -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:
index cf1e6932eb92a851dd87990d6806c4948b800517..94e7741f8841b70a9cf813aaa7026b4970a11c05 100644 (file)
@@ -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({
index 0dd8e58075a30a627b896dfb58ebb9a26d3d58da..aa18b04e13af1c572791cdcecf7072a26acf6623 100644 (file)
@@ -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 {}, []
 
index 9136b7ba9187c72986e456c557d56bc91589d833..b82c6e91277186f7ff324e8076735887e3a6c56c 100644 (file)
@@ -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')
 
index dc502243981cb7ee1742fd734b977c506be6051f..41b04febcd1cca16625274d48001d49e4318c2a9 100644 (file)
@@ -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',
index 06a34498c0b513cb482e5e4efebb3242ae0b1957..916859b63858b6cdf689ba7a55e6be5836132578 100644 (file)
@@ -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)