lae.travis-lxc
lae.travis-lxc
Configura y comienza N contenedores LXC para usar en el entorno de Travis CI, facilitando las pruebas de roles de Ansible en diferentes distribuciones.
Uso
Si quieres probar tus roles de Ansible en Travis CI, pero no deseas usar Docker porque no emula un sistema operativo completo, LXC es lo que debes utilizar. Este rol pretende abstraer gran parte del código repetitivo que podrías necesitar.
Para comenzar, un .travis.yml
mínimo que pruebe a fondo que tu rol es válido, idempotente y funcional podría verse así:
---
language: python
sudo: required
dist: bionic
install:
- pip install ansible
- ansible-galaxy install lae.travis-lxc,v0.9.0
- ansible-playbook tests/install.yml -i tests/inventory
before_script: cd tests/
script:
# Valida la sintaxis de tu libro de despliegue, que debería contener tu rol
- ansible-playbook -i inventory deploy.yml --syntax-check
# Ejecuta el libro de despliegue
- ansible-playbook -i inventory deploy.yml
# Ejecuta nuevamente el libro de despliegue, guardando la salida en un archivo llamado play.log,
# luego verifica que no haya tareas cambiadas/fallidas y falla si las hay.
- 'ANSIBLE_STDOUT_CALLBACK=debug ANSIBLE_DISPLAY_SKIPPED_HOSTS=no ANSIBLE_DISPLAY_OK_HOSTS=no
unbuffer ansible-playbook -vvi inventory deploy.yml &>play.log; printf "Idempotencia: ";
grep -A1 "PLAY RECAP" play.log | grep -qP "changed=0 .*failed=0 .*"
&& (echo "APROBADO"; exit 0) || (echo "FALLIDO"; cat play.log; exit 1)'
# Pruebas de integración y demás
- ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook -i inventory -v test.yml
Notarás que se hacen referencia a cuatro archivos. Puedes decidir cómo definir tu proceso de construcción, pero lo siguiente suele servir para la mayoría de los propósitos:
- tests/install.yml: ejecuta
lae.travis-lxc
y otros pasos previos a la instalación - tests/deploy.yml: ejecuta el rol que estás probando
- tests/test.yml: ejecuta pruebas de validación contra tu despliegue
- tests/inventory: contiene una lista de nombres de host de contenedores LXC
install.yml
podría verse así:
---
- hosts: localhost
connection: local
roles:
- lae.travis-lxc
vars:
test_profiles:
- profile: debian-buster
- profile: ubuntu-focal
- profile: centos-7
- profile: alpine-v3.11
# Agrega cualquier otra tarea de configuración que necesites, pero que no necesariamente debes tener en tu rol
- hosts: all
tasks: []
El primer play levantará tres contenedores de tres distribuciones diferentes. El segundo play podría usarse para ejecutar otros roles o tareas previas a la instalación que no esperarías que tu rol realizara (por ejemplo, instalar epel-release
o crear un nodo de dispositivo para FUSE (porque LXC no lo hace por ti)).
deploy.yml
podría verse así:
---
- hosts: all
become: true
any_errors_fatal: true
roles:
- ansible-role-strawberry-milk
vars:
number_of_cartons: 15
Esto es básicamente una versión de lo que ansible-galaxy init
generaría en test.yml
. Esto tendría todo lo que necesitas para ejecutar tu rol correctamente. Para roles más complejos, tiene sentido dividir las variables en la carpeta tests/group_vars
y configurar tu inventario de manera apropiada.
test.yml
debería contener tus pruebas, si deseas ejecutar alguna:
---
- hosts: all
tasks:
- name: Asegurarse de que el servicio HTTP de Strawberry Milk esté funcionando
uri:
url: "http://{{ inventory_hostname }}:1515"
- block:
- name: Imprimir la configuración de Strawberry Milk
shell: cat /etc/strawberry_milk.conf
changed_when: false
- name: Imprimir los registros del sistema
shell: "cat /var/log/messages || cat /var/log/syslog || journalctl -xb"
ignore_errors: yes
Esto puede ser útil para asegurarse de que un servicio esté corriendo, que un clúster esté en un estado saludable, que se estén creando ciertos archivos... ya entiendes la idea. El bloque que tengo aquí es un área donde ejecuto tareas similares a diagnósticos para ayudarme a depurar problemas, que incluye imprimir registros y cosas por el estilo. Está envuelto con ignore_errors
para que las tareas aquí no afecten la construcción (una de las principales tareas que causa errores es la tarea de imprimir registros al probar múltiples distribuciones).
Y finalmente, el inventario:
debian-buster-01
ubuntu-focal-01
centos-7-01
alpine-v3-11-01
Los nombres de host se generan a partir de dos partes, un prefijo y un sufijo. Por defecto, se generan a partir de la clave profile
en test_profiles
en el formato de {{ profile }}-{{ suffix }}
, donde el sufijo por defecto es 01
.
Una vez que tengas esos archivos escritos, estarás listo para probar tu rol en Travis CI. Sin embargo, probablemente quieras más de esto, así que repasemos algunos otros temas.
Probando múltiples versiones de Ansible
Es probable que desees probar tu rol contra la rama de desarrollo, así como todas las versiones de Ansible actualmente soportadas. Esto es algo que deberías configurar en el .travis.yml
y hay varias formas de hacerlo:
env:
- ANSIBLE_GIT_VERSION='devel'
- ANSIBLE_VERSION='~=2.9.0'
- ANSIBLE_VERSION='~=2.9.0'
- ANSIBLE_VERSION='~=2.7.0'
install:
- if [ "$ANSIBLE_GIT_VERSION" ]; then pip install "https://github.com/ansible/ansible/archive/${ANSIBLE_GIT_VERSION}.tar.gz";
else pip install "ansible${ANSIBLE_VERSION}"; fi
- ansible --version
Aquí, hemos agregado una tarea de instalación que tomará ANSIBLE_GIT_VERSION
, como una referencia válida en el repositorio git de Ansible, o ANSIBLE_VERSION
, una cadena de versión válida que se puede pasar a pip durante la instalación.
Rendimiento y perfilado de Ansible
Puedes agregar prácticamente cualquier cosa en tests/ansible.cfg
.
[defaults]
callback_whitelist=profile_tasks
forks=20
internal_poll_interval = 0.001
Esto ejecuta el callback profile_tasks
en tu playbook, lo que ayuda a identificar qué tareas tardan más en completarse. Podrías usar esto para identificar cualquier regresión de rendimiento, por ejemplo. Si estás levantando y ejecutando tu playbook contra múltiples contenedores, especifica forks
. internal_poll_interval
es una buena configuración general cuando tienes múltiples tareas/bucles.
Caching
Las imágenes de LXC pueden ser almacenadas en caché para ahorrar tiempo de arranque, especialmente cuando estás probando contra varias perfiles. Agrega lo siguiente en tu .travis.yml
y este rol se encargará del resto.
cache:
directories:
- "$HOME/lxc"
pip: true
(pip: true
no tiene ningún efecto para este rol, pero se incluye aquí ya que podrías querer almacenar en caché tu instalación de Ansible también.)
Variables del Rol
Para especificar qué distribuciones probar, usa test_profiles
. Los perfiles soportados incluyen (siéntete libre de solicitar/contribuir nuevos):
test_profiles:
- profile: alpine-v3.11
- profile: alpine-v3.10
- profile: alpine-v3.9
- profile: centos-7
- profile: debian-buster
- profile: debian-stretch
- profile: ubuntu-focal
- profile: ubuntu-bionic
- profile: ubuntu-xenial
Los siguientes perfiles tienen definiciones, pero no necesariamente son soportados activamente como objetivos por este rol (es decir, ya no se ejecutan pruebas contra estos), ya sea porque oficialmente han llegado a su fin de vida o son relativamente antiguos. No se garantiza que todavía funcionen (pero probablemente lo hagan).
test_profiles:
- profile: alpine-v3.8
- profile: alpine-v3.7
- profile: alpine-v3.6
- profile: centos-6
- profile: debian-jessie
- profile: debian-wheezy
- profile: fedora-28
- profile: fedora-27
- profile: fedora-26
- profile: fedora-25
- profile: ubuntu-trusty
Puedes consultar vars/main.yml
para más información sobre esos perfiles.
Un contenedor de prueba, si no se especifica un prefijo, recibe un nombre de host de {{ profile }}-{{ suffix }}
, donde profile
es sanitizado para su uso en un nombre DNS. Los prefijos por defecto están definidos en vars/main.yml
, así que consulta este archivo si no estás seguro de cuál es el prefijo de un perfil en particular. Si test_host_suffixes
no está definido, suffix
aquí se convierte en un número entero de dos dígitos con ceros a la izquierda, comenzando desde 1 (hasta el número de hosts solicitado especificado por test_hosts_per_profile
).
Por ejemplo, lo siguiente crea debian01
, debian02
, y debian03
:
test_profiles:
- profile: debian-buster
prefix: debian
test_hosts_per_profile: 3
Lo siguiente crea ubuntu-app-python2
y ubuntu-app-python3
:
test_profiles:
- profile: ubuntu-focal
prefix: ubuntu-
test_host_suffixes:
- app-python2
- app-python3
También puedes sobrescribir la configuración del contenedor utilizada, si es necesario (por ejemplo, montando una carpeta compartida):
container_config:
- "lxc.aa_profile=unconfined"
- "lxc.mount.auto=proc:rw sys:rw cgroup-full:rw"
- "lxc.cgroup.devices.allow=a *:* rmw"
En el caso de que necesites instalar paquetes adicionales dentro de los contenedores de prueba, puedes hacerlo también:
additional_packages:
- make
Si se identifica que la caché está habilitada en el .travis.yml
, puedes almacenar en caché selectivamente un subconjunto de tus perfiles de prueba especificándolos en lxc_cache_profiles
. Estos deben ser perfiles válidos y estar presentes en test_profiles
.
Para almacenar en caché en un directorio diferente de $HOME/lxc
, modifica lxc_cache_directory
.
Si necesitas deshabilitar el uso de OverlayFS en los contenedores LXC (por ejemplo, si estás intentando usar OverlayFS dentro del contenedor LXC), establece lxc_use_overlayfs
a no
(o a cualquier variante de False
).
Contribuidores
Musee Ullah (@lae, lae@lae.is)
Wilmar den Ouden (@wilmardo)
Estabilidad
Este rol sigue siendo pre-1.0 y, por lo tanto, no se garantiza su estabilidad. Si te encuentras con un problema al usar este rol, por favor abre un problema con una breve descripción y cualquier registro pertinente para que pueda ser solucionado y podamos acercarnos un paso más a nuestra primera versión estable.
Asegúrate de fijar a una versión específica (el fijar a versiones menores puede estar bien) al usar este rol. No hacerlo puede resultar en que tus pruebas empiecen a fallar debido a cambios incompatibles en una versión menor antes de un lanzamiento 1.0.
Builds and configures LXC container hosts to use for integration testing Ansible roles on Travis CI
ansible-galaxy install lae.travis-lxc