]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm/schedule: pass per-type allow_colo to the scheduler
authorSage Weil <sage@newdream.net>
Tue, 9 Mar 2021 23:26:43 +0000 (18:26 -0500)
committerSage Weil <sage@newdream.net>
Tue, 16 Mar 2021 12:56:18 +0000 (07:56 -0500)
Signed-off-by: Sage Weil <sage@newdream.net>
(cherry picked from commit 927694ba4aeed42b2fa70c962c96e3ef5882d46c)

src/pybind/mgr/cephadm/schedule.py
src/pybind/mgr/cephadm/serve.py
src/pybind/mgr/cephadm/services/cephadmservice.py
src/pybind/mgr/cephadm/tests/test_scheduling.py

index e64991cee8a8bd64040e12ca8ed9133ee9eb80ea..6148b6a181dee7305d78dd92c969dbb73289c54a 100644 (file)
@@ -59,6 +59,7 @@ class HostAssignment(object):
                  daemons: List[orchestrator.DaemonDescription],
                  filter_new_host=None,  # type: Optional[Callable[[str],bool]]
                  scheduler=None,  # type: Optional[BaseScheduler]
+                 allow_colo: bool = False,
                  ):
         assert spec
         self.spec = spec  # type: ServiceSpec
@@ -67,6 +68,7 @@ class HostAssignment(object):
         self.filter_new_host = filter_new_host
         self.service_name = spec.service_name()
         self.daemons = daemons
+        self.allow_colo = allow_colo
 
     def hosts_by_label(self, label: str) -> List[orchestrator.HostSpec]:
         return [h for h in self.hosts if label in h.labels]
@@ -81,6 +83,15 @@ class HostAssignment(object):
             raise OrchestratorValidationError(
                 f'<count> can not be 0 for {self.spec.one_line_str()}')
 
+        if (
+                self.spec.placement.count_per_host is not None
+                and self.spec.placement.count_per_host > 1
+                and not self.allow_colo
+        ):
+            raise OrchestratorValidationError(
+                f'Cannot place more than one {self.spec.service_type} per host'
+            )
+
         if self.spec.placement.hosts:
             explicit_hostnames = {h.hostname for h in self.spec.placement.hosts}
             unknown_hosts = explicit_hostnames.difference(set(self.get_hostnames()))
index 3c9e38fe675411caff5ba78c70744f3e17e13eb2..fcd371f0f6aaf980e358bd3c108a737fd5f04244 100644 (file)
@@ -554,6 +554,7 @@ class CephadmServe:
             daemons=daemons,
             filter_new_host=matches_network if service_type == 'mon'
             else virtual_ip_allowed if service_type == 'ha-rgw' else None,
+            allow_colo=svc.allow_colo(),
         )
 
         try:
index 52f22133e4787d069ce57ef38f657f7fcb8f963b..7cb10f1aa36fd5ddfa6696b5978cfbf4e87b1f47 100644 (file)
@@ -97,6 +97,9 @@ class CephadmService(metaclass=ABCMeta):
     def __init__(self, mgr: "CephadmOrchestrator"):
         self.mgr: "CephadmOrchestrator" = mgr
 
+    def allow_colo(self) -> bool:
+        return False
+
     def make_daemon_spec(self, host: str,
                          daemon_id: str,
                          network: str,
@@ -610,6 +613,9 @@ class MgrService(CephService):
 class MdsService(CephService):
     TYPE = 'mds'
 
+    def allow_colo(self) -> bool:
+        return True
+
     def config(self, spec: ServiceSpec, daemon_id: str) -> None:
         assert self.TYPE == spec.service_type
         assert spec.service_id
@@ -782,6 +788,9 @@ class RgwService(CephService):
 class RbdMirrorService(CephService):
     TYPE = 'rbd-mirror'
 
+    def allow_colo(self) -> bool:
+        return True
+
     def prepare_create(self, daemon_spec: CephadmDaemonDeploySpec) -> CephadmDaemonDeploySpec:
         assert self.TYPE == daemon_spec.daemon_type
         daemon_id, _ = daemon_spec.daemon_id, daemon_spec.host
index 0dbd414b6c9b7f3ed7f6734aa41a9b5021c3a45d..2b370588bd5fa38320f6de596de9cb0e59015255 100644 (file)
@@ -353,12 +353,12 @@ class NodeAssignmentTest(NamedTuple):
         ),
         # all_hosts + count_per_host
         NodeAssignmentTest(
-            'mgr',
+            'mds',
             PlacementSpec(host_pattern='*', count_per_host=2),
             'host1 host2 host3'.split(),
             [
-                DaemonDescription('mgr', 'a', 'host1'),
-                DaemonDescription('mgr', 'b', 'host2'),
+                DaemonDescription('mds', 'a', 'host1'),
+                DaemonDescription('mds', 'b', 'host2'),
             ],
             ['host1', 'host2', 'host3', 'host1', 'host2', 'host3']
         ),
@@ -433,7 +433,7 @@ class NodeAssignmentTest(NamedTuple):
         ),
         # label only + count_per_hst
         NodeAssignmentTest(
-            'mgr',
+            'mds',
             PlacementSpec(label='foo', count_per_host=3),
             'host1 host2 host3'.split(),
             [],
@@ -450,17 +450,21 @@ class NodeAssignmentTest(NamedTuple):
         ),
         # host_pattern + count_per_host
         NodeAssignmentTest(
-            'mgr',
-            PlacementSpec(host_pattern='mgr*', count_per_host=3),
-            'mgrhost1 mgrhost2 datahost'.split(),
+            'mds',
+            PlacementSpec(host_pattern='mds*', count_per_host=3),
+            'mdshost1 mdshost2 datahost'.split(),
             [],
-            ['mgrhost1', 'mgrhost2', 'mgrhost1', 'mgrhost2', 'mgrhost1', 'mgrhost2']
+            ['mdshost1', 'mdshost2', 'mdshost1', 'mdshost2', 'mdshost1', 'mdshost2']
         ),
     ])
 def test_node_assignment(service_type, placement, hosts, daemons, expected):
     service_id = None
+    allow_colo = False
     if service_type == 'rgw':
         service_id = 'realm.zone'
+    elif service_type == 'mds':
+        service_id = 'myfs'
+        allow_colo = True
 
     spec = ServiceSpec(service_type=service_type,
                        service_id=service_id,
@@ -469,7 +473,8 @@ def test_node_assignment(service_type, placement, hosts, daemons, expected):
     hosts = HostAssignment(
         spec=spec,
         hosts=[HostSpec(h, labels=['foo']) for h in hosts],
-        daemons=daemons
+        daemons=daemons,
+        allow_colo=allow_colo
     ).place()
     assert sorted([h.hostname for h in hosts]) == sorted(expected)