mgr/orchestrator: unify StatelessServiceSpec and StatefulServiceSpec

Both classes are essentially equal. Keeping both just makes thigs
more compicated.

Signed-off-by: Sebastian Wagner <sebastian.wagner@suse.com>
This commit is contained in:
Sebastian Wagner 2020-02-10 11:58:06 +01:00
parent 67a2a4e7aa
commit 80a2a70893
9 changed files with 52 additions and 64 deletions

View File

@ -242,6 +242,8 @@ Service Actions
.. automethod:: Orchestrator.service_action
.. autoclass:: ServiceSpec
OSD management
--------------
@ -287,8 +289,6 @@ Phase two is a call to :meth:`Orchestrator.create_osds` with a Drive Group with
Stateless Services
------------------
.. autoclass:: StatelessServiceSpec
.. automethod:: Orchestrator.add_mds
.. automethod:: Orchestrator.remove_mds
.. automethod:: Orchestrator.update_mds

View File

@ -1756,7 +1756,7 @@ class CephadmOrchestrator(MgrModule, orchestrator.OrchestratorClientMixin):
extra_config=extra_config)
def update_mons(self, spec):
# type: (orchestrator.StatefulServiceSpec) -> orchestrator.Completion
# type: (orchestrator.ServiceSpec) -> orchestrator.Completion
"""
Adjust the number of cluster managers.
"""
@ -1768,7 +1768,7 @@ class CephadmOrchestrator(MgrModule, orchestrator.OrchestratorClientMixin):
return self._update_mons(spec)
def _update_mons(self, spec):
# type: (orchestrator.StatefulServiceSpec) -> orchestrator.Completion
# type: (orchestrator.ServiceSpec) -> orchestrator.Completion
"""
Adjust the number of cluster monitors.
"""
@ -1826,7 +1826,7 @@ class CephadmOrchestrator(MgrModule, orchestrator.OrchestratorClientMixin):
@with_services('mgr')
def update_mgrs(self, spec, services):
# type: (orchestrator.StatefulServiceSpec, List[orchestrator.ServiceDescription]) -> orchestrator.Completion
# type: (orchestrator.ServiceSpec, List[orchestrator.ServiceDescription]) -> orchestrator.Completion
"""
Adjust the number of cluster managers.
"""
@ -2265,19 +2265,19 @@ class NodeAssignment(object):
"""
def __init__(self,
spec=None, # type: Optional[orchestrator.StatefulServiceSpec]
spec=None, # type: Optional[orchestrator.ServiceSpec]
scheduler=None, # type: Optional[BaseScheduler]
get_hosts_func=None, # type: Optional[Callable]
service_type=None, # type: Optional[str]
):
assert spec and get_hosts_func and service_type
self.spec = spec # type: orchestrator.StatefulServiceSpec
self.spec = spec # type: orchestrator.ServiceSpec
self.scheduler = scheduler if scheduler else SimpleScheduler(self.spec.placement)
self.get_hosts_func = get_hosts_func
self.service_type = service_type
def load(self):
# type: () -> orchestrator.StatefulServiceSpec
# type: () -> orchestrator.ServiceSpec
"""
Load nodes into the spec.placement.nodes container.
"""

View File

@ -10,7 +10,7 @@ except ImportError:
pass
from orchestrator import ServiceDescription, InventoryNode, \
StatelessServiceSpec, PlacementSpec, RGWSpec, StatefulServiceSpec, HostSpec
ServiceSpec, PlacementSpec, RGWSpec, HostSpec
from tests import mock
from .fixtures import cephadm_module, wait
@ -105,7 +105,7 @@ class TestCephadm(object):
def test_mon_update(self, _send_command, _get_connection, cephadm_module):
with self._with_host(cephadm_module, 'test'):
ps = PlacementSpec(hosts=['test:0.0.0.0=a'], count=1)
c = cephadm_module.update_mons(StatefulServiceSpec(placement=ps))
c = cephadm_module.update_mons(ServiceSpec(placement=ps))
assert wait(cephadm_module, c) == ["Deployed mon.a on host 'test'"]
@mock.patch("cephadm.module.CephadmOrchestrator._run_cephadm", _run_cephadm('[]'))
@ -115,7 +115,7 @@ class TestCephadm(object):
def test_mgr_update(self, _send_command, _get_connection, cephadm_module):
with self._with_host(cephadm_module, 'test'):
ps = PlacementSpec(hosts=['test:0.0.0.0=a'], count=1)
c = cephadm_module.update_mgrs(StatefulServiceSpec(placement=ps))
c = cephadm_module.update_mgrs(ServiceSpec(placement=ps))
[out] = wait(cephadm_module, c)
assert "Deployed mgr." in out
assert " on host 'test'" in out
@ -157,7 +157,7 @@ class TestCephadm(object):
def test_mds(self, _send_command, _get_connection, cephadm_module):
with self._with_host(cephadm_module, 'test'):
ps = PlacementSpec(hosts=['test'], count=1)
c = cephadm_module.add_mds(StatelessServiceSpec('name', placement=ps))
c = cephadm_module.add_mds(ServiceSpec('name', placement=ps))
[out] = wait(cephadm_module, c)
assert "Deployed mds.name." in out
assert " on host 'test'" in out
@ -202,7 +202,7 @@ class TestCephadm(object):
def test_rbd_mirror(self, _send_command, _get_connection, cephadm_module):
with self._with_host(cephadm_module, 'test'):
ps = PlacementSpec(hosts=['test'], count=1)
c = cephadm_module.add_rbd_mirror(StatelessServiceSpec(name='name', placement=ps))
c = cephadm_module.add_rbd_mirror(ServiceSpec(name='name', placement=ps))
[out] = wait(cephadm_module, c)
assert "Deployed rbd-mirror." in out
assert " on host 'test'" in out

View File

@ -907,7 +907,7 @@ class Orchestrator(object):
raise NotImplementedError()
def update_mgrs(self, spec):
# type: (StatefulServiceSpec) -> Completion
# type: (ServiceSpec) -> Completion
"""
Update the number of cluster managers.
@ -917,7 +917,7 @@ class Orchestrator(object):
raise NotImplementedError()
def update_mons(self, spec):
# type: (StatefulServiceSpec) -> Completion
# type: (ServiceSpec) -> Completion
"""
Update the number of cluster monitors.
@ -927,7 +927,7 @@ class Orchestrator(object):
raise NotImplementedError()
def add_mds(self, spec):
# type: (StatelessServiceSpec) -> Completion
# type: (ServiceSpec) -> Completion
"""Create a new MDS cluster"""
raise NotImplementedError()
@ -937,7 +937,7 @@ class Orchestrator(object):
raise NotImplementedError()
def update_mds(self, spec):
# type: (StatelessServiceSpec) -> Completion
# type: (ServiceSpec) -> Completion
"""
Update / redeploy existing MDS cluster
Like for example changing the number of service instances.
@ -945,7 +945,7 @@ class Orchestrator(object):
raise NotImplementedError()
def add_rbd_mirror(self, spec):
# type: (StatelessServiceSpec) -> Completion
# type: (ServiceSpec) -> Completion
"""Create rbd-mirror cluster"""
raise NotImplementedError()
@ -955,7 +955,7 @@ class Orchestrator(object):
raise NotImplementedError()
def update_rbd_mirror(self, spec):
# type: (StatelessServiceSpec) -> Completion
# type: (ServiceSpec) -> Completion
"""
Update / redeploy rbd-mirror cluster
Like for example changing the number of service instances.
@ -1200,51 +1200,39 @@ class ServiceDescription(object):
return cls(**data)
class StatefulServiceSpec(object):
""" Such as mgrs/mons
class ServiceSpec(object):
"""
# TODO: create base class for Stateless/Stateful service specs and propertly inherit
Details of service creation.
Request to the orchestrator for a cluster of daemons
such as MDS, RGW, iscsi gateway, MONs, MGRs, Prometheus
This structure is supposed to be enough information to
start the services.
"""
def __init__(self, name=None, placement=None):
# type: (Optional[str], Optional[PlacementSpec]) -> None
self.placement = PlacementSpec() if placement is None else placement # type: PlacementSpec
self.name = name
# for backwards-compatibility
#: Give this set of stateless services a name: typically it would
#: be the name of a CephFS filesystem, RGW zone, etc. Must be unique
#: within one ceph cluster. Note: Not all clusters have a name
self.name = name # type: Optional[str]
if self.placement is not None and self.placement.count is not None:
self.count = self.placement.count
#: Count of service instances. Deprecated.
self.count = self.placement.count # type: int
else:
self.count = 1
class StatelessServiceSpec(object):
# Request to orchestrator for a group of stateless services
# such as MDS, RGW, nfs gateway, iscsi gateway
"""
Details of stateless service creation.
Request to orchestrator for a group of stateless services
such as MDS, RGW or iscsi gateway
"""
# This structure is supposed to be enough information to
# start the services.
def __init__(self, name, placement=None):
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 # type: str
#: Count of service instances
self.count = self.placement.count if self.placement is not None else 1 # for backwards-compatibility
def validate_add(self):
if not self.name:
raise OrchestratorValidationError('Cannot add Service: Name required')
class NFSServiceSpec(StatelessServiceSpec):
class NFSServiceSpec(ServiceSpec):
def __init__(self, name, pool=None, namespace=None, placement=None):
super(NFSServiceSpec, self).__init__(name, placement)
@ -1261,7 +1249,7 @@ class NFSServiceSpec(StatelessServiceSpec):
raise OrchestratorValidationError('Cannot add NFS: No Pool specified')
class RGWSpec(StatelessServiceSpec):
class RGWSpec(ServiceSpec):
"""
Settings to configure a (multisite) Ceph RGW

View File

@ -408,7 +408,7 @@ Usage:
"name=hosts,type=CephString,n=N,req=false",
'Create an rbd-mirror service')
def _rbd_mirror_add(self, num=None, hosts=None):
spec = orchestrator.StatelessServiceSpec(
spec = orchestrator.ServiceSpec(
None,
placement=orchestrator.PlacementSpec(hosts=hosts, count=num))
completion = self.add_rbd_mirror(spec)
@ -423,7 +423,7 @@ Usage:
"name=label,type=CephString,req=false",
'Update the number of rbd-mirror instances')
def _rbd_mirror_update(self, num, label=None, hosts=[]):
spec = orchestrator.StatelessServiceSpec(
spec = orchestrator.ServiceSpec(
None,
placement=orchestrator.PlacementSpec(hosts=hosts, count=num, label=label))
completion = self.update_rbd_mirror(spec)
@ -448,7 +448,7 @@ Usage:
"name=hosts,type=CephString,n=N,req=false",
'Create an MDS service')
def _mds_add(self, fs_name, num=None, hosts=None):
spec = orchestrator.StatelessServiceSpec(
spec = orchestrator.ServiceSpec(
fs_name,
placement=orchestrator.PlacementSpec(hosts=hosts, count=num))
completion = self.add_mds(spec)
@ -467,7 +467,7 @@ Usage:
placement = orchestrator.PlacementSpec(label=label, count=num, hosts=hosts)
placement.validate()
spec = orchestrator.StatelessServiceSpec(
spec = orchestrator.ServiceSpec(
fs_name,
placement=placement)
@ -630,7 +630,7 @@ Usage:
placement = orchestrator.PlacementSpec(label=label, count=num, hosts=hosts)
placement.validate()
spec = orchestrator.StatefulServiceSpec(placement=placement)
spec = orchestrator.ServiceSpec(placement=placement)
completion = self.update_mgrs(spec)
self._orchestrator_wait([completion])
@ -650,7 +650,7 @@ Usage:
placement = orchestrator.PlacementSpec(label=label, count=num, hosts=hosts)
placement.validate()
spec = orchestrator.StatefulServiceSpec(placement=placement)
spec = orchestrator.ServiceSpec(placement=placement)
completion = self.update_mons(spec)
self._orchestrator_wait([completion])

View File

@ -304,7 +304,7 @@ class RookOrchestrator(MgrModule, orchestrator.Orchestrator):
)
def add_mds(self, spec):
# type: (orchestrator.StatelessServiceSpec) -> RookCompletion
# type: (orchestrator.ServiceSpec) -> RookCompletion
return self._service_add_decorate('MDS', spec,
self.rook_cluster.add_filesystem)
@ -341,7 +341,7 @@ class RookOrchestrator(MgrModule, orchestrator.Orchestrator):
)
def update_mons(self, spec):
# type: (orchestrator.StatefulServiceSpec) -> RookCompletion
# type: (orchestrator.ServiceSpec) -> RookCompletion
if spec.placement.hosts or spec.placement.label:
raise RuntimeError("Host list or label is not supported by rook.")
@ -352,7 +352,7 @@ class RookOrchestrator(MgrModule, orchestrator.Orchestrator):
)
def update_mds(self, spec):
# type: (orchestrator.StatelessServiceSpec) -> RookCompletion
# type: (orchestrator.ServiceSpec) -> RookCompletion
num = spec.count
return write_completion(
lambda: self.rook_cluster.update_mds_count(spec.name, num),

View File

@ -336,7 +336,7 @@ class RookCluster(object):
raise
def add_filesystem(self, spec):
# type: (orchestrator.StatelessServiceSpec) -> None
# type: (orchestrator.ServiceSpec) -> None
# TODO use spec.placement
# TODO warn if spec.extended has entries we don't kow how
# to action.

View File

@ -284,14 +284,14 @@ class TestOrchestrator(MgrModule, orchestrator.Orchestrator):
@deferred_write("update_mgrs")
def update_mgrs(self, spec):
# type: (orchestrator.StatefulServiceSpec) -> None
# type: (orchestrator.ServiceSpec) -> None
assert not spec.placement.hosts or len(spec.placement.hosts) == spec.placement.count
assert all([isinstance(h, str) for h in spec.placement.hosts])
@deferred_write("update_mons")
def update_mons(self, spec):
# type: (orchestrator.StatefulServiceSpec) -> None
# type: (orchestrator.ServiceSpec) -> None
assert not spec.placement.hosts or len(spec.placement.hosts) == spec.placement.count
assert all([isinstance(h[0], str) for h in spec.placement.hosts])

View File

@ -34,7 +34,7 @@ def remove_filesystem(mgr, fs_name):
return mgr.mon_command(command)
def create_mds(mgr, fs_name):
spec = orchestrator.StatelessServiceSpec(fs_name)
spec = orchestrator.ServiceSpec(fs_name)
try:
completion = mgr.add_mds(spec)
mgr._orchestrator_wait([completion])