2017-09-07 22:44:48 +00:00
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
import yaml
|
|
|
|
|
|
|
|
from teuthology import misc
|
|
|
|
from teuthology.orchestra import run
|
|
|
|
from teuthology.task import Task
|
|
|
|
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class CBT(Task):
|
|
|
|
"""
|
|
|
|
Passes through a CBT configuration yaml fragment.
|
|
|
|
"""
|
|
|
|
def __init__(self, ctx, config):
|
|
|
|
super(CBT, self).__init__(ctx, config)
|
|
|
|
self.log = log
|
|
|
|
|
|
|
|
def hosts_of_type(self, type_):
|
|
|
|
return [r.name for r in self.ctx.cluster.only(misc.is_type(type_)).remotes.keys()]
|
|
|
|
|
|
|
|
def generate_cbt_config(self):
|
|
|
|
mon_hosts = self.hosts_of_type('mon')
|
|
|
|
osd_hosts = self.hosts_of_type('osd')
|
|
|
|
client_hosts = self.hosts_of_type('client')
|
2018-04-25 23:00:11 +00:00
|
|
|
rgw_client = {}
|
|
|
|
rgw_client[client_hosts[0]] = None
|
|
|
|
rgw_hosts = self.config.get('cluster', {}).get('rgws', rgw_client)
|
2017-09-07 22:44:48 +00:00
|
|
|
cluster_config = dict(
|
|
|
|
user=self.config.get('cluster', {}).get('user', 'ubuntu'),
|
|
|
|
head=mon_hosts[0],
|
|
|
|
osds=osd_hosts,
|
|
|
|
mons=mon_hosts,
|
|
|
|
clients=client_hosts,
|
2018-04-25 23:00:11 +00:00
|
|
|
rgws=rgw_hosts,
|
2017-09-07 22:44:48 +00:00
|
|
|
osds_per_node=self.config.get('cluster', {}).get('osds_per_node', 1),
|
|
|
|
rebuild_every_test=False,
|
|
|
|
use_existing=True,
|
2018-04-25 23:00:11 +00:00
|
|
|
is_teuthology=self.config.get('cluster', {}).get('is_teuthology', True),
|
2017-09-07 22:44:48 +00:00
|
|
|
iterations=self.config.get('cluster', {}).get('iterations', 1),
|
|
|
|
tmp_dir='/tmp/cbt',
|
|
|
|
pool_profiles=self.config.get('cluster', {}).get('pool_profiles'),
|
|
|
|
)
|
2018-04-25 23:00:11 +00:00
|
|
|
|
2017-09-12 15:26:27 +00:00
|
|
|
benchmark_config = self.config.get('benchmarks')
|
qa/tasks: use next(iter(..)) for accessing first element in a view
in python2, dict.values() and dict.keys() return lists. but in python3,
they return views, which cannot be indexed directly using an integer index.
there are three use cases when we access these views in python3:
1. get the first element
2. get all the elements and then *might* want to access them by index
3. get the first element assuming there is only a single element in
the view
4. iterate thru the view
in the 1st case, we cannot assume the number of elements, so to be
python3 compatible, we should use `next(iter(a_dict))` instead.
in the 2nd case, in this change, the view is materialized using
`list(a_dict)`.
in the 3rd case, we can just continue using the short hand of
```py
(first_element,) = a_dict.keys()
```
to unpack the view. this works in both python2 and python3.
in the 4th case, the existing code works in both python2 and python3, as
both list and view can be iterated using `iter`, and `len` works as
well.
Signed-off-by: Kefu Chai <kchai@redhat.com>
2020-03-31 02:16:40 +00:00
|
|
|
benchmark_type = next(iter(benchmark_config.keys()))
|
2019-06-12 00:33:53 +00:00
|
|
|
if benchmark_type in ['librbdfio', 'fio']:
|
2017-09-12 15:26:27 +00:00
|
|
|
testdir = misc.get_testdir(self.ctx)
|
2019-06-12 00:33:53 +00:00
|
|
|
benchmark_config[benchmark_type]['cmd_path'] = os.path.join(testdir, 'fio/fio')
|
2018-04-25 23:00:11 +00:00
|
|
|
if benchmark_type == 'cosbench':
|
|
|
|
# create cosbench_dir and cosbench_xml_dir
|
|
|
|
testdir = misc.get_testdir(self.ctx)
|
|
|
|
benchmark_config['cosbench']['cosbench_dir'] = os.path.join(testdir, 'cos')
|
|
|
|
benchmark_config['cosbench']['cosbench_xml_dir'] = os.path.join(testdir, 'xml')
|
|
|
|
self.ctx.cluster.run(args=['mkdir', '-p', '-m0755', '--', benchmark_config['cosbench']['cosbench_xml_dir']])
|
|
|
|
benchmark_config['cosbench']['controller'] = osd_hosts[0]
|
|
|
|
|
|
|
|
# set auth details
|
|
|
|
remotes_and_roles = self.ctx.cluster.remotes.items()
|
|
|
|
ips = [host for (host, port) in
|
|
|
|
(remote.ssh.get_transport().getpeername() for (remote, role_list) in remotes_and_roles)]
|
2019-06-07 00:21:38 +00:00
|
|
|
benchmark_config['cosbench']['auth'] = "username=cosbench:operator;password=intel2012;url=http://%s:80/auth/v1.0;retry=9" %(ips[0])
|
2019-06-12 00:33:53 +00:00
|
|
|
client_endpoints_config = self.config.get('client_endpoints', None)
|
2018-04-25 23:00:11 +00:00
|
|
|
|
2017-09-07 22:44:48 +00:00
|
|
|
return dict(
|
|
|
|
cluster=cluster_config,
|
2017-09-12 15:26:27 +00:00
|
|
|
benchmarks=benchmark_config,
|
2019-06-12 00:33:53 +00:00
|
|
|
client_endpoints = client_endpoints_config,
|
2017-09-07 22:44:48 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
def install_dependencies(self):
|
|
|
|
system_type = misc.get_system_type(self.first_mon)
|
|
|
|
|
|
|
|
if system_type == 'rpm':
|
|
|
|
install_cmd = ['sudo', 'yum', '-y', 'install']
|
2019-12-16 16:17:26 +00:00
|
|
|
cbt_depends = ['python3-yaml', 'python3-lxml', 'librbd-devel', 'pdsh', 'collectl']
|
2017-09-07 22:44:48 +00:00
|
|
|
else:
|
|
|
|
install_cmd = ['sudo', 'apt-get', '-y', '--force-yes', 'install']
|
2019-12-16 16:17:26 +00:00
|
|
|
cbt_depends = ['python3-yaml', 'python3-lxml', 'librbd-dev', 'collectl']
|
2017-09-07 22:44:48 +00:00
|
|
|
self.first_mon.run(args=install_cmd + cbt_depends)
|
2018-04-25 23:00:11 +00:00
|
|
|
|
qa/tasks: use next(iter(..)) for accessing first element in a view
in python2, dict.values() and dict.keys() return lists. but in python3,
they return views, which cannot be indexed directly using an integer index.
there are three use cases when we access these views in python3:
1. get the first element
2. get all the elements and then *might* want to access them by index
3. get the first element assuming there is only a single element in
the view
4. iterate thru the view
in the 1st case, we cannot assume the number of elements, so to be
python3 compatible, we should use `next(iter(a_dict))` instead.
in the 2nd case, in this change, the view is materialized using
`list(a_dict)`.
in the 3rd case, we can just continue using the short hand of
```py
(first_element,) = a_dict.keys()
```
to unpack the view. this works in both python2 and python3.
in the 4th case, the existing code works in both python2 and python3, as
both list and view can be iterated using `iter`, and `len` works as
well.
Signed-off-by: Kefu Chai <kchai@redhat.com>
2020-03-31 02:16:40 +00:00
|
|
|
benchmark_type = next(iter(self.cbt_config.get('benchmarks').keys()))
|
2018-04-25 23:00:11 +00:00
|
|
|
self.log.info('benchmark: %s', benchmark_type)
|
|
|
|
|
2019-06-12 00:33:53 +00:00
|
|
|
if benchmark_type in ['librbdfio', 'fio']:
|
2018-04-25 23:00:11 +00:00
|
|
|
# install fio
|
|
|
|
testdir = misc.get_testdir(self.ctx)
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'git', 'clone', '-b', 'master',
|
|
|
|
'https://github.com/axboe/fio.git',
|
|
|
|
'{tdir}/fio'.format(tdir=testdir)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'cd', os.path.join(testdir, 'fio'), run.Raw('&&'),
|
|
|
|
'./configure', run.Raw('&&'),
|
|
|
|
'make'
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
if benchmark_type == 'cosbench':
|
|
|
|
# install cosbench
|
2018-09-18 03:21:13 +00:00
|
|
|
self.log.info('install dependencies for cosbench')
|
2018-04-25 23:00:11 +00:00
|
|
|
if system_type == 'rpm':
|
|
|
|
cosbench_depends = ['wget', 'unzip', 'java-1.7.0-openjdk', 'curl']
|
|
|
|
else:
|
|
|
|
cosbench_depends = ['wget', 'unzip', 'openjdk-8-jre', 'curl']
|
|
|
|
self.first_mon.run(args=install_cmd + cosbench_depends)
|
|
|
|
testdir = misc.get_testdir(self.ctx)
|
|
|
|
cosbench_version = '0.4.2.c3'
|
2018-06-05 00:23:21 +00:00
|
|
|
cosbench_location = 'https://github.com/intel-cloud/cosbench/releases/download/v0.4.2.c3/0.4.2.c3.zip'
|
|
|
|
os_version = misc.get_system_type(self.first_mon, False, True)
|
|
|
|
|
|
|
|
# additional requirements for bionic
|
|
|
|
if os_version == '18.04':
|
|
|
|
self.first_mon.run(
|
|
|
|
args=['sudo', 'apt-get', '-y', 'purge', 'openjdk-11*'])
|
|
|
|
# use our own version of cosbench
|
|
|
|
cosbench_version = 'cosbench-0.4.2.c3.1'
|
2018-09-18 03:21:13 +00:00
|
|
|
# contains additional parameter "-N" to nc
|
2018-06-05 00:23:21 +00:00
|
|
|
cosbench_location = 'http://drop.ceph.com/qa/cosbench-0.4.2.c3.1.zip'
|
|
|
|
cosbench_dir = os.path.join(testdir, cosbench_version)
|
|
|
|
self.ctx.cluster.run(args=['mkdir', '-p', '-m0755', '--', cosbench_dir])
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'cd', testdir, run.Raw('&&'),
|
|
|
|
'wget',
|
|
|
|
cosbench_location, run.Raw('&&'),
|
|
|
|
'unzip', '{name}.zip'.format(name=cosbench_version), '-d', cosbench_version
|
|
|
|
]
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'cd', testdir, run.Raw('&&'),
|
|
|
|
'wget',
|
|
|
|
cosbench_location, run.Raw('&&'),
|
|
|
|
'unzip', '{name}.zip'.format(name=cosbench_version)
|
|
|
|
]
|
|
|
|
)
|
2018-04-25 23:00:11 +00:00
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'cd', testdir, run.Raw('&&'),
|
|
|
|
'ln', '-s', cosbench_version, 'cos',
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'cd', os.path.join(testdir, 'cos'), run.Raw('&&'),
|
|
|
|
'chmod', '+x', run.Raw('*.sh'),
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
# start cosbench and check info
|
|
|
|
self.log.info('start cosbench')
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'cd', testdir, run.Raw('&&'),
|
|
|
|
'cd', 'cos', run.Raw('&&'),
|
|
|
|
'sh', 'start-all.sh'
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.log.info('check cosbench info')
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'cd', testdir, run.Raw('&&'),
|
|
|
|
'cd', 'cos', run.Raw('&&'),
|
|
|
|
'sh', 'cli.sh', 'info'
|
|
|
|
]
|
|
|
|
)
|
2017-09-07 22:44:48 +00:00
|
|
|
|
|
|
|
def checkout_cbt(self):
|
|
|
|
testdir = misc.get_testdir(self.ctx)
|
2017-10-25 17:22:43 +00:00
|
|
|
repo = self.config.get('repo', 'https://github.com/ceph/cbt.git')
|
2017-09-07 22:44:48 +00:00
|
|
|
branch = self.config.get('branch', 'master')
|
|
|
|
branch = self.config.get('force-branch', branch)
|
|
|
|
sha1 = self.config.get('sha1')
|
2019-08-12 08:50:14 +00:00
|
|
|
if sha1 is None:
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'git', 'clone', '--depth', '1', '-b', branch, repo,
|
|
|
|
'{tdir}/cbt'.format(tdir=testdir)
|
|
|
|
]
|
|
|
|
)
|
|
|
|
else:
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'git', 'clone', '-b', branch, repo,
|
|
|
|
'{tdir}/cbt'.format(tdir=testdir)
|
|
|
|
]
|
|
|
|
)
|
2017-09-07 22:44:48 +00:00
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'cd', os.path.join(testdir, 'cbt'), run.Raw('&&'),
|
|
|
|
'git', 'reset', '--hard', sha1,
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
def setup(self):
|
|
|
|
super(CBT, self).setup()
|
qa/tasks: use next(iter(..)) for accessing first element in a view
in python2, dict.values() and dict.keys() return lists. but in python3,
they return views, which cannot be indexed directly using an integer index.
there are three use cases when we access these views in python3:
1. get the first element
2. get all the elements and then *might* want to access them by index
3. get the first element assuming there is only a single element in
the view
4. iterate thru the view
in the 1st case, we cannot assume the number of elements, so to be
python3 compatible, we should use `next(iter(a_dict))` instead.
in the 2nd case, in this change, the view is materialized using
`list(a_dict)`.
in the 3rd case, we can just continue using the short hand of
```py
(first_element,) = a_dict.keys()
```
to unpack the view. this works in both python2 and python3.
in the 4th case, the existing code works in both python2 and python3, as
both list and view can be iterated using `iter`, and `len` works as
well.
Signed-off-by: Kefu Chai <kchai@redhat.com>
2020-03-31 02:16:40 +00:00
|
|
|
self.first_mon = next(iter(self.ctx.cluster.only(misc.get_first_mon(self.ctx, self.config)).remotes.keys()))
|
2017-09-07 22:44:48 +00:00
|
|
|
self.cbt_config = self.generate_cbt_config()
|
|
|
|
self.log.info('cbt configuration is %s', self.cbt_config)
|
|
|
|
self.cbt_dir = os.path.join(misc.get_archive_dir(self.ctx), 'cbt')
|
|
|
|
self.ctx.cluster.run(args=['mkdir', '-p', '-m0755', '--', self.cbt_dir])
|
2020-07-20 10:33:48 +00:00
|
|
|
self.first_mon.write_file(
|
|
|
|
os.path.join(self.cbt_dir, 'cbt_config.yaml'),
|
|
|
|
yaml.safe_dump(self.cbt_config, default_flow_style=False))
|
2017-09-07 22:44:48 +00:00
|
|
|
self.checkout_cbt()
|
|
|
|
self.install_dependencies()
|
|
|
|
|
|
|
|
def begin(self):
|
|
|
|
super(CBT, self).begin()
|
|
|
|
testdir = misc.get_testdir(self.ctx)
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'{tdir}/cbt/cbt.py'.format(tdir=testdir),
|
|
|
|
'-a', self.cbt_dir,
|
|
|
|
'{cbtdir}/cbt_config.yaml'.format(cbtdir=self.cbt_dir),
|
|
|
|
],
|
|
|
|
)
|
2017-12-06 21:23:44 +00:00
|
|
|
preserve_file = os.path.join(self.ctx.archive, '.preserve')
|
|
|
|
open(preserve_file, 'a').close()
|
2017-09-07 22:44:48 +00:00
|
|
|
|
|
|
|
def end(self):
|
|
|
|
super(CBT, self).end()
|
|
|
|
testdir = misc.get_testdir(self.ctx)
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'rm', '--one-file-system', '-rf', '--',
|
|
|
|
'{tdir}/cbt'.format(tdir=testdir),
|
|
|
|
]
|
|
|
|
)
|
qa/tasks: use next(iter(..)) for accessing first element in a view
in python2, dict.values() and dict.keys() return lists. but in python3,
they return views, which cannot be indexed directly using an integer index.
there are three use cases when we access these views in python3:
1. get the first element
2. get all the elements and then *might* want to access them by index
3. get the first element assuming there is only a single element in
the view
4. iterate thru the view
in the 1st case, we cannot assume the number of elements, so to be
python3 compatible, we should use `next(iter(a_dict))` instead.
in the 2nd case, in this change, the view is materialized using
`list(a_dict)`.
in the 3rd case, we can just continue using the short hand of
```py
(first_element,) = a_dict.keys()
```
to unpack the view. this works in both python2 and python3.
in the 4th case, the existing code works in both python2 and python3, as
both list and view can be iterated using `iter`, and `len` works as
well.
Signed-off-by: Kefu Chai <kchai@redhat.com>
2020-03-31 02:16:40 +00:00
|
|
|
benchmark_type = next(iter(self.cbt_config.get('benchmarks').keys()))
|
2019-06-12 00:33:53 +00:00
|
|
|
if benchmark_type in ['librbdfio', 'fio']:
|
2018-04-25 23:00:11 +00:00
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'rm', '--one-file-system', '-rf', '--',
|
|
|
|
'{tdir}/fio'.format(tdir=testdir),
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
if benchmark_type == 'cosbench':
|
2018-06-05 00:23:21 +00:00
|
|
|
os_version = misc.get_system_type(self.first_mon, False, True)
|
|
|
|
if os_version == '18.04':
|
|
|
|
cosbench_version = 'cosbench-0.4.2.c3.1'
|
|
|
|
else:
|
|
|
|
cosbench_version = '0.4.2.c3'
|
2019-10-26 00:20:05 +00:00
|
|
|
# note: stop-all requires 'nc'
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'cd', testdir, run.Raw('&&'),
|
|
|
|
'cd', 'cos', run.Raw('&&'),
|
|
|
|
'sh', 'stop-all.sh',
|
|
|
|
run.Raw('||'), 'true'
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'sudo', 'killall', '-9', 'java',
|
|
|
|
run.Raw('||'), 'true'
|
|
|
|
]
|
|
|
|
)
|
2018-04-25 23:00:11 +00:00
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'rm', '--one-file-system', '-rf', '--',
|
|
|
|
'{tdir}/cos'.format(tdir=testdir),
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'rm', '--one-file-system', '-rf', '--',
|
2018-06-05 00:23:21 +00:00
|
|
|
'{tdir}/{version}'.format(tdir=testdir, version=cosbench_version),
|
2018-04-25 23:00:11 +00:00
|
|
|
]
|
|
|
|
)
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'rm', '--one-file-system', '-rf', '--',
|
2018-06-05 00:23:21 +00:00
|
|
|
'{tdir}/{version}.zip'.format(tdir=testdir, version=cosbench_version),
|
2018-04-25 23:00:11 +00:00
|
|
|
]
|
|
|
|
)
|
|
|
|
self.first_mon.run(
|
|
|
|
args=[
|
|
|
|
'rm', '--one-file-system', '-rf', '--',
|
|
|
|
'{tdir}/xml'.format(tdir=testdir),
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
2017-09-07 22:44:48 +00:00
|
|
|
|
|
|
|
task = CBT
|