]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mgr/cephadm: Add CephadmDaemonSpec class
authorSebastian Wagner <sebastian.wagner@suse.com>
Mon, 8 Jun 2020 07:36:20 +0000 (09:36 +0200)
committerSebastian Wagner <sebastian.wagner@suse.com>
Wed, 15 Jul 2020 08:15:15 +0000 (10:15 +0200)
Signed-off-by: Sebastian Wagner <sebastian.wagner@suse.com>
src/pybind/mgr/cephadm/module.py
src/pybind/mgr/cephadm/services/cephadmservice.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

index 0f1ca5a2660608489b56eae36de8a4f8ab953327..4cd880059a70c8f238c27493413fd64ce2fcd7c7 100644 (file)
@@ -24,6 +24,7 @@ from ceph.deployment import inventory
 from ceph.deployment.drive_group import DriveGroupSpec
 from ceph.deployment.service_spec import \
     NFSServiceSpec, ServiceSpec, PlacementSpec, assert_valid_host
+from cephadm.services.cephadmservice import CephadmDaemonSpec
 
 from mgr_module import MgrModule, HandleCommandResult
 import orchestrator
@@ -1646,7 +1647,7 @@ you may want to run:
 
     @trivial_completion
     def create_osds(self, drive_group: DriveGroupSpec):
-        return self.osd_service.create(drive_group)
+        return self.osd_service.create_from_spec(drive_group)
 
     @trivial_completion
     def preview_osdspecs(self,
@@ -1814,28 +1815,6 @@ you may want to run:
         self.cache.invalidate_host_daemons(host)
         return "Removed {} from host '{}'".format(name, host)
 
-    def _create_fn(self, service_type: str) -> Callable[..., str]:
-        try:
-            d: Dict[str, function] = {
-                'mon': self.mon_service.create,
-                'mgr': self.mgr_service.create,
-                'osd': self.osd_service.create,
-                'mds': self.mds_service.create,
-                'rgw': self.rgw_service.create,
-                'rbd-mirror': self.rbd_mirror_service.create,
-                'nfs': self.nfs_service.create,
-                'grafana': self.grafana_service.create,
-                'alertmanager': self.alertmanager_service.create,
-                'prometheus': self.prometheus_service.create,
-                'node-exporter': self.node_exporter_service.create,
-                'crash': self.crash_service.create,
-                'iscsi': self.iscsi_service.create,
-            }
-            return d[service_type]  # type: ignore
-        except KeyError:
-            self.log.exception(f'unknown service type {service_type}')
-            raise OrchestratorError(f'unknown service type {service_type}') from e
-
     def _config_fn(self, service_type) -> Optional[Callable[[ServiceSpec], None]]:
         return {
             'mds': self.mds_service.config,
@@ -1856,11 +1835,10 @@ you may want to run:
             return False
         self.log.debug('Applying service %s spec' % service_name)
 
-        create_func = self._create_fn(daemon_type)
         config_func = self._config_fn(daemon_type)
 
         if daemon_type == 'osd':
-            create_func(spec)
+            self.osd_service.create_from_spec(cast(DriveGroupSpec, spec))
             # TODO: return True would result in a busy loop
             return False
 
@@ -1918,14 +1896,11 @@ you may want to run:
             daemon_id = self.get_unique_name(daemon_type, host, daemons,
                                              prefix=spec.service_id,
                                              forcename=name)
+            daemon_spec = self.cephadm_services[daemon_type].make_daemon_spec(host, daemon_id, network, spec)
             self.log.debug('Placing %s.%s on host %s' % (
                 daemon_type, daemon_id, host))
-            if daemon_type == 'mon':
-                create_func(daemon_id, host, network)  # type: ignore
-            elif daemon_type in ['nfs', 'iscsi']:
-                create_func(daemon_id, host, spec)  # type: ignore
-            else:
-                create_func(daemon_id, host)  # type: ignore
+
+            self.cephadm_services[daemon_type].create(daemon_spec)
 
             # add to daemon list so next name(s) will also be unique
             sd = orchestrator.DaemonDescription(
@@ -2052,19 +2027,15 @@ you may want to run:
         if config_func:
             config_func(spec)
 
-        args = []  # type: List[tuple]
+        args = []  # type: List[CephadmDaemonSpec]
         for host, network, name in hosts:
             daemon_id = self.get_unique_name(daemon_type, host, daemons,
                                              prefix=spec.service_id,
                                              forcename=name)
+            daemon_spec = self.cephadm_services[daemon_type].make_daemon_spec(host, daemon_id, network, spec)
             self.log.debug('Placing %s.%s on host %s' % (
                 daemon_type, daemon_id, host))
-            if daemon_type == 'mon':
-                args.append((daemon_id, host, network))  # type: ignore
-            elif daemon_type in ['nfs', 'iscsi']:
-                args.append((daemon_id, host, spec))  # type: ignore
-            else:
-                args.append((daemon_id, host))  # type: ignore
+            args.append(daemon_spec)
 
             # add to daemon list so next name(s) will also be unique
             sd = orchestrator.DaemonDescription(
index 61f9a8983c02a9156abe7b96c0af6075d13d244d..f3f4695acee8b26a74e74b34b925e9ecc84b4437 100644 (file)
@@ -1,7 +1,7 @@
 import json
 import logging
 from abc import ABCMeta, abstractmethod
-from typing import TYPE_CHECKING, List, Callable, Any
+from typing import TYPE_CHECKING, List, Callable, Any, TypeVar, Generic
 
 from mgr_module import MonCommandFailed
 
@@ -14,6 +14,16 @@ if TYPE_CHECKING:
 
 logger = logging.getLogger(__name__)
 
+ServiceSpecs = TypeVar('ServiceSpecs', bound=ServiceSpec)
+
+
+class CephadmDaemonSpec(Generic[ServiceSpecs]):
+    # typing.NamedTuple + Generic is broken in py36
+    def __init__(self, host, daemon_id, spec: ServiceSpecs, network):
+        self.host = host
+        self.daemon_id = daemon_id
+        self.spec: ServiceSpecs = spec
+        self.network = network  # mons
 
 class CephadmService(metaclass=ABCMeta):
     """
@@ -28,6 +38,17 @@ class CephadmService(metaclass=ABCMeta):
     def __init__(self, mgr: "CephadmOrchestrator"):
         self.mgr: "CephadmOrchestrator" = mgr
 
+    def make_daemon_spec(self, host, daemon_id, netowrk, spec: ServiceSpecs) -> CephadmDaemonSpec:
+        return CephadmDaemonSpec(
+            host=host,
+            daemon_id=daemon_id,
+            spec=spec,
+            network=netowrk
+        )
+
+    def create(self, daemon_spec: CephadmDaemonSpec):
+        raise NotImplementedError()
+
     def daemon_check_post(self, daemon_descrs: List[DaemonDescription]):
         """The post actions needed to be done after daemons are checked"""
         if self.mgr.config_dashboard:
@@ -149,10 +170,12 @@ class CephadmService(metaclass=ABCMeta):
 class MonService(CephadmService):
     TYPE = 'mon'
 
-    def create(self, name, host, network):
+    def create(self, daemon_spec: CephadmDaemonSpec):
         """
         Create a new monitor on the given host.
         """
+        name, host, network = daemon_spec.daemon_id, daemon_spec.host, daemon_spec.network
+
         # get mon. key
         ret, keyring, err = self.mgr.check_mon_command({
             'prefix': 'auth get',
@@ -225,10 +248,11 @@ class MonService(CephadmService):
 class MgrService(CephadmService):
     TYPE = 'mgr'
 
-    def create(self, mgr_id, host):
+    def create(self, daemon_spec: CephadmDaemonSpec):
         """
         Create a new manager instance on a host.
         """
+        mgr_id, host = daemon_spec.daemon_id, daemon_spec.host
         # get mgr. key
         ret, keyring, err = self.mgr.check_mon_command({
             'prefix': 'auth get-or-create',
@@ -254,7 +278,9 @@ class MdsService(CephadmService):
             'value': spec.service_id,
         })
 
-    def create(self, mds_id, host) -> str:
+    def create(self, daemon_spec: CephadmDaemonSpec):
+        mds_id, host = daemon_spec.daemon_id, daemon_spec.host
+
         # get mgr. key
         ret, keyring, err = self.mgr.check_mon_command({
             'prefix': 'auth get-or-create',
@@ -324,7 +350,8 @@ class RgwService(CephadmService):
             spec.service_name(), spec.placement.pretty_str()))
         self.mgr.spec_store.save(spec)
 
-    def create(self, rgw_id, host) -> str:
+    def create(self, daemon_spec: CephadmDaemonSpec):
+        rgw_id, host = daemon_spec.daemon_id, daemon_spec.host
         ret, keyring, err = self.mgr.check_mon_command({
             'prefix': 'auth get-or-create',
             'entity': f"{utils.name_to_config_section('rgw')}.{rgw_id}",
@@ -338,7 +365,9 @@ class RgwService(CephadmService):
 class RbdMirrorService(CephadmService):
     TYPE = 'rbd-mirror'
 
-    def create(self, daemon_id, host) -> str:
+    def create(self, daemon_spec: CephadmDaemonSpec):
+        daemon_id, host = daemon_spec.daemon_id, daemon_spec.host
+
         ret, keyring, err = self.mgr.check_mon_command({
             'prefix': 'auth get-or-create',
             'entity': 'client.rbd-mirror.' + daemon_id,
@@ -352,7 +381,9 @@ class RbdMirrorService(CephadmService):
 class CrashService(CephadmService):
     TYPE = 'crash'
 
-    def create(self, daemon_id, host) -> str:
+    def create(self, daemon_spec: CephadmDaemonSpec):
+        daemon_id, host = daemon_spec.daemon_id, daemon_spec.host
+
         ret, keyring, err = self.mgr.check_mon_command({
             'prefix': 'auth get-or-create',
             'entity': 'client.crash.' + host,
index 08db11590dbb3cace7227e5e92d107840fe724e9..a6c997f886cddf7d89c7b8e9e312566b49269032 100644 (file)
@@ -6,7 +6,7 @@ from mgr_module import MonCommandFailed
 from ceph.deployment.service_spec import IscsiServiceSpec
 
 from orchestrator import DaemonDescription
-from .cephadmservice import CephadmService
+from .cephadmservice import CephadmService, CephadmDaemonSpec
 from .. import utils
 
 logger = logging.getLogger(__name__)
@@ -22,7 +22,10 @@ class IscsiService(CephadmService):
             spec.service_name(), spec.placement.pretty_str()))
         self.mgr.spec_store.save(spec)
 
-    def create(self, igw_id, host, spec) -> str:
+    def create(self, daemon_spec: CephadmDaemonSpec[IscsiServiceSpec]) -> str:
+        spec = daemon_spec.spec
+        igw_id = daemon_spec.daemon_id
+        host = daemon_spec.host
         ret, keyring, err = self.mgr.check_mon_command({
             'prefix': 'auth get-or-create',
             'entity': utils.name_to_auth_entity('iscsi', igw_id),
index e9efabcf8e9546e1229f7e7668bb98a278286079..9de48b31326e02233e7312afc00310d1f5f1b3d3 100644 (file)
@@ -3,7 +3,7 @@ import os
 from typing import List, Any, Tuple, Dict
 
 from orchestrator import DaemonDescription
-from cephadm.services.cephadmservice import CephadmService
+from cephadm.services.cephadmservice import CephadmService, CephadmDaemonSpec
 from mgr_util import verify_tls, ServerConfigException, create_self_signed_cert
 
 logger = logging.getLogger(__name__)
@@ -12,8 +12,9 @@ class GrafanaService(CephadmService):
     TYPE = 'grafana'
     DEFAULT_SERVICE_PORT = 3000
 
-    def create(self, daemon_id, host):
-        # type: (str, str) -> str
+    def create(self, daemon_spec: CephadmDaemonSpec):
+        daemon_id, host = daemon_spec.daemon_id, daemon_spec.host
+
         return self.mgr._create_daemon('grafana', daemon_id, host)
 
     def generate_config(self):
@@ -77,7 +78,9 @@ class AlertmanagerService(CephadmService):
     TYPE = 'alertmanager'
     DEFAULT_SERVICE_PORT = 9093
 
-    def create(self, daemon_id, host) -> str:
+    def create(self, daemon_spec: CephadmDaemonSpec):
+        daemon_id, host = daemon_spec.daemon_id, daemon_spec.host
+
         return self.mgr._create_daemon('alertmanager', daemon_id, host)
 
     def generate_config(self):
@@ -145,7 +148,9 @@ class PrometheusService(CephadmService):
     TYPE = 'prometheus'
     DEFAULT_SERVICE_PORT = 9095
 
-    def create(self, daemon_id, host) -> str:
+    def create(self, daemon_spec: CephadmDaemonSpec):
+        daemon_id, host = daemon_spec.daemon_id, daemon_spec.host
+
         return self.mgr._create_daemon('prometheus', daemon_id, host)
 
     def generate_config(self):
@@ -233,7 +238,9 @@ class PrometheusService(CephadmService):
 class NodeExporterService(CephadmService):
     TYPE = 'node-exporter'
 
-    def create(self, daemon_id, host) -> str:
+    def create(self, daemon_spec: CephadmDaemonSpec):
+        daemon_id, host = daemon_spec.daemon_id, daemon_spec.host
+
         return self.mgr._create_daemon('node-exporter', daemon_id, host)
 
     def generate_config(self) -> Tuple[Dict[str, Any], List[str]]:
index 05d0199a18e69f10c271c3aba0855dea016d3d06..f46b823a451d07703219d88d0b6e63c139445e93 100644 (file)
@@ -12,7 +12,8 @@ from orchestrator import DaemonDescription
 import cephadm
 from .. import utils
 
-from .cephadmservice import CephadmService
+from .cephadmservice import CephadmService, CephadmDaemonSpec
+
 logger = logging.getLogger(__name__)
 
 
@@ -68,10 +69,10 @@ class NFSService(CephadmService):
             spec.service_name(), spec.placement.pretty_str()))
         self.mgr.spec_store.save(spec)
 
-    def create(self, daemon_id, host, spec):
+    def create(self, daemon_spec: CephadmDaemonSpec[NFSServiceSpec]):
         logger.info('Create daemon %s on host %s with spec %s' % (
             daemon_id, host, spec))
-        return self.mgr._create_daemon('nfs', daemon_id, host)
+        return self.mgr._create_daemon('nfs', daemon_spec.daemon_id, daemon_spec.host)
 
     def config_dashboard(self, daemon_descrs: List[DaemonDescription]):
         
index 65b352ad7a20f69646127b96f05ea4eca87b303f..f565896279e8b8d497df14c685c352e137947d2f 100644 (file)
@@ -20,7 +20,7 @@ logger = logging.getLogger(__name__)
 class OSDService(CephadmService):
     TYPE = 'osd'
 
-    def create(self, drive_group: DriveGroupSpec) -> str:
+    def create_from_spec(self, drive_group: DriveGroupSpec) -> str:
         logger.debug(f"Processing DriveGroup {drive_group}")
         ret = []
         osd_id_claims = self.find_destroyed_osds()