]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
orch: extend PlacementSpec and add StatefulServiceSpec
authorJoshua Schmid <jschmid@suse.de>
Wed, 4 Dec 2019 12:37:58 +0000 (13:37 +0100)
committerJoshua Schmid <jschmid@suse.de>
Thu, 12 Dec 2019 09:06:03 +0000 (10:06 +0100)
* add public set_nodes()
* add StatefulServiceSpec

Signed-off-by: Joshua Schmid <jschmid@suse.de>
src/pybind/mgr/orchestrator.py

index 6a8a52f1ef3cda72c9a20beea071e5be4bf817ac..653d0ec216cfcc8e375a17d1cac41c8311cd2174 100644 (file)
@@ -36,7 +36,6 @@ logger = logging.getLogger(__name__)
 
 HostSpec = namedtuple('HostSpec', ['hostname', 'network', 'name'])
 
-
 def parse_host_specs(host, require_network=True):
     """
     Split host into host, network, and (optional) daemon name parts.  The network
@@ -1042,12 +1041,29 @@ class PlacementSpec(object):
     """
     For APIs that need to specify a node subset
     """
-    def __init__(self, label=None, nodes=None):
+    def __init__(self, label=None, nodes=None, count=None):
         self.label = label
         if nodes:
-            self.nodes = [parse_host_specs(x, require_network=False) for x in nodes]
+            self.nodes = [parse_host_specs(x, require_network=False) for x in nodes if x]
         else:
             self.nodes = []
+        self.count = count if count else 1
+
+    def set_nodes(self, nodes):
+        # To backpopulate the .nodes attribute when using labels or count
+        # in the orchestrator backend.
+        self.nodes = nodes
+
+    @classmethod
+    def from_yaml(cls, data):
+        return cls(**data)
+
+    def validate(self):
+        if self.nodes and self.label:
+            # TODO: a less generic Exception
+            raise Exception('Node and label are mutually exclusive')
+        if self.count <= 0:
+            raise Exception("num/count must be > 1")
 
 
 def handle_type_error(method):
@@ -1157,6 +1173,20 @@ class ServiceDescription(object):
         return cls(**data)
 
 
+class StatefulServiceSpec(object):
+    """ Such as mgrs/mons
+    """
+    # TODO: create base class for Stateless/Stateful service specs and propertly inherit
+    def __init__(self,
+                 name=None,
+                 placement=None,
+                 count=None,
+                 scheduler=None):
+        self.placement = PlacementSpec() if placement is None else placement
+        self.name = name
+        self.count = self.placement.count if self.placement else 1  # for backwards-compatibility
+
+
 class StatelessServiceSpec(object):
     # Request to orchestrator for a group of stateless services
     # such as MDS, RGW, nfs gateway, iscsi gateway
@@ -1169,7 +1199,8 @@ class StatelessServiceSpec(object):
     # This structure is supposed to be enough information to
     # start the services.
 
-    def __init__(self, name, placement=None, count=None):
+    def __init__(self, name,
+                 placement=None):
         self.placement = PlacementSpec() if placement is None else placement
 
         #: Give this set of statelss services a name: typically it would
@@ -1178,7 +1209,7 @@ class StatelessServiceSpec(object):
         self.name = name
 
         #: Count of service instances
-        self.count = 1 if count is None else count
+        self.count = self.placement.count if self.placement else 1  # for backwards-compatibility
 
     def validate_add(self):
         if not self.name:
@@ -1228,7 +1259,6 @@ class RGWSpec(StatelessServiceSpec):
         # in Rook itself. Thus we don't set any defaults here in this class.
 
         super(RGWSpec, self).__init__(name=rgw_realm + '.' + rgw_zone,
-                                      count=count,
                                       placement=placement)
 
         #: List of hosts where RGWs should run. Not for Rook.