Add stress-ng plugin to run workloads within vms

The aim of this patch is to not only spawn a bunch of
vm's but also run some stress test inside the vm's.The
patch creates jumphost on network with fip and all
other vm's on the same neutron network so that jumphost
can access the other vm's and run the stress tests.

You need to set the following params to run this plugin:
- specify the external network in browbeat-config.yaml
- In the group_vars/all.yml install_browbeat_workloads: true,
  browbeat_network, in browbeat-workloads enable stress-ng

Change-Id: Ica15af5de0c60916fd89661fb411e4bd10382b8f
This commit is contained in:
Asma Syed Hameed 2020-07-22 17:04:36 +05:30
parent f6b24967d6
commit 934eaf78af
6 changed files with 208 additions and 5 deletions

View File

@ -123,6 +123,13 @@ browbeat_workloads:
image: cirro5
enabled: false
flavor: m1.tiny-cirros
stress_ng:
name: browbeat-stress-ng
src: stress-ng-user.file
dest: "{{ browbeat_path }}/stress-ng-user.file"
image: centos7
enabled: false
flavor: m1.small
########################################
# Other Install Configuration Items

View File

@ -21,7 +21,7 @@
shell: source {{ overcloudrc }} ; nova console-log {{ item.stdout }}
register: guest_output
until: guest_output.stdout.find("Browbeat workload installed") != -1
retries: 30
retries: 60
with_items: "{{ workload_ids.results }}"
when: item.changed

View File

@ -0,0 +1,11 @@
#!/bin/bash
sudo yum clean all
sudo yum install -y epel-release
sudo yum install -y stress-ng
sudo sed -i 's/disable_root: 1/disable_root: 0/g' /etc/cloud/cloud.cfg
sudo sed -i 's/^.*sleep 10" //g' /root/.ssh/authorized_keys
sudo cat /root/.ssh/authorized_keys
sudo cat /etc/cloud/cloud.cfg
sudo chattr +i /etc/cloud/cloud.cfg
echo "Browbeat workload installed"

View File

@ -520,7 +520,7 @@ workloads:
times: 1
scenarios:
- name: linpack
enabled: true
enabled: false
image_name: browbeat-linpack
flavor_name: m1.small
external_network:
@ -528,7 +528,7 @@ workloads:
file: rally/rally-plugins/workloads/linpack.yml
- name: sysbench
enabled: true
enabled: false
user: root
image_name: browbeat-sysbench
flavor_name: m1.small
@ -540,7 +540,7 @@ workloads:
file: rally/rally-plugins/workloads/sysbench.yml
- name: browbeat-pbench-uperf
enabled: true
enabled: false
user: root
image_name: browbeat-uperf
flavor_name: m1.small
@ -562,7 +562,7 @@ workloads:
file: rally/rally-plugins/workloads/pbench-uperf.yml
- name: browbeat-abench
enabled: true
enabled: false
user: centos
image_name: browbeat-abench
flavor_name: m1.small
@ -579,6 +579,21 @@ workloads:
send_results: true
file: rally/rally-plugins/workloads/abench.yml
- name: browbeat-stress-ng
enabled: false
username: centos
image_name: browbeat-stress-ng
flavor_name: m1.small
external_network:
ssh_timeout: 120
num_clients: 2
cpu: 4
io: 2
vm: 1
vm_bytes: '1G'
timeout: '60s'
file: rally/rally-plugins/workloads/stress-ng.yml
- name: dynamic-workloads
enabled: false
type: rally

View File

@ -0,0 +1,119 @@
# 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_openstack import consts
from rally_openstack.scenarios.vm import utils as vm_utils
from rally_openstack.scenarios.neutron import utils as neutron_utils
from rally.common import sshutils
from rally.task import scenario
from rally.task import types
from rally.task import validation
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("number", param_name="port", minval=1, maxval=65535,
nullable=True, integer_only=True)
@validation.add("external_network_exists", param_name="floating_network")
@validation.add("required_services", services=[consts.Service.NOVA])
@validation.add("required_param_or_context",
param_name="image", ctx_name="image_command_customizer")
@validation.add("required_platform", platform="openstack", users=True)
@scenario.configure(context={"cleanup@openstack": ["nova", "neutron"],
"keypair@openstack": {},
"allow_ssh@openstack": None},
name="BrowbeatPlugin.stress_ng",
platform="openstack")
class BrowbeatStressNg(vm_utils.VMScenario, neutron_utils.NeutronScenario):
def run(self, flavor, username, ssh_timeout, num_clients,
command, image=None, floating_network=None, port=22,
use_floating_ip=True, **kwargs):
"""Create a jumphost on network with fip and all
other vm's on the same neutron network so that jumphost
can access the other vm's and run the stress tests
:param flavor: VM flavor name
:param username: ssh username on server
:param ssh_timeout: ssh timeout in seconds
:param num_clients: no.of clients
:param command: command that runs inside the client vm's
:param floating_network: external network name, for floating ip
:param port: ssh port for SSH connection
:param use_floating_ip: bool, floating or fixed IP for SSH connection
:param kwargs: optional args to create a VM
"""
jump_host, fip = self._boot_server_with_fip(
image, flavor, use_floating_ip=use_floating_ip,
floating_network=floating_network,
key_name=self.context["user"]["keypair"]["name"],
**kwargs)
ssh = sshutils.SSH(username, fip["ip"], port=port, pkey=self.context[
"user"]["keypair"]["private"])
self._wait_for_ssh(ssh, timeout=ssh_timeout)
# Write id_rsa to get to guests.
self._run_command_over_ssh(ssh, {'remote_path': "rm -rf ~/.ssh"})
self._run_command_over_ssh(ssh, {'remote_path': "mkdir ~/.ssh"})
ssh.run(
"cat > ~/.ssh/id_rsa",
stdin=self.context["user"]["keypair"]["private"])
ssh.execute("chmod 0600 ~/.ssh/id_rsa")
_clients = self.create_clients(
ssh, num_clients, image, flavor, username, **kwargs)
# Run stress test
for sip in _clients:
cmd = " {} 'ssh {}@{}' ".format(command, username, sip)
exitcode, stdout, stderr = ssh.execute(cmd)
LOG.error(" couldn't run the stress-ng command: {}".format(stderr))
def create_clients(self, jump_ssh, num_clients, image, flavor, user, **kwargs):
"""Creates Client VM's
:param jump_ssh: ssh connection
:param num_clients: no.of clients
:param image: VM image name
:param flavor: VM flavor name
:param user: ssh username on server
:param kwargs: optional args to create a VM
"""
_clients = []
for i in range(num_clients):
LOG.info("Launching Client : {}".format(i))
server = self._boot_server(
image,
flavor,
key_name=self.context["user"]["keypair"]["name"],
**kwargs)
for net in server.addresses:
network_name = net
break
if network_name is None:
return False
# IP Address
_clients.append(
str(server.addresses[network_name][0]["addr"]))
for sip in _clients:
cmd = "ssh -o StrictHostKeyChecking=no {}@{} /bin/true".format(
user, sip)
s1_exitcode, s1_stdout, s1_stderr = jump_ssh.execute(cmd)
return _clients

View File

@ -0,0 +1,51 @@
{% set flavor_name = flavor_name or "m1.small" %}
{% set image_name = image_name or "browbeat-stress-ng" %}
{% set username = username or "centos7" %}
{% set num_clients = num_clients or 2 %}
{% set cpu = cpu or 4 %}
{% set io = io or 2 %}
{% set password = password or 'None' %}
{% set vm = vm or 1 %}
{% set vm_bytes = vm_bytes or "1G" %}
{% set timeout = timeout or "60s" %}
{% set ssh_timeout = ssh_timeout or 120 %}
{% 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.stress_ng:
-
args:
flavor:
name: "{{flavor_name}}"
image:
name: "{{image_name}}"
floating_network: "{{external_network}}"
username: "{{username}}"
ssh_timeout: {{ssh_timeout}}
num_clients: {{num_clients}}
command: "stress-ng --cpu {{cpu}} --io {{io}} --vm {{vm}} --vm-bytes {{vm_bytes}} --timeout {{timeout}} --metrics-brief"
runner:
type: "constant"
times: {{times}}
concurrency: {{concurrency}}
context:
users:
tenants: 3
users_per_tenant: 2
network: {}
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}}