Centralisation des compilations FreeBSD

Nous avons vu dans un précédent article comment utiliser les ports FreeBSD. Mais, lorsque l’on gère un parc de machines, il peut vite devenir pénible de devoir compiler les différents ports machine par machine. C’est consommateur en temps et fastidieux.

Dans le monde des distributions Unix/Linux binaires, il est possible de centraliser le stockage des paquets sur des dépôts privés. FreeBSD permet la même chose… dans le monde des distribution sources ! Grâce à un outil nommé poudrière, dont nous allons parler maintenant.

Qu’est-ce que poudrière ?

Poudrière est un logiciel FreeBSD permettant de créer des paquets à partir des sources pour les mettre à disposition d’un ensemble de machines.

Il a l’avantage de pouvoir gérer, sur un même hôte, plusieurs versions de FreeBSD ainsi que plusieurs architectures processeur.

Pour cela, poudrière utilise le système des jails (containeur FreeBSD) et décorrèle ses différents arbres des ports de celui de la machine sur laquelle il est installé.

Installation de poudrière

Commençons par installer poudrière, comme nous le ferions pour n’importe quel paquet :

root@poudriere:~ # cd /usr/ports/ports-mgmt/poudriere
root@poudriere:/usr/ports/ports-mgmt/poudriere # make config-recursive
root@poudriere:/usr/ports/ports-mgmt/poudriere # make install clean

Configuration de poudrière

ZFS

Pour des questions de performance, poudrière nécessite l’utilisation d’un système de fichiers nommé ZFS.

Avant de configurer poudrière en lui-même, nous allons donc créer et monter un pool ZFS.

Activation du service ZFS :

root@poudriere:~ # sysrc zfs_enable=YES
zfs_enable: NO -> YES

Création du répertoire et montage du pool ZFS :

root@poudriere:~ # mkdir /poudriere-zfs
root@poudriere:~ # zpool create -m /poudriere-zfs/ poudriere /dev/ada1

Nous venons de créer un pool ZFS poudriere que l’on a monté dans le répertoire /poudriere-zfs/. Ce pool utilise le disque dur /dev/ada1.

Vérifions que tout s’est bien passé :

root@poudriere:~ # zfs list
NAME        USED  AVAIL  REFER  MOUNTPOINT
poudriere   334K  18.9G    23K  /poudriere-zfs/
root@poudriere:~ # df -h
Filesystem      Size    Used   Avail Capacity  Mounted on
/dev/ada0s1a     11G    3.3G    6.5G    34%    /
devfs           1.0K    1.0K      0B   100%    /dev
poudriere        19G     23K     19G     0%    /poudriere-zfs

Poudrière

La configuration de poudrière se fait dans le fichier /usr/local/etc/poudriere.conf.

Une fois la configuration terminée vous devriez obtenir le fichier suivant :

root@poudriere:~ # cat /usr/local/etc/poudriere.conf | grep -v '^$\|^#'
ZPOOL=poudriere
FREEBSD_HOST=https://download.FreeBSD.org
RESOLV_CONF=/etc/resolv.conf
BASEFS=/poudriere-zfs/poudriere
USE_TMPFS=yes
DISTFILES_CACHE=/usr/ports/distfiles
PKG_REPO_SIGNING_KEY=/usr/local/etc/ssl/keys/poudriere.key

Détail des options

  • ZPOOL : nom du pool ZFS utilisé par poudriere ;
  • FREEBSD_HOST : adresse utilisée par pourdière pour télécharger les ports ;
  • RESOLV_CONF : fichier de résolution DNS utilisé par les jails de poudrière. Ici, celui de notre hôte ;
  • BASEFS : répertoire utilisé sur l’hôte pour stocker les ports et les jails. Ici, le point de montage de notre pool ZFS ;
  • USE_TMPS : permet à poudrière d’utiliser un TMPFS pour augmenter les performances lors de la compilation. Cette option n’est pas obligatoire et dépend de la quantité de RAM de votre machine ;
  • DISFILES_CACHE : répertoire dans lequel sont stockés les distfiles. Ici, vu que l’hôte dispose d’un arbre des ports, nous mutualisons le stockage des distfiles entre les jails de poudrière et l’hôte lui-même ;
  • PKG_REPO_SIGNING_KEY : emplacement de la clef privée utilisée pour signer les paquets créés. Cette option n’est pas obligatoire, mais signer ses paquets est préférable, surtout pour les installations via HTTP ou FTP.

Certificats pour la signature des paquets

Vu que nous avons décidé de signer nos paquets, nous allons devoir générer notre certificat.

Création du répertoire :

root@poudriere:~ # mkdir -p /usr/local/etc/ssl/{keys,certs}

Génération de la clef privée :

root@poudriere:~ # openssl genrsa -out /usr/local/etc/ssl/keys/poudriere.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
..............................................................++++
....................................................................++++
e is 65537 (0x010001)

Génération du certificat associé :

root@poudriere:~ # openssl rsa -in /usr/local/etc/ssl/keys/poudriere.key -pubout -out /usr/local/etc/ssl/certs/poudriere.cert
writing RSA key

Utilisation de poudrière

Maintenant que poudrière est configuré, voyons comment l’utiliser.

Instanciation des ports et des jails de poudrière

Ports

Comme nous l’avons vu, poudrière utilise ses propres arbres des ports, il faut donc en créer au moins un :

root@poudriere:~ # poudriere ports -c -p default

Détail des options

  • -c : création de l’arbre des ports ;
  • -p : nom de l’arbre des ports. Attention, une fois créé, il n’est plus possible de le changer.

Jails

Créons maintenant notre premier jail :

root@poudriere:~ # poudriere jail -c -j "FreeBSD_12-1_amd64" -v "12.1-RELEASE" -a amd64

Détail des options

  • -c : création du jail ;
  • -j : nom du jail. Attention, le nom ne peut pas contenir de « . » ;
  • -v : version de FreeBSD souhaitée ;
  • -a : architecture processeur du jail créé ;

Nous disposons maintenant d’un jail capable de compiler des paquets pour FreeBSD 12.1 en amd64.

Liste des ports à compiler et options de make

Liste des ports à compiler

Une des façons de gérer la liste des ports à compiler consiste à lister tous les ports dans un fichier.

Dans notre exemple, nous utiliserons le fichier /usr/local/etc/poudriere.d/nom_du_jail-ports :

root@poudriere:~ # cat /usr/local/etc/poudriere.d/FreeBSD_12-1_amd64-ports
games/sl
www/nginx

Ce fichier permettra de compiler sl et nginx ainsi que toutes leurs dépendances.

Options de make

Comme nous l’avons vu précédemment, un des intérêts du système des ports est la flexibilité concernant les options de compilation. Il en va de même lors de l’utilisation de poudrière.

Dans poudrière, il existe plusieurs niveaux d’options pour make :

  • options pour l’ensemble des jails ;
  • options pour un jail en particulier ;
  • options pour un port en particulier.

Options pour l’ensemble des jails

Il est possible de configurer des options qui seront valables pour l’ensemble des compilations. Pour cela, il suffit de créer le fichier /usr/local/etc/poudriere.d/make.conf et d’y ajouter l’ensemble des options souhaitées.

Exemple :

root@poudriere:~ # cat /usr/local/etc/poudriere.d/make.conf
WITH_PKGNG=yes

Options pour un jail en particulier

Si l’on souhaite ajouter des options pour un jail en particulier, le principe est le même que pour l’ensemble des jails, à minima du fichier utilisé (usr/local/etc/poudriere.d/nom_du_jail-make.conf).

Exemple :

root@poudriere:~ # cat /usr/local/etc/poudriere.d/FreeBSD_12-1_amd64-make.conf
WITHOUT_X11=yes

Options pour un port en particulier au sein d’un jail

Enfin, le dernier niveau d’options consiste à les configurer directement au niveau du port.

Par exemple, en utilisant la commande poudriere options qui est l’équivalent d’un make config-recursive pour l’ensemble des ports listés :

root@poudriere:~ # poudriere options -f /usr/local/etc/poudriere.d/FreeBSD_12-1_amd64-ports -j FreeBSD_12-1_amd64 -p default

Détail des options

  • -f : fichier contenant la liste des ports ;
  • -j : nom du jail concerné ;
  • -p : nom de l’arbre des ports à utiliser.

Compilation

Compilons maintenant nos paquets en utilisant la commande poudriere bulk :

root@poudriere:/home/netkm# poudriere bulk -f /usr/local/etc/poudriere.d/FreeBSD_12-1_amd64-ports -j FreeBSD_12-1_amd64 -p default

Détail des options

  • -f : fichier contenant la liste des ports ;
  • -j : nom du jail concerné ;
  • -p : nom de l’arbre des ports à utiliser.

Les paquets se trouvent maintenant dans le répertoire /poudriere-zfs/poudriere/data/packages/FreeBSD_12-1_amd64-default/All/.

Configuration d’un dépôt

Nos paquets sont enfin là ! L’étape finale consiste à les mettre à disposition des machines et à configurer ces dernières pour les consommer.

Configuration d’un serveur http

Mettons en place un serveur nginx pour rendre nos paquets disponibles :

server {
listen 80;
server_name pkg.example.com;
location / {
root   /poudriere-zfs/poudriere/data/packages/;
index  index.html index.htm;
autoindex on;
}

Configuration du dépôt sur les machines

Ayant maintenant un dépôt fonctionnel, il ne reste plus qu’à configurer les machines qui vont l’utiliser.

Désactivation du dépôt officiel FreeBSD

Commençons par désactiver le dépôt officiel de FreeBSD :

root@poudriere:~ # mkdir -p /usr/local/etc/pkg/repos
root@poudriere:~ # echo "FreeBSD: { enabled: no }" > /usr/local/etc/pkg/repos/FreeBSD.conf

Si, à l’avenir, on souhaite réactiver le dépôt officiel, il suffira de supprimer le fichier /usr/local/etc/pkg/repos/FreeBSD.conf ou passer la valeur de no à yes.

Activation de notre dépôt

Comme nous avons signé nos paquets, il est nécessaire de déposer le certificat généré précédemment (/usr/local/etc/ssl/certs/poudriere.cert) sur les différentes machines.

Puis, de créer le fichier contenant l’ensemble des informations concernant le dépôt :

root@poudriere:~ # cat /usr/local/etc/pkg/repos/pkg.examples.com.conf
examples: {
url: "pkg+http://pkg.examples.com/FreeBSD_12-1_amd64-default",
mirror_type: "srv",
signature_type: "pubkey",
pubkey: "/usr/local/etc/ssl/certs/poudriere.cert",
fingerprints: "/usr/share/keys/pkg",
enabled: yes
}

Détail des options

  • url : l’URL à laquelle le dépôt sera joignable. Elle doit préciser le protocole utilisé. L’usage de l’option mirror_type:”srv” implique que l’URL soit de la forme pkg+protocol://adresse ;
  • mirror_type : type de miroir utilisé, ici srv, ce qui permet d’avoir de la haute disponibilité en passant par une entrée DNS ;
  • signature_type : type de signature utilisé ;
  • pubkey : fichier contenant la clef publique permettant d’authentifier les paquets ;
  • fingerprints : fichier dans lequel les empreintes des signatures sont stockées ;
  • enabled : définit si le dépôt est activé ou non.

Utilisation de notre dépôt

Enfin, nous allons pouvoir utiliser nos propres paquets avec pkg :

Conclusion

L’utilisation de poudrière permet de combiner les avantages de deux mondes : celui des distributions sources et celui des paquets binaires. En effet, il est possible d’intervenir sur la compilation des paquets tout en unifiant celle-ci.