]> git.apps.os.sepia.ceph.com Git - teuthology.git/commitdiff
Review: switch to selecting remotes by roles in the 'normal' way 188/head
authorDan Mick <dan.mick@inktank.com>
Fri, 14 Feb 2014 03:44:36 +0000 (19:44 -0800)
committerDan Mick <dan.mick@inktank.com>
Fri, 14 Feb 2014 19:28:08 +0000 (11:28 -0800)
This buys us, also, the ability to select remotes by rule, i.e.
"any osd or mon gets calamari-agent installed"

Signed-off-by: Dan Mick <dan.mick@inktank.com>
teuthology/misc.py
teuthology/task/calamari.py

index 2f7495332bc8495a8c0e688afa38c4fe9a9c7deb..1bc2fa65b21483a1f4071cae375336eb051c70b2 100644 (file)
@@ -872,21 +872,6 @@ def replace_all_with_clients(cluster, config):
         norm_config['client.{id}'.format(id=client)] = config['all']
     return norm_config
 
-def roles_to_remotes(cluster, config, attrname='roles', unique=True):
-    """
-    Get a list of roles from attrname, and return a list of
-    remotes corresponding to those roles.  If 'unique' is False,
-    allow duplicates in the returned remote list (if a remote serves
-    multiple roles).  attrname may not exist, in which case the
-    returned list is empty.
-    """
-    roles = config.get(attrname, list())
-    remotes = []
-    for role in roles:
-        rem = cluster.only(role).remotes.keys()[0]
-        if (not unique) or (rem not in remotes):
-            remotes.append(rem)
-    return remotes
 
 def deep_merge(a, b):
     if a is None:
index 1e49c185d5645c553b424e7e223a7081bf2a75d4..f3c1495f699e59d18ac697496595d42518103470 100644 (file)
@@ -14,6 +14,30 @@ five tasks:
 calamari.test runs on the local machine, as it accesses the Calamari
 server across https using requests.py, which must be present.  It uses
 several external modules in calamari_test/.
+
+Sample configuration:
+roles:
+- [osd.0, osd.1, mon.0, calamari.restapi]
+- [osd.2, osd.3, calamari.server]
+
+tasks:
+- install:
+    branch: dumpling
+- ceph:
+- calamari.reposetup:
+- calamari.agent:
+- calamari.restapi:
+- calamari.server:
+- calamari.test:
+    delay: 40
+
+calamari.reposetup will happen on all osd/mon/calamari.* remotes
+calamari.agent will run on all osd/mon
+calamari.restapi must run on a remote with a monitor
+calamari.server must be able to find calamari.restapi to talk to
+calamari.test has an optional delay to allow the webapp to settle before
+ talking to it (we could make the test retry/timeout instead)
+
 """
 
 from cStringIO import StringIO
@@ -83,6 +107,9 @@ def _setup_calamari_cluster(remote, restapi_remote):
                       stdout=StringIO())
 
 
+def _remotes(ctx, selector):
+    return ctx.cluster.only(selector).remotes.keys()
+
 """
 Tasks
 """
@@ -92,32 +119,41 @@ Tasks
 def agent(ctx, config):
     """
     task agent
-    calamari.agent: install stats collection (for each cluster host)
+    calamari.agent: install stats collection
+       (for each role of type 'mon.' or 'osd.')
 
     For example::
 
+        roles:
+        - [osd.0, mon.a]
+        - [osd.1]
         tasks:
         - calamari.agent:
-           roles:
-               - mon.0
-               - osd.0
-               - osd.1
-           server: server.0
     """
 
     log.info('calamari.agent starting')
     overrides = ctx.config.get('overrides', {})
     teuthology.deep_merge(config, overrides.get('calamari.agent', {}))
 
-    remotes = teuthology.roles_to_remotes(ctx.cluster, config)
+    # agent gets installed on any remote with role mon or osd
+    def needs_agent(role):
+        for type in 'mon.', 'osd.':
+            if role.startswith(type):
+                return True
+        return False
+
+    remotes = _remotes(ctx, needs_agent)
+    if remotes is None:
+        raise RuntimeError('No role configured')
     try:
         for rem in remotes:
             log.info('Installing calamari-agent on %s', rem)
             pkg.install_package('calamari-agent', rem)
-            server_role = config.get('server')
-            if not server_role:
-                raise RuntimeError('must supply \'server\' config key')
-            server_remote = ctx.cluster.only(server_role).remotes.keys()[0]
+            server_remote = _remotes(ctx,
+                lambda r: r.startswith('calamari.server'))
+            if not server_remote:
+                raise RuntimeError('No calamari.server role available')
+            server_remote = server_remote[0]
             # why isn't shortname available by default?
             serverhost = server_remote.name.split('@')[1]
             log.info('configuring Diamond for {}'.format(serverhost))
@@ -135,7 +171,8 @@ def agent(ctx, config):
 def reposetup(ctx, config):
     """
     task reposetup
-    Sets up calamari repository on all remotes; cleans up when done
+    Sets up calamari repository on all 'osd', 'mon', and 'calamari.' remotes;
+     cleans up when done
 
     calamari.reposetup:
         pkgdir:
@@ -163,7 +200,16 @@ def reposetup(ctx, config):
     except KeyError:
         raise RuntimeError('requires pkgdir, username, and password')
 
-    remotes = ctx.cluster.remotes.keys()
+    # repo gets installed on any remote with role mon, osd, or calamari
+    def needs_repo(role):
+        for type in 'mon.', 'osd.', 'calamari.':
+            if role.startswith(type):
+                return True
+        return False
+
+    remotes = _remotes(ctx, needs_repo)
+    if remotes is None:
+        raise RuntimeError('No roles configured')
 
     try:
         for rem in remotes:
@@ -188,23 +234,33 @@ def restapi(ctx, config):
 
     For example::
 
+        roles:
+        - [mon.a, osd.0, osd.1, calamari.restapi]
+        - [osd.2, osd.3]
         tasks:
         - calamari.restapi:
-          roles: mon.0
     """
     overrides = ctx.config.get('overrides', {})
     teuthology.deep_merge(config, overrides.get('calamari.restapi', {}))
 
-    remotes = teuthology.roles_to_remotes(ctx.cluster, config)
+    remotes_and_roles = \
+        ctx.cluster.only(lambda r: r.startswith('calamari.restapi')).remotes
+    if remotes_and_roles is None:
+        raise RuntimeError('No role configured')
+
+    # check that the role selected also has at least one mon role
+    for rem, roles in remotes_and_roles.iteritems():
+        if not any([r for r in roles if r.startswith('mon.')]):
+            raise RuntimeError('no mon on remote with roles %s', roles)
 
     try:
-        for rem in remotes:
+        for rem in remotes_and_roles.iterkeys():
             log.info(rem)
             pkg.install_package('calamari-restapi', rem)
         yield
 
     finally:
-        for rem in remotes:
+        for rem in remotes_and_roles.iterkeys():
             pkg.remove_package('calamari-restapi', rem)
 
 
@@ -213,27 +269,34 @@ def server(ctx, config):
     """
     task server:
 
-    Calamari server setup.  "roles" is a list of roles that should run
-    the webapp, and "restapi_server" is a list of roles that will
-    be running the calamari-restapi package.  Both lists probably should
-    have only one entry (only the first is used).
+    Calamari server setup.  Add role 'calamari.server' to the remote
+    that will run the webapp.  'calamari.restapi' role must be present
+    to serve as the cluster-api target for calamari-server.  Only one
+    of calamari.server and calamari.restapi roles is supported currently.
 
     For example::
 
-        roles: [[server.0], [mon.0], [osd.0, osd.1]]
+        roles:
+        - [calamari.server]
+        - [mon.0, calamari.restapi]
+        - [osd.0, osd.1]
         tasks:
+        - calamari.restapi:
         - calamari.server:
-            roles: [server.0]
-            restapi_server: [mon.0]
     """
     overrides = ctx.config.get('overrides', {})
     teuthology.deep_merge(config, overrides.get('calamari.server', {}))
 
-    remote = teuthology.roles_to_remotes(ctx.cluster, config)[0]
-    restapi_remote = teuthology.roles_to_remotes(ctx.cluster, config,
-                                                 attrname='restapi_server')[0]
+    remote = _remotes(ctx, lambda r: r.startswith('calamari.server'))
+    if not remote:
+        raise RuntimeError('No role configured')
+
+    restapi_remote = _remotes(ctx, lambda r: r.startswith('calamari.restapi'))
     if not restapi_remote:
-        raise RuntimeError('Must supply restapi_server')
+        raise RuntimeError('Must supply calamari.restapi role')
+
+    remote = remote[0]
+    restapi_remote = restapi_remote[0]
 
     try:
         # sqlite3 command is required; on some platforms it's already
@@ -260,7 +323,7 @@ def server(ctx, config):
 def test(ctx, config):
     """
     task test
-    Run the calamari smoketest
+    Run the calamari smoketest on the teuthology host (no role required)
     Tests to run are in calamari_testdir.
     delay: wait this long before starting
 
@@ -273,8 +336,8 @@ def test(ctx, config):
     if delay:
         log.info("delaying %d sec", delay)
         time.sleep(delay)
-    testhost = ctx.cluster.only(config['server']).remotes.keys()[0].name
-    testhost = testhost.split('@')[1]
+    testhost = _remotes(ctx, lambda r: r.startswith('calamari.server'))[0]
+    testhost = testhost.name.split('@')[1]
     mypath = os.path.dirname(__file__)
     cmd_list = [os.path.join(mypath, 'calamari', 'servertest_1_0.py')]
     os.environ['CALAMARI_BASE_URI'] = 'http://{0}/api/v1/'.format(testhost)