- Added `bootstrap_sparrowdo` role for bootstrapping Sparrowdo on a VM. - Introduced `cleanup_vm` role for cleaning up VMs and disk images. - Created `download_image` role to download and cache QCOW2 images. - Developed `golden_image` role for creating and customizing golden images. - Implemented `provision_vm` role for provisioning VMs as linked clones. - Added `run_test` role for executing tests with Sparrowdo. - Created playbooks for building golden images, running single tests, and running test suites. - Enhanced documentation with usage examples, configuration details, and troubleshooting tips. - Added support for multiple cloud providers (AWS, Azure) in the test execution workflow. Signed-off-by: Stephen Simpson <ssimpson89@users.noreply.github.com>
12 KiB
Rocky Linux Testing Framework - Ansible Guide
This guide covers the Ansible-based implementation of the Rocky Linux Testing Framework.
Table of Contents
- Overview
- Prerequisites
- Quick Start
- Ansible Structure
- Playbooks
- Roles
- Configuration
- Usage Examples
- Advanced Usage
- Troubleshooting
Overview
The Ansible implementation provides the same functionality as the shell scripts, but with:
- Better error handling and idempotency
- Structured configuration management
- Parallel test execution with better control
- Reusable roles for composability
Prerequisites
# Install required packages
sudo dnf install -y ansible qemu-kvm libvirt virt-install guestfs-tools rakudo
# Enable libvirtd
sudo systemctl enable --now libvirtd
sudo usermod -a -G libvirt $(whoami)
# Generate SSH keys if not present
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
# Install Ansible collections (if needed)
ansible-galaxy collection install community.libvirt
Quick Start
1. Build Golden Image
cd ansible
# Build with defaults (Rocky 9)
ansible-playbook playbooks/build-golden-image.yml
# Build with custom URL
ansible-playbook playbooks/build-golden-image.yml \
-e "qcow2_url=https://download.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud-Base.latest.x86_64.qcow2"
2. Run Single Test
ansible-playbook playbooks/run-single-test.yml \
-e "test_name=my-test" \
-e "test_repo_url=https://github.com/your-org/test-repo.git"
3. Run Test Suite
# Edit playbooks/run-test-suite.yml to define your test matrix
# Then run:
ansible-playbook playbooks/run-test-suite.yml
Ansible Structure
ansible/
├── ansible.cfg # Ansible configuration
├── inventory/
│ ├── hosts.yml # Inventory file
│ └── group_vars/
│ └── all.yml # Global variables
├── playbooks/
│ ├── build-golden-image.yml # Build golden image workflow
│ ├── run-single-test.yml # Run single test
│ └── run-test-suite.yml # Run multiple tests
└── roles/
├── download_image/ # Download and cache QCOW2
├── golden_image/ # Build golden image
├── bootstrap_sparrowdo/ # Bootstrap Sparrowdo
├── provision_vm/ # Provision test VM
├── run_test/ # Run Sparrowdo test
└── cleanup_vm/ # Cleanup VMs
Playbooks
build-golden-image.yml
Complete workflow to create a golden image ready for testing.
Variables:
qcow2_url: URL of base QCOW2 imageimages_dir: Directory for images (default: /var/lib/libvirt/images)golden_image_path: Output path for golden imageforce_download: Force re-download of base image
Example:
ansible-playbook playbooks/build-golden-image.yml \
-e "qcow2_url=https://..." \
-e "force_download=true"
run-single-test.yml
Run a single Sparrowdo test against the golden image.
Required Variables:
test_name: Name of the testtest_repo_url: Git repository URL containing the test
Optional Variables:
test_repo_branch: Branch to use (default: main)golden_image_path: Path to golden image
Example:
ansible-playbook playbooks/run-single-test.yml \
-e "test_name=webserver-test" \
-e "test_repo_url=https://github.com/org/webserver-test.git" \
-e "test_repo_branch=develop"
run-test-suite.yml
Run multiple tests in parallel from a test matrix.
Variables:
test_matrix: List of tests to runmax_parallel: Maximum parallel teststest_filter: Regex to filter tests
Example:
# Edit the playbook to define your tests:
test_matrix:
- name: "ssh-test"
url: "https://github.com/org/ssh-test.git"
branch: "main"
description: "SSH service validation"
- name: "network-test"
url: "https://github.com/org/network-test.git"
branch: "main"
description: "Network configuration test"
Then run:
ansible-playbook playbooks/run-test-suite.yml
# Or filter tests:
ansible-playbook playbooks/run-test-suite.yml -e "test_filter=ssh.*"
Roles
download_image
Downloads and caches QCOW2 images.
Variables:
qcow2_url: URL to downloadimages_dir: Cache directoryforce_download: Force re-downloadimage_path_var: Variable name to store result
Example:
- include_role:
name: download_image
vars:
qcow2_url: "https://..."
image_path_var: "my_image_path"
golden_image
Creates a golden image using virt-customize.
Variables:
base_image_path: Source QCOW2 image (required)golden_image_path: Output pathssh_public_key_path: SSH key to injectcustom_prep_script: Custom preparation scriptuse_default_prep: Use default prep script
Example:
- include_role:
name: golden_image
vars:
base_image_path: "/path/to/base.qcow2"
golden_image_path: "/path/to/golden.qcow2"
bootstrap_sparrowdo
Bootstraps Sparrowdo on a golden image.
Variables:
golden_image_path: Golden image to bootstrapssh_private_key_path: SSH key for connectionssh_user: User to connect asvm_boot_timeout: Boot timeout in secondsbootstrap_timeout: Bootstrap timeout
Example:
- include_role:
name: bootstrap_sparrowdo
vars:
golden_image_path: "/path/to/golden.qcow2"
provision_vm
Provisions a VM as a linked clone.
Variables:
vm_name: VM name (required)golden_image_path: Base imagevm_memory: Memory in MBvm_vcpus: Number of vCPUsmax_wait_ip: Timeout for IP assignmentvm_ip_var: Variable name for returned IP
Example:
- include_role:
name: provision_vm
vars:
vm_name: "test-vm-1"
vm_ip_var: "test_vm_ip"
- debug:
msg: "VM IP: {{ test_vm_ip }}"
run_test
Runs a complete test: provision -> test -> cleanup.
Variables:
test_name: Test name (required)test_repo_url: Git repository (required)test_repo_branch: Branch to usegolden_image_path: Golden imagecleanup_after_test: Cleanup VM after testsave_logs: Save test logs
Example:
- include_role:
name: run_test
vars:
test_name: "my-test"
test_repo_url: "https://github.com/org/test.git"
cleanup_vm
Cleans up VMs and disk images.
Variables:
vm_name: Single VM to cleanupcleanup_pattern: Regex pattern for multiple VMscleanup_vm_list: List of VMs to cleanupforce_destroy: Force destroy running VMsremove_disk: Remove disk images
Example:
# Cleanup single VM
- include_role:
name: cleanup_vm
vars:
vm_name: "test-vm-1"
# Cleanup by pattern
- include_role:
name: cleanup_vm
vars:
cleanup_pattern: "test-.*"
# Cleanup list
- include_role:
name: cleanup_vm
vars:
cleanup_vm_list:
- "vm1"
- "vm2"
Configuration
Inventory Variables
Edit ansible/inventory/group_vars/all.yml:
# VM defaults
vm_memory: 4096 # Increase for heavy tests
vm_vcpus: 4
# Parallel execution
max_parallel: 5 # Run 5 tests concurrently
# Sparrowdo options
sparrowdo_timeout: 1200 # Increase timeout
sparrowdo_verbose: false # Less output
Per-Test Configuration
Override variables when running playbooks:
ansible-playbook playbooks/run-single-test.yml \
-e "test_name=my-test" \
-e "test_repo_url=https://..." \
-e "vm_memory=4096" \
-e "vm_vcpus=4" \
-e "sparrowdo_timeout=1800"
Usage Examples
Example 1: Build Golden Image for Rocky 8
ansible-playbook playbooks/build-golden-image.yml \
-e "qcow2_url=https://download.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud-Base.latest.x86_64.qcow2" \
-e "golden_image_path=/var/lib/libvirt/images/golden-rocky8.qcow2"
Example 2: Run Test with Custom Resources
ansible-playbook playbooks/run-single-test.yml \
-e "test_name=heavy-test" \
-e "test_repo_url=https://github.com/org/test.git" \
-e "vm_memory=8192" \
-e "vm_vcpus=8"
Example 3: Custom Test Suite
Create my-test-suite.yml:
---
- name: My Custom Test Suite
hosts: localhost
connection: local
gather_facts: true
vars:
golden_image_path: "/var/lib/libvirt/images/golden.qcow2"
my_tests:
- name: "database-test"
url: "https://github.com/org/db-test.git"
- name: "web-test"
url: "https://github.com/org/web-test.git"
tasks:
- name: Run each test
include_role:
name: run_test
vars:
test_name: "{{ item.name }}"
test_repo_url: "{{ item.url }}"
loop: "{{ my_tests }}"
Run it:
ansible-playbook my-test-suite.yml
Example 4: Custom Golden Image Preparation
Create custom prep script custom-prep.sh:
#!/bin/bash
dnf install -y postgresql nginx redis
systemctl enable postgresql nginx redis
Then:
ansible-playbook playbooks/build-golden-image.yml \
-e "custom_prep_script=/path/to/custom-prep.sh"
Advanced Usage
Using Tags
Add tags to control execution:
# Only download image
ansible-playbook playbooks/build-golden-image.yml --tags download
# Skip bootstrap
ansible-playbook playbooks/build-golden-image.yml --skip-tags bootstrap
Ansible Vault for Secrets
Store sensitive data in vault:
ansible-vault create ansible/inventory/group_vars/secrets.yml
Add passwords:
root_password: "my-secure-password"
rocky_user_password: "another-secure-password"
Use it:
ansible-playbook playbooks/build-golden-image.yml --ask-vault-pass
Cleanup Orphaned VMs
ansible-playbook -m include_role -a name=cleanup_vm \
-e "cleanup_pattern=test-.*" \
localhost,
Troubleshooting
Check Ansible Syntax
ansible-playbook playbooks/build-golden-image.yml --syntax-check
Dry Run (Check Mode)
ansible-playbook playbooks/build-golden-image.yml --check
Verbose Output
ansible-playbook playbooks/run-single-test.yml -vvv \
-e "test_name=my-test" \
-e "test_repo_url=https://..."
List Tasks
ansible-playbook playbooks/build-golden-image.yml --list-tasks
Debugging Failed Tests
# Keep VM after failure
ansible-playbook playbooks/run-single-test.yml \
-e "test_name=my-test" \
-e "test_repo_url=https://..." \
-e "cleanup_after_test=false"
# Then SSH to investigate
ssh -i ~/.ssh/id_rsa rocky@<vm-ip>
Common Issues
Issue: "Golden image not found"
# Build golden image first
ansible-playbook playbooks/build-golden-image.yml
Issue: "VM failed to get IP"
# Check libvirt network
sudo virsh net-list --all
sudo virsh net-start default
# Increase timeout
ansible-playbook ... -e "max_wait_ip=60"
Issue: "Bootstrap timeout"
# Increase timeout
ansible-playbook playbooks/build-golden-image.yml \
-e "bootstrap_timeout=1800"
Issue: "Parallel tests failing"
# Reduce parallelism
ansible-playbook playbooks/run-test-suite.yml \
-e "max_parallel=1"
Performance Tips
- Cache base images: First download is slow, subsequent runs are fast
- Reuse golden images: Build once, test many times
- Tune parallel execution: Balance between speed and resource usage
- Use local mirrors: Speed up package installation in prep scripts
- Disable verbose logging: For faster execution in production
Migration from Shell Scripts
| Shell Script | Ansible Equivalent |
|---|---|
download-image.sh |
Role: download_image |
setup_base.sh |
Role: golden_image |
bootstrap_golden.sh |
Role: bootstrap_sparrowdo |
provision_vm.sh |
Role: provision_vm |
run-test.sh |
Role: run_test |
cleanup_vm.sh |
Role: cleanup_vm |
cleanup-all.sh |
Role: cleanup_vm with pattern |
| Manual workflow | Playbook: build-golden-image.yml |
| Test execution | Playbooks: run-single-test.yml, run-test-suite.yml |
Contributing
When adding new functionality:
- Create a new role in
ansible/roles/ - Add defaults in
defaults/main.yml - Document variables in role README
- Create example playbook in
playbooks/ - Update this documentation
License
[Your License Here]
Authors
Rocky Linux Testing Team