From: Sebastian Wagner Date: Fri, 13 Dec 2019 16:32:00 +0000 (+0100) Subject: mgr/orchestrator: Rename PlacementSpec.nodes -> PlacementSpec.hosts X-Git-Tag: v15.1.0~450^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=70bae966aa48b932f019c1f081d66c47858faaee;p=ceph-ci.git mgr/orchestrator: Rename PlacementSpec.nodes -> PlacementSpec.hosts By definition in the orchestrator's docs, we're using `host` insted of `node` Fixes wrong usage of PlacementSpec in mgr/ansible Signed-off-by: Sebastian Wagner --- diff --git a/src/pybind/mgr/ansible/module.py b/src/pybind/mgr/ansible/module.py index 45cbfe00e37..0948f20a622 100644 --- a/src/pybind/mgr/ansible/module.py +++ b/src/pybind/mgr/ansible/module.py @@ -487,7 +487,7 @@ class Module(MgrModule, orchestrator.Orchestrator): # Add the hosts to the inventory in the right group - hosts = spec.hosts + hosts = spec.placement.hosts if not hosts: raise orchestrator.OrchestratorError("No hosts provided. " "At least one destination host is needed to install the RGW " diff --git a/src/pybind/mgr/cephadm/module.py b/src/pybind/mgr/cephadm/module.py index 660d666c1fe..32877e5fcf9 100644 --- a/src/pybind/mgr/cephadm/module.py +++ b/src/pybind/mgr/cephadm/module.py @@ -1127,6 +1127,7 @@ class CephadmOrchestrator(MgrModule, orchestrator.Orchestrator): return self._update_mons(spec) def _update_mons(self, spec): + # type: (orchestrator.StatefulServiceSpec) -> orchestrator.Completion """ Adjust the number of cluster monitors. """ @@ -1138,30 +1139,30 @@ class CephadmOrchestrator(MgrModule, orchestrator.Orchestrator): if spec.count < num_mons: raise NotImplementedError("Removing monitors is not supported.") - self.log.debug("Trying to update monitors on: {}".format(spec.placement.nodes)) + self.log.debug("Trying to update monitors on: {}".format(spec.placement.hosts)) # check that all the hosts are registered - [self._require_hosts(host.hostname) for host in spec.placement.nodes] + [self._require_hosts(host.hostname) for host in spec.placement.hosts] # current support requires a network to be specified - for host, network, _ in spec.placement.nodes: + for host, network, _ in spec.placement.hosts: if not network: raise RuntimeError("Host '{}' is missing a network spec".format(host)) def update_mons_with_daemons(daemons): - for _, _, name in spec.placement.nodes: + for _, _, name in spec.placement.hosts: if name and len([d for d in daemons if d.service_instance == name]): raise RuntimeError('name %s alrady exists', name) # explicit placement: enough hosts provided? num_new_mons = spec.count - num_mons - if len(spec.placement.nodes) < num_new_mons: + if len(spec.placement.hosts) < num_new_mons: raise RuntimeError("Error: {} hosts provided, expected {}".format( - len(spec.placement.nodes), num_new_mons)) + len(spec.placement.hosts), num_new_mons)) self.log.info("creating {} monitors on hosts: '{}'".format( - num_new_mons, ",".join(map(lambda h: ":".join(h), spec.placement.nodes)))) + num_new_mons, ",".join(map(lambda h: ":".join(h), spec.placement.hosts)))) # TODO: we may want to chain the creation of the monitors so they join # the quorum one at a time. - return self._create_mon(spec.placement.nodes) + return self._create_mon(spec.placement.hosts) return self._get_services('mon').then(update_mons_with_daemons) @async_map_completion @@ -1183,6 +1184,7 @@ class CephadmOrchestrator(MgrModule, orchestrator.Orchestrator): return self._create_daemon('mgr', name, host, keyring) def update_mgrs(self, spec): + # type: (orchestrator.StatefulServiceSpec) -> orchestrator.Completion """ Adjust the number of cluster managers. """ @@ -1190,13 +1192,14 @@ class CephadmOrchestrator(MgrModule, orchestrator.Orchestrator): return self._get_services('mgr').then(lambda daemons: self._update_mgrs(spec, daemons)) def _update_mgrs(self, spec, daemons): + # type: (orchestrator.StatefulServiceSpec, List[orchestrator.ServiceDescription]) -> orchestrator.Completion num_mgrs = len(daemons) if spec.count == num_mgrs: return orchestrator.Completion(value="The requested number of managers exist.") - self.log.debug("Trying to update managers on: {}".format(spec.placement.nodes)) + self.log.debug("Trying to update managers on: {}".format(spec.placement.hosts)) # check that all the hosts are registered - [self._require_hosts(host.hostname) for host in spec.placement.nodes] + [self._require_hosts(host.hostname) for host in spec.placement.hosts] if spec.count < num_mgrs: num_to_remove = num_mgrs - spec.count @@ -1230,39 +1233,39 @@ class CephadmOrchestrator(MgrModule, orchestrator.Orchestrator): else: # we assume explicit placement by which there are the same number of # hosts specified as the size of increase in number of daemons. - num_new_mgrs = spec.placement.count - num_mgrs - if len(spec.placement.nodes) < num_new_mgrs: + num_new_mgrs = spec.count - num_mgrs + if len(spec.placement.hosts) < num_new_mgrs: raise RuntimeError( "Error: {} hosts provided, expected {}".format( - len(spec.placement.nodes), num_new_mgrs)) + len(spec.placement.hosts), num_new_mgrs)) - for host_spec in spec.placement.nodes: + for host_spec in spec.placement.hosts: if host_spec.name and len([d for d in daemons if d.service_instance == host_spec.name]): raise RuntimeError('name %s alrady exists', host_spec.name) - for host_spec in spec.placement.nodes: + for host_spec in spec.placement.hosts: if host_spec.name and len([d for d in daemons if d.service_instance == host_spec.name]): raise RuntimeError('name %s alrady exists', host_spec.name) self.log.info("creating {} managers on hosts: '{}'".format( - num_new_mgrs, ",".join([_spec.hostname for _spec in spec.placement.nodes]))) + num_new_mgrs, ",".join([_spec.hostname for _spec in spec.placement.hosts]))) args = [] - for host_spec in spec.placement.nodes: + for host_spec in spec.placement.hosts: name = host_spec.name or self.get_unique_name(daemons) host = host_spec.hostname args.append((host, name)) return self._create_mgr(args) def add_mds(self, spec): - if not spec.placement.nodes or len(spec.placement.nodes) < spec.placement.count: + if not spec.placement.hosts or len(spec.placement.hosts) < spec.placement.count: raise RuntimeError("must specify at least %d hosts" % spec.placement.count) return self._get_services('mds').then(lambda ds: self._add_mds(ds, spec)) def _add_mds(self, daemons, spec): args = [] num_added = 0 - for host, _, name in spec.placement.nodes: + for host, _, name in spec.placement.hosts: if num_added >= spec.count: break mds_id = self.get_unique_name(daemons, spec.name, name) @@ -1309,7 +1312,7 @@ class CephadmOrchestrator(MgrModule, orchestrator.Orchestrator): return self._get_services('mds').then(_remove_mds) def add_rgw(self, spec): - if not spec.placement.nodes or len(spec.placement.nodes) < spec.count: + if not spec.placement.hosts or len(spec.placement.hosts) < spec.count: raise RuntimeError("must specify at least %d hosts" % spec.count) # ensure rgw_realm and rgw_zone is set for these daemons ret, out, err = self.mon_command({ @@ -1328,7 +1331,7 @@ class CephadmOrchestrator(MgrModule, orchestrator.Orchestrator): def _add_rgw(daemons): args = [] num_added = 0 - for host, _, name in spec.placement.nodes: + for host, _, name in spec.placement.hosts: if num_added >= spec.count: break rgw_id = self.get_unique_name(daemons, spec.name, name) @@ -1375,14 +1378,14 @@ class CephadmOrchestrator(MgrModule, orchestrator.Orchestrator): return self._update_service('rgw', self.add_rgw, spec) def add_rbd_mirror(self, spec): - if not spec.placement.nodes or len(spec.placement.nodes) < spec.count: + if not spec.placement.hosts or len(spec.placement.hosts) < spec.count: raise RuntimeError("must specify at least %d hosts" % spec.count) - self.log.debug('nodes %s' % spec.placement.nodes) + self.log.debug('nodes %s' % spec.placement.hosts) def _add_rbd_mirror(daemons): args = [] num_added = 0 - for host, _, name in spec.placement.nodes: + for host, _, name in spec.placement.hosts: if num_added >= spec.count: break daemon_id = self.get_unique_name(daemons, None, name) @@ -1530,7 +1533,7 @@ class NodeAssignment(object): service_type=None, # type: Optional[str] ): assert spec and get_hosts_func and service_type - self.spec = spec + self.spec = spec # type: orchestrator.StatefulServiceSpec self.scheduler = scheduler if scheduler else SimpleScheduler(self.spec.placement) self.get_hosts_func = get_hosts_func self.service_type = service_type @@ -1556,7 +1559,7 @@ class NodeAssignment(object): logger.info("Found labels. Assinging nodes that match the label") candidates = [HostSpec(x[0], '', '') for x in self.get_hosts_func()] # TODO: query for labels logger.info('Assigning nodes to spec: {}'.format(candidates)) - self.spec.placement.set_nodes(candidates) + self.spec.placement.set_hosts(candidates) def assign_nodes(self): # type: () -> None @@ -1565,7 +1568,7 @@ class NodeAssignment(object): """ # If no imperative or declarative host assignments, use the scheduler to pick from the # host pool (assuming `count` is set) - if not self.spec.placement.label and not self.spec.placement.nodes and self.spec.placement.count: + if not self.spec.placement.label and not self.spec.placement.hosts and self.spec.placement.count: logger.info("Found num spec. Looking for labeled nodes.") # TODO: actually query for labels (self.service_type) candidates = self.scheduler.place([x[0] for x in self.get_hosts_func()], @@ -1577,7 +1580,7 @@ class NodeAssignment(object): format(self.spec.placement.count)) else: logger.info('Assigning nodes to spec: {}'.format(candidates)) - self.spec.placement.set_nodes(candidates) + self.spec.placement.set_hosts(candidates) return None candidates = self.scheduler.place([x[0] for x in self.get_hosts_func()], count=self.spec.placement.count) @@ -1587,6 +1590,6 @@ class NodeAssignment(object): format(self.spec.placement.count, len(candidates))) logger.info('Assigning nodes to spec: {}'.format(candidates)) - self.spec.placement.set_nodes(candidates) + self.spec.placement.set_hosts(candidates) return None diff --git a/src/pybind/mgr/cephadm/tests/test_cephadm.py b/src/pybind/mgr/cephadm/tests/test_cephadm.py index 396c5610ab4..3700c20f0c0 100644 --- a/src/pybind/mgr/cephadm/tests/test_cephadm.py +++ b/src/pybind/mgr/cephadm/tests/test_cephadm.py @@ -85,7 +85,7 @@ class TestCephadm(object): @mock.patch("cephadm.module.CephadmOrchestrator._get_connection") def test_mon_update(self, _send_command, _get_connection, cephadm_module): with self._with_host(cephadm_module, 'test'): - ps = PlacementSpec(nodes=['test:0.0.0.0=a'], count=1) + ps = PlacementSpec(hosts=['test:0.0.0.0=a'], count=1) c = cephadm_module.update_mons(StatefulServiceSpec(placement=ps)) assert self._wait(cephadm_module, c) == ["(Re)deployed mon.a on host 'test'"] @@ -95,7 +95,7 @@ class TestCephadm(object): @mock.patch("cephadm.module.CephadmOrchestrator._get_connection") def test_mgr_update(self, _send_command, _get_connection, cephadm_module): with self._with_host(cephadm_module, 'test'): - ps = PlacementSpec(nodes=['test:0.0.0.0=a'], count=1) + ps = PlacementSpec(hosts=['test:0.0.0.0=a'], count=1) c = cephadm_module.update_mgrs(StatefulServiceSpec(placement=ps)) [out] = self._wait(cephadm_module, c) assert "(Re)deployed mgr." in out @@ -117,7 +117,7 @@ class TestCephadm(object): @mock.patch("cephadm.module.CephadmOrchestrator._get_connection") def test_mds(self, _send_command, _get_connection, cephadm_module): with self._with_host(cephadm_module, 'test'): - ps = PlacementSpec(nodes=['test'], count=1) + ps = PlacementSpec(hosts=['test'], count=1) c = cephadm_module.add_mds(StatelessServiceSpec('name', placement=ps)) [out] = self._wait(cephadm_module, c) assert "(Re)deployed mds.name." in out @@ -129,7 +129,7 @@ class TestCephadm(object): @mock.patch("cephadm.module.CephadmOrchestrator._get_connection") def test_rgw(self, _send_command, _get_connection, cephadm_module): with self._with_host(cephadm_module, 'test'): - ps = PlacementSpec(nodes=['test'], count=1) + ps = PlacementSpec(hosts=['test'], count=1) c = cephadm_module.add_rgw(RGWSpec('realm', 'zone', placement=ps)) [out] = self._wait(cephadm_module, c) assert "(Re)deployed rgw.realm.zone." in out @@ -160,7 +160,7 @@ class TestCephadm(object): @mock.patch("cephadm.module.CephadmOrchestrator._get_connection") def test_rbd_mirror(self, _send_command, _get_connection, cephadm_module): with self._with_host(cephadm_module, 'test'): - ps = PlacementSpec(nodes=['test'], count=1) + ps = PlacementSpec(hosts=['test'], count=1) c = cephadm_module.add_rbd_mirror(StatelessServiceSpec(name='name', placement=ps)) [out] = self._wait(cephadm_module, c) assert "(Re)deployed rbd-mirror." in out diff --git a/src/pybind/mgr/orchestrator.py b/src/pybind/mgr/orchestrator.py index 169e8e2585f..751c62517bc 100644 --- a/src/pybind/mgr/orchestrator.py +++ b/src/pybind/mgr/orchestrator.py @@ -1050,22 +1050,23 @@ class PlacementSpec(object): """ For APIs that need to specify a node subset """ - def __init__(self, label=None, nodes=None, count=None): + def __init__(self, label=None, hosts=None, count=None): # type: (Optional[str], Optional[List], Optional[int]) -> None self.label = label - if nodes: - if all([isinstance(node, HostSpec) for node in nodes]): - self.nodes = nodes + if hosts: + if all([isinstance(host, HostSpec) for host in hosts]): + self.hosts = hosts # type: List[HostSpec] else: - self.nodes = [parse_host_specs(x, require_network=False) for x in nodes if x] + self.hosts = [parse_host_specs(x, require_network=False) for x in hosts if x] else: - self.nodes = [] + self.hosts = [] + self.count = count # type: Optional[int] - def set_nodes(self, nodes): - # To backpopulate the .nodes attribute when using labels or count + def set_hosts(self, hosts): + # To backpopulate the .hosts attribute when using labels or count # in the orchestrator backend. - self.nodes = nodes + self.hosts = hosts @classmethod def from_dict(cls, data): @@ -1074,7 +1075,7 @@ class PlacementSpec(object): return _cls def validate(self): - if self.nodes and self.label: + if self.hosts and self.label: # TODO: a less generic Exception raise Exception('Node and label are mutually exclusive') if self.count is not None and self.count <= 0: @@ -1193,9 +1194,15 @@ class StatefulServiceSpec(object): """ # TODO: create base class for Stateless/Stateful service specs and propertly inherit def __init__(self, name=None, placement=None): - self.placement = PlacementSpec() if placement is None else placement + # type: (Optional[str], Optional[PlacementSpec]) -> None + self.placement = PlacementSpec() if placement is None else placement # type: PlacementSpec self.name = name - self.count = self.placement.count if self.placement is not None else 1 # for backwards-compatibility + + # for backwards-compatibility + if self.placement is not None and self.placement.count is not None: + self.count = self.placement.count + else: + self.count = 1 class StatelessServiceSpec(object): @@ -1211,12 +1218,12 @@ class StatelessServiceSpec(object): # start the services. def __init__(self, name, placement=None): - self.placement = PlacementSpec() if placement is None else placement + self.placement = PlacementSpec() if placement is None else placement # type: PlacementSpec #: Give this set of statelss services a name: typically it would #: be the name of a CephFS filesystem, RGW zone, etc. Must be unique #: within one ceph cluster. - self.name = name + self.name = name # type: str #: Count of service instances self.count = self.placement.count if self.placement is not None else 1 # for backwards-compatibility @@ -1273,7 +1280,7 @@ class RGWSpec(StatelessServiceSpec): #: List of hosts where RGWs should run. Not for Rook. if hosts: - self.placement.hosts = hosts + self.placement = PlacementSpec(hosts=hosts) #: is multisite self.rgw_multisite = rgw_multisite diff --git a/src/pybind/mgr/orchestrator_cli/module.py b/src/pybind/mgr/orchestrator_cli/module.py index 9dd74a4c982..ef101061dcb 100644 --- a/src/pybind/mgr/orchestrator_cli/module.py +++ b/src/pybind/mgr/orchestrator_cli/module.py @@ -384,7 +384,7 @@ Usage: def _rbd_mirror_add(self, num=None, hosts=None): spec = orchestrator.StatelessServiceSpec( None, - placement=orchestrator.PlacementSpec(nodes=hosts, count=num)) + placement=orchestrator.PlacementSpec(hosts=hosts, count=num)) completion = self.add_rbd_mirror(spec) self._orchestrator_wait([completion]) orchestrator.raise_if_exception(completion) @@ -399,7 +399,7 @@ Usage: def _rbd_mirror_update(self, num, label=None, hosts=[]): spec = orchestrator.StatelessServiceSpec( None, - placement=orchestrator.PlacementSpec(nodes=hosts, count=num, label=label)) + placement=orchestrator.PlacementSpec(hosts=hosts, count=num, label=label)) completion = self.update_rbd_mirror(spec) self._orchestrator_wait([completion]) orchestrator.raise_if_exception(completion) @@ -424,7 +424,7 @@ Usage: def _mds_add(self, fs_name, num=None, hosts=None): spec = orchestrator.StatelessServiceSpec( fs_name, - placement=orchestrator.PlacementSpec(nodes=hosts, count=num)) + placement=orchestrator.PlacementSpec(hosts=hosts, count=num)) completion = self.add_mds(spec) self._orchestrator_wait([completion]) orchestrator.raise_if_exception(completion) @@ -438,7 +438,7 @@ Usage: "name=hosts,type=CephString,n=N,req=false " 'Update the number of MDS instances for the given fs_name') def _mds_update(self, fs_name, num=None, label=None, hosts=[]): - placement = orchestrator.PlacementSpec(label=label, count=num, nodes=hosts) + placement = orchestrator.PlacementSpec(label=label, count=num, hosts=hosts) placement.validate() spec = orchestrator.StatelessServiceSpec( @@ -483,7 +483,7 @@ Usage: rgw_spec = orchestrator.RGWSpec( rgw_realm=realm_name, rgw_zone=zone_name, - placement=orchestrator.PlacementSpec(nodes=hosts, count=num)) + placement=orchestrator.PlacementSpec(hosts=hosts, count=num)) completion = self.add_rgw(rgw_spec) self._orchestrator_wait([completion]) @@ -502,7 +502,7 @@ Usage: spec = orchestrator.RGWSpec( rgw_realm=realm_name, rgw_zone=zone_name, - placement=orchestrator.PlacementSpec(nodes=hosts, label=label, count=num)) + placement=orchestrator.PlacementSpec(hosts=hosts, label=label, count=num)) completion = self.update_rgw(spec) self._orchestrator_wait([completion]) orchestrator.raise_if_exception(completion) @@ -587,7 +587,7 @@ Usage: 'Update the number of manager instances') def _update_mgrs(self, num=None, hosts=[], label=None): - placement = orchestrator.PlacementSpec(label=label, count=num, nodes=hosts) + placement = orchestrator.PlacementSpec(label=label, count=num, hosts=hosts) placement.validate() spec = orchestrator.StatefulServiceSpec(placement=placement) @@ -605,7 +605,7 @@ Usage: 'Update the number of monitor instances') def _update_mons(self, num=None, hosts=[], label=None): - placement = orchestrator.PlacementSpec(label=label, count=num, nodes=hosts) + placement = orchestrator.PlacementSpec(label=label, count=num, hosts=hosts) if not hosts and not label: # Improve Error message. Point to parse_host_spec examples raise orchestrator.OrchestratorValidationError("Mons need a host spec. (host, network, name(opt))")