Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 0 additions & 212 deletions .github/workflows/ci-ansible-molecule-kvm.yml

This file was deleted.

77 changes: 65 additions & 12 deletions .github/workflows/ci-ansible-molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,21 @@ name: CI - Ansible Molecule
#
# Scenario discovery:
# - If `scenarios` (JSON array) is provided, that list is used verbatim.
# - Otherwise the workflow lists `extensions/molecule/` and skips any
# directory whose name begins with `.` (e.g. `.config`).
# - Otherwise the workflow lists `scenarios_root` and skips any directory
# whose name begins with `.` (e.g. `.config`).
#
# Driver: docker (containers from geerlingguy/docker-*-ansible). Roles
# that touch the kernel (sysctl write, nftables load, swap, ethtool)
# should ship a `test_sequence:` in their scenario's molecule.yml that
# stops at `syntax` — running them under docker is otherwise unreliable.
# Driver (input `driver`):
# - `docker` (default): containers from geerlingguy/docker-*-ansible. Roles
# that touch the kernel (sysctl write, nftables load, swap, ethtool) should
# ship a `test_sequence:` stopping at `syntax` in their molecule.yml —
# running them under docker is otherwise unreliable.
# - `qemu`: boots full VMs via the molecule-qemu driver for roles that need a
# real kernel and init system (k3s, container engines, systemd services).
# GitHub-hosted ubuntu-latest exposes a writable /dev/kvm, so molecule-qemu
# auto-detects hardware acceleration (falls back to TCG otherwise). The job
# installs QEMU, adds the runner user to the kvm group, and runs molecule
# via `sg kvm` (group changes do not affect the current shell). Each role's
# molecule.yml selects `driver: molecule-qemu` and defines its platforms.

on:
workflow_call:
Expand All @@ -29,6 +37,13 @@ on:
type: string
required: true
description: 'Collection name.'
driver:
type: string
required: false
default: 'docker'
description: |
Molecule driver: `docker` (default, fast containers) or `qemu`
(full VMs via molecule-qemu, for roles needing a real kernel/init).
python_version:
type: string
required: false
Expand All @@ -39,7 +54,7 @@ on:
required: false
default: ''
description: |
JSON array of scenario directory names under `extensions/molecule/`.
JSON array of scenario directory names under `scenarios_root`.
When empty, the workflow discovers scenarios automatically and
builds the matrix from the directory listing (entries starting
with `.` are skipped).
Expand All @@ -50,13 +65,15 @@ on:
description: |
Path (relative to the collection root) where scenarios live.
Defaults to the layout shipped inside published collection
tarballs; override for repos that keep scenarios outside
`extensions/`.
tarballs; override for repos that keep scenarios elsewhere.
runs_on:
type: string
required: false
default: 'ubuntu-latest'
description: 'GitHub-hosted runner label for the molecule matrix legs.'
description: |
GitHub-hosted runner label for the molecule matrix legs. The
standard ubuntu-latest runner exposes /dev/kvm, so the `qemu`
driver does not require a larger/paid runner.
cancel-in-progress:
type: boolean
required: false
Expand Down Expand Up @@ -93,6 +110,16 @@ jobs:
outputs:
scenarios: ${{ steps.list.outputs.scenarios }}
steps:
- name: Validate driver input
env:
DRIVER: ${{ inputs.driver }}
run: |
set -euo pipefail
case "$DRIVER" in
docker|qemu) ;;
*) echo "::error::Invalid driver '$DRIVER' (expected 'docker' or 'qemu')"; exit 1 ;;
esac

- name: Checkout collection
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
Expand Down Expand Up @@ -157,6 +184,25 @@ jobs:
cache: 'pip'
cache-dependency-path: ansible_collections/${{ inputs.collection_namespace }}/${{ inputs.collection_name }}/requirements.txt

- name: Install QEMU/KVM and enable /dev/kvm access
if: inputs.driver == 'qemu'
run: |
set -euo pipefail
sudo apt-get update -qq
# genisoimage provides mkisofs (cloud-init seed ISO); qemu-system-x86
# + qemu-utils are the molecule-qemu runtime dependencies.
sudo apt-get install -y -qq \
qemu-system-x86 qemu-utils genisoimage
# The runner user is not in the kvm group by default; add it. Log
# whether acceleration is available without failing the step
# (molecule-qemu falls back to TCG when /dev/kvm is absent).
sudo usermod -aG kvm "$USER"
if [ -e /dev/kvm ]; then
ls -l /dev/kvm
else
echo "::warning::/dev/kvm absent — molecule-qemu will fall back to TCG"
fi

- name: Install collection dev dependencies
working-directory: ansible_collections/${{ inputs.collection_namespace }}/${{ inputs.collection_name }}
run: |
Expand Down Expand Up @@ -184,23 +230,30 @@ jobs:
ANSIBLE_FORCE_COLOR: '1'
PY_COLORS: '1'
MOLECULE_NO_LOG: 'false'
DRIVER: ${{ inputs.driver }}
SCENARIO: ${{ matrix.scenario }}
SCENARIOS_ROOT: ${{ inputs.scenarios_root }}
run: |
# Molecule resolves scenarios relative to the cwd that contains
# `molecule/`. SCENARIOS_ROOT is the parent of that directory
# (e.g. `extensions/molecule` -> cd `extensions/`).
cd "$(dirname "$SCENARIOS_ROOT")"
molecule test -s "$SCENARIO"
if [ "$DRIVER" = "qemu" ]; then
# `sg kvm` activates the freshly added group membership for this command.
sg kvm -c "molecule test -s '$SCENARIO'"
else
molecule test -s "$SCENARIO"
fi

- name: Summarise scenario outcome
if: always()
env:
DRIVER: ${{ inputs.driver }}
SCENARIO: ${{ matrix.scenario }}
STATUS: ${{ job.status }}
run: |
{
echo "## Molecule scenario: \`$SCENARIO\`"
echo "## Molecule scenario (${DRIVER}): \`$SCENARIO\`"
echo
echo "**Status:** $STATUS"
} >> "$GITHUB_STEP_SUMMARY"
3 changes: 1 addition & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ This repository provides shared Renovate presets for consumer repositories:
| Workflow | File | Description |
|----------|------|-------------|
| Ansible Collection CI | [ci-ansible-collection.yml](./.github/workflows/ci-ansible-collection.yml) | Linting, security scan, sanity/unit/integration tests, build |
| Ansible Molecule CI | [ci-ansible-molecule.yml](./.github/workflows/ci-ansible-molecule.yml) | Auto-discovered Molecule scenarios under `extensions/molecule/`, docker driver |
| Ansible Molecule CI (KVM) | [ci-ansible-molecule-kvm.yml](./.github/workflows/ci-ansible-molecule-kvm.yml) | Molecule scenarios in full VMs via the `molecule-qemu` driver — for roles needing a real kernel/init (k3s, container engines, systemd-service agents) |
| Ansible Molecule CI | [ci-ansible-molecule.yml](./.github/workflows/ci-ansible-molecule.yml) | Auto-discovered Molecule scenarios under `extensions/molecule/`; `driver` input selects `docker` (default) or `qemu` (full VMs via `molecule-qemu` for roles needing a real kernel/init — k3s, container engines, systemd-service agents) |
| Go CI | [ci-go.yml](./.github/workflows/ci-go.yml) | golangci-lint, gofmt, go vet, go test |
| Lint | [ci-lint.yml](./.github/workflows/ci-lint.yml) | MegaLinter aggregator |

Expand Down
20 changes: 10 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ This is a rolling release - changes are deployed continuously to `main`.

### Added

- **ci-ansible-molecule-kvm.yml**: New reusable Molecule runner that boots full
VMs via the `molecule-qemu` driver instead of the docker driver, for roles
that need a real kernel and init system (k3s `modprobe`/cgroups, container
engines, agents that must run as a stable `systemd` service — under docker
the unit reports started while it has crash-looped, masking config bugs).
GitHub-hosted `ubuntu-latest` exposes a writable `/dev/kvm`, so the job
installs `qemu-system-x86`/`qemu-utils`/`genisoimage`, adds the runner to the
`kvm` group, and runs molecule via `sg kvm`; molecule-qemu auto-detects KVM
- **ci-ansible-molecule.yml**: `driver` input (`docker` default, `qemu`) to
pick the Molecule driver. `qemu` boots full VMs via the `molecule-qemu`
driver for roles that need a real kernel and init system (k3s
`modprobe`/cgroups, container engines, agents that must run as a stable
`systemd` service — under docker the unit reports started while it has
crash-looped, masking config bugs). GitHub-hosted `ubuntu-latest` exposes a
writable `/dev/kvm`, so the job installs
`qemu-system-x86`/`qemu-utils`/`genisoimage`, adds the runner to the `kvm`
group, and runs molecule via `sg kvm`; molecule-qemu auto-detects KVM
acceleration and falls back to TCG. Validated end-to-end on `arillso.agent`
(alloy) and `arillso.container` (k3s). Docker-driver roles keep using
`ci-ansible-molecule.yml`
(alloy) and `arillso.container` (k3s).
Comment thread
sbaerlocher marked this conversation as resolved.
- **AGENTS.md**: New "Ansible Collection Conventions" section documenting the
shared release workflow shape (`name`, `run-name`, `concurrency`), the
Keep-a-Changelog format, the cross-collection dependency-bound matrix
Expand Down