From 7bc22f61cd69dcb5e7ee2aaa275f9f8cef3b3b26 Mon Sep 17 00:00:00 2001 From: Sebastian Wagner Date: Mon, 8 Jun 2020 09:36:20 +0200 Subject: [PATCH] mgr/cephadm: Add CephadmDaemonSpec class Signed-off-by: Sebastian Wagner --- src/pybind/mgr/cephadm/module.py | 47 ++++--------------- .../mgr/cephadm/services/cephadmservice.py | 45 +++++++++++++++--- src/pybind/mgr/cephadm/services/iscsi.py | 7 ++- src/pybind/mgr/cephadm/services/monitoring.py | 19 +++++--- src/pybind/mgr/cephadm/services/nfs.py | 7 +-- src/pybind/mgr/cephadm/services/osd.py | 2 +- 6 files changed, 70 insertions(+), 57 deletions(-) diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index 0f1ca5a2660..4cd880059a7 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -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( diff --git a/src/pybind/mgr/cephadm/services/cephadmservice.py b/src/pybind/mgr/cephadm/services/cephadmservice.py index 61f9a8983c0..f3f4695acee 100644 --- a/src/pybind/mgr/cephadm/services/cephadmservice.py +++ b/src/pybind/mgr/cephadm/services/cephadmservice.py @@ -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, diff --git a/src/pybind/mgr/cephadm/services/iscsi.py b/src/pybind/mgr/cephadm/services/iscsi.py index 08db11590db..a6c997f886c 100644 --- a/src/pybind/mgr/cephadm/services/iscsi.py +++ b/src/pybind/mgr/cephadm/services/iscsi.py @@ -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), diff --git a/src/pybind/mgr/cephadm/services/monitoring.py b/src/pybind/mgr/cephadm/services/monitoring.py index e9efabcf8e9..9de48b31326 100644 --- a/src/pybind/mgr/cephadm/services/monitoring.py +++ b/src/pybind/mgr/cephadm/services/monitoring.py @@ -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]]: diff --git a/src/pybind/mgr/cephadm/services/nfs.py b/src/pybind/mgr/cephadm/services/nfs.py index 05d0199a18e..f46b823a451 100644 --- a/src/pybind/mgr/cephadm/services/nfs.py +++ b/src/pybind/mgr/cephadm/services/nfs.py @@ -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]): diff --git a/src/pybind/mgr/cephadm/services/osd.py b/src/pybind/mgr/cephadm/services/osd.py index 65b352ad7a2..f565896279e 100644 --- a/src/pybind/mgr/cephadm/services/osd.py +++ b/src/pybind/mgr/cephadm/services/osd.py @@ -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() -- 2.39.5