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):
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
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):
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':
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':
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]]
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 '
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
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))
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
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 = []
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
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]:
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:
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