From: Sebastian Wagner Date: Tue, 9 Jun 2020 12:36:38 +0000 (+0200) Subject: mgr/cephadm: move ok_to_stop to CephadmService X-Git-Tag: v15.2.5~147^2~24 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=844c8a272037c5e6a2505f7a2a7639a4c0584616;p=ceph.git mgr/cephadm: move ok_to_stop to CephadmService Signed-off-by: Sebastian Wagner (cherry picked from commit 2b41d0a470c91d4395a2af4ee88b2f26253791ca) --- diff --git a/src/pybind/mgr/cephadm/services/cephadmservice.py b/src/pybind/mgr/cephadm/services/cephadmservice.py index d66b3df83ea..b7571ae6f5d 100644 --- a/src/pybind/mgr/cephadm/services/cephadmservice.py +++ b/src/pybind/mgr/cephadm/services/cephadmservice.py @@ -1,4 +1,5 @@ import logging +from abc import ABCMeta, abstractmethod from typing import TYPE_CHECKING, List, Callable, Any from mgr_module import MonCommandFailed @@ -13,10 +14,16 @@ if TYPE_CHECKING: logger = logging.getLogger(__name__) -class CephadmService: +class CephadmService(metaclass=ABCMeta): """ Base class for service types. Often providing a create() and config() fn. """ + + @property + @abstractmethod + def TYPE(self): + pass + def __init__(self, mgr: "CephadmOrchestrator"): self.mgr: "CephadmOrchestrator" = mgr @@ -113,7 +120,29 @@ class CephadmService: logger.warning('Failed to set Dashboard config for %s: %s', service_name, e) + + def ok_to_stop(self, daemon_ids: List[str]) -> bool: + names = [f'{self.TYPE}.{d_id}' for d_id in daemon_ids] + + if self.TYPE not in ['mon', 'osd', 'mds']: + logger.info('Upgrade: It is presumed safe to stop %s' % names) + return True + + ret, out, err = self.mgr.mon_command({ + 'prefix': f'{self.TYPE} ok-to-stop', + 'ids': daemon_ids, + }) + + if ret: + logger.info(f'It is NOT safe to stop {names}: {err}') + return False + + return True + + class MonService(CephadmService): + TYPE = 'mon' + def create(self, name, host, network): """ Create a new monitor on the given host. @@ -155,6 +184,8 @@ class MonService(CephadmService): class MgrService(CephadmService): + TYPE = 'mgr' + def create(self, mgr_id, host): """ Create a new manager instance on a host. @@ -172,6 +203,8 @@ class MgrService(CephadmService): class MdsService(CephadmService): + TYPE = 'mds' + def config(self, spec: ServiceSpec): # ensure mds_join_fs is set for these daemons assert spec.service_id @@ -195,6 +228,8 @@ class MdsService(CephadmService): class RgwService(CephadmService): + TYPE = 'rgw' + def config(self, spec: RGWSpec): # ensure rgw_realm and rgw_zone is set for these daemons ret, out, err = self.mgr.check_mon_command({ @@ -262,6 +297,8 @@ class RgwService(CephadmService): class RbdMirrorService(CephadmService): + TYPE = 'rbd-mirror' + def create(self, daemon_id, host) -> str: ret, keyring, err = self.mgr.check_mon_command({ 'prefix': 'auth get-or-create', @@ -274,6 +311,8 @@ class RbdMirrorService(CephadmService): class CrashService(CephadmService): + TYPE = 'crash' + def create(self, daemon_id, host) -> str: ret, keyring, err = self.mgr.check_mon_command({ 'prefix': 'auth get-or-create', diff --git a/src/pybind/mgr/cephadm/services/iscsi.py b/src/pybind/mgr/cephadm/services/iscsi.py index 5e63c4788bf..89939ce31f0 100644 --- a/src/pybind/mgr/cephadm/services/iscsi.py +++ b/src/pybind/mgr/cephadm/services/iscsi.py @@ -13,6 +13,8 @@ logger = logging.getLogger(__name__) class IscsiService(CephadmService): + TYPE = 'iscsi' + def config(self, spec: IscsiServiceSpec): self.mgr._check_pool_exists(spec.pool, spec.service_name()) diff --git a/src/pybind/mgr/cephadm/services/monitoring.py b/src/pybind/mgr/cephadm/services/monitoring.py index 47fa90deb19..e9efabcf8e9 100644 --- a/src/pybind/mgr/cephadm/services/monitoring.py +++ b/src/pybind/mgr/cephadm/services/monitoring.py @@ -9,6 +9,7 @@ from mgr_util import verify_tls, ServerConfigException, create_self_signed_cert logger = logging.getLogger(__name__) class GrafanaService(CephadmService): + TYPE = 'grafana' DEFAULT_SERVICE_PORT = 3000 def create(self, daemon_id, host): @@ -73,6 +74,7 @@ class GrafanaService(CephadmService): ) class AlertmanagerService(CephadmService): + TYPE = 'alertmanager' DEFAULT_SERVICE_PORT = 9093 def create(self, daemon_id, host) -> str: @@ -140,6 +142,7 @@ class AlertmanagerService(CephadmService): class PrometheusService(CephadmService): + TYPE = 'prometheus' DEFAULT_SERVICE_PORT = 9095 def create(self, daemon_id, host) -> str: @@ -228,6 +231,8 @@ class PrometheusService(CephadmService): ) class NodeExporterService(CephadmService): + TYPE = 'node-exporter' + def create(self, daemon_id, host) -> str: return self.mgr._create_daemon('node-exporter', daemon_id, host) diff --git a/src/pybind/mgr/cephadm/services/nfs.py b/src/pybind/mgr/cephadm/services/nfs.py index e3f3aa4335b..98e0eb04544 100644 --- a/src/pybind/mgr/cephadm/services/nfs.py +++ b/src/pybind/mgr/cephadm/services/nfs.py @@ -17,6 +17,8 @@ logger = logging.getLogger(__name__) class NFSService(CephadmService): + TYPE = 'nfs' + def _generate_nfs_config(self, daemon_type, daemon_id, host): # type: (str, str, str) -> Tuple[Dict[str, Any], List[str]] deps = [] # type: List[str] diff --git a/src/pybind/mgr/cephadm/services/osd.py b/src/pybind/mgr/cephadm/services/osd.py index 1e6db9b0da9..470c0cfbf13 100644 --- a/src/pybind/mgr/cephadm/services/osd.py +++ b/src/pybind/mgr/cephadm/services/osd.py @@ -18,6 +18,8 @@ logger = logging.getLogger(__name__) class OSDService(CephadmService): + TYPE = 'osd' + def create(self, drive_group: DriveGroupSpec) -> str: logger.debug(f"Processing DriveGroup {drive_group}") ret = [] diff --git a/src/pybind/mgr/cephadm/tests/test_services.py b/src/pybind/mgr/cephadm/tests/test_services.py index de0f9ea059c..9857e6fe4dc 100644 --- a/src/pybind/mgr/cephadm/tests/test_services.py +++ b/src/pybind/mgr/cephadm/tests/test_services.py @@ -1,6 +1,6 @@ from unittest.mock import MagicMock -from cephadm.services.cephadmservice import CephadmService +from cephadm.services.monitoring import GrafanaService class FakeMgr: @@ -23,7 +23,7 @@ class TestCephadmService: # pylint: disable=protected-access mgr = FakeMgr() service_url = 'http://svc:1000' - service = CephadmService(mgr) + service = GrafanaService(mgr) service._set_service_url_on_dashboard('svc', 'get-cmd', 'set-cmd', service_url) assert mgr.config == service_url diff --git a/src/pybind/mgr/cephadm/upgrade.py b/src/pybind/mgr/cephadm/upgrade.py index cdf432b62c5..7e5445204d8 100644 --- a/src/pybind/mgr/cephadm/upgrade.py +++ b/src/pybind/mgr/cephadm/upgrade.py @@ -6,7 +6,7 @@ from typing import TYPE_CHECKING, Optional import orchestrator from cephadm.utils import name_to_config_section -from orchestrator import OrchestratorError +from orchestrator import OrchestratorError, DaemonDescription if TYPE_CHECKING: from .module import CephadmOrchestrator @@ -119,29 +119,23 @@ class CephadmUpgrade: return True return False - def _wait_for_ok_to_stop(self, s) -> bool: + def _wait_for_ok_to_stop(self, s: DaemonDescription) -> bool: # only wait a little bit; the service might go away for something tries = 4 while tries > 0: - if s.daemon_type not in ['mon', 'osd', 'mds']: - logger.info('Upgrade: It is presumed safe to stop %s.%s' % - (s.daemon_type, s.daemon_id)) - return True - ret, out, err = self.mgr.mon_command({ - 'prefix': '%s ok-to-stop' % s.daemon_type, - 'ids': [s.daemon_id], - }) if not self.upgrade_state or self.upgrade_state.get('paused'): return False - if ret: - logger.info('Upgrade: It is NOT safe to stop %s.%s' % - (s.daemon_type, s.daemon_id)) - time.sleep(15) - tries -= 1 - else: - logger.info('Upgrade: It is safe to stop %s.%s' % + + ok = self.mgr.cephadm_services[s.daemon_type].ok_to_stop([s.daemon_id]) + + if ok: + logger.info('Upgrade: It is presumed safe to stop %s.%s' % (s.daemon_type, s.daemon_id)) return True + logger.info('Upgrade: It is NOT safe to stop %s.%s' % + (s.daemon_type, s.daemon_id)) + time.sleep(15) + tries -= 1 return False def _clear_upgrade_health_checks(self) -> None: