From: Joshua Schmid Date: Tue, 12 May 2020 08:24:10 +0000 (+0200) Subject: mgr/cephadm: placementspec->host matching adaption X-Git-Tag: v16.1.0~2165^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=02231859860d096689c4f2e3f5ea4d502d8dc761;p=ceph.git mgr/cephadm: placementspec->host matching adaption Signed-off-by: Joshua Schmid --- diff --git a/src/pybind/mgr/cephadm/inventory.py b/src/pybind/mgr/cephadm/inventory.py index 2231f7fe9e3..e107ee4abb4 100644 --- a/src/pybind/mgr/cephadm/inventory.py +++ b/src/pybind/mgr/cephadm/inventory.py @@ -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): diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index 6fc2f140257..e252dffca79 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -1051,9 +1051,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)) @trivial_completion def add_host(self, spec): @@ -1228,18 +1227,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): @@ -1290,7 +1277,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': @@ -1315,7 +1302,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': diff --git a/src/pybind/mgr/cephadm/schedule.py b/src/pybind/mgr/cephadm/schedule.py index 80a4b3d97e4..6e9bb689931 100644 --- a/src/pybind/mgr/cephadm/schedule.py +++ b/src/pybind/mgr/cephadm/schedule.py @@ -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 diff --git a/src/pybind/mgr/cephadm/services/osd.py b/src/pybind/mgr/cephadm/services/osd.py index b37f7c586b7..1e6db9b0da9 100644 --- a/src/pybind/mgr/cephadm/services/osd.py +++ b/src/pybind/mgr/cephadm/services/osd.py @@ -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 = [] diff --git a/src/pybind/mgr/cephadm/tests/test_scheduling.py b/src/pybind/mgr/cephadm/tests/test_scheduling.py index 54402bad469..bc6a8b6b8fd 100644 --- a/src/pybind/mgr/cephadm/tests/test_scheduling.py +++ b/src/pybind/mgr/cephadm/tests/test_scheduling.py @@ -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