Task to deploy clusters with DeepSea
'''
import logging
+import time
from teuthology import misc
from teuthology.orchestra import run
log = logging.getLogger(__name__)
class DeepSea(Task):
+ """
+ Automated DeepSea integration testing via teuthology: set up a Salt
+ cluster, clone the DeepSea git repo, run DeepSea integration test(s)
+ The number of machines in the cluster is determined by the roles stanza, as
+ usual. One, and only one, of the machines must have a role of type
+ "master", e.g. master.1 or master.a (the part following the dot is not
+ significant, but must be there).
+
+ The task starts the Salt Master daemon on the master node, and Salt Minion
+ daemons on all the nodes (including the master node), and ensures that the
+ minions are properly linked to the master. TODO: The role types are stored
+ in the role grain on the minions.
+
+ After that, the DeepSea git repo is cloned to the master node (in
+ accordance with the "repo" and "branch" options, if given).
+
+ Finally, the task iterates over the list of commands given in the "exec"
+ property, executing each one inside the 'qa/' directory of the DeepSea repo
+ clone.
+
+ Possible options for this task are:
+
+ repo: (DeepSea git repo, defaults to https://github.com/SUSE/DeepSea.git)
+ branch: (DeepSea git branch, defaults to master)
+ exec: (list of commands, relative to qa/ of the DeepSea repo)
+
+ Example:
+
+ tasks
+ - deepsea:
+ exec:
+ - suites/basic/health-ok.sh
+ """
def __init__(self, ctx, config):
super(DeepSea, self).__init__(ctx, config)
+ # make sure self.config dict has values for important keys
if config is None:
config = {}
assert isinstance(config, dict), \
'deepsea task only accepts a dict for configuration'
self.config["repo"] = config.get('repo', 'https://github.com/SUSE/DeepSea.git')
self.config["branch"] = config.get('branch', 'master')
+ self.config["exec"] = config.get('exec', ['suites/basic/health-ok.sh'])
+ assert isinstance(self.config["exec"], list), \
+ 'exec property of deepsea yaml must be a list'
+
+ # prepare the list of commands to be executed on the master node
+ self.exec_cmd = []
+ assert len(self.config["exec"]) > 0, \
+ 'deepsea exec list must have at least one element'
+ for cmd in self.config["exec"]:
+ self.exec_cmd.append('cd DeepSea/qa ; ' + cmd)
# determine the role id of the master role
if(misc.num_instances_of_type(self.cluster, 'master') != 1):
# into a string
self.config["master_remote"] = get_remote_for_role(self.ctx,
master_role).name
+ self.log.info("master remote: {}".format(self.config["master_remote"]))
self.salt = Salt(self.ctx, self.config)
def setup(self):
self.log.info("DeepSea repo: {}".format(self.config["repo"]))
self.log.info("DeepSea branch: {}".format(self.config["branch"]))
- self.log.info("master remote: {}".format(self.config["master_remote"]))
self.salt.master_remote.run(args=[
'git',
'clone',
+ '--depth',
+ '1',
'--branch',
self.config["branch"],
self.config["repo"],
+ ])
+
+ self.log.info("printing DeepSea branch name and sha1...")
+ self.salt.master_remote.run(args=[
+ 'cd',
+ 'DeepSea',
run.Raw(';'),
+ 'git',
+ 'rev-parse',
+ '--abbrev-ref',
+ 'HEAD',
+ run.Raw(';'),
+ 'git',
+ 'rev-parse',
+ 'HEAD',
+ ])
+
+ self.log.info("Running \"make install\" in DeepSea clone...")
+ self.salt.master_remote.run(args=[
'cd',
'DeepSea',
run.Raw(';'),
self.salt.ping_minions()
- self.log.info("listing contents of DeepSea/qa/ directory tree...")
- self.salt.master_remote.run(args=[
- 'ls',
- '-lR',
- '--color=never',
- 'DeepSea/qa/'
- ])
-
- self.log.info("running basic-health-ok.sh workunit...")
- self.salt.master_remote.run(args=[
- 'sudo',
- 'DeepSea/qa/workunits/basic-health-ok.sh'
- ])
-
-
def begin(self):
super(DeepSea, self).begin()
+ for cmd in self.exec_cmd:
+ self.log.info(
+ "command to be executed on master node: {}".format(cmd)
+ )
+ self.salt.master_remote.run(args=[
+ 'sudo', 'sh', '-c',
+ cmd
+ ])
def end(self):
+ # replace this hack with DeepSea purge when it's ready
+ for _remote, _ in self.ctx.cluster.remotes.iteritems():
+ self.log.info("stopping OSD services on {}"
+ .format(_remote.hostname))
+ _remote.run(args=[
+ 'sudo', 'sh', '-c',
+ 'systemctl stop ceph-osd.target ; sleep 10'
+ ])
+ self.log.info("unmounting OSD data devices on {}"
+ .format(_remote.hostname))
+ _remote.run(args=[
+ 'sudo', 'sh', '-c',
+ 'umount /dev/vdb2 ; umount /dev/vdc2'
+ ])
super(DeepSea, self).end()
task = DeepSea