openwisp.openwisp2-imagegenerator

ansible-openwisp2-imagegenerator

Galaxy

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:

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:

  1. Abre el navegador en https://<openwisp-base-url>/api/v1/user/token/.
  2. Introduce el nombre de usuario y la contraseña en el formulario en la parte inferior de la página.
  3. 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 y CONFIG_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.

Acerca del proyecto

Generate different OpenWISP2 firmware images for several organizations

Instalar
ansible-galaxy install openwisp.openwisp2-imagegenerator
Licencia
bsd-3-clause
Descargas
998
Propietario
Modular and Programmable Open Source Network Management System for Linux OpenWrt.