primary_daemon_type: Optional[str] = None,
per_host_daemon_type: Optional[str] = None,
rank_map: Optional[Dict[int, Dict[int, Optional[str]]]] = None,
+ blocking_daemon_hosts: Optional[List[orchestrator.HostSpec]] = None,
):
assert spec
self.spec = spec # type: ServiceSpec
self.hosts: List[orchestrator.HostSpec] = hosts
self.unreachable_hosts: List[orchestrator.HostSpec] = unreachable_hosts
self.draining_hosts: List[orchestrator.HostSpec] = draining_hosts
+ self.blocking_daemon_hosts: List[orchestrator.HostSpec] = blocking_daemon_hosts or []
self.filter_new_host = filter_new_host
self.service_name = spec.service_name()
self.daemons = daemons
existing = existing_active + existing_standby
# build to_add
+ blocking_daemon_hostnames = [
+ h.hostname for h in self.blocking_daemon_hosts
+ ]
+ unreachable_hostnames = [
+ h.hostname for h in self.unreachable_hosts
+ ]
if not count:
- to_add = [dd for dd in others if dd.hostname not in [
- h.hostname for h in self.unreachable_hosts]]
+ to_add = [
+ dd for dd in others if (
+ dd.hostname not in blocking_daemon_hostnames
+ and dd.hostname not in unreachable_hostnames
+ )
+ ]
else:
+ if blocking_daemon_hostnames:
+ to_remove.extend([
+ dd for dd in existing if dd.hostname in blocking_daemon_hostnames
+ ])
+ existing = [
+ dd for dd in existing if dd.hostname not in blocking_daemon_hostnames
+ ]
+
# The number of new slots that need to be selected in order to fulfill count
need = count - len(existing)
for dp in matching_dps:
if need <= 0:
break
- if dp.hostname in related_service_hosts and dp.hostname not in [h.hostname for h in self.unreachable_hosts]:
+ if dp.hostname in related_service_hosts and dp.hostname not in unreachable_hostnames:
logger.debug(f'Preferring {dp.hostname} for service {self.service_name} as related daemons have been placed there')
to_add.append(dp)
need -= 1 # this is last use of need so it can work as a counter
for dp in others:
if need <= 0:
break
- if dp.hostname not in [h.hostname for h in self.unreachable_hosts]:
+ if (
+ dp.hostname not in unreachable_hostnames
+ and dp.hostname not in blocking_daemon_hostnames
+ ):
to_add.append(dp)
need -= 1 # this is last use of need in this function so it can work as a counter
svc = service_registry.get_service(service_type)
daemons = self.mgr.cache.get_daemons_by_service(service_name)
+
+ blocking_daemon_hosts = svc.get_blocking_daemon_hosts(service_name)
related_service_daemons = self.mgr.cache.get_related_service_daemons(spec)
public_networks: List[str] = []
) == 'agent' else self.mgr.cache.get_schedulable_hosts(),
unreachable_hosts=self.mgr.cache.get_unreachable_hosts(),
draining_hosts=self.mgr.cache.get_draining_hosts(),
+ blocking_daemon_hosts=blocking_daemon_hosts,
daemons=daemons,
related_service_daemons=related_service_daemons,
networks=self.mgr.cache.networks,
)
from ceph.deployment.utils import is_ipv6, unwrap_ipv6
from mgr_util import build_url, merge_dicts
-from orchestrator import OrchestratorError, DaemonDescription, DaemonDescriptionStatus
+from orchestrator import (
+ OrchestratorError,
+ DaemonDescription,
+ DaemonDescriptionStatus,
+ HostSpec
+)
from orchestrator._interface import daemon_type_to_service
from cephadm import utils
from .service_registry import register_cephadm_service
"""
return False
+ def get_blocking_daemon_hosts(self, service_name: str) -> List[HostSpec]:
+ return []
+
class CephService(CephadmService):