mirror of
https://github.com/spantaleev/matrix-docker-ansible-deploy.git
synced 2026-08-29 20:13:13 +00:00
Scenarios install their Galaxy dependencies with `force: true`, so two roles running at once re-extract the same collections and roles into ~/.ansible and pull them out from under each other mid-play. It surfaces as a collection that was working moments earlier going missing: the connection plugin 'community.docker.docker' was not found Found while running five scenarios in parallel, where it cost a run. ANSIBLE_HOME relocates both `collections/` and `roles/`, so one variable covers both halves; the scenarios' ANSIBLE_ROLES_PATH workaround now follows it rather than hardcoding ~/.ansible/roles. Left alone if already set, and unset in CI, where each role runs in its own job and has nothing to collide with. Verified by removing var/molecule-ansible-home entirely and running matrix-alertmanager-receiver from cold: green through idempotence, with the collections and roles landing under the per-role directory - which also shows nothing was quietly relying on the shared ~/.ansible being populated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
99 lines
3.3 KiB
Bash
Executable File
99 lines
3.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# Runs a role's Molecule scenario locally.
|
|
#
|
|
# Called through `just molecule [role] [args...]`. With no role, lists the roles
|
|
# that have a scenario.
|
|
#
|
|
# The same scenarios run in CI (.github/workflows/molecule.yml), but running one
|
|
# here is the faster loop while writing or fixing a role: CI only tells you after
|
|
# a push, and only about the roles that push touched.
|
|
#
|
|
# Deliberately NOT wired into prek. A run takes minutes, pulls container images
|
|
# and needs a working Docker - which is fine when you ask for it, and not fine on
|
|
# every commit.
|
|
#
|
|
# Usage:
|
|
# just molecule # list roles that have a scenario
|
|
# just molecule matrix-alertmanager-receiver
|
|
# just molecule matrix-alertmanager-receiver converge # any molecule subcommand
|
|
#
|
|
# Environment:
|
|
# MOLECULE_DISTRO base image to test on (default: ubuntu2604)
|
|
|
|
set -euo pipefail
|
|
|
|
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
roles_dir="${repo_dir}/roles/custom"
|
|
venv_dir="${repo_dir}/var/molecule-venv"
|
|
|
|
list_roles() {
|
|
find "${roles_dir}" -mindepth 1 -maxdepth 1 -type d -printf '%f\n' \
|
|
| while read -r candidate; do
|
|
if [ -f "${roles_dir}/${candidate}/molecule/default/molecule.yml" ]; then
|
|
echo "${candidate}"
|
|
fi
|
|
done \
|
|
| sort
|
|
}
|
|
|
|
role="${1:-}"
|
|
|
|
if [ -z "${role}" ]; then
|
|
echo "Roles with a Molecule scenario:"
|
|
found="$(list_roles)"
|
|
if [ -z "${found}" ]; then
|
|
echo " (none yet)"
|
|
else
|
|
printf ' %s\n' ${found}
|
|
fi
|
|
echo
|
|
echo "Run one with: just molecule <role>"
|
|
exit 0
|
|
fi
|
|
|
|
shift || true
|
|
|
|
if [ ! -f "${roles_dir}/${role}/molecule/default/molecule.yml" ]; then
|
|
echo "No Molecule scenario at roles/custom/${role}/molecule/default" >&2
|
|
echo >&2
|
|
echo "Roles that have one:" >&2
|
|
list_roles | sed 's/^/ /' >&2
|
|
exit 1
|
|
fi
|
|
|
|
# The virtualenv lives under var/, which is gitignored, and is shared by every
|
|
# role - the dependencies are the same for all of them.
|
|
if [ ! -x "${venv_dir}/bin/molecule" ]; then
|
|
echo "Creating the Molecule virtualenv in ${venv_dir/#$HOME/\~} ..."
|
|
python3 -m venv "${venv_dir}"
|
|
"${venv_dir}/bin/pip" install --quiet --upgrade pip
|
|
"${venv_dir}/bin/pip" install --quiet -r "${repo_dir}/molecule-shared/requirements.txt"
|
|
fi
|
|
|
|
# Galaxy content is installed with `force: true` on every run, so two scenarios
|
|
# running at once will re-extract collections and roles into the same directory
|
|
# and pull them out from under each other mid-play. It shows up as a collection
|
|
# that was working moments earlier going missing:
|
|
#
|
|
# the connection plugin 'community.docker.docker' was not found
|
|
#
|
|
# ANSIBLE_HOME relocates both `collections/` and `roles/`, so one variable is
|
|
# enough to give each role its own. The scenarios' ANSIBLE_ROLES_PATH follows it.
|
|
#
|
|
# Unset in CI, where it falls back to ~/.ansible - each role runs in its own job
|
|
# there, so there is nothing to collide with and nothing to gain from isolation.
|
|
export ANSIBLE_HOME="${ANSIBLE_HOME:-${repo_dir}/var/molecule-ansible-home/${role}}"
|
|
|
|
export MOLECULE_DISTRO="${MOLECULE_DISTRO:-ubuntu2604}"
|
|
export PY_COLORS="${PY_COLORS:-1}"
|
|
export ANSIBLE_FORCE_COLOR="${ANSIBLE_FORCE_COLOR:-1}"
|
|
|
|
echo "Running Molecule for ${role} on ${MOLECULE_DISTRO} ..."
|
|
cd "${roles_dir}/${role}"
|
|
|
|
if [ $# -eq 0 ]; then
|
|
exec "${venv_dir}/bin/molecule" test --scenario-name default
|
|
fi
|
|
|
|
exec "${venv_dir}/bin/molecule" "$@" --scenario-name default
|