)
parser_deploy.add_argument(
'--send-signal-to-daemon',
- action='store_true',
- default=False,
+ type=str,
+ default=None,
help='Send signal to daemon'
)
else:
# method uses new action enum type
_scheduled_action = utils.Action.create(scheduled_action)
- _action = svc_obj.choose_next_action(
+ _step = svc_obj.choose_next_action(
_scheduled_action,
dd.daemon_type,
spec,
curr_deps=deps,
last_deps=last_deps,
)
- if _action is not _scheduled_action:
+ if _step.action is not _scheduled_action:
self.log.info(
(
'Daemon %s chose new action %s (was %s)'
' (deps: %r, last_deps: %r)'
),
dd.name(),
- _action,
+ _step.action,
_scheduled_action,
deps,
last_deps,
)
# convert back to legacy str type
- action = str(_action)
+ action = str(_step.action)
+ skip_restart_for_reconfig = _step.skip_restart_for_reconfig
+ send_signal_to_daemon = _step.send_signal_to_daemon
action = _ceph_service_next_action(
action, dd.daemon_type, dd.name(), self.mgr, last_config
)
action = 'redeploy'
try:
daemon_spec = CephadmDaemonDeploySpec.from_daemon_description(dd)
- self.mgr._daemon_action(daemon_spec, action=action,
- skip_restart_for_reconfig=skip_restart_for_reconfig,
- send_signal_to_daemon=send_signal_to_daemon)
+ reconfig_extras: dict[str, Any] = {}
+ if skip_restart_for_reconfig:
+ reconfig_extras['skip_restart_for_reconfig'] = True
+ if send_signal_to_daemon:
+ reconfig_extras['send_signal_to_daemon'] = send_signal_to_daemon
+ self.mgr._daemon_action(daemon_spec, action=action, **reconfig_extras)
+
if self.mgr.cache.rm_scheduled_daemon_action(dd.hostname, dd.name()):
self.mgr.cache.save_host(dd.hostname)
except OrchestratorError as e:
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
- ) -> utils.Action:
+ ) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
this service would prefer cephadm take.
"""
if curr_deps == last_deps:
- return scheduled_action
+ return utils.NextDaemonStep(scheduled_action)
sym_diff = set(curr_deps).symmetric_difference(last_deps)
logger.info(
'Reconfigure wanted %s: deps %r -> %r (diff %r)',
curr_deps,
sym_diff,
)
- return utils.Action.RECONFIG
+ return utils.NextDaemonStep(utils.Action.RECONFIG)
class CephService(CephadmService):
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
- ) -> utils.Action:
+ ) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
this service would prefer cephadm take.
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
-) -> utils.Action:
+) -> utils.NextDaemonStep:
"""This function exists to help refactor existing code to use
choose_next_action instead of if-blocks inside serve.py.
It avoids the need to muck around with common base classes at the
Call this from choose_next_action.
"""
if curr_deps == last_deps:
- return scheduled_action
+ return utils.NextDaemonStep(scheduled_action)
sym_diff = set(curr_deps).symmetric_difference(last_deps)
logger.info(
'Reconfigure wanted %s: deps %r -> %r (diff %r)',
# If so we ought to be able to vastly simplify this...
if any(svc in e for e in sym_diff for svc in REDEPLOY_TRIGGERS):
action = utils.Action.REDEPLOY
- return action
+ return utils.NextDaemonStep(action)
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
- ) -> utils.Action:
+ ) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
this service would prefer cephadm take.
"""
- action = super().choose_next_action(
+ step = super().choose_next_action(
scheduled_action, daemon_type, spec, curr_deps, last_deps
)
+ action = step.action
if (
action is not utils.Action.REDEPLOY
and daemon_type == 'haproxy'
and hasattr(spec, 'backend_service')
):
backend_spec = self.mgr.spec_store[spec.backend_service].spec
- if (
- backend_spec.service_type == 'nfs'
- and self.has_placement_changed(last_deps, spec)
- ):
- logger.debug(
- 'Redeploy wanted %s: placement has changed',
- spec.service_name(),
- )
- action = utils.Action.REDEPLOY
- return action
+ if backend_spec.service_type == 'nfs':
+ if self.has_placement_changed(last_deps, spec):
+ logger.debug(
+ 'Redeploy wanted %s: placement has changed',
+ spec.service_name(),
+ )
+ return utils.NextDaemonStep(utils.Action.REDEPLOY)
+ sym_diff = set(curr_deps).symmetric_difference(last_deps)
+ if sym_diff and all(
+ s.startswith(f'nfs.{backend_spec.service_id}')
+ for s in sym_diff
+ ):
+ logger.debug(
+ 'Reconfigure HAProxy with SIGHUP due to change in NFS backend '
+ '(%s)',
+ spec.service_name(),
+ )
+ return utils.NextDaemonStep(
+ utils.Action.RECONFIG,
+ skip_restart_for_reconfig=True,
+ send_signal_to_daemon='SIGHUP',
+ )
+ return step
+from dataclasses import replace
from typing import List, cast, Optional, TYPE_CHECKING
from cephadm.services.cephadmservice import CephadmService, CephadmDaemonDeploySpec
from ceph.deployment.service_spec import TracingSpec, ServiceSpec
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
- ) -> utils.Action:
+ ) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
this service would prefer cephadm take.
"""
- action = super().choose_next_action(
+ step = super().choose_next_action(
scheduled_action, daemon_type, spec, curr_deps, last_deps
)
# changes to jaeger-agent deps affect the way the unit.run for
# the daemon is written, which we rewrite on redeploy, but not
# on reconfig.
- if action is utils.Action.RECONFIG:
- action = utils.Action.REDEPLOY
- return action
+ if step.action is utils.Action.RECONFIG:
+ return replace(step, action=utils.Action.REDEPLOY)
+ return step
@register_cephadm_service
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
- ) -> utils.Action:
+ ) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
this service would prefer cephadm take.
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
- ) -> utils.Action:
+ ) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
this service would prefer cephadm take.
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
- ) -> utils.Action:
+ ) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
this service would prefer cephadm take.
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
- ) -> utils.Action:
+ ) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
this service would prefer cephadm take.
"""
if curr_deps == last_deps:
- return scheduled_action
+ return utils.NextDaemonStep(scheduled_action)
sym_diff = set(curr_deps).symmetric_difference(last_deps)
logger.info(
'Reconfigure wanted %s: deps %r -> %r (diff %r)',
only_kmip_updated = all(s.startswith('kmip') for s in sym_diff)
if not only_kmip_updated:
action = utils.Action.REDEPLOY
- return action
+ return utils.NextDaemonStep(action)
import logging
import json
import socket
+from dataclasses import dataclass
from enum import Enum
from functools import wraps
from typing import (
return self.value
+@dataclass(frozen=True)
+class NextDaemonStep:
+ """Result of CephadmService.choose_next_action: high-level action plus
+ optional reconfig hints (e.g. HAProxy reload via signal instead of restart).
+ """
+ action: Action
+ skip_restart_for_reconfig: bool = False
+ send_signal_to_daemon: Optional[str] = None
+
+
def name_to_config_section(name: str) -> ConfEntity:
"""
Map from daemon names to ceph entity names (as seen in config)