Skip to content

Commit 60154d7

Browse files
committed
[rally] Add Rally role and test_operator integration
Add a new `rally` Ansible role that runs OpenStack Rally benchmarks inside a podman container (quay.io/airshipit/xrally-openstack:3.0.0). The role auto-discovers OpenStack credentials from the cluster's KeystoneAPI resource and appends the deployment CA to the trust bundle so SSL verification works without any manual configuration. Wire Rally into the `test_operator` multi-stage framework via a new `rally_runner.yml` dispatcher and `cifmw_test_operator_rally_*` defaults, so it can run as a named stage alongside Tempest. Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: lkuchlan <lkuchlan@redhat.com>
1 parent 240c126 commit 60154d7

14 files changed

Lines changed: 523 additions & 0 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
- name: Ensure Rally prerequisites exist
3+
hosts: "{{ cifmw_target_hook_host | default('localhost') }}"
4+
gather_facts: false
5+
environment:
6+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
7+
PATH: "{{ cifmw_path }}"
8+
tasks:
9+
- name: Create m1.tiny flavor if missing
10+
ansible.builtin.shell: |
11+
set -xe -o pipefail
12+
oc -n {{ namespace }} rsh openstackclient \
13+
openstack flavor show m1.tiny &>/dev/null || \
14+
oc -n {{ namespace }} rsh openstackclient \
15+
openstack flavor create m1.tiny \
16+
--ram 512 --disk 1 --vcpus 1 --public

roles/rally/OWNERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# See the OWNERS docs at https://www.kubernetes.dev/docs/guide/owners/
2+
3+
approvers:
4+
- ciops-team
5+
6+
reviewers:
7+
- ciops-team

roles/rally/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# rally
2+
Role to setup and run Rally benchmarking tests against an OpenStack deployment.
3+
4+
Rally is run inside the `quay.io/airshipit/xrally-openstack` container via podman.
5+
OpenStack credentials are discovered automatically from the Kubernetes KeystoneAPI resource,
6+
or can be supplied directly via `cifmw_rally_os_*` variables.
7+
8+
## Prerequisites
9+
- `oc` CLI available and pointing to the target OpenStack cluster (used for credential and CA discovery).
10+
- `cifmw_openstack_namespace` must be set to the OpenStack namespace (typically `openstack`).
11+
12+
## Privilege escalation
13+
become - Required to install podman and fix artifact directory ownership after the container run.
14+
15+
## Parameters
16+
17+
* `cifmw_rally_artifacts_basedir`: (String) Directory where all Rally artifacts are stored.
18+
Default: `{{ cifmw_basedir }}/tests/rally`
19+
* `cifmw_rally_registry`: (String) Container registry. Default: `quay.io`
20+
* `cifmw_rally_namespace`: (String) Registry namespace. Default: `airshipit`
21+
* `cifmw_rally_container`: (String) Container image name. Default: `xrally-openstack`
22+
* `cifmw_rally_image`: (String) Full image reference. Composed from registry/namespace/container.
23+
* `cifmw_rally_image_tag`: (String) Container image tag. Default: `3.0.0`
24+
* `cifmw_rally_dry_run`: (Boolean) Skip actual container execution. Default: `false`
25+
* `cifmw_rally_remove_container`: (Boolean) Remove container after run. Default: `true`
26+
* `cifmw_rally_fail_on_task_failure`: (Boolean) Fail the play if Rally exits non-zero. Default: `true`
27+
* `cifmw_rally_deployment_name`: (String) Rally deployment name. Default: `cifmw`
28+
* `cifmw_rally_concurrency`: (Integer) Concurrency passed to the Rally task via `--task-args`. Default: `1`
29+
* `cifmw_rally_task_file`: (String) Filename of the Rally task YAML inside the tasks directory.
30+
Must exist in the role's `files/` directory or be pre-staged in `cifmw_rally_artifacts_basedir/tasks/`
31+
via a pre-test hook. Default: `default-task.yaml`
32+
* `cifmw_rally_task_extra_args`: (String) Extra arguments passed verbatim to `rally task start`. Default: `""`
33+
* `cifmw_rally_dns_servers`: (List) DNS servers used inside the Rally container. Default: `["192.168.122.10"]`
34+
* `cifmw_rally_os_auth_url`: (String) OpenStack auth URL. Auto-discovered from KeystoneAPI if unset.
35+
* `cifmw_rally_os_username`: (String) OpenStack username. Default: `admin`
36+
* `cifmw_rally_os_password`: (String) OpenStack password. Auto-discovered from Kubernetes secret if unset.
37+
* `cifmw_rally_os_project_name`: (String) OpenStack project. Default: `admin`
38+
* `cifmw_rally_os_user_domain_name`: (String) User domain. Default: `Default`
39+
* `cifmw_rally_os_project_domain_name`: (String) Project domain. Default: `Default`
40+
* `cifmw_rally_os_region_name`: (String) OpenStack region. Default: `regionOne`
41+
42+
## Standalone usage
43+
44+
```yaml
45+
- hosts: hypervisor
46+
roles:
47+
- role: rally
48+
vars:
49+
cifmw_rally_concurrency: 2
50+
cifmw_rally_task_file: my-benchmark.yaml
51+
cifmw_rally_fail_on_task_failure: false
52+
```
53+
54+
Set `cifmw_run_test_role: rally` in a scenario `05-tests.yaml` to invoke this role
55+
from the cifmw_setup workflow without using the test_operator.
56+
57+
## Usage as a test_operator stage
58+
59+
Add a `rally` stage to `cifmw_test_operator_stages` in your scenario's `05-tests.yaml`:
60+
61+
```yaml
62+
cifmw_run_tests: true
63+
cifmw_run_test_role: test_operator
64+
cifmw_test_operator_stages:
65+
- name: tempest
66+
type: tempest
67+
- name: rally
68+
type: rally
69+
test_vars:
70+
cifmw_test_operator_rally_concurrency: 2
71+
cifmw_test_operator_rally_fail_on_task_failure: false
72+
```
73+
74+
## Custom task files
75+
76+
To use a custom Rally task file, either:
77+
78+
1. Add it to the role's `files/` directory and set `cifmw_rally_task_file` to its filename.
79+
2. Pre-stage it in `cifmw_rally_artifacts_basedir/tasks/` via a `pre_test_stage_hooks` hook
80+
and set `cifmw_rally_task_file` to the filename.

roles/rally/defaults/main.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
18+
# All variables intended for modification should be placed in this file.
19+
# All variables within this role should have a prefix of "cifmw_rally"
20+
cifmw_rally_artifacts_basedir: "{{ cifmw_basedir }}/tests/rally"
21+
cifmw_rally_registry: "quay.io"
22+
cifmw_rally_namespace: "airshipit"
23+
cifmw_rally_container: "xrally-openstack"
24+
cifmw_rally_image: "{{ cifmw_rally_registry }}/{{ cifmw_rally_namespace }}/{{ cifmw_rally_container }}"
25+
cifmw_rally_image_tag: "3.0.0"
26+
cifmw_rally_dry_run: false
27+
cifmw_rally_remove_container: true
28+
cifmw_rally_fail_on_task_failure: true
29+
cifmw_rally_deployment_name: "cifmw"
30+
cifmw_rally_concurrency: 1
31+
cifmw_rally_task_file: ""
32+
cifmw_rally_openstack_tests: ""
33+
cifmw_rally_task_extra_args: ""
34+
cifmw_rally_dns_servers:
35+
- "192.168.122.10"

roles/rally/meta/main.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
18+
galaxy_info:
19+
author: CI Framework
20+
description: CI Framework Role -- rally
21+
company: Red Hat
22+
license: Apache-2.0
23+
min_ansible_version: "2.14"
24+
namespace: cifmw
25+
galaxy_tags:
26+
- cifmw
27+
- rally
28+
29+
dependencies: []
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
18+
- name: Converge
19+
hosts: all
20+
vars:
21+
cifmw_rally_dry_run: true
22+
roles:
23+
- role: "rally"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
# Mainly used to override the defaults set in .config/molecule/
3+
# By default, it uses the "config_podman.yml" - in CI, it will use
4+
# "config_local.yml".
5+
log: true
6+
7+
provisioner:
8+
name: ansible
9+
log: true
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
18+
- name: Prepare
19+
hosts: all
20+
vars:
21+
cifmw_basedir: "{{ ansible_user_dir }}/ci-framework-data"
22+
cifmw_install_yamls_tasks_out: "{{ ansible_user_dir }}/zuul-jobs/roles/install_yamls_makes/tasks"
23+
cifmw_install_yamls_defaults:
24+
NAMESPACE: openstack
25+
roles:
26+
- role: test_deps
27+
- role: ci_setup
28+
- role: install_yamls
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
- name: Discover credentials from Kubernetes when not overridden
18+
when: cifmw_rally_os_auth_url is not defined
19+
block:
20+
- name: Get keystone data
21+
register: _cifmw_rally_keystone_data
22+
environment:
23+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
24+
PATH: "{{ cifmw_path }}"
25+
ansible.builtin.command:
26+
cmd: "oc get keystoneapi keystone -n {{ cifmw_openstack_namespace }} -o json"
27+
28+
- name: Set keystone vars
29+
vars:
30+
_keystone_json: "{{ _cifmw_rally_keystone_data.stdout | from_json }}"
31+
ansible.builtin.set_fact:
32+
_cifmw_rally_keystone_secret_name: "{{ _keystone_json['spec']['secret'] }}"
33+
_cifmw_rally_keystone_passwd_select: "{{ _keystone_json['spec']['passwordSelectors']['admin'] }}"
34+
_cifmw_rally_keystone_api: "{{ _keystone_json['status']['apiEndpoints']['public'] }}"
35+
36+
- name: Get credentials data
37+
register: _cifmw_rally_os_password_data
38+
environment:
39+
KUBECONFIG: "{{ cifmw_openshift_kubeconfig }}"
40+
PATH: "{{ cifmw_path }}"
41+
ansible.builtin.command:
42+
cmd: >-
43+
oc get secret {{ _cifmw_rally_keystone_secret_name }}
44+
-n {{ cifmw_openstack_namespace }} -o json
45+
46+
- name: Set OpenStack credentials facts
47+
vars:
48+
_pw_json: "{{ _cifmw_rally_os_password_data.stdout | from_json }}"
49+
ansible.builtin.set_fact:
50+
cifmw_rally_os_auth_url: "{{ _cifmw_rally_keystone_api }}"
51+
cifmw_rally_os_password: >-
52+
{{
53+
_pw_json['data'][_cifmw_rally_keystone_passwd_select] |
54+
ansible.builtin.b64decode
55+
}}

0 commit comments

Comments
 (0)