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.