mirror of https://github.com/ceph/ceph
121 lines
3.6 KiB
Python
121 lines
3.6 KiB
Python
"""
|
|
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=<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
|