Ansible Collection Packaging Guidelines

Adelante

Ansible collections are packaged units of Ansible content, including modules and other types of plugins. Most Ansible Plugins are written in Python or Powershell.

Some collections are also included in Ansible Community’s ansible collection bundle, which is packaged in Fedora. All collections, whether or not they are included in the ansible package, MAY be packaged in Fedora.

ansible depende de ansible-core, que contiene el motor central y los programas CLI (por ejemplo, ansible, ansible-playbook). El paquete ansible tiene un ciclo de publicación diferente al de las colecciones individuales, y puede contener versiones antiguas de los componentes individuales. ansible instala las colecciones en un espacio de nombres diferente y se puede instalar en paralelo con las colecciones individuales. El motor de Ansible busca primero las colecciones en el directorio de colecciones independientes.

Consulta Changes/Ansible5 para obtener más información sobre la división entre ansible y ansible-core.

Nombrando

Los paquetes de colección DEBEN llamarse ansible-collection-NAMESPACE-NAME. Por ejemplo, el paquete de la colección community.general se llama ansible-collection-community-general.

Fuente de la colección

El código fuente de la colección DEBE descargarse de la forja Git respectiva de la colección/otro repositorio SCM. Aunque los archivos tar publicados en Ansible Galaxy contienen todo el código fuente Python/Powershell de la colección, así como algunos archivos de desarrollo, no incluyen la configuración de compilación galaxy.yml ni los archivos de desarrollo (por ejemplo, pruebas unitarias) que el autor decida eliminar. Tenga en cuenta que los requisitos de la colección de la Comunidad Ansible exigen que las colecciones etiqueten las versiones en un repositorio SCM público.

Los paquetes de colecciones DEBERÍAN utilizar %{ansible_collection_url NAMESPACE NAME} como URL: del paquete. Esto apunta a la página de inicio de la colección en Ansible Galaxy.

Dependencias

Construido

Las colecciones DEBEN tener BuildRequires: ansible-packaging. ansible-packaging proporciona macros y un generador de dependencias para empaquetar las colecciones de Ansible. También incluye ansible-core, por lo que BuildRequires: ansible-core NO DEBE añadirse manualmente.

Tiempo de ejecución

El generador de dependencias generará la dependencia apropiada del motor de Ansible. Esto garantiza la compatibilidad con Fedora 35, que contiene el paquete clásico ansible 2.9 (en lugar del paquete de colecciones) y ansible-core. Ambas versiones del motor Ansible soportan colecciones, pero no son instalables en paralelo. Los paquetes NO DEBEN Requerir ansible-core o ansible manualmente, a menos que se sepa que requieren una versión específica, en cuyo caso se deben usar las restricciones de versión apropiadas.

El generador de dependencias también gestiona las dependencias entre colecciones.

Dependencias externas de los plugins

Las colecciones de Ansible pueden contener varios plugins que tienen varias dependencias externas. La guía de desarrollo de Ansible https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_best_practices.html#importing-and-using-shared-code [ordena] que los plugins fallen limpiamente si estas dependencias no están instaladas. Muchas veces, las dependencias externas sólo son necesarias para un pequeño subconjunto de la colección que puede o no ser ampliamente utilizado. Por lo tanto, los paquetes de la colección DEBERÍAN depender débilmente de estas bibliotecas externas, es decir, utilizar Recommends en lugar de Requires.

Las dependencias de módulos sólo son necesarias en el nodo destino, no en el nodo controlador. Por lo tanto, los paquetes de recolección NO DEBERÍAN depender de estas dependencias en absoluto, ni débil ni fuertemente. Los usuarios son responsables de instalar estas dependencias en el host de destino. Los módulos destinados a ser utilizados con delegate_to: localhost son una excepción a esta regla.

La situación es un poco diferente para los plugins de controlador, como los plugins de filtro, los plugins de búsqueda, los plugins de conexión o los plugins de inventario. Las colecciones PUEDEN añadir Recommends para las dependencias de los plugins controladores. Sin embargo, los empaquetadores deben ser discretos a la hora de añadir cualquier tipo de dependencia y sólo hacerlo cuando sea necesario para la funcionalidad central de la colección. Por ejemplo, tiene sentido que ansible-collection-community-docker recomiende python3-docker, pero no tiene sentido que la colección ansible-collection-community-general, más amplia y general, recomiende python3-redis para el complemento de búsqueda redis. Esta directriz pretende evitar que se amplíen los paquetes de la colección. ansible-core y ansible siguen este mismo principio.

Construcción e instalación

Para construir el artefacto de colección, los paquetes DEBEN usar %ansible_collection_build en %build. Para instalar el artefacto, se DEBE utilizar %ansible_collection_install en %install.

Los empaquetadores DEBERÍAN utilizar %files -f %{ansible_collection_filelist} para instalar la colección. La %{ansible_collection_filelist} se rellena con %ansible_collection_install.

Pruebas Unitarias

Según las Directrices generales de empaquetado de Fedora, los paquetes de recolección DEBERÍAN ejecutar pruebas unitarias ascendentes en %check si es práctico. Las pruebas de integración son imposibles de ejecutar en el entorno de compilación RPM. Para ejecutar pruebas unitarias, las colecciones DEBEN BuildRequire ansible-packaging-tests, que extrae las dependencias necesarias. Algunas colecciones tienen otras dependencias de pruebas, que normalmente se especifican en tests/unit/requirements.txt. Hay que añadirlas manualmente. La macro %ansible_test_unit DEBE utilizarse para ejecutar pruebas.

Compatibilidad EPEL

Actualmente es imposible ejecutar pruebas unitarias en EPEL 8 y 9.

ansible-core en RHEL 8 y 9 se construyen contra pilas python alternativas para las que no están disponibles las dependencias de prueba necesarias.

El resto de estas directrices son aplicables a EPEL 8 y 9, y ansible-packaging en sí está disponible allí.

Archivos innecesarios

Por defecto, las colecciones se envían con todos los archivos de la raíz del repositorio, a menos que se excluyan manualmente. Por lo tanto, muchas colecciones contienen archivos de desarrollo no deseados por los usuarios.

Los empaquetadores DEBERÍAN excluir estos archivos, lo que debería hacerse parcheando el galaxy.yml de la colección para añadir estos archivos a la configuración build_ignore. Estos archivos NO DEBERÍAN eliminarse con rm. Consulte documentación de Ansible para obtener más información sobre la sintaxis de galaxy.yml.

Los archivos de desarrollo más comunes son:

  • El directorio tests que contiene las pruebas unitarias y de integración

  • Configuración del SCM, como los archivos .gitignore y .keep

  • Los directorios .azure-pipelines y .github que contienen la configuración de IC

Estos archivos a menudo tienen que ser eliminados, ya que hay algunos problemas no resueltos con el envío de estos cambios a las colecciones de la comunidad. Estos problemas son irrelevantes en el contexto de Fedora.

Shebangs

Los plugins de Ansible no son ejecutables. Sin embargo, muchos de ellos tienen shebangs #!/usr/bin/python por razones de legado. Estos shebangs DEBEN ser eliminados por las siguientes razones:

  1. Los archivos no ejecutables no deberían tener shebangs

  2. Mantener los shebangs resulta en una dependencia innecesaria de python-unversioned-command.

NO DEBE utilizarse %py3_shebang_fix, ya que romperá la compatibilidad con ciertos nodos destino de Ansible. Tampoco solucionará el problema de los archivos no ejecutables.

Las espinillas se pueden quitar con:

find -type f ! -executable -name '*.py' -print -exec sed -i -e '1{\@^#!.*@d}' '{}' +

Documentación y archivos de licencia

License files and documentation for collections are installed to the collection’s directory in /usr/share/ansible, by default. Packagers MAY choose to either mark the license and documentation files in this directory with %license and %doc or to add the correct paths to build_ignore in galaxy.yml and install them into the standard directories. Avoid duplicating these files in both places.

Tenga en cuenta que algunas colecciones multilicencia almacenan las licencias en un directorio LICENCIAS. Todo este directorio DEBE estar marcado con %license.

Consulte en Legal docs las normas sobre licencias permitidas y la determinación del campo Licencia:.

Ejemplo de fichero de especificaciones

# Ejecutar pruebas sólo cuando las dependencias estén disponibles
%if %{defined fedora}
%bcond_without tests
%else
%bcond_with tests
%endif

Name:           ansible-collection-community-rabbitmq
Version:        1.2.2
Release:        1%{?dist}
Summary:        RabbitMQ collection for Ansible

# plugins/module_utils/_version.py: Licencia de la Python Software Foundation versión 2
License:        GPL-3.0-or-later and PSF-2.0
URL:            %{ansible_collection_url community rabbitmq}
%global forgeurl https://github.com/ansible-collections/community.rabbitmq
Source0:        %{forgeurl}/archive/%{version}/%{name}-%{version}.tar.gz
# Parchea galaxy.yml para excluir archivos innecesarios de la colección creada.
# Se trata de un parche sólo para versiones posteriores.
Patch0:         build_ignore.patch

BuildRequires:  ansible-packaging
%if %{with tests}
BuildRequires:  ansible-packaging-tests
# Collection specific test dependency
BuildRequires:  glibc-all-langpacks
%endif

BuildArch:      noarch

%description
%{summary}.


%prep
%autosetup -n community.rabbitmq-%{version} -p1
find -type f ! -executable -name '*.py' -print -exec sed -i -e '1{\@^#!.*@d}' '{}' +


%build
%ansible_collection_build


%install
%ansible_collection_install


%if %{with tests}
%check
%ansible_test_unit
%endif


%files -f %{ansible_collection_filelist}
%license COPYING PSF-license.txt
%doc README.md CHANGELOG.rst

%changelog

build_ignore.patch:

diff --git a/galaxy.yml b/galaxy.yml
index 0b37162..acd029a 100644
--- a/galaxy.yml
+++ b/galaxy.yml
@@ -13,3 +13,13 @@ repository: https://github.com/ansible-collections/community.rabbitmq
 documentation: https://docs.ansible.com/ansible/latest/collections/community/rabbitmq/
 homepage: https://github.com/ansible-collections/community.rabbitmq
 issues: https://github.com/ansible-collections/community.rabbitmq/issues
+build_ignore:
+  # Remove unnecessary development files from the built package.
+  - tests
+  - .azure-pipelines
+  - .gitignore
+  # Licenses and docs are installed with %%doc and %%license
+  - PSF-license.txt
+  - COPYING
+  - README.md
+  - CHANGELOG.rst

Macro Breakdown

He aquí un breve desglose de lo que hace exactamente cada macro incluida en ansible-packaging.

%ansible_collection_url

Utilización:

URL:            %{ansible_collection_url NAMESPACE NAME}

Esta macro apunta a la página Ansible Galaxy de una colección. Se utiliza para la etiqueta URL: en el preámbulo del archivo de especificaciones. Toma como argumentos el espacio de nombres de la colección y el nombre de la colección.

Si no se pasan argumentos a esta macro, se vuelve a los valores de %{collection_namespace} y %{collection_name} si están definidos en el fichero de especificaciones. Los nuevos paquetes DEBERÍAN pasar explícitamente el espacio de nombres y el nombre como argumentos. El fallback puede ser eliminado en el futuro. Consulte la sección Macros heredadas para obtener más información.

%ansible_collection_build

Utilización:

%build
%ansible_collection_build

Esta macro simplemente ejecuta ansible-galaxy collection build.

%ansible_collection_install

Utilización:

%install
%ansible_collection_install

Esta macro extrae el espacio de nombres de la colección, el nombre y la versión de galaxy.yml y luego lo utiliza para ejecutar ansible-galaxy collection install. Después de eso, se escribe %{ansible_collection_filelist} basado en los metadatos que previamente extraído

%ansible_test_unit

Utilización:

%check
%ansible_test_unit

Esta macro analiza galaxy.yml para determinar el espacio de nombres de la colección y el nombre que se necesita para crear la estructura de directorios que ansible-test espera. Después de crear un directorio de construcción temporal con la estructura necesaria, el script ejecuta las unidades ansible-test con los argumentos proporcionados.

%{ansible_collection_filelist}

Utilización:

%files -f %{ansible_collection_filelist}
%doc ...
%license ...

Esta macro apunta a una lista de archivos que es escrita por %ansible_collection_install. Actualmente, sólo contiene una única entrada para poseer el directorio completo de la colección en %{ansible_collections_dir}.

This macro expands to %{_datadir}/ansible/collections/ansible_collections. It is used internally by the other macros. Packagers are expected to use %ansible_collection_install and %ansible_collection_filelist instead of directly referencing this directory.

Legacy macros

%{collection_namepsace}

Utilización:

%global collection_namespace NAMESPACE

The ansible-packaging macros previously required packagers to manually set %collection_namespace in specfiles. Now, the macros extract the collection namespace from the galaxy.yml.

%{collection_name}

Utilización:

%global collection_name NAME

Anteriormente, las macros de ansible-packaging requerían que los empaquetadores establecieran manualmente %collection_name en los archivos de especificaciones. Ahora, las macros extraen el nombre de la colección del archivo galaxy.yml.

%{ansible_collection_files}

Utilización:

%files
%doc ...
%license ...
%{ansible_collection_files}

Los nuevos archivos de especificaciones deben utilizar %files -f %{ansible_collection_filelist} en lugar de esta macro. %{ansible_collection_files} requiere configurar %collection_namespace y %collection_name.