En este artÃculo explicaremos como migrar un sistema FreeBSD 13.2 a 14.0, las principales caracterÃsticas a destacar de la versión 14 son la mejora en la gestión de discos nvme, reimplementación de Wireguard y mejora del passthrough de gráficas en BHyve entre otras, para mas detalles podemos ver las notas de lanzamiento en este enlace: https://www.freebsd.org/releases/14.0R/relnotes/ . Cabe destacar que en esta ocasión he esperado unos 4 meses desde su lanzamiento para evitar posibles bugs de lanzamiento.
La migración se llevará a cabo de distinto modo según se trate de un sistema fÃsico o una jail virtualizada, además hay variaciones dependiendo del sistema de boot que se emplee. Por otro lado también explicaremos algunos aspectos a tener en cuenta si utilizamos ZFS o Poudriere.
- Sistema operativo
- Loader update: EFI
- Loader update: BIOS
- ZFS update
- Bastille update
- IOCage update
- IOCage - Template
- Poudriere
- Poudriere - limpieza
- MTA
Sistema operativo
Actualizamos el kernel y las core tools a la última versión dentro de la 13.2:
freebsd-update install
Hacemos lo mismo con los paquetes binarios:
pkg autoremove
Comprobamos la versión actual
13.2-RELEASE-p10
Upgradeamos a 14.0:
Algunos ficheros necesitarán intervención manual por parte del usuario, como el /etc/group por ejemplo:
<<<<<<< current version
# $FreeBSD$
#
wheel:*:0:root,kr0m
=======
wheel:*:0:root
>>>>>>> 14.0-RELEASE
Instalamos el kernel y los módulos del kernel:
Instalamos userspace/binaries/libraries
Reinstalamos según utilicemos paquetes binarios o ports:
pkg upgrade
git -C /usr/ports pull
cd /usr/ports
make fetchindex
for PORT in $(pkg info|awk '{print$1}'); do PORT_PATH=$(pkg info $PORT|grep Origin|awk '{print$3}') && echo PORT: $PORT - $PORT_PATH && cd /usr/ports/$PORT_PATH && export BATCH="yes" && make clean reinstall clean; done
Detectará el cambio de ABI y reinstalará todos los paquetes instalados.
Eliminamos librerias y ficheros antiguos:
NOTA: Si tenemos un kernel custom debemos recompilarlo con la rama releng/14.0.
Reiniciamos el SO:
Comprobamos la versión del SO, tanto el kernel en /boot/kernel/kernel el cargado en RAM y las userlands:
14.0-RELEASE-p5 /boot/kernel/kernel
14.0-RELEASE-p5 RAM loaded kernel
14.0-RELEASE-p5 Userland version
Loader update: EFI
Este paso resulta muy importante si tenemos raÃz en un pool ZFS, ya que si actualizamos el pool y no la imagen EFI el SO puede dejar de arrancar.
Localizamos la partición EFI(ESP):
BootCurrent: 0002
+Boot0002* FreeBSD HD(1,GPT,9ca4da68-f165-11eb-8209-3497f636bf45,0x28,0x82000)/File(\EFI\FREEBSD\LOADER.EFI)
nvd0p1:/EFI/FREEBSD/LOADER.EFI (null)
Montamos la partición:
Comprobamos que se haya montado y que el sistema de ficheros sea el correcto:
Filesystem Type Size Used Avail Capacity Mounted on
/dev/nvd0p1 msdosfs 260M 1.8M 258M 1% /boot/efi
Podemos ver la imagen de EFI que tenemos configurada como arranque:
-rwxr-xr-x 1 root wheel 896000 Jul 30 2021 /boot/efi/efi/freebsd/loader.efi
También podemos ver la imagen EFI por defecto si no configuramos ninguna entrada:
-rwxr-xr-x 1 root wheel 896000 Jul 30 2021 /boot/efi/efi/boot/bootx64.efi
Debemos actualizar ambas versiones:
cp /boot/loader.efi /boot/efi/efi/boot/bootx64.efi
Reiniciamos para asegurarnos que que cargue la imagen EFI sin problemas:
Loader update: BIOS
Este paso resulta muy importante si tenemos raÃz en un pool ZFS, ya que si actualizamos el pool y no la imagen EFI el SO puede dejar de arrancar.
Localizamos la partición boot:
=> 40 1953525088 ada0 GPT (932G)
40 1024 1 freebsd-boot (512K)
1064 984 - free - (492K)
2048 4194304 2 freebsd-swap (2.0G)
4196352 1949327360 3 freebsd-zfs (930G)
1953523712 1416 - free - (708K)
Volcamos el contenido del fichero /boot/pmbr a la MBR(primeros 512bytes) del disco y el contenido del fichero /boot/gptzfsboot sobre la partición de boot:
ZFS update
Cuando se actualiza el código ZFS debemos updatear los pools del sistema para habilitar las nuevas funcionalidades:
pool: zroot
state: ONLINE
status: Some supported and requested features are not enabled on the pool.
The pool can still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
the pool may no longer be accessible by software that does not support
the features. See zpool-features(7) for details.
scan: scrub repaired 0B in 00:04:24 with 0 errors on Sun Mar 17 09:04:24 2024
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
nda0p2 ONLINE 0 0 0
errors: No known data errors
Actualizamos el pool:
This system supports ZFS pool feature flags.
Enabled the following features on 'zroot':
edonr
zilsaxattr
head_errlog
blake3
block_cloning
vdev_zaps_v2
Pool 'zroot' has the bootfs property set, you might need to update
the boot code. See gptzfsboot(8) and loader.efi(8) for details.
NOTA: Como podemos ver el propio comando nos avisa de que tenemos el zroot con el bootfs property habilitado, lo que puede dar problemas si no actualizamos el loader acorde a nuestro sistema EFI / BIOS
pool: zroot
state: ONLINE
scan: scrub repaired 0B in 00:04:24 with 0 errors on Sun Mar 17 09:04:24 2024
config:
NAME STATE READ WRITE CKSUM
zroot ONLINE 0 0 0
nda0p2 ONLINE 0 0 0
errors: No known data errors
Bastille update
El sistema base puede actualizarse dentro de la misma versión 13.2-p1 -> 13.2-p2, la misma versión principal 13.2 -> 13.3 u otra versión principal 13.2 -> 14.0.
El primer paso será obtener la nueva versión de FreeBSD, para ello bootstrapeamos la versión 14.0 y aplicamos los últimos parches de seguridad:
Consultamos las releases disponibles:
13.1-RELEASE
13.2-RELEASE
14.0-RELEASE
Cuando terminemos podremos eliminar las releases viejas con:
NOTA: Si alguna jail depende de los binarios compilados desde poudriere, debemos preparar poudriere antes .
Thin jail:
Si se trata de una Thin jail estas comparten la base, por lo tanto actualizando la RELEASE desde Bastille estaremos actualizando el sistema base de todas las jails que compartan dicha RELEASE.
Para saber si un jail es Thick/Thin se puede comprobar consultando el fichero /usr/local/bastille/jails/JAILNAME/jail.conf, si aparece la linea osrelease se trata de una thinjail:
-- Atlas: Thick jail
-- DataDyne: Thick jail
-- HellStorm: Thick jail
-- MetaCortex: Thick jail
-- PostgreSQL00-test: Thick jail
-- PostgreSQL01-test: Thick jail
-- PostgreSQLBackups-test: Thick jail
-- PostgreSQLRestore-test: Thick jail
-- RECLog: Thick jail
-- thinJail: Thin jail
-- thinJail2: Thin jail
Paramos la jail:
Actualizamos a la versión 14 tal como indica la
documentación oficial
:
Cambiamos el path de 13.2 a 14.0:
/usr/local/bastille/releases/13.2-RELEASE /usr/local/bastille/jails/JAILNAME/root/.bastille nullfs ro 0 0
/usr/local/bastille/releases/14.0-RELEASE /usr/local/bastille/jails/JAILNAME/root/.bastille nullfs ro 0 0
Arrancamos la jail:
Reinstalamos todo el software según utilicemos paquetes binarios o ports:
Si vemos el siguiente mensaje de error, debemos cambiar la shell a la por defecto antes de acceder a la jail:
>ld-elf.so.1: Shared object "libncursesw.so.8" not found, required by "bash"
pkg-static upgrade -f
exit
git -C /usr/ports pull
cd /usr/ports
make fetchindex
for PORT in $(pkg info|awk \'{print$1}\'); do PORT_PATH=$(pkg info $PORT|grep Origin|awk \'{print$3}\') && echo PORT: $PORT - $PORT_PATH && cd /usr/ports/$PORT_PATH && export BATCH=\"yes\" && make clean reinstall clean; done
exit
Revertimos el cambio de shell:
Actualizamos por si ha salido algún parche de la última release:
Reiniciamos la jail para asegurarnos de que todo funciona correctamente:
bastille start JAILNAME
Podemos ver como las thinjails ya están actualizadas a la 14.0:
JID State IP Address Published Ports Hostname Release Path
Atlas Up 192.168.69.19 - Atlas 13.2-RELEASE-p10 /usr/local/bastille/jails/Atlas/root
DataDyne Up 192.168.69.25 - DataDyne 13.2-RELEASE-p10 /usr/local/bastille/jails/DataDyne/root
HellStorm Up 192.168.69.17 - HellStorm 13.2-RELEASE-p10 /usr/local/bastille/jails/HellStorm/root
MetaCortex Up 192.168.69.20 - MetaCortex 13.2-RELEASE-p10 /usr/local/bastille/jails/MetaCortex/root
PostgreSQL00-test Up 192.168.69.26 - PostgreSQL00-test 13.2-RELEASE-p10 /usr/local/bastille/jails/PostgreSQL00-test/root
PostgreSQL01-test Up 192.168.69.27 - PostgreSQL01-test 13.2-RELEASE-p10 /usr/local/bastille/jails/PostgreSQL01-test/root
PostgreSQLBackups-test Up 192.168.69.29 - PostgreSQLBackups-test 13.2-RELEASE-p10 /usr/local/bastille/jails/PostgreSQLBackups-test/root
PostgreSQLRestore-test Up 192.168.69.28 - PostgreSQLRestore-test 13.2-RELEASE-p10 /usr/local/bastille/jails/PostgreSQLRestore-test/root
RECLog Up 192.168.69.21 - RECLog 13.2-RELEASE-p10 /usr/local/bastille/jails/RECLog/root
thinJail Up 192.168.40.190 - thinJail 14.0-RELEASE-p5 /usr/local/bastille/jails/thinJail/root
thinJail2 Up 192.168.40.191 - thinJail2 14.0-RELEASE-p5 /usr/local/bastille/jails/thinJail2/root
Thick jail:
Por el contrario si se trata de un Thick jail habrá que actualizar cada jail de forma independiente, pero siempre desde Bastille ya que las jails arrancan en securelevel 2 y no lo permiten desde dentro:
kern.securelevel: 2
Para saber si un jail es Thick/Thin se puede comprobar consultando el fichero /usr/local/bastille/jails/JAILNAME/jail.conf, si aparece la linea osrelease se trata de una thinjail:
-- Atlas: Thick jail
-- DataDyne: Thick jail
-- HellStorm: Thick jail
-- MetaCortex: Thick jail
-- PostgreSQL00-test: Thick jail
-- PostgreSQL01-test: Thick jail
-- PostgreSQLBackups-test: Thick jail
-- PostgreSQLRestore-test: Thick jail
-- RECLog: Thick jail
-- thinJail: Thin jail
-- thinJail2: Thin jail
Para actualizar las thickjails primero debemos saber la versión de release actual:
JID State IP Address Published Ports Hostname Release Path
Atlas Up 192.168.69.19 - Atlas 13.2-RELEASE-p10 /usr/local/bastille/jails/Atlas/root
DataDyne Up 192.168.69.25 - DataDyne 13.2-RELEASE-p10 /usr/local/bastille/jails/DataDyne/root
HellStorm Up 192.168.69.17 - HellStorm 13.2-RELEASE-p10 /usr/local/bastille/jails/HellStorm/root
MetaCortex Up 192.168.69.20 - MetaCortex 13.2-RELEASE-p10 /usr/local/bastille/jails/MetaCortex/root
PostgreSQL00-test Up 192.168.69.26 - PostgreSQL00-test 13.2-RELEASE-p10 /usr/local/bastille/jails/PostgreSQL00-test/root
PostgreSQL01-test Up 192.168.69.27 - PostgreSQL01-test 13.2-RELEASE-p10 /usr/local/bastille/jails/PostgreSQL01-test/root
PostgreSQLBackups-test Up 192.168.69.29 - PostgreSQLBackups-test 13.2-RELEASE-p10 /usr/local/bastille/jails/PostgreSQLBackups-test/root
PostgreSQLRestore-test Up 192.168.69.28 - PostgreSQLRestore-test 13.2-RELEASE-p10 /usr/local/bastille/jails/PostgreSQLRestore-test/root
RECLog Up 192.168.69.21 - RECLog 13.2-RELEASE-p10 /usr/local/bastille/jails/RECLog/root
thinJail Up 192.168.40.190 - thinJail 14.0-RELEASE-p5 /usr/local/bastille/jails/thinJail/root
thinJail2 Up 192.168.40.191 - thinJail2 14.0-RELEASE-p5 /usr/local/bastille/jails/thinJail2/root
En la documentación solo está documentado a dÃa de hoy(18/03/2024) como actualizar thinjails , el procedimiento de como actualizar una thickjail se ha deducido de las páginas man de bastille y de la ayuda del comando:
man bastille
bastille upgrade
Usage: bastille upgrade release newrelease | target newrelease | target install | [force]
Actualizamos:
Aplicamos la actualización:
Reiniciamos la jail:
bastille start JAILNAME
Seguimos con la actualización:
Reinstalamos todo el software según utilicemos paquetes binarios o ports:
Si vemos el siguiente mensaje de error, debemos cambiar la shell a la por defecto antes de acceder a la jail:
>ld-elf.so.1: Shared object "libncursesw.so.8" not found, required by "bash"
pkg-static upgrade -f
exit
git -C /usr/ports pull
cd /usr/ports
make fetchindex
for PORT in $(pkg info|awk \'{print$1}\'); do PORT_PATH=$(pkg info $PORT|grep Origin|awk \'{print$3}\') && echo PORT: $PORT - $PORT_PATH && cd /usr/ports/$PORT_PATH && export BATCH=\"yes\" && make clean reinstall clean; done
exit
Revertimos el cambio de shell:
Finalizamos la actualización:
Actualizamos por si ha salido algún parche de la última release:
Reiniciamos la jail para asegurarnos de que todo funciona correctamente:
bastille start JAILNAME
Podemos ver todas las jails actualizadas:
JID State IP Address Published Ports Hostname Release Path
Atlas Up 192.168.69.19 - Atlas 14.0-RELEASE-p5 /usr/local/bastille/jails/Atlas/root
DataDyne Up 192.168.69.25 - DataDyne 14.0-RELEASE-p5 /usr/local/bastille/jails/DataDyne/root
HellStorm Up 192.168.69.17 - HellStorm 14.0-RELEASE-p5 /usr/local/bastille/jails/HellStorm/root
MetaCortex Up 192.168.69.20 - MetaCortex 14.0-RELEASE-p5 /usr/local/bastille/jails/MetaCortex/root
PostgreSQL00-test Up 192.168.69.26 - PostgreSQL00-test 14.0-RELEASE-p5 /usr/local/bastille/jails/PostgreSQL00-test/r
PostgreSQL01-test Up 192.168.69.27 - PostgreSQL01-test 14.0-RELEASE-p5 /usr/local/bastille/jails/PostgreSQL01-test/r
PostgreSQLBackups-test Up 192.168.69.29 - PostgreSQLBackups-test 14.0-RELEASE-p5 /usr/local/bastille/jails/PostgreSQLBackups-t
PostgreSQLRestore-test Up 192.168.69.28 - PostgreSQLRestore-test 14.0-RELEASE-p5 /usr/local/bastille/jails/PostgreSQLRestore-t
RECLog Up 192.168.69.21 - RECLog 14.0-RELEASE-p5 /usr/local/bastille/jails/RECLog/root
thinJail Up 192.168.40.190 - thinJail 14.0-RELEASE-p5 /usr/local/bastille/jails/thinJail/root
thinJail2 Up 192.168.40.191 - thinJail2 14.0-RELEASE-p5 /usr/local/bastille/jails/thinJail2/root
IOCAGE update
Primero actualizamos el padre a 14.0 siguiendo los pasos anteriores de este mismo artÃculo.
El siguiente paso es actualizar tanto el SO como los paquetes a su última versión en cada una de las jails.
iocage console JAILNAME
pkg upgrade
pkg autoremove
exit
Ahora ya podemos actualizarlas a 14.0, bajamos la RELEASE desde Iocage:
[0] 12.4-RELEASE
[1] 13.2-RELEASE
[2] 13.3-RELEASE
[3] 14.0-RELEASE
Type the number of the desired RELEASE
Press [Enter] to fetch the default selection: (14.0-RELEASE)
Type EXIT to quit: 3
Fetching: 14.0-RELEASE
Downloading: MANIFEST [####################] 100%
Downloading: base.txz [####################] 100%
Downloading: lib32.txz [####################] 100%
Downloading: src.txz [####################] 100%
Extracting: base.txz...
Extracting: lib32.txz...
Extracting: src.txz...
* Updating 14.0-RELEASE to the latest patch level...
Actualizamos cada una de las jails:
Reinstalamos todo el software según utilicemos paquetes binarios o ports:
Si vemos el siguiente mensaje de error, debemos cambiar la shell a la por defecto antes de acceder a la jail:
>ld-elf.so.1: Shared object "libncursesw.so.8" not found, required by "bash"
pkg-static upgrade -f
exit
git -C /usr/ports pull
cd /usr/ports
make fetchindex
for PORT in $(pkg info|awk '{print$1}'); do PORT_PATH=$(pkg info $PORT|grep Origin|awk '{print$3}') && echo PORT: $PORT - $PORT_PATH && cd /usr/ports/$PORT_PATH && export BATCH="yes" && make clean reinstall clean; done
exit
Revertimos el cambio de shell:
Actualizamos por si ha salido algún parche de la última release:
Reiniciamos la jail para asegurarnos de que todo funciona correctamente:
iocage start JAILNAME
Comprobamos la versión de la jail actualizada:
+-----+--------------------+-------+--------------+---------------+
| JID | NAME | STATE | RELEASE | IP4 |
+=====+====================+=======+==============+===============+
+-----+--------------------+-------+--------------+---------------+
| 3 | haproxy | up | 14.0-RELEASE | 192.168.1.202 |
+-----+--------------------+-------+--------------+---------------+
| 4 | web00 | up | 13.2-RELEASE | 192.168.1.203 |
+-----+--------------------+-------+--------------+---------------+
NOTA: Las actualizaciones mediante Iocage realizan de forma automática un snapshot en cada actualización de este modo si algo saliese mal se podrÃa revertir sin problemas. Pero debemos tener en cuenta que los snapshots ocupan espacio en disco.
Iocage - Template
Para actualizar templates primero debemos convertilos a jail, actualizarlos y volvemos a convertirlos a template:
+-----+----------------+-------+--------------+---------------+
| JID | NAME | STATE | RELEASE | IP4 |
+=====+================+=======+==============+===============+
| - | basic_template | down | 13.2-RELEASE | 192.168.1.201 |
+-----+----------------+-------+--------------+---------------+
iocage start JAILNAME
Actualizar como si de una jail regular se tratase.
Volvemos a convertirla a template:
+-----+----------------+-------+--------------+---------------+
| JID | NAME | STATE | RELEASE | IP4 |
+=====+================+=======+==============+===============+
| - | basic_template | down | 14.0-RELEASE | 192.168.1.201 |
+-----+----------------+-------+--------------+---------------+
Poudriere
Nos bajamos la nueva versÃon de RELEASE:
JAILNAME VERSION ARCH METHOD TIMESTAMP PATH
freebsd_13-2x64 13.2-RELEASE-p10 amd64 http 2024-03-17 05:25:03 /usr/local/poudriere/jails/freebsd_13-2x64
freebsd_14-0x64 14.0-RELEASE-p5 amd64 http 2024-03-18 16:46:00 /usr/local/poudriere/jails/freebsd_14-0x64
Migramos las opciones genéricas de compilación:
Migramos las opciones especÃficas de los paquetes:
Actualizamos la jail y el árbol de ports:
poudriere ports -u -p latest
Compilamos los ports:
La parte del cliente quedarÃa del siguiente modo:
poudriere: {
url: "http://poudriere.alfaexploit.com/packages/freebsd_14-0x64-latest/",
mirror_type: "http",
signature_type: "pubkey",
pubkey: "/usr/local/etc/ssl/certs/poudriere.cert",
enabled: yes,
}
Recompilamos todos los paquetes:
Poudriere - limpieza
Eliminamos la jail:
Eliminamos el código fuente de los paquetes:
Eliminamos los logs:
Eliminamos algunos directorios residuales:
rm -rf /usr/local/etc/poudriere.d/freebsd_13-2x64-latest-options/
rm /usr/local/etc/poudriere.d/freebsd_13-2x64-make.conf
Eliminamos la versión antigua del fichero data.json:
MTA:
El MTA por defecto en 14.0 es DragonFly Mail Agent, pero si queremos seguir utilizando nuestro buen amigo Sendmail tan solo debemos copiar la configuración apropiada en /etc/mail/mailer.conf:
The default mail transport agent (MTA) is now the Dragonfly Mail Agent (dma(8)) rather than sendmail(8). Configuration of the MTA is done via mailer.conf(5). sendmail(8) and its configuration remain available. a67b925ff3e5
cp /usr/share/examples/sendmail/mailer.conf /etc/mail/mailer.conf
make
cp HellStorm.cf sendmail.cf
service sendmail restart