diff --git a/ansible/install/group_vars/all.yml b/ansible/install/group_vars/all.yml index 89f395057..8eefd23a1 100644 --- a/ansible/install/group_vars/all.yml +++ b/ansible/install/group_vars/all.yml @@ -68,9 +68,15 @@ pbench_internal_url: # linpack url linpack_url: http://registrationcenter-download.intel.com/akdlm/irc_nas/9752/l_mklb_p_2018.3.011.tgz linpack_path: /benchmarks_2018/linux/mkl/benchmarks/linpack/ +sysbench_url : http://pkgs.fedoraproject.org/repo/pkgs/sysbench/sysbench-0.4.12.tar.gz/3a6d54fdd3fe002328e4458206392b9d/sysbench-0.4.12.tar.gz # Browbeat Rally workloads browbeat_workloads: + sysbench: + name: browbeat-sysbench + src: sysbench-user.file + dest: "{{ browbeat_path }}/sysbench-user.file" + image: centos7 linpack: name: browbeat-linpack src: linpack-user.file diff --git a/ansible/install/roles/workloads/tasks/main.yml b/ansible/install/roles/workloads/tasks/main.yml index 03600f3d5..b5fd06ac5 100644 --- a/ansible/install/roles/workloads/tasks/main.yml +++ b/ansible/install/roles/workloads/tasks/main.yml @@ -19,7 +19,7 @@ shell: source {{ overcloudrc }} ; nova console-log {{ item.stdout }} register: guest_output until: guest_output.stdout.find("Browbeat workload installed") != -1 - retries: 10 + retries: 30 with_items: "{{ workload_ids.results }}" - name: Clean up glance diff --git a/ansible/install/roles/workloads/templates/sysbench-user.file b/ansible/install/roles/workloads/templates/sysbench-user.file new file mode 100644 index 000000000..ccf9f860c --- /dev/null +++ b/ansible/install/roles/workloads/templates/sysbench-user.file @@ -0,0 +1,46 @@ +#!/bin/bash +sudo echo "nameserver {{ dns_server }}" > /etc/resolv.conf +if [ $? -gt 0 ] +then + exit 1 +fi +sudo yum install -y wget libtool.x86_64 openssl-devel.x86_64 openssl-static.x86_64 +if [ $? -gt 0 ] +then + exit 1 +fi + +# When wget is performed, special characters appear in stdout which cause encoding errors. +# So the output is redirected to a temporary text file. + +wget {{ sysbench_url }} >> /opt/temp.txt 2>&1 +sudo tar -xvzf {{ sysbench_url | basename }} >> /opt/temp.txt 2>&1 +sudo rm -rf /opt/temp.txt + +sudo mkdir /opt/sysbench +sudo cp -r {{ sysbench_url | basename | replace(".tar.gz", "") }}/* /opt/sysbench/ + +pushd /opt/sysbench/ +sudo libtoolize --force --copy +sudo ./autogen.sh +sudo ./configure --without-mysql +if [ $? -gt 0 ] +then + exit 1 +fi +sudo make +if [ $? -gt 0 ] +then + exit 1 +fi +sudo make install + +# Allow for root access +sudo sed -i 's/disable_root: 1/disable_root: 0/g' /etc/cloud/cloud.cfg +cat /etc/cloud/cloud.cfg | grep disable_root +if [ $? -gt 0 ] +then + exit 1 +fi + +echo "Browbeat workload installed" diff --git a/browbeat-config.yaml b/browbeat-config.yaml index 61c7aaacf..575efdfb7 100644 --- a/browbeat-config.yaml +++ b/browbeat-config.yaml @@ -258,6 +258,17 @@ workloads: net_id: file: rally/rally-plugins/workloads/linpack.yml + - name: sysbench + enabled: true + image_name: browbeat-sysbench + flavor_name: m1.small + external_network: + net_id: + # test_name: Type of Sysbench Benchmark to be run. Example: cpu + test_name: cpu + cpu_max_prime: + file: rally/rally-plugins/workloads/sysbench.yml + - name: browbeat-pbench-uperf enabled: true user: root diff --git a/conf/browbeat-workloads.yml b/conf/browbeat-workloads.yml index fecc24a14..f08d88c4e 100644 --- a/conf/browbeat-workloads.yml +++ b/conf/browbeat-workloads.yml @@ -73,6 +73,18 @@ workloads: net_id: file: rally/rally-plugins/workloads/linpack.yml + - name: sysbench + enabled: true + user: root + image_name: browbeat-sysbench + flavor_name: m1.small + external_network: + net_id: + # test_name: Type of Sysbench Benchmark to be run. Example: cpu + test_name: cpu + cpu_max_prime: + file: rally/rally-plugins/workloads/sysbench.yml + - name: browbeat-pbench-uperf enabled: true user: root diff --git a/rally/rally-plugins/workloads/sysbench.py b/rally/rally-plugins/workloads/sysbench.py new file mode 100644 index 000000000..8b52de206 --- /dev/null +++ b/rally/rally-plugins/workloads/sysbench.py @@ -0,0 +1,90 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging + +from rally.plugins.openstack.scenarios.neutron import utils as neutron_utils +from rally.plugins.openstack.scenarios.vm import utils as vm_utils +from rally.common import sshutils +from rally.task import scenario +from rally.task import types +from rally.task import validation +from rally import consts + +LOG = logging.getLogger(__name__) + +@types.convert(image={"type": "glance_image"}, flavor={"type": "nova_flavor"}) +@validation.add("image_valid_on_flavor", flavor_param="flavor", image_param="image") +@validation.add("required_services", services=[consts.Service.NEUTRON, consts.Service.NOVA]) +@validation.add("required_platform", platform="openstack", users=True) +@scenario.configure(context={"cleanup@openstack": ["neutron", "nova"], + "keypair@openstack": {}, "allow_ssh@openstack": None}, + name="BrowbeatPlugin.sysbench", platform="openstack") +class BrowbeatSysbench(neutron_utils.NeutronScenario,vm_utils.VMScenario): + def build_host(self, external, image, flavor, user, password=None, **kwargs): + keyname = self.context["user"]["keypair"]["name"] + host, host_ip = self._boot_server_with_fip(image, + flavor, + use_floating_ip=True, + floating_network=external[ + 'name'], + key_name=keyname, + **kwargs) + # Wait for ping + self._wait_for_ping(host_ip['ip']) + + # Open SSH Connection + host_ssh = sshutils.SSH(user, host_ip['ip'], 22, self.context[ + "user"]["keypair"]["private"], password) + + # Check for connectivity + self._wait_for_ssh(host_ssh) + + return host_ssh, host_ip, host + + def run(self, image, flavor, user, test_name, cpu_max_prime=10000, external=None, + password="", network_id=None, **kwargs): + + sysbench_path = "/opt/sysbench" + + if not network_id: + router = self._create_router({}, external_gw=external) + network = self._create_network({}) + subnet = self._create_subnet(network, {}) + kwargs["nics"] = [{'net-id': network['network']['id']}] + self._add_interface_router(subnet['subnet'], router['router']) + else: + kwargs["nics"] = [{'net-id': network_id}] + + host_ssh, host_ip, host = self.build_host( + external, image, flavor, user, **kwargs) + cmd = "cd {}".format(sysbench_path) + LOG.info("Running command : {}".format(cmd)) + exitcode, stdout, stderr = host_ssh.execute(cmd) + if exitcode is 1: + LOG.error(stderr) + return False + if test_name == "cpu": + sysbench = "sysbench --test=cpu --cpu-max-prime={} run".format(cpu_max_prime) + sysbench += " | grep '{}' | grep -E -o '[0-9]+([.][0-9]+)?'".format("total time: ") + LOG.info("Starting sysbench with CPU test") + LOG.info("Running command : {}".format(sysbench)) + test_exitcode, test_stdout, test_stderr = host_ssh.execute(sysbench) + if test_exitcode is not 1: + LOG.info("Result: {}".format(test_stdout)) + report = [[cpu_max_prime,float(test_stdout)]] + self.add_output(additive={"title": "Sysbench Stats", + "description": "Sysbench CPU Scenario", + "chart_plugin": "StatsTable", + "data": report}) + else: + LOG.error(test_stderr) diff --git a/rally/rally-plugins/workloads/sysbench.yml b/rally/rally-plugins/workloads/sysbench.yml new file mode 100644 index 000000000..f6f2eb960 --- /dev/null +++ b/rally/rally-plugins/workloads/sysbench.yml @@ -0,0 +1,45 @@ +{% set image_name = image_name or 'browbeat-sysbench' %} +{% set flavor_name = flavor_name or 'm1.small' %} +{% set password = password or 'None' %} +{% set net_id = net_id or 'None' %} +{% set sla_max_avg_duration = sla_max_avg_duration or 60 %} +{% set sla_max_failure = sla_max_failure or 0 %} +{% set sla_max_seconds = sla_max_seconds or 60 %} +--- +BrowbeatPlugin.sysbench: + - + args: + image: + name: '{{image_name}}' + flavor: + name: '{{flavor_name}}' + external: + name: '{{external_network}}' + user: '{{user}}' + test_name: '{{test_name}}' + cpu_max_prime: '{{cpu_max_prime}}' + password: '{{password}}' + network_id: '{{net_id}}' + runner: + concurrency: 1 + times: 1 + type: "constant" + context: + users: + tenants: 1 + users_per_tenant: 1 + quotas: + neutron: + network: -1 + port: -1 + router: -1 + subnet: -1 + nova: + instances: -1 + cores: -1 + ram: -1 + sla: + max_avg_duration: {{sla_max_avg_duration}} + max_seconds_per_iteration: {{sla_max_seconds}} + failure_rate: + max: {{sla_max_failure}}