openwisp.openwisp2-imagegenerator
ansible-openwisp2-imagegenerator
Este rol de Ansible permite construir varias imágenes de firmware de openwisp2 para diferentes organizaciones, mientras se realiza un seguimiento de sus configuraciones.
NOTA: este rol aún no ha sido probado en ambientes de producción. Si planeas usarlo, pruébalo y si algo sale mal, informa tu problema. Ten en cuenta que necesitas estar dispuesto a entender el proceso de construcción y su funcionamiento interno para que funcione para ti.
Variables requeridas
Las siguientes variables son necesarias:
openwisp2fw_source_dir
: indica el directorio del código fuente de OpenWRT que se utiliza durante la compilación.openwisp2fw_generator_dir
: indica el directorio utilizado para la preparación de generadores.openwisp2fw_bin_dir
: indica el directorio utilizado al construir las imágenes finales.openwisp2fw_organizations
: una lista de organizaciones; consulta el archivo de ejemploplaybook.yml
en la sección de creación de playbook para entender su estructura.
Uso (tutorial)
Si no sabes cómo usar Ansible, no te preocupes, este procedimiento te guiará paso a paso.
Si ya sabes cómo usar Ansible, puedes saltarte esta sección e ir directamente a la sección "Instalar este rol".
Primero, necesitas entender dos conceptos clave:
- por "servidor de compilación" nos referimos a un servidor que se utiliza para compilar las imágenes.
- por "máquina local" nos referimos al host desde el cual inicias Ansible, por ejemplo: tu propia computadora portátil o servidor CI.
Ansible es una herramienta de gestión/configuración automática que funciona ingresando al servidor de compilación a través de SSH y ejecutando una serie de comandos.
1. Instalar Ansible
Instala Ansible en tu máquina local si aún no lo has hecho. Puedes hacerlo de varias maneras, pero preferimos usar el administrador de paquetes de Python oficial, por ejemplo:
sudo pip install ansible
Si no tienes pip instalado, consulta Instalar pip.
Instalar ansible de otras maneras también está bien, solo asegúrate de instalar una versión de la serie 2.0.x
(que es la versión con la cual hemos probado este playbook).
2. Instalar este rol
Para simplificar, la forma más fácil es instalar este rol en tu máquina local a través de ansible-galaxy
(que se instaló al instalar Ansible), por lo tanto, ejecuta:
sudo ansible-galaxy install openwisp.openwisp2-imagegenerator
3. Elegir un directorio de trabajo
Elige un directorio de trabajo en tu máquina local donde colocar la configuración de tus imágenes de firmware.
Por ejemplo:
mkdir ~/my-openwisp2-firmware-conf
cd ~/my-openwisp2-firmware-conf
Es una buena idea poner este directorio de trabajo bajo control de versiones, te ayudará a rastrear cambios, hacer reversiones, configurar un servidor CI para compilar las imágenes automáticamente, etc.
4. Crear archivo de inventario
El archivo de inventario es donde se definen los grupos de servidores. En nuestro caso simple, podemos definir un grupo en el que colocaremos solo un servidor.
Crea un nuevo archivo hosts
en tu máquina local con el siguiente contenido:
[myserver]
mycompiler.mydomain.com ansible_user=<tuusuario> ansible_become_pass=<contraseña-sudo>
Sustituye mycompiler.mydomain.com
por tu nombre de host (también se permiten direcciones IP).
Además, coloca tu usuario SSH y contraseña en lugar de <tuusuario>
y <contraseña-sudo>
(debe ser un usuario con privilegios sudo y no root). Estas credenciales se utilizan durante el paso de instalación de dependencias.
5. Crear archivo de playbook
Crea un nuevo archivo de playbook playbook.yml
en tu máquina local con el siguiente contenido:
# playbook.yml
- hosts: your_host_here
roles:
- openwisp.openwisp2-imagegenerator
vars:
openwisp2fw_source_dir: /home/user/openwisp2-firmware-source
openwisp2fw_generator_dir: /home/user/openwisp2-firmware-generator
openwisp2fw_bin_dir: /home/user/openwisp2-firmware-builds
openwisp2fw_source_targets:
- system: ar71xx
subtarget: generic
profile: Default
- system: x86
subtarget: generic
profile: Generic
openwisp2fw_organizations:
- name: snakeoil # nombre de la org
flavours: # sabores soportados
- standard
luci_openwisp: # /etc/config/luci_openwisp
username: "operator"
password: "<CAMBIA_ME>"
openwisp: # /etc/config/openwisp
url: "https://mi-instancia-openwisp2.com"
shared_secret: "mi-secreto-openwisp2"
unmanaged: "{{ openwisp2fw_default_unmanaged }}"
root_password: "<CAMBIA_ME>"
Este playbook te permitirá compilar imágenes de firmware para una organización llamada snakeoil
utilizando solo el sabor standard
(que incluye una imagen OpenWRT 19.07 predeterminada con los módulos estándar de OpenWISP2) para dos arquitecturas, ar71xx y x86.
Consulta la sección Variables del rol para saber cómo personalizar las configuraciones disponibles.
En este punto, la estructura de tu directorio debería verse como sigue:
.
├── hosts
└── playbook.yml
6. Ejecutar el playbook
Ahora es el momento de iniciar la compilación del firmware de OpenWISP2.
Lanza el playbook desde tu máquina local con:
ansible-playbook -i hosts playbook.yml -e "recompile=1 cores=4"
Puedes sustituir cores=4
por el número de núcleos que tengas disponibles.
Cuando haya terminado de ejecutarse el playbook, encontrarás las imágenes en el servidor de compilación ubicado en el directorio especificado en openwisp2fw_bin_dir
, que en nuestro ejemplo es /home/user/openwisp2-firmware-builds
, con una estructura de directorio como la siguiente:
/home/user/openwisp2-firmware-builds
├── snakeoil/ # (cada org tiene su propio dir)
├── snakeoil/2016-12-02-094316/ar71xx/standard/ # (contiene imágenes ar71xx para el sabor estándar)
├── snakeoil/2016-12-02-094316/x86/standard/ # (contiene imágenes x86 para el sabor estándar)
└── snakeoil/latest/ # (latest es un enlace simbólico a la última compilación)
Ahora, si seguiste este tutorial y todo salió bien, ¡estás listo para personalizar tu configuración según tus necesidades! Sigue leyendo para aprender cómo lograrlo.
Variables del rol
Hay muchas variables que se pueden personalizar si es necesario, consulta los valores predeterminados para una lista completa.
Algunas de estas variables también se explican en Organizaciones y Sabores.
Organizaciones
Si estás trabajando con OpenWISP, es probable que estés compilando imágenes para diferentes grupos de personas: clientes con fines de lucro, organizaciones sin fines de lucro o cualquier grupo que se pueda definir como una "organización".
Las organizaciones se pueden definir libremente en openwisp2fw_organizations
.
Para un ejemplo de cómo hacer esto, consulta el "archivo de ejemplo playbook.yml".
Si necesitas agregar archivos específicos en el sistema de archivos de las imágenes de cada organización, consulta "Agregar archivos para organizaciones específicas".
Sabores
Un sabor es una combinación de paquetes que se incluyen en una imagen.
Es posible que desees crear diferentes sabores para tus imágenes, por ejemplo:
standard
: el caso de uso más común.minimal
: una imagen para dispositivos que tienen poco espacio de almacenamiento disponible.mesh
: una imagen con paquetes necesarios para implementar una red de malla.
Por defecto, solo está disponible un sabor standard
.
Puedes definir tus propios sabores estableciendo openwisp2fw_image_flavours
- consulta las variables predeterminadas para entender su estructura.
Proceso de construcción
El proceso de construcción se compone de los siguientes pasos.
1. Instalación de dependencias
etiqueta: install
En esta fase se instalan o actualizan las dependencias del sistema operativo necesarias para los pasos posteriores.
2. Compilación
etiqueta: compile
El código fuente de OpenWRT se compila para producir algo llamado "Generador de Imágenes". El generador de imágenes es un archivo que contiene los paquetes precompilados y un Makefile
especial que se utilizará para generar las imágenes personalizadas para cada organización.
El código fuente se descarga y compila en el directorio especificado en openwisp2fw_source_dir
.
3. Preparación de generadores
etiqueta: generator
Durante este paso, los generadores de imágenes se extraen y preparan para construir diferentes imágenes para diferentes organizaciones; cada organización puede construir imágenes para diferentes sabores (por ejemplo: con todas las funciones, mínimas, red de malla, etc.);
Las imágenes se extraen y se preparan en el directorio especificado en openwisp2fw_generator_dir
.
4. Construcción de imágenes finales
etiqueta: build
En esta fase se produce una serie de imágenes.
Se construirán varias imágenes para cada arquitectura, organización y sabor. Esto puede generar muchos archivos, por lo tanto, usa este poder con cuidado: probablemente sea mejor comenzar con menos opciones y agregar más casos a medida que avanzas.
Por ejemplo, si eliges usar 2 arquitecturas (ar71xx y x86), 2 organizaciones (por ejemplo: A y B) y 2 sabores (por ejemplo: estándar y mini), obtendrás 8 grupos de imágenes:
- organización: A / sabor: estándar / arch: ar71xx
- organización: A / sabor: estándar / arch: x86
- organización: A / sabor: mini / arch: ar71xx
- organización: A / sabor: mini / arch: x86
- organización: B / sabor: estándar / arch: ar71xx
- organización: B / sabor: estándar / arch: x86
- organización: B / sabor: mini / arch: ar71xx
- organización: B / sabor: mini / arch: x86
Las imágenes se crearán en el directorio especificado en openwisp2fw_bin_dir
.
5. Subir imágenes al OpenWISP Firmware Upgrader
El último paso es subir las imágenes al módulo OpenWISP Firmware Upgrader. Este paso es opcional y está deshabilitado de forma predeterminada.
Para habilitar esta función, las variables openwisp2fw_uploader
y openwisp2fw_organizations.categories
deben configurarse como en el siguiente ejemplo:
- hosts:
- myhost
roles:
- openwisp.openwisp2-imagegenerator
vars:
openwisp2fw_controller_url: "https://openwisp.miproyecto.com"
openwisp2fw_organizations:
- name: staging
flavours:
- default
openwisp:
url: "{{ openwisp2fw_controller_url }}"
shared_secret: "xxxxx"
root_password: "xxxxx"
categories:
default: <CATEGORY-UUID>
- name: prod
flavours:
- default
openwisp:
url: "{{ openwisp2fw_controller_url }}"
shared_secret: "xxxxx"
root_password: "xxxxx"
categories:
default: <CATEGORY-UUID>
openwisp2fw_uploader:
enabled: true
url: "{{ openwisp2fw_controller_url }}"
token: "<REST-API-USER-TOKEN>"
image_types:
- ath79-generic-ubnt_airrouter-squashfs-sysupgrade.bin
- ar71xx-generic-ubnt-bullet-m-xw-squashfs-sysupgrade.bin
- ar71xx-generic-ubnt-bullet-m-squashfs-sysupgrade.bin
- octeon-erlite-squashfs-sysupgrade.tar
- ath79-generic-ubnt_nanostation-loco-m-xw-squashfs-sysupgrade.bin
- ath79-generic-ubnt_nanostation-loco-m-squashfs-sysupgrade.bin
- ath79-generic-ubnt_nanostation-m-xw-squashfs-sysupgrade.bin
- ar71xx-generic-ubnt-nano-m-squashfs-sysupgrade.bin
- ath79-generic-ubnt_unifiac-mesh-squashfs-sysupgrade.bin
- x86-64-combined-squashfs.img.gz
- x86-generic-combined-squashfs.img.gz
- x86-geode-combined-squashfs.img.gz
- ar71xx-generic-xd3200-squashfs-sysupgrade.bin
Los siguientes marcadores de posición en el ejemplo deberán ser sustituidos:
<CATEGORY-UUID>
es el UUID de la categoría de firmware en OpenWISP Firmware Upgrader.<REST-API-USER-TOKEN>
es el token de autenticación REST de un usuario con permisos para subir imágenes.
Puedes recuperar el token de autenticación REST enviando una solicitud POST usando la interfaz API web de OpenWISP:
- Abre el navegador en
https://<openwisp-base-url>/api/v1/user/token/
. - Introduce el nombre de usuario y la contraseña en el formulario en la parte inferior de la página.
- Envía el formulario y recibirás el token de autenticación REST en la respuesta.
El script de carga crea un nuevo objeto de construcción y luego sube las imágenes de firmware especificadas en image_types
, que deben corresponder a los identificadores como ar71xx-generic-tl-wdr4300-v1-il-squashfs-sysupgrade.bin
definidos en el archivo hardware.py de OpenWISP Firmware Upgrader.
Otros puntos importantes a saber sobre el script upload_firmware.py
:
- El script lee
CONFIG_VERSION_DIST
yCONFIG_VERSION_NUMBER
del archivo.config
del código fuente de OpenWrt para determinar la versión de compilación. - El script averiguará si ya existe una compilación con la misma versión y categoría e intentará agregar imágenes a esa compilación en lugar de crear una nueva. Si se encuentran duplicados, se imprimirá un mensaje de error en la consola, pero el script no se detendrá; esto permite generar imágenes para nuevos modelos de hardware y agregarlas a compilaciones existentes.
Agregar archivos a las imágenes
Puedes agregar archivos arbitrarios en cada imagen generada ubicando estos archivos en un directorio llamado files/
en el directorio de tu playbook.
Ejemplo:
.
├── hosts
├── playbook.yml
└── files/etc/profile
files/etc/profile
se añadirá en cada imagen generada.
Agregar archivos para organizaciones específicas
También puedes agregar archivos a las imágenes de organizaciones específicas.
Supongamos que tienes una organización llamada snakeoil
y deseas agregar un banner personalizado, puedes lograrlo creando la siguiente estructura de directorios:
.
├── hosts
├── playbook.yml
└── organizations/snakeoil/etc/banner
Dado que este paso es uno de los últimos realizados antes de construir las imágenes finales, puedes usar esta función para sobrescribir cualquier archivo construido automáticamente durante los pasos anteriores.
Parámetros adicionales
Puedes pasar los siguientes parámetros adicionales a ansible-playbook
:
recompile
: si repetir el paso de compilación.cores
: número de núcleos a utilizar durante el paso de compilación.orgs
: lista separada por comas de nombres de organizaciones si necesitas limitar la generación de imágenes a organizaciones específicas.
Ejemplos
Recompilar con 16 núcleos:
ansible-playbook -i hosts playbook.yml -e "recompile=1 cores=16"
Generar imágenes solo para la organización foo
:
ansible-playbook -i hosts playbook.yml -e "orgs=foo"
Generar imágenes solo para las organizaciones foo
y bar
:
ansible-playbook -i hosts playbook.yml -e "orgs=foo,bar"
Ejecutar pasos específicos
Dado que cada paso en el proceso está etiquetado, puedes ejecutar pasos específicos utilizando etiquetas de ansible.
Ejemplo 1, ejecutar solo la preparación de generadores:
ansible-playbook -i hosts playbook.yml -t generator
Ejemplo 2, ejecutar solo la preparación de generadores y los pasos de construcción:
ansible-playbook -i hosts playbook.yml -t generator,build
Objetivos sin subobjetivo
Este ejemplo muestra cómo llenar openwisp2fw_source_targets
para compilar objetivos que no especifican un subobjetivo (por ejemplo: sunxi, ARMv8, QEMU):
openwisp2fw_source_targets:
# SOC Allwinner, Lamobo R1
- system: sunxi
profile: sun7i-a20-lamobo-r1
# Imagen virtual QEMU ARM
- system: armvirt
profile: Default
Soporte
Consulta Canales de Soporte de OpenWISP.
Generate different OpenWISP2 firmware images for several organizations
ansible-galaxy install openwisp.openwisp2-imagegenerator