""" Task for running rbd mirroring daemons and configuring mirroring """ import logging from teuthology.orchestra import run from teuthology import misc from teuthology.exceptions import ConfigError from teuthology.task import Task from tasks.ceph_manager import get_valgrind_args from tasks.util import get_remote_for_role log = logging.getLogger(__name__) class RBDMirror(Task): """ Run an rbd-mirror daemon to sync rbd images between clusters. This requires two clients (one from each cluster) on the same host to connect with. The pool configuration should be adjusted by later test scripts to include the remote client and cluster name. This task just needs to know how to connect to the local cluster. For example: roles: - [primary.mon.a, primary.osd.0, primary.osd.1, primary.osd.2] - [secondary.mon.a, secondary.osd.0, secondary.osd.1, secondary.osd.2] - [primary.client.mirror, secondary.client.mirror] tasks: - ceph: cluster: primary - ceph: cluster: secondary - rbd-mirror: client: primary.client.mirror To mirror back to the primary cluster as well, add another rbd_mirror instance: - rbd-mirror: client: secondary.client.mirror Possible options for this task are: client: role - ceph client to connect as valgrind: [--tool=] - none by default coverage: bool - whether this run may be collecting coverage data thrash: bool - whether this run may be thrashed """ def __init__(self, ctx, config): super(RBDMirror, self).__init__(ctx, config) self.log = log def setup(self): super(RBDMirror, self).setup() try: self.client = self.config['client'] except KeyError: raise ConfigError('rbd-mirror requires a client to connect with') self.cluster_name, type_, self.client_id = misc.split_role(self.client) if type_ != 'client': msg = 'client role ({0}) must be a client'.format(self.client) raise ConfigError(msg) self.remote = get_remote_for_role(self.ctx, self.client) def begin(self): super(RBDMirror, self).begin() testdir = misc.get_testdir(self.ctx) daemon_signal = 'kill' if 'coverage' in self.config or 'valgrind' in self.config or \ self.config.get('thrash', False): daemon_signal = 'term' args = [ 'adjust-ulimits', 'ceph-coverage', '{tdir}/archive/coverage'.format(tdir=testdir), 'daemon-helper', daemon_signal, ] if 'valgrind' in self.config: args = get_valgrind_args( testdir, 'rbd-mirror-{id}'.format(id=self.client), args, self.config.get('valgrind') ) args.extend([ 'rbd-mirror', '--foreground', '--cluster', self.cluster_name, '--id', self.client_id, ]) self.ctx.daemons.add_daemon( self.remote, 'rbd-mirror', self.client, cluster=self.cluster_name, args=args, logger=self.log.getChild(self.client), stdin=run.PIPE, wait=False, ) def end(self): mirror_daemon = self.ctx.daemons.get_daemon('rbd-mirror', self.client, self.cluster_name) mirror_daemon.stop() super(RBDMirror, self).end() task = RBDMirror