Files
resf-testing-repo/docs/ANSIBLE-GUIDE.md
Stephen Simpson ec04f0bec5 Implement Ansible roles for Rocky Linux Testing Framework
- 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>
2025-12-29 16:02:39 -06:00

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

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 image
  • images_dir: Directory for images (default: /var/lib/libvirt/images)
  • golden_image_path: Output path for golden image
  • force_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 test
  • test_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 run
  • max_parallel: Maximum parallel tests
  • test_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 download
  • images_dir: Cache directory
  • force_download: Force re-download
  • image_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 path
  • ssh_public_key_path: SSH key to inject
  • custom_prep_script: Custom preparation script
  • use_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 bootstrap
  • ssh_private_key_path: SSH key for connection
  • ssh_user: User to connect as
  • vm_boot_timeout: Boot timeout in seconds
  • bootstrap_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 image
  • vm_memory: Memory in MB
  • vm_vcpus: Number of vCPUs
  • max_wait_ip: Timeout for IP assignment
  • vm_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 use
  • golden_image_path: Golden image
  • cleanup_after_test: Cleanup VM after test
  • save_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 cleanup
  • cleanup_pattern: Regex pattern for multiple VMs
  • cleanup_vm_list: List of VMs to cleanup
  • force_destroy: Force destroy running VMs
  • remove_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

  1. Cache base images: First download is slow, subsequent runs are fast
  2. Reuse golden images: Build once, test many times
  3. Tune parallel execution: Balance between speed and resource usage
  4. Use local mirrors: Speed up package installation in prep scripts
  5. 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:

  1. Create a new role in ansible/roles/
  2. Add defaults in defaults/main.yml
  3. Document variables in role README
  4. Create example playbook in playbooks/
  5. Update this documentation

License

[Your License Here]

Authors

Rocky Linux Testing Team