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>
This commit is contained in:
562
docs/ANSIBLE-GUIDE.md
Normal file
562
docs/ANSIBLE-GUIDE.md
Normal file
@@ -0,0 +1,562 @@
|
||||
# Rocky Linux Testing Framework - Ansible Guide
|
||||
|
||||
This guide covers the Ansible-based implementation of the Rocky Linux Testing Framework.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Ansible Structure](#ansible-structure)
|
||||
- [Playbooks](#playbooks)
|
||||
- [Roles](#roles)
|
||||
- [Configuration](#configuration)
|
||||
- [Usage Examples](#usage-examples)
|
||||
- [Advanced Usage](#advanced-usage)
|
||||
- [Troubleshooting](#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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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:**
|
||||
```bash
|
||||
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:**
|
||||
```bash
|
||||
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:**
|
||||
```yaml
|
||||
# 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:
|
||||
```bash
|
||||
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:**
|
||||
```yaml
|
||||
- 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:**
|
||||
```yaml
|
||||
- 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:**
|
||||
```yaml
|
||||
- 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:**
|
||||
```yaml
|
||||
- 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:**
|
||||
```yaml
|
||||
- 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:**
|
||||
```yaml
|
||||
# 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`:
|
||||
|
||||
```yaml
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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`:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- 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:
|
||||
```bash
|
||||
ansible-playbook my-test-suite.yml
|
||||
```
|
||||
|
||||
### Example 4: Custom Golden Image Preparation
|
||||
|
||||
Create custom prep script `custom-prep.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
dnf install -y postgresql nginx redis
|
||||
systemctl enable postgresql nginx redis
|
||||
```
|
||||
|
||||
Then:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
ansible-vault create ansible/inventory/group_vars/secrets.yml
|
||||
```
|
||||
|
||||
Add passwords:
|
||||
```yaml
|
||||
root_password: "my-secure-password"
|
||||
rocky_user_password: "another-secure-password"
|
||||
```
|
||||
|
||||
Use it:
|
||||
```bash
|
||||
ansible-playbook playbooks/build-golden-image.yml --ask-vault-pass
|
||||
```
|
||||
|
||||
### Cleanup Orphaned VMs
|
||||
|
||||
```bash
|
||||
ansible-playbook -m include_role -a name=cleanup_vm \
|
||||
-e "cleanup_pattern=test-.*" \
|
||||
localhost,
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Check Ansible Syntax
|
||||
|
||||
```bash
|
||||
ansible-playbook playbooks/build-golden-image.yml --syntax-check
|
||||
```
|
||||
|
||||
### Dry Run (Check Mode)
|
||||
|
||||
```bash
|
||||
ansible-playbook playbooks/build-golden-image.yml --check
|
||||
```
|
||||
|
||||
### Verbose Output
|
||||
|
||||
```bash
|
||||
ansible-playbook playbooks/run-single-test.yml -vvv \
|
||||
-e "test_name=my-test" \
|
||||
-e "test_repo_url=https://..."
|
||||
```
|
||||
|
||||
### List Tasks
|
||||
|
||||
```bash
|
||||
ansible-playbook playbooks/build-golden-image.yml --list-tasks
|
||||
```
|
||||
|
||||
### Debugging Failed Tests
|
||||
|
||||
```bash
|
||||
# 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"**
|
||||
```bash
|
||||
# Build golden image first
|
||||
ansible-playbook playbooks/build-golden-image.yml
|
||||
```
|
||||
|
||||
**Issue: "VM failed to get IP"**
|
||||
```bash
|
||||
# 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"**
|
||||
```bash
|
||||
# Increase timeout
|
||||
ansible-playbook playbooks/build-golden-image.yml \
|
||||
-e "bootstrap_timeout=1800"
|
||||
```
|
||||
|
||||
**Issue: "Parallel tests failing"**
|
||||
```bash
|
||||
# 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
|
||||
Reference in New Issue
Block a user