mgr/cephadm: redeploy stopped keepalived when ingress deps change

Fixes: https://tracker.ceph.com/issues/76304
Signed-off-by: Shweta Bhosale <Shweta.Bhosale1@ibm.com>
This commit is contained in:
Shweta Bhosale 2026-05-18 21:19:44 +05:30
parent 6ec51414a9
commit c20ba11040
7 changed files with 105 additions and 0 deletions

View File

@ -1236,6 +1236,7 @@ class CephadmServe:
spec,
curr_deps=deps,
last_deps=last_deps,
daemon=dd,
)
if _step.action is not _scheduled_action:
self.log.info(

View File

@ -969,6 +969,7 @@ class CephadmService(metaclass=ABCMeta):
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
daemon: Optional[DaemonDescription] = None,
) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
@ -1997,6 +1998,7 @@ class CephExporterService(CephService):
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
daemon: Optional[DaemonDescription] = None,
) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that

View File

@ -605,6 +605,7 @@ class IngressService(CephService):
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
daemon: Optional[DaemonDescription] = None,
) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
@ -614,6 +615,20 @@ class IngressService(CephService):
scheduled_action, daemon_type, spec, curr_deps, last_deps
)
action = step.action
# keepalived is not systemd-enabled; when stopped, redeploy rewrites
# the unit and container so the serve loop can start the daemon again.
if (
daemon_type == 'keepalived'
and action is utils.Action.RECONFIG
and daemon is not None
and daemon.status == DaemonDescriptionStatus.stopped
):
logger.debug(
'Redeploy wanted %s: keepalived deps changed (daemon stopped)',
spec.service_name() if spec else daemon_type,
)
return utils.NextDaemonStep(utils.Action.REDEPLOY)
if (
action is not utils.Action.REDEPLOY
and daemon_type == 'haproxy'

View File

@ -2,6 +2,7 @@ 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
from orchestrator import DaemonDescription
from .service_registry import register_cephadm_service
from mgr_util import build_url
from cephadm import utils
@ -58,6 +59,7 @@ class JaegerAgentService(CephadmService):
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
daemon: Optional[DaemonDescription] = None,
) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that

View File

@ -491,6 +491,7 @@ class AlertmanagerService(CephadmService):
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
daemon: Optional[DaemonDescription] = None,
) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
@ -824,6 +825,7 @@ class PrometheusService(CephadmService):
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
daemon: Optional[DaemonDescription] = None,
) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that
@ -891,6 +893,7 @@ class NodeExporterService(CephadmService):
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
daemon: Optional[DaemonDescription] = None,
) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that

View File

@ -578,6 +578,7 @@ class NFSService(CephService):
spec: Optional[ServiceSpec],
curr_deps: List[str],
last_deps: List[str],
daemon: Optional[DaemonDescription] = None,
) -> utils.NextDaemonStep:
"""Given the scheduled_action, service spec, daemon_type, and
current and previous dependency lists return the next action that

View File

@ -16,6 +16,7 @@ from cephadm.tests.fixtures import with_host, with_service, async_side_effect
from ceph.utils import datetime_now
from orchestrator._interface import DaemonDescription, DaemonDescriptionStatus
from orchestrator import HostSpec
from cephadm import utils
from cephadm.services.ingress import IngressService
@ -1459,6 +1460,86 @@ class TestIngressService:
assert "Bind_addr = 10.10.2.20" in ganesha_conf
def test_keepalived_choose_next_action_redeploy_on_deps_change_when_stopped():
mgr = MagicMock()
svc = IngressService(mgr)
spec = IngressSpec(
service_id='test',
backend_service='nfs.foo',
frontend_port=2049,
monitor_port=9049,
virtual_ip='192.168.122.100/24',
placement=PlacementSpec(hosts=['host1']),
)
daemon = DaemonDescription(
daemon_type='keepalived',
daemon_id='test',
hostname='host1',
service_name='ingress.test',
status=DaemonDescriptionStatus.stopped,
)
next_step = svc.choose_next_action(
utils.Action.NO_ACTION,
'keepalived',
spec,
curr_deps=['haproxy.test'],
last_deps=['haproxy.old'],
daemon=daemon,
)
assert next_step.action is utils.Action.REDEPLOY
def test_keepalived_choose_next_action_reconfig_when_running():
mgr = MagicMock()
svc = IngressService(mgr)
spec = IngressSpec(
service_id='test',
backend_service='nfs.foo',
frontend_port=2049,
monitor_port=9049,
virtual_ip='192.168.122.100/24',
placement=PlacementSpec(hosts=['host1']),
)
daemon = DaemonDescription(
daemon_type='keepalived',
daemon_id='test',
hostname='host1',
service_name='ingress.test',
status=DaemonDescriptionStatus.running,
)
next_step = svc.choose_next_action(
utils.Action.NO_ACTION,
'keepalived',
spec,
curr_deps=['haproxy.test'],
last_deps=['haproxy.old'],
daemon=daemon,
)
assert next_step.action is utils.Action.RECONFIG
def test_keepalived_choose_next_action_scheduled_when_deps_unchanged():
mgr = MagicMock()
svc = IngressService(mgr)
spec = IngressSpec(
service_id='test',
backend_service='nfs.foo',
frontend_port=2049,
monitor_port=9049,
virtual_ip='192.168.122.100/24',
placement=PlacementSpec(hosts=['host1']),
)
deps = ['haproxy.test']
next_step = svc.choose_next_action(
utils.Action.NO_ACTION,
'keepalived',
spec,
curr_deps=deps,
last_deps=deps,
)
assert next_step.action is utils.Action.NO_ACTION
def test_keepalived_should_auto_start_colocated_haproxy():
mgr = MagicMock()
mgr.cache.get_schedulable_hosts.return_value = [HostSpec('host-a')]