Skip to content

Commit

Permalink
[WIP] Add support for OSProfiler
Browse files Browse the repository at this point in the history
  • Loading branch information
rcherrueau committed Apr 26, 2017
1 parent eb8f79d commit 3369a62
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 93 deletions.
3 changes: 3 additions & 0 deletions enos/ansible/group_vars/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ os_env:
OS_IDENTITY_API_VERSION: 3
OS_REGION_NAME: "{{ openstack_region_name }}"

# Pip package to download rally
rally_pip : "rally"

# list of available patchs
# to enable one patch copy past its description
# to your local config file and enable it
Expand Down
151 changes: 95 additions & 56 deletions enos/ansible/roles/bench/tasks/rally.yml
Original file line number Diff line number Diff line change
@@ -1,73 +1,112 @@
---
# Install and launch a rally benchmark
- name: Install rally result directory
file: path=/root/rally_home state=directory owner=65500
- name: Install rally dependencies
apt: name={{ item }} state=present
with_items:
- libpq-dev
- libxml2-dev
- libxslt1-dev
# rally
- build-essential
- libssl-dev
- libffi-dev
# - python-virtualenv
- python-netifaces
- python-dev

- name: Test whether the rally database has been initialized or not
stat: path=/root/rally_home/.rally.sqlite
register: sqlite
# Note: apt: python-pymongo is too old for OSProfiler
- name: Install python mongo client for OSProfiler
pip:
name: pymongo
state: present

# TODO: Do that in a virtualenv using ansible:pip virtualenv
- name: Install custom Rally
pip:
name: "{{ rally_pip }}"
state: present
editable: false

- name: Create Rally result directory
file: path=/root/rally_home state=directory

- name: Create Rally configuration directory
file: path=/etc/rally state=directory

- name: Build Rally configuration and set database to sqlite
copy:
content: "[database]\nconnection='sqlite:////root/rally_home/.rally.sqlite'"
dest: /etc/rally/rally.conf

- name: Initialize database
when: not sqlite.stat.exists
docker_container:
name: "{{ 'database' | to_uuid }}"
image: rallyforge/rally
state: started
volumes:
- /root/rally_home:/home/rally
command: rally-manage db create

# NOTE(msimonin): without the pause
# the file seems not to be synced in the next task.
# Relaunching the play a second time is also a possible wokaround.
- pause: seconds=1
command: rally-manage db recreate
args:
chdir: /root/rally_home

- name: Test whether the rally deployment has been created or not
command: docker run -v /root/rally_home:/home/rally rallyforge/rally rally deployment list
register: deployment
# NOTE: without the pause the file seems not to be synced in the next
# task. Relaunching the play a second time is also a possible
# wokaround.
- pause: seconds=1

- name: Deploy discovery context
when: "'discovery' not in deployment.stdout"
docker_container:
name: "{{ 'deployment' | to_uuid }}"
image: rallyforge/rally
state: started
volumes:
- /root/rally_home:/home/rally
env: "{{ os_env }}"
command: rally deployment create --fromenv --name=discovery
command: rally deployment create --fromenv --name=discovery
args:
chdir: /root/rally_home
environment: "{{ os_env }}"

- name: Copy rally scenarios
copy: src={{ bench.location }} dest=/root/rally_home/ owner=655500
copy: src="{{ bench.location }}" dest=/root/rally_home/

- name: debug
debug: msg="rally task start {{ bench.location | basename }} --task-args '{{ bench.args }}'"

# NOTE(msimonin): ansible 2.2.0 breaks the return value.
# see https://github.com/BeyondTheClouds/enos/issues/41
- name: Run rally benchmark
docker_container:
name: "{{ bench.location | to_uuid }}"
image: rallyforge/rally
state: started
volumes:
- /root/rally_home:/home/rally
command: rally task start {{ bench.location | basename }} --task-args '{{ bench.args }}'
register: docker_output

- name: Wait for the end of the test, this may take a while...
command: "docker ps -q --filter id={{ docker_output.ansible_facts.ansible_docker_container.Id }}"
register: finished
until: finished.stdout == ""
delay: 20
retries: 10000

- name: List available rally reports
command: docker run -v /root/rally_home:/home/rally rallyforge/rally rally task list --uuids-only
debug: msg="rally task start /root/rally_home/{{ bench.location | basename}} --task-args '{{ bench.args }}' {{ '--os-profile SECRET_KEY' if bench.osprofiler }}"

- name: Run Rally benchmark
command: rally task start {{ bench.location | basename }} --task-args '{{ bench.args }}' {{ '--os-profile SECRET_KEY' if bench.osprofiler }}
args:
chdir: /root/rally_home
register: rally_output

- name: Output of Rally execution
debug: msg="{{ rally_output }}"

- name: List available Rally reports
command: rally task list --uuids-only
args:
chdir: /root/rally_home
register: list

# Download rally results only if there are some reports to get back
- name: Generating rally reports (html)
command: rally task report --tasks {{ list.stdout | replace('\n', ' ') }} --out rally-{{ bench.location | basename }}.html
args:
chdir: /root/rally_home
when: list.stdout != ""

- name: Generating rally reports
command: docker run -v /root/rally_home:/home/rally rallyforge/rally rally task report --tasks {{ list.stdout | replace('\n', ' ') }} --out report.html
- name: Generation rally reports (json)
command: rally task report --tasks {{ list.stdout | replace('\n', ' ') }} --out rally-{{ bench.location | basename }}.json
args:
chdir: /root/rally_home
when: list.stdout != ""

- name: Get OSProfiler Trace Id
shell: echo "{{ rally_output.stdout }}" | grep 'osprofiler trace show --html' | sed 's/osprofiler trace show --html //g'
register: trace_id
when: "{{ bench.osprofiler | bool }}"

- name: Output of OSProfiler Trace ID
debug: msg="OSProfiler Trace ID {{ trace_id.stdout_lines[0] }}"
when: "{{ bench.osprofiler | bool }}"

- name: Generating OSProfiler trace (json)
command: osprofiler trace show --json --out trace-{{ bench.location | basename }}.json {{ trace_id.stdout_lines[0] }}
args:
chdir: /root/rally_home
environment: "{{ os_env }}"
when: "{{ bench.osprofiler | bool }}"

- name: Generation OSprofiler trace (html)
command: osprofiler trace show --html --out trace-{{ bench.location | basename }}.html {{ trace_id.stdout_lines[0] }}
args:
chdir: /root/rally_home
environment: "{{ os_env }}"
when: "{{ bench.osprofiler | bool }}"
6 changes: 5 additions & 1 deletion enos/ansible/roles/bootstrap_kolla/files/passwords.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
ceilometer_database_password: demo
ceilometer_keystone_password: demo
ceph_cluster_fsid: demo
cinder_database_password: demo
cinder_keystone_password: demo
Expand Down Expand Up @@ -28,7 +30,6 @@ murano_database_password: demo
murano_keystone_password: demo
neutron_database_password: demo
neutron_keystone_password: demo
placement_keystone_password: demo
nova_api_database_password: demo
nova_database_password: demo
nova_keystone_password: demo
Expand Down Expand Up @@ -87,6 +88,9 @@ nova_ssh_key:
-----END RSA PRIVATE KEY-----'
public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDB4/0Og1pgRqvb9NaPJs6UmTjtbjdC03rlwEUwbBratFuM/D/Qyj2j7AwZQCwLOqMFVtIrDW+pbTgsKo0pDCcU9VFiyP+8ixY2YMuNgXKFW1BjvQLxhJzaj9EJvBBLZMWAzfrWczakKKJrEJSEoL7M3YQPeN13XIcVVN8SADTS1+ZvSshvodVbvTN+YyaEVQanc5VB2b3NjSVDPBQAoeBVVX+qgR77nIaALflcXYm0hKh2C+AVH6+BG5tkN3QSkf0QuhonvkB2a2ZVN41vYMdIMEfRqqu9b4IirDdpBc4uQ0LPWRYLHE3DmKjiNN2VFKE/K9he2OS9groDSFOJzAM/
panko_database_password: demo
panko_keystone_password: demo
placement_keystone_password: demo
rabbitmq_cluster_cookie: demo
rabbitmq_password: demo
rbd_secret_uuid: demo
Expand Down
1 change: 0 additions & 1 deletion enos/ansible/roles/utils/tasks/ips.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@
src: ips.txt.j2
dest: "{{ ips_file }}"
delegate_to: localhost
run_once: true
39 changes: 17 additions & 22 deletions enos/enos.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
command.
"""
from utils.constants import (SYMLINK_NAME, TEMPLATE_DIR, ANSIBLE_DIR,
NETWORK_IFACE, EXTERNAL_IFACE, VERSION)
from utils.constants import (SYMLINK_NAME, ANSIBLE_DIR, NETWORK_IFACE,
EXTERNAL_IFACE, VERSION)
from utils.extra import (run_ansible, generate_inventory,
bootstrap_kolla, to_abs_path, pop_ip,
make_provider)
make_provider, mk_enos_values)

from utils.network_constraints import (build_grp_constraints,
build_ip_constraints)
Expand Down Expand Up @@ -147,7 +147,8 @@ def up(env=None, **kwargs):
'network_interface': eths[NETWORK_IFACE],
'resultdir': env['resultdir'],
'rabbitmq_password': "demo",
'database_password': "demo"
'database_password': "demo",
'external_vip': pop_ip(env)
})

# Executes hooks and runs playbook that initializes resources (eg,
Expand Down Expand Up @@ -191,23 +192,9 @@ def install_os(env=None, **kwargs):
kolla_path),
shell=True)

# Construct values required by kolla-ansible playbooks
required_kolla_values = {
'neutron_external_address': pop_ip(env),
'network_interface': env['eths'][NETWORK_IFACE],
'kolla_internal_vip_address': env['config']['vip'],
'neutron_external_interface': env['eths'][EXTERNAL_IFACE],
'influx_vip': env['config']['influx_vip'],
'kolla_ref': env['config']['kolla_ref'],
'resultdir': env['resultdir']
}
if 'enable_monitoring' in env['config']:
required_kolla_values['enable_monitoring'] = \
env['config']['enable_monitoring']

# Bootstrap kolla running by patching kolla sources (if any) and
# generating admin-openrc, globals.yml, passwords.yml
bootstrap_kolla(env, required_kolla_values)
bootstrap_kolla(env)

# Construct kolla-ansible command...
kolla_cmd = [os.path.join(kolla_path, "tools", "kolla-ansible")]
Expand Down Expand Up @@ -376,19 +363,24 @@ def cartesian(d):
return product

logging.debug('phase[bench]: args=%s' % kwargs)

workload_dir = kwargs["--workload"]

playbook_values = mk_enos_values(env)
with open(os.path.join(workload_dir, "run.yml")) as workload_f:
workload = yaml.load(workload_f)
for bench_type, desc in workload.items():
scenarios = desc.get("scenarios", [])
for scenario in scenarios:
print(scenario)
# merging args
top_args = desc.get("args", {})
args = scenario.get("args", {})
top_args.update(args)
# merging enabled, skipping if not enabled
top_enabled = desc.get("enabled", True)
enabled = scenario.get("enabled", True)
osprofiler = scenario.get("osprofiler", False)
if not (top_enabled and enabled):
continue
for a in cartesian(top_args):
Expand All @@ -398,15 +390,18 @@ def cartesian(d):
'multinode')
# NOTE(msimonin) all the scenarios must reside on
# the workload directory
env['config']['bench'] = {
playbook_values.update(bench={
'type': bench_type,
'location': os.path.abspath(
os.path.join(workload_dir,
scenario["file"])),
'file': scenario["file"],
'osprofiler': osprofiler,
'args': a
}
run_ansible([playbook_path], inventory_path, env['config'])
})
run_ansible([playbook_path],
inventory_path,
playbook_values)


@enostask("""
Expand Down
Loading

0 comments on commit 3369a62

Please sign in to comment.