]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm: redeploy stopped keepalived when ingress deps change 66037/head
authorShweta Bhosale <Shweta.Bhosale1@ibm.com>
Mon, 18 May 2026 15:49:44 +0000 (21:19 +0530)
committerShweta Bhosale <Shweta.Bhosale1@ibm.com>
Wed, 1 Jul 2026 15:40:09 +0000 (21:10 +0530)
Fixes: https://tracker.ceph.com/issues/76304
Signed-off-by: Shweta Bhosale <Shweta.Bhosale1@ibm.com>
src/pybind/mgr/cephadm/serve.py
src/pybind/mgr/cephadm/services/cephadmservice.py
src/pybind/mgr/cephadm/services/ingress.py
src/pybind/mgr/cephadm/services/jaeger.py
src/pybind/mgr/cephadm/services/monitoring.py
src/pybind/mgr/cephadm/services/nfs.py
src/pybind/mgr/cephadm/tests/services/test_ingress.py

index 24e7e581a9e45c7052cc36d0127ebf35e49269ee..5bbaa8fbeeb75e2d8408126264a8022057b2c1f0 100644 (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(
index 426b86f1b5ca9d1b158322637b2c7c3be1514e7c..37657d33e645c3145c7089654080be98ada08aa9 100644 (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
index 84955d755493e5d4ecd1fbcbbe0621311c476fbf..360f84b70558b46510f601c24f19610489b82f3f 100644 (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'
index 8d69c53cec8f67ae947d7d80fb346cd9d82eb481..6d0b5f441a2726137fa518c2ba22b638129e0ca9 100644 (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
index 0294fdfafa4ef0d0ba467b17ba5fc43782224daf..6d0008f0ef643009cf572167ef4ec73c1911acef 100644 (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
index 45d7aad1b9c3b7aea7a266f36496fd0be9d26961..83fc8ec945e4d8be20acca501b64e216878f0bf0 100644 (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
index 537e77283a9b498ac20613ba56db4347032a22a5..4166f06179ceab036fb6867caaccea0b83fcf663 100644 (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')]