]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/cephadm: placementspec->host matching adaption
authorJoshua Schmid <jschmid@suse.de>
Tue, 12 May 2020 08:24:10 +0000 (10:24 +0200)
committerSebastian Wagner <sebastian.wagner@suse.com>
Mon, 8 Jun 2020 11:52:24 +0000 (13:52 +0200)
Signed-off-by: Joshua Schmid <jschmid@suse.de>
(cherry picked from commit 02231859860d096689c4f2e3f5ea4d502d8dc761)

src/pybind/mgr/cephadm/inventory.py
src/pybind/mgr/cephadm/module.py
src/pybind/mgr/cephadm/schedule.py
src/pybind/mgr/cephadm/services/osd.py
src/pybind/mgr/cephadm/tests/test_scheduling.py

index 2231f7fe9e383354ad5e522351aece068989fa4a..e107ee4abb46586fe1b248c67941a315e323b766 100644 (file)
@@ -79,9 +79,11 @@ class Inventory:
         self.assert_host(host)
         return self._inventory[host].get('addr', host)
 
-    def filter_by_label(self, label=None) -> Iterator[str]:
+    def filter_by_label(self, label: Optional[str] = '', as_hostspec: bool = False) -> Iterator:
         for h, hostspec in self._inventory.items():
             if not label or label in hostspec.get('labels', []):
+                if as_hostspec:
+                    yield hostspec
                 yield h
 
     def spec_from_dict(self, info):
index 7e2eaed206cc29803a44cc3dd1771926ec8948e7..295eaae46b069d68c42971d585c26757dd39f5f1 100644 (file)
@@ -1064,9 +1064,8 @@ you may want to run:
             self.log.exception(ex)
             raise
 
-    def _get_hosts(self, label=None):
-        # type: (Optional[str]) -> List[str]
-        return list(self.inventory.filter_by_label(label))
+    def _get_hosts(self, label: Optional[str] = '', as_hostspec: bool = False) -> List:
+        return list(self.inventory.filter_by_label(label=label, as_hostspec=as_hostspec))
 
     def _add_host(self, spec):
         # type: (HostSpec) -> str
@@ -1244,18 +1243,6 @@ you may want to run:
         self.cache.save_host(host)
         return None
 
-    def _get_spec_size(self, spec):
-        if spec.placement.count:
-            return spec.placement.count
-        elif spec.placement.host_pattern:
-            return len(spec.placement.pattern_matches_hosts(self.inventory.keys()))
-        elif spec.placement.label:
-            return len(self._get_hosts(spec.placement.label))
-        elif spec.placement.hosts:
-            return len(spec.placement.hosts)
-        # hmm!
-        return 0
-
     @trivial_completion
     def describe_service(self, service_type=None, service_name=None,
                          refresh=False):
@@ -1306,7 +1293,7 @@ you may want to run:
                         osd_count += 1
                         sm[n].size = osd_count
                     else:
-                        sm[n].size = self._get_spec_size(spec)
+                        sm[n].size = spec.placement.get_host_selection_size(self._get_hosts)
 
                     sm[n].created = self.spec_store.spec_created[n]
                     if service_type == 'nfs':
@@ -1331,7 +1318,7 @@ you may want to run:
                 continue
             sm[n] = orchestrator.ServiceDescription(
                 spec=spec,
-                size=self._get_spec_size(spec),
+                size=spec.placement.get_host_selection_size(self._get_hosts),
                 running=0,
             )
             if service_type == 'nfs':
index 80a4b3d97e49a9643a5f842afe5e2d8ae0561b27..6e9bb6899318cc3dfdf5da1dc253d10710aaae2c 100644 (file)
@@ -58,7 +58,7 @@ class HostAssignment(object):
 
     def __init__(self,
                  spec,  # type: ServiceSpec
-                 get_hosts_func,  # type: Callable[[Optional[str]],List[str]]
+                 get_hosts_func,  # type: Callable
                  get_daemons_func, # type: Callable[[str],List[orchestrator.DaemonDescription]]
 
                  filter_new_host=None, # type: Optional[Callable[[str],bool]]
@@ -78,19 +78,19 @@ class HostAssignment(object):
 
         if self.spec.placement.hosts:
             explicit_hostnames = {h.hostname for h in self.spec.placement.hosts}
-            unknown_hosts = explicit_hostnames.difference(set(self.get_hosts_func(None)))
+            unknown_hosts = explicit_hostnames.difference(set(self.get_hosts_func()))
             if unknown_hosts:
                 raise OrchestratorValidationError(
                     f'Cannot place {self.spec.one_line_str()} on {unknown_hosts}: Unknown hosts')
 
         if self.spec.placement.host_pattern:
-            pattern_hostnames = self.spec.placement.pattern_matches_hosts(self.get_hosts_func(None))
+            pattern_hostnames = self.spec.placement.filter_matching_hosts(self.get_hosts_func)
             if not pattern_hostnames:
                 raise OrchestratorValidationError(
                     f'Cannot place {self.spec.one_line_str()}: No matching hosts')
 
         if self.spec.placement.label:
-            label_hostnames = self.get_hosts_func(self.spec.placement.label)
+            label_hostnames = self.get_hosts_func(label=self.spec.placement.label)
             if not label_hostnames:
                 raise OrchestratorValidationError(
                     f'Cannot place {self.spec.one_line_str()}: No matching '
@@ -117,7 +117,7 @@ class HostAssignment(object):
         if self.spec.placement.host_pattern:
             candidates = [
                 HostPlacementSpec(x, '', '')
-                for x in self.spec.placement.pattern_matches_hosts(self.get_hosts_func(None))
+                for x in self.spec.placement.filter_matching_hosts(self.get_hosts_func)
             ]
             logger.debug('All hosts: {}'.format(candidates))
             return candidates
@@ -133,7 +133,7 @@ class HostAssignment(object):
         elif self.spec.placement.label:
             hosts = [
                 HostPlacementSpec(x, '', '')
-                for x in self.get_hosts_func(self.spec.placement.label)
+                for x in self.get_hosts_func(label=self.spec.placement.label)
             ]
             if not self.spec.placement.count:
                 logger.debug('Labeled hosts: {}'.format(hosts))
@@ -144,7 +144,7 @@ class HostAssignment(object):
         else:
             hosts = [
                 HostPlacementSpec(x, '', '')
-                for x in self.get_hosts_func(None)
+                for x in self.get_hosts_func()
             ]
             if self.spec.placement.count:
                 count = self.spec.placement.count
index b37f7c586b75f06610de3a1bd1fd8fada3967379..1e6db9b0da9149927c4fcd0e09b6257c15c46299 100644 (file)
@@ -97,8 +97,7 @@ class OSDService(CephadmService):
 
     def prepare_drivegroup(self, drive_group: DriveGroupSpec) -> List[Tuple[str, DriveSelection]]:
         # 1) use fn_filter to determine matching_hosts
-        matching_hosts = drive_group.placement.pattern_matches_hosts(
-            [x for x in self.mgr.cache.get_hosts()])
+        matching_hosts = drive_group.placement.filter_matching_hosts(self.mgr._get_hosts)
         # 2) Map the inventory to the InventoryHost object
         host_ds_map = []
 
index 54402bad469c0f07d4c2dac1c5750403a5e9257e..bc6a8b6b8fdb09484824cfec2417b1302efa67a4 100644 (file)
@@ -116,10 +116,11 @@ class NodeAssignmentTest(NamedTuple):
 def test_node_assignment(service_type, placement, hosts, daemons, expected):
     hosts = HostAssignment(
         spec=ServiceSpec(service_type, placement=placement),
-        get_hosts_func=lambda _: hosts,
+        get_hosts_func=lambda label=None, as_hostspec=False: hosts,
         get_daemons_func=lambda _: daemons).place()
     assert sorted([h.hostname for h in hosts]) == sorted(expected)
 
+
 class NodeAssignmentTest2(NamedTuple):
     service_type: str
     placement: PlacementSpec
@@ -203,7 +204,7 @@ def test_node_assignment2(service_type, placement, hosts,
                           daemons, expected_len, in_set):
     hosts = HostAssignment(
         spec=ServiceSpec(service_type, placement=placement),
-        get_hosts_func=lambda _: hosts,
+        get_hosts_func=lambda label=None, as_hostspec=False: hosts,
         get_daemons_func=lambda _: daemons).place()
     assert len(hosts) == expected_len
     for h in [h.hostname for h in hosts]:
@@ -234,7 +235,7 @@ def test_node_assignment3(service_type, placement, hosts,
                           daemons, expected_len, must_have):
     hosts = HostAssignment(
         spec=ServiceSpec(service_type, placement=placement),
-        get_hosts_func=lambda _: hosts,
+        get_hosts_func=lambda label=None, as_hostspec=False: hosts,
         get_daemons_func=lambda _: daemons).place()
     assert len(hosts) == expected_len
     for h in must_have:
@@ -293,6 +294,6 @@ def test_bad_specs(service_type, placement, hosts, daemons, expected):
     with pytest.raises(OrchestratorValidationError) as e:
         hosts = HostAssignment(
             spec=ServiceSpec(service_type, placement=placement),
-            get_hosts_func=lambda _: hosts,
+            get_hosts_func=lambda label=None, as_hostspec=False: hosts,
             get_daemons_func=lambda _: daemons).place()
     assert str(e.value) == expected