Compilar una versión más moderna de "Bind" que la disponible en PkgSrc para SmartOS

En Compilar "Bind" en PkgSrc para SmartOS con la opción de "dnstap" describo cómo compilar Bind en SmartOS con soporte dnstap, utilizando PkgSrc. Por favor, lee dicho artículo para entender qué estoy haciendo y por qué.

El principal problema en ese artículo es que estoy utilizando la versión trunk de PkgSrc para beneficiarme de una versión más moderna de Bind, pero eso implica que la versión compilada utiliza bibliotecas no disponibles en la paquetería estándar de SmartOS y tenemos que compilarlas, distribuirlas e instalarlas a mano.

Si en vez de utilizar la versión trunk de PkgSrc utilizamos la versión que se corresponda a la Zona SmartOS en la que vamos a instalar Bind, no necesitaremos hacer nada especial con las dependencias.

Nota

Para lo que sigue nos conviente conocer la filosofía de PkgSrc: En PkgSrc, de forma automática, se descarga una versión concreta del código fuente que queremos compilar, se verifica su hash para asegurarnos de que es la versión correcta y no nos están colando gato por liebre, se le aplican una serie de parches locales, que es lo que se mantiene en realidad en PkgSrc, se compila y se genera un paquete. Esta gestión separada del código fuente original y los parches locales que necesitamos en nuestro sistema es la piedra angular de PkgSrc. Permite, por ejemplo, que no se requiera colaboración por parte de los autores originales de los programas para que soporten nuestro sistema operativo. Esto va como anillo al dedo con SmartOS, porque no podemos contar con que nadie ajeno le de mimos y cuide de él.

Los cambios respecto a Compilar "Bind" en PkgSrc para SmartOS con la opción de "dnstap", serán:

  1. Usamos una zona nativa SmartOS con la versión del software PkgSrc que se corresponda a las zonas nativas SmartOS donde vamos a instalar el Bind que compilamos, en vez de la versión trunk de PkgSrc:

    [root@xXx ~]# imgadm avail|grep -i pkgbuild-lts
    188ee9ce-540a-11eb-9cc1-2748cd10e5e2  pkgbuild-lts                    20.4.0        smartos  zone-dataset  2021-01-11
    bd5afd7a-7ec1-11ec-80ab-7b01241031f6  pkgbuild-lts                    21.4.0        smartos  zone-dataset  2022-01-26
    758a4572-911d-11ed-b841-00151714048c  pkgbuild-lts                    22.4.0        smartos  zone-dataset  2023-01-10
    

    Queremos compilar Bind para utilizarlo en una zona 22.4.0, así que importamos esa versión de zona PkgSrc y la desplegamos en una zona de nuestra máquina SmartOS.

  2. Entramos en la zona PkgSrc por SSH y le pedimos que cree un entorno virtual de compilación:

    [root@PkgSrc ~]# run-sandbox 2022Q4-x86_64
    
    It looks like this is the first sandbox creation for this pkgbuild.  It
    will take longer than normal, as support packages need to be downloaded
    first.  Subsequent runs will be much faster after they have been cached.
    
    [...]
    
    Unpacking bootstrap-2022Q4-x86_64 into /data/chroot/dev-2022Q4-x86_64...done.
    Setting up environment...done.
    Installing additional tools packages...done.
    Logging in.  WARNING: On logout the sandbox will be destroyed.
    
    ,---.                   |     ,---. ,---.
    `---. ,-.-. ,---. ,---. |---  |   | `---.  pkgbuild-lts
        | | | | ,---| |     |     |   |     |  22.4.0
    `---' ` ' ' `---' `     `---' `---' `---'
    
    --<root@PkgSrc>-(/data/chroot/dev-2022Q4-x86_64)-<~>--
    ->
    

    Obsérvese que le estamos pidiendo un entorno de compilación 2022Q4-x86_64. En teoría las zonas PkgSrc modernas pueden compilar código para versiones más antiguas de las zonas SmartOS, solicitando la creación del entorno de compilación adecuado.

  1. Compilamos Bind tal y como se describe en Compilar "Bind" en PkgSrc para SmartOS con la opción de "dnstap".

    Esto genera un paquete con la versión 9.16.35 de Bind, que es lo que se distribuye con las zonas nativas SmartOS 22.4.0.

    Ese paquete no nos interesa, ya está disponible de serie en SmartOS, pero esta demostración nos confirma que todo va bien y tenemos un entorno en el que podemos confiar.

  2. La versión de Bind en PkgSrc 22.4.0 es la 9.16.35, pero la versión actual oficial de Bind es la 9.16.39. Vamos a intentar compilarla de la forma más simple posible.

  3. Lo primero es limpiar el entorno de compilación. Esto es más importante de lo que parece, no seamos tímidos con ello [1]:

    -> bmake clean
    
    [1]

    Es conveniente hacer esto con frecuencia. Si ves resultados extraños, esto es lo primero que hay que probar. Más detalles al final.

  4. Ahora editamos el fichero Makefile. Las primeras líneas contienen lo siguiente (me salto líneas irrelevantes para lo que necesitamos hacer):

    DISTNAME=       bind-${BIND_VERSION}
    PKGNAME=        ${DISTNAME:S/-P/pl/}
    PKGREVISION=    1
    [...]
    BIND_VERSION=   9.16.35
    

    Aquí vemos que se está compilando la versión 9.16.35 de Bind y que en PkgSrc tiene un patch level de 1 (se aplicó alguna modificación a este paquete posterior a la publicación original en PkgSrc). Es decir, el paquete generado es la versión bind-9.16.35nb1.

  5. Nos interesa la versión 9.16.39, sin patch level y queremos un número de versión bind-99.16.39. Obsérvese el 9 adicional. Esto es para que si actualizamos los paquetes del sistema operativo y hay una actualización de Bind, que no sobreescriba nuestra versión personalizada.

    Por tanto, reemplazamos las líneas del punto anterior con lo siguiente:

    DISTNAME=       bind-${BIND_VERSION}
    PKGNAME=        bind-9${BIND_VERSION}
    [...]
    BIND_VERSION=   9.16.39
    

    Aquí eliminamos el patch level, indicamos el 9 adicional en la versión del paquete generado y la base será Bind 9.16.39.

  6. Compilamos el paquete tal como y como ya hemos hecho antes. Nos saldrá un error:

    checksum: No checksum recorded for bind-9.16.39.tar.xz
    fetch: Checksum of the file bind-9.16.39.tar.xz doesn't match.
    checksum: No checksum recorded for bind-9.16.39.tar.xz
    ERROR: Make sure the Makefile and checksum file (/data/pkgsrc/net/bind916/distinfo)
    ERROR: are up to date.  If you want to override this check, type
    ERROR: "/opt/local/bin/bmake NO_CHECKSUM=yes [other args]".
    *** Error code 1
    
    Stop.
    bmake: stopped in /data/pkgsrc/net/bind916
    

    Esto nos indica que el hash no es el esperado. Esto es correcto, ya que hemos cambiado el fichero origen.

  7. Para actualizar el hash del nuevo fichero, podemos indicarlo directamente en el fichero distinfo, si podemos obtenerlo de forma segura. Si nos fiamos de la conexión de red, podemos actualizar el hash de forma automática:

    -> bmake makesum
    => Bootstrap dependency digest>=20211023: found digest-20220214
    
  8. Ahora que hemos actualizado el hash, volvemos a intentar compilar el paquete. Nos saldrá otro error:

    ERROR: Patching failed due to modified or broken patch file(s):
    ERROR:  /data/pkgsrc/net/bind916/patches/patch-configure.ac
    ERROR:  /data/pkgsrc/net/bind916/patches/patch-lib_isc_siphash.c
    ERROR:  /data/pkgsrc/net/bind916/patches/patch-lib_ns_update.c
    

    Este error nos indica que hay tres ficheros de parches locales a aplicar sobre el código fuente de Bind 9.16.35 no encajan exactamente sobre Bind 9.16.39.

  9. Podemos solucionar el punto anterior examinando el código fuente de Bind 9.16.35, Bind 9.16.39 y los parches con problemas. Otra posibilidad es revisar el sistema de control de versiones de PkgSrc y examinar los cambios en esos ficheros cuando se incluyó la versión 9.16.39 de Bind.

    Eso puede verse, por ejemplo, en la historia mostrada en https://pkgsrc.se/hist/net/bind916. Ahí comprobamos que la versión 9.16.39 de Bind se metió el 17 de marzo de 2023. Examinemos el contenido de esos ficheros tal y como están presentes en dicha versión [2].

    [2]

    El proyecto PkgSrc utiliza CVS, un vestusto sistema de control de versiones. Digo vetusto porque fue creado en 1986 y no se publican actualizaciones desde 2008. Existen espejos en otros formatos. Por ejemplo, https://github.com/NetBSD/pkgsrc.

    La cuestión es obtener el estado de los parches que necesitamos en el momento de añadir la versión 9.16.39 de Bind a PkgSrc. Una forma simple es buscar esos ficheros en el sistema de control de versiones, usando la fecha como referencia. En nuestro caso los ficheros son los siguientes:

    Debemos copiar esos ficheros en el directorio patches.

  10. Volvemos a intentar compilar el Bind 9.16.39. Salta el mismo error de antes, pero ahora tiene un significado distinto:

    ERROR: Patching failed due to modified or broken patch file(s):
    ERROR:  /data/pkgsrc/net/bind916/patches/patch-configure.ac
    ERROR:  /data/pkgsrc/net/bind916/patches/patch-lib_isc_siphash.c
    ERROR:  /data/pkgsrc/net/bind916/patches/patch-lib_ns_update.c
    ERROR: ==========================================================================
    ERROR:
    ERROR: Some of the selected build options and/or local patches may be incompatible.
    

    El error de antes era que los tres parches indicados no encajaban con la versión 9.16.39 de Bind. El error de ahora es que esos parches se han modificado o están corruptos. Eso es debido a que PkgSrc aplica hashes a todo, incluyendo los parches, como forma de detectar errores, manipulaciones y corrupciones.

    Debemos indicarle a PkgSrc que esos tres parches son correctos y que actualice sus hashes. Eso se puede hacer a mano, pero es más fácil que lo haga el propio PkgSrc [3]:

    -> bmake makedistinfo
    => Bootstrap dependency digest>=20211023: found digest-20220214
    
    [3]

    El comando bmake makedistinfo también recalcula el hash del código fuente original, pero he preferido separar las dos operaciones para que el proceso se entienda mejor.

  11. Ahora sí podremos compilar el código sin ningún problema.

  12. En este momento tendremos un paquete Bind que podemos distribuir e instalar con pkg_add [4].

    Recuerda que el paquete es bind-99.16.39, con un 9 extra al principio.

    [4]

    Si acaso necesitamos bibliotecas adicionales, podemos instalar el paquete Bind original del sistema con pkgin install bind916. Esto instala el paquete original, junto a las bibliotecas que necesita. Luego podemos instalar nuestro Bind encima con pkg_add -U.

Advertencia

Nos ahorraremos mucho tiempo y disgustos si cada vez que hacemos algun cambio de versión, alguna modificación en los parches, si la compilación falla, etc., empezamos la siguiente compilación con un borrado previo para tener un estado limpio y consistente:

-> bmake clean

Créeme que agradecerás seguir mi consejo.

Si el tiempo de compilación se te va de las manos, aplica el truco que describo en Cómo usar "ccache" para compilar en PkgSrc de SmartOS (II).