Páginas

martes, 26 de agosto de 2025

Poudriere en FreeBSD ZFS 14.2

Instalación y configuración de poudriere FreeBSD 14.2 ZFS


Referencias bibliográficas:

https://freebsdfoundation.org/wp-content/uploads/2023/11/reushling_poudrier.pdf
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-poudriere-build-system-to-create-packages-for-your-freebsd-servers


Intel core i5-8350U 1.7 GHz
Procesador 4 cores
Procesador 8 hilos
RAM 16 GB
SWAP 16 GB
NVMe Pcie 4.0

ZPOOL=zroot
ZROOTFS=/poudriere
BASEFS=/usr/local/poudriere

FreeBSD 14.2-RELEASE (amd64) instalado El dataset raíz de poudriere estará en zroot/poudriere y se montará en /usr/local/poudriere

Paquetes mínimos

pkg install -y poudriere \
	       git-lite
	       vim
	       screen
	       curl
	       ca_root_nss

Crear datasets ZFS.

Ventajas: posibilidad de hacer snapshots, rollback y compression por separado

zfs create -o mountpoint=/usr/local/poudriere -o compression=lz4 zroot/poudriere
zfs create zroot/poudriere/jails
zfs create zroot/poudriere/ports
zfs create zroot/poudriere/data
zfs create zroot/poudriere/data/packages
zfs create zroot/poudriere/data/logs

Archivo /usr/local/etc/poudriere.conf

ZPOOL=zroot
ZROOTFS=/poudriere
FREEBSD_HOST=ftp://ftp.freebsd.org
RESOLV_CONF=/etc/resolv.conf
BASEFS=/usr/local/poudriere
POUDRIERE_DATA=${BASEFS}/data
USE_TMPFS=all # usa RAM + swap para las builds
DISTFILES_CACHE=/usr/ports/distfiles
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
CCACHE_DIR=/var/cache/ccache
ALLOW_MAKE_JOBS_PACKAGES="pkg ccache py* rust llvm*"
PARALLEL_JOBS=8 # 8 hilos logicos

Descargar y crear la jail base (14.2-RELEASE)

poudriere jail -c -j 142amd64 -v 14.2-RELEASE -a amd64

Esto descarga sets.txz y crea un dataset zroot/poudriere/jails/142amd64

Git -

poudriere ports -c -p default -m git -U https://git.FreeBSD.org/ports.git     

poudriere ports -l

PORTSTREE METHOD    TIMESTAMP           PATH
default   git+https 2025-08-24 18:50:19 /usr/local/poudriere/ports/default
local     null      2025-08-24 16:41:27 /usr/local/poudriere/ports/default

poudriere jails -l

JAILNAME VERSION         ARCH  METHOD TIMESTAMP           PATH
142amd64 14.2-RELEASE-p5 amd64 http   2025-08-24 18:42:25 /usr/local/poudriere/jails/142amd64

Ajustes globales

Archivo /usr/local/etc/poudriere.d/make.conf

# general
DEFAULT_VERSIONS+=ssh=openssl
OPTIONS_UNSET+=DOCS NLS EXAMPLES X11 IPV6
WITH_PKGNG=yes
DISABLE_LICENSES=yes

Crear listas de paquetes

Archivo /usr/local/etc/poudriere.d/port-list.txt

security/sudo
ports-mgmt/pkg

Primer bulk build

poudriere bulk -j 142amd64 -p default -f /usr/local/etc/poudriere.d/port-list.txt

Servidor de paquetes local (nginx)

pkg install nginx
sysrc nginx_enable=YES

Archivo de configuración de nginx

$ sed -e '/^[ ]*#/d' -e '/^$/d' /usr/local/etc/nginx/nginx.conf
    
    server {
        listen       80 default;
        server_name  localhost;
	    root /usr/local/share/poudriere/html;
        
        location /data {
            alias  /usr/local/poudriere/data/logs/bulk;
            autoindex on;
        }
	
	location /packages {
		root /usr/local/poudriere/data;
		autoindex on;
	}
}

Configurar pkg en la máquina anfitriona

mkdir /usr/local/etc/pkg/repos

Archivo /usr/local/etc/pkg/repos/poudriere.conf

poudriere {
  url: "http://127.0.0.1/packages/142amd64-default/",
  enabled = yes,
  mirror_type: "http",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}

Generar clave (una sola vez)

Crear el directorio donde se guardarán las claves

mkdir -p /usr/local/etc/poudriere

Generar la clave privada (4096 bits)

openssl genrsa -out /usr/local/etc/poudriere/poudriere.key 4096
chmod 600 /usr/local/etc/poudriere/poudriere.key

Extraer la clave pública

openssl rsa -in /usr/local/etc/poudriere/poudriere.key -pubout -out \
/usr/local/etc/poudriere/poudriere.pub
chmod 644 /usr/local/etc/poudriere/poudriere.pub

Asegúrarse de que poudiere la use al firmar.

Añadir esta línea al archivo /usr/local/etc/poudriere.conf

PKG_REPO_SIGNING_KEY=/usr/local/etc/poudriere/poudriere.key

El archivo /usr/local/etc/poudriere.conf queda así:

ZPOOL=zroot
ZROOTFS=/poudriere
FREEBSD_HOST=ftp://ftp.freebsd.org
RESOLV_CONF=/etc/resolv.conf
BASEFS=/usr/local/poudriere
POUDRIERE_DATA=${BASEFS}/data
USE_TMPFS=all # usa RAM + swap para las builds
DISTFILES_CACHE=/usr/ports/distfiles
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
ALLOW_MAKE_JOBS_PACKAGES="pkg ccache py* rust llvm*"
PARALLEL_JOBS=8 # 8 hilos logicos
PKG_REPO_SIGNING_KEY=/usr/local/etc/poudriere/poudriere.key

Firmar el repositorio con la clave nueva

poudriere bulk -j 142amd64 -p default -f /usr/local/etc/poudriere.d/port-list.txt

Monitorear durante la compilación


poudriere status

SET PORTS JAIL BUILD STATUS  QUEUE BUILT FAIL SKIP IGNORE FETCH REMAIN TIME     LOGS
- default 142amd64 2025-08-26_08h57m21s parallel_build  3  0  0  0 0 0  3 00:00:22 \
/usr/local/poudriere/data/logs/bulk/142amd64-default/2025-08-26_08h57m21s

poudriere jail -l

JAILNAME VERSION         ARCH  METHOD TIMESTAMP           PATH
142amd64 14.2-RELEASE-p5 amd64 http   2025-08-25 23:10:54 /usr/local/poudriere/jails/142amd64

poudriere ports -l

PORTSTREE METHOD    TIMESTAMP           PATH
default   git+https 2025-08-26 08:55:04 /usr/local/poudriere/ports/default
local     null      2025-08-24 16:41:27 /usr/local/poudriere/ports/default
root@solaris:/usr/local/etc/pkg/repos# poudriere 
FreeBSD.conf        packagesite.yaml    
poudriere.conf     

Logs en tiempo real

poudriere log -f -j 142amd64 -p default 

Configurar pkg en los clientes, (o en la misma máquina), para que use la clave pública

mkdir -p /usr/local/etc/pkg/repos/
$ cat /usr/local/etc/pkg/repos/poudriere.conf
poudriere {
  url: "http://127.0.0.1/packages/142amd64-default/",
  enabled = yes,
  mirror_type: "http",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}

Tras esto, pkg install validará las firmas sin errores.

Comandos útiles de rescate. Limpiar paquetes obsoletos

poudriere pkgclean -j 142amd64 -p default -f port-list.txt

Destruir jail y volver a crear (por ejemplo, tras nueva RELEASE)

poudriere jail -d -j 142amd64
poudriere jail -c -j 142amd64 -v 14.3-RELEASE -a amd64

Actualizar paquetes

pkg update -f
Updating FreeBSD repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%   10 MiB  10.4MB/s    00:01    
Processing entries: 100%
FreeBSD repository update completed. 35669 packages processed.
Updating poudriere repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%    2 KiB   2.0kB/s    00:01    
Processing entries: 100%
poudriere repository update completed. 3 packages processed.
All repositories are up to date.
pkg upgrade
curl -I http://127.0.0.1/
HTTP/1.1 200 OK
Server: nginx/1.28.0
Date: Tue, 26 Aug 2025 12:07:38 GMT
Content-Type: text/html
Content-Length: 13036
Last-Modified: Sat, 09 Aug 2025 09:58:45 GMT
Connection: keep-alive
ETag: "68971bd5-32ec"
Accept-Ranges: bytes

Actualizar el árbol existente (lo mantiene, solo descarga nuevos commits)

poudriere ports -u -p default

Listo para compilar y servir paquetes locales con poudriere en FreeBSD 14.2


Opciones

Poudriere no guarda automáticamente las elecciones que se hacen al ejecutar poudriere options, pero le indicamos con la bandera -z myset que lo guarde.

Ejecutar una vez poudriere options para el port que quiera

Las opciones seleccionadas se guardan en /usr/local/etc/poudriere.d/myset-options

poudriere options -z myset -c security/sudo

el flag -c fuerza que aparezca el menú incluso si ya existen opciones guardadas.


Un directorio "myset-options" es generado automaticamente por make config

/usr/local/etc/poudriere.d/myset-options/

y dentro del directorio los directorios categoria_paquete

ls /usr/local/etc/poudriere.d/myset-options
converters_libiconv/ devel_autoconf/      devel_m4/            lang_tcl86/
databases_sqlite3/   devel_kyua/          lang_lua54/          security_sudo/
devel_atf/           devel_lutok/         lang_perl5.42/

y dentro de esos directorio un archivo llamado options contiene las opciones de configuración.


cat /usr/local/etc/poudriere.d/myset-options/security_sudo/options
# This file is auto-generated by 'make config'.
# Options for sudo-1.9.17p2
_OPTIONS_READ=sudo-1.9.17p2
_FILE_COMPLETE_OPTIONS_LIST=AUDIT DISABLE_AUTH DISABLE_ROOT_SUDO DOCS EXAMPLES \
INSULTS LDAP NLS NOARGS_SHELL OPIE PAM PYTHON SSL GSSAPI_BASE GSSAPI_HEIMDAL \
GSSAPI_MIT
OPTIONS_FILE_SET+=AUDIT
OPTIONS_FILE_UNSET+=DISABLE_AUTH
OPTIONS_FILE_UNSET+=DISABLE_ROOT_SUDO
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_UNSET+=EXAMPLES
OPTIONS_FILE_SET+=INSULTS
OPTIONS_FILE_UNSET+=LDAP
OPTIONS_FILE_UNSET+=NLS
OPTIONS_FILE_UNSET+=NOARGS_SHELL
OPTIONS_FILE_UNSET+=OPIE
OPTIONS_FILE_SET+=PAM
OPTIONS_FILE_UNSET+=PYTHON
OPTIONS_FILE_SET+=SSL
OPTIONS_FILE_UNSET+=GSSAPI_BASE
OPTIONS_FILE_UNSET+=GSSAPI_HEIMDAL
OPTIONS_FILE_UNSET+=GSSAPI_MIT

...

Compilar paquetes

poudriere bulk -j 142amd64 -p default -z myset -f /usr/local/etc/poudriere.d/port-list.txt

Para que pkg use los paquetes que acaba de compilar poudriere necesitas:
- Que poudriere haya terminado de firmar y publicar los paquetes.
- Un repositorio local servido por nginx (u otro)
- Un fichero /usr/local/etc/pkg/repos/poudriere.conf correctamente escrito

fichero /usr/local/etc/pkg/repos/poudriere.conf

poudriere {
  url: "http://127.0.0.1/packages/142amd64-default/",
  # url = "file:///usr/local/poudriere/data/packages/142amd64-default",
  enabled = yes,
  mirror_type: "http",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}
root@solaris:/usr/local/poudriere/data/packages/142amd64-default/All# pkg repo .
Creating repository in .: 100%
Packing files for repository: 100%
root@solaris:/usr/local/poudriere/data/packages/142amd64-default/All# ls
data.pkg            meta.conf           pkg-2.2.2.pkg
data.tzst           packagesite.pkg     pkgconf-2.4.3,1.pkg
meta                packagesite.tzst    sudo-1.9.17p2.pkg

Desactivar el repositorio oficial (opcional)

#
# To disable this repository, instead of modifying or removing this file,
# create a /usr/local/etc/pkg/repos/FreeBSD.conf file:
#
#   mkdir -p /usr/local/etc/pkg/repos
#   echo "FreeBSD: { enabled: no }" > /usr/local/etc/pkg/repos/FreeBSD.conf
#

FreeBSD: {
 url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly",
# url: "pkg+https://pkg.FreeBSD.org/${ABI}/latest",
 mirror_type: "srv",
 signature_type: "fingerprints",
 fingerprints: "/usr/share/keys/pkg",
 enabled: no
}

Otra opción. La prioridad define el orden en que se utilizan estos repositorios

Por defecto, se utiliza el repositorio upstream de FreeBSD.org. Pero como queremos que nuestros propios paquetes tengan precedencia, le daremos una prioridad más alta que cero para que use nuestro repositorio de paquetes primero.

Quedaría así:

#
# To disable this repository, instead of modifying or removing this file,
# create a /usr/local/etc/pkg/repos/FreeBSD.conf file:
#
#   mkdir -p /usr/local/etc/pkg/repos
#   echo "FreeBSD: { enabled: no }" > /usr/local/etc/pkg/repos/FreeBSD.conf
#

FreeBSD: {
 url: "pkg+https://pkg.FreeBSD.org/${ABI}/quarterly",
# url: "pkg+https://pkg.FreeBSD.org/${ABI}/latest",
 mirror_type: "srv",
 signature_type: "fingerprints",
 fingerprints: "/usr/share/keys/pkg",
 enabled: yes
}

Archivo /usr/local/etc/pkg/repos/poudriere.conf

poudriere {
  url: "http://127.0.0.1/packages/142amd64-default/",
  # url = "file:///usr/local/poudriere/data/packages/142amd64-default",
  enabled = yes,
  priority: 23,
  mirror_type: "http",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/poudriere/poudriere.pub",
}

Veamos en acción

 pkg update
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating poudriere repository catalogue...
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01    
Fetching data.pkg: 100%    2 KiB   2.0kB/s    00:01    
Processing entries: 100%
poudriere repository update completed. 3 packages processed.
All repositories are up to date.
root@solaris:/usr/local/etc/pkg/repos# pkg upgrade
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating poudriere repository catalogue...
poudriere repository is up to date.
All repositories are up to date.
Checking for upgrades (206 candidates): 100%
Processing candidates (206 candidates): 100%
The following 4 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	p5-Crypt-URandom: 0.54 [FreeBSD]

Installed packages to be UPGRADED:
	nss: 3.115 -> 3.115.1 [FreeBSD]
	p5-Authen-SASL: 2.18 -> 2.1900 [FreeBSD]
	perl5: 5.40.2_2 -> 5.40.3_2 [FreeBSD]

Number of packages to be installed: 1
Number of packages to be upgraded: 3

18 MiB to be downloaded.

Proceed with this action? [y/N]: y
[1/4] Fetching nss-3.115.1.pkg: 100%    2 MiB   2.3MB/s    00:01    
[2/4] Fetching p5-Crypt-URandom-0.54.pkg: 100%   17 KiB  17.6kB/s    00:01    
[3/4] Fetching perl5-5.40.3_2.pkg: 100%   16 MiB  16.4MB/s    00:01    
[4/4] Fetching p5-Authen-SASL-2.1900.pkg: 100%   44 KiB  44.7kB/s    00:01    
Checking integrity... done (0 conflicting)
[1/6] Deinstalling p5-Authen-SASL-2.18...
[1/6] Deleting files for p5-Authen-SASL-2.18: 100%
[2/6] Deinstalling perl5-5.40.2_2...
[2/6] Deleting files for perl5-5.40.2_2: 100%
[3/6] Upgrading nss from 3.115 to 3.115.1...
[3/6] Extracting nss-3.115.1: 100%
[4/6] Installing perl5-5.40.3_2...
[4/6] Extracting perl5-5.40.3_2: 100%
[5/6] Installing p5-Crypt-URandom-0.54...
[5/6] Extracting p5-Crypt-URandom-0.54: 100%
[6/6] Installing p5-Authen-SASL-2.1900...
[6/6] Extracting p5-Authen-SASL-2.1900: 100%
tree /usr/local/poudriere/data/packages/
/usr/local/poudriere/data/packages/
└── 142amd64-default
    ├── All -> .latest/All
    ├── Latest -> .latest/Latest
    ├── data
    ├── data.pkg -> .latest/data.pkg
    ├── data.tzst -> .latest/data.tzst
    ├── logs -> .latest/logs
    ├── meta -> .latest/meta
    ├── meta.conf -> .latest/meta.conf
    ├── packagesite.pkg -> .latest/packagesite.pkg
    ├── packagesite.tzst -> .latest/packagesite.tzst
    └── packagesite.yaml

5 directories, 8 files

Instalar paquete desde repositorio local

pkg install sudo
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating poudriere repository catalogue...
poudriere repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	sudo: 1.9.17p2 [poudriere]

Number of packages to be installed: 1

The process will require 2 MiB more space.

Proceed with this action? [y/N]: y
[1/1] Installing sudo-1.9.17p2...
[1/1] Extracting sudo-1.9.17p2: 100%
Comprobar security con INSULTS activado:
sudo vim /etc/rc.conf                 
Password:
Quizás si usaras más de dos dedos...
Password:
¡Este hombre no sabe cuándo está vencido! Tampoco sabe cuándo está ganando. 
No tiene... una especie de... aparato sensorial...
Password:
FreeBSD es genial!.