Il y a quelque temps, j’ai décidé de migrer l’ensemble de mes postes de travail tournant sous OpenSUSE vers Rocky Linux, un clone de Red Hat Enterprise Linux. La plupart des paquets dont j’ai normalement besoin pour configurer un poste de travail cohérent sont fournis soit par les dépôts de paquets officiels de la distribution, soit par des dépôts tiers comme EPEL, RPMFusion ou ELRepo. Or, il arrive tôt ou tard qu’un paquet que j’utilise au quotidien n’est disponible nulle part. Dans ce cas, ce n’est pas une mauvaise idée de retourner aux sources – littéralement – et de construire moi-même mes paquets RPM.
Étant donné que Rocky Linux est un clone binairement compatible à Red Hat Enterprise Linux et que cette dernière peut être considérée comme une Fedora stabilisée, la solution pragmatique consiste à partir d’un paquet SRPM (Source RPM) de Fedora pour construire mes propres paquets binaires. C’est d’ailleurs à quelques menus détails près la démarche des mainteneurs du dépôt EPEL (Extra Packages for Enterprise Linux).
Le premier problème qui se pose, c’est la mise en place d’un environnement de construction. La compilation d’un paquet nécessite l’installation de toutes les dépendances de construction, ce qui fait que je me retrouve assez rapidement à spammer mon système de tout un fatras de paquets de développement. Non content de cela, cette manière de procéder me limite à construire des paquets pour la version et l’architecture spécifique que j’utilise, en l’occurence Rocky Linux dans sa version 8.6 sur une architecture x86_64
.
C’est là où Mock entre en jeu. Mock est une surcouche à rpmbuild
qui simplifie de manière significative la construction d’un paquet RPM.
- La construction a lieu dans un environnement
chroot
bien isolé, ce qui m’évite d’encombrer mon système voire même de le mettre en péril. - En dehors de cela, Mock permet également de compiler des paquets pour d’autres distributions dans plusieurs déclinaisons de versions et d’architectures.
Installation
L’utilitaire mock
est fourni par le dépôt tiers EPEL :
# dnf install -y mock rpm-build
L’installation du paquet a créé un nouveau groupe système mock
:
# grep mock /etc/group mock:x:135:
J’ajoute mon utilisateur à ce groupe :
# usermod -aG mock kikinovak
Je me reconnecte et je vérifie si j’appartiens bien à ce groupe :
$ groups
kikinovak wheel mock systemd-journal vboxusers
Un peu de pratique
En guise de démonstration, je vais construire un paquet binaire pour le client OwnCloud. Pour des raisons mystérieuses, l’équipe de OwnCloud ne propose pas le moindre paquet binaire pour Red Hat Enterprise Linux et les distributions dérivées, et le paquet n’est pas fourni par le dépôt EPEL non plus. Qu’à cela ne tienne, on va donc chasser l’ours à mains nues.
Le portail rpm.pbone.net est une excellente adresse pour trouver des paquets SRPM (Source RPM) :
- Je crée un répertoire local
~/SRPMS
. - J’ouvre la page d’accueil du site dans un navigateur Web.
- Je sélectionne Advanced RPM Search.
- Je coche Fedora 35 et je lance une recherche sur
owncloud-client
. - Dans la liste des résultats, j’opte pour
owncloud-client-2.10.1-1.fc35.src.rpm
. - Je copie l’adresse du lien et je télécharge le paquet vers
~/SRPMS
en utilisantwget
.
J’installe le paquet en tant qu’utilisateur simple (et non pas en tant que root
) :
$ cd ~/SRPMS $ rpm -ivh owncloud-client-2.10.1-1.fc35.src.rpm
L’installation a créé une arborescence ~/rpmbuild
qui ressemble à ceci :
$ tree ~/rpmbuild/ /home/kikinovak/rpmbuild/ ├── SOURCES │ ├── 69-sync-inotify.conf │ ├── ownCloud-2.10.1.7389.tar.xz │ ├── owncloud.appdata.xml │ ├── owncloud-client-2.10.1.7389-gcc12.patch │ ├── owncloud-client-2.9.0-syslibs.patch │ └── ownCloud.conf └── SPECS └── owncloud-client.spec 2 directories, 7 files
Je me rends dans le répertoire rpmbuild/SPECS
pour préparer les sources :
$ cd ~/rpmbuild/SPECS/ $ rpmbuild -bs owncloud-client.spec Écrit : /home/kikinovak/rpmbuild/SRPMS/owncloud-client-2.10.1-1.el8.src.rpm
Cette dernière commande a créé quelques répertoires supplémentaires, notamment rpmbuild/SRPMS
:
$ tree ~/rpmbuild/ /home/kikinovak/rpmbuild/ ├── BUILD ├── BUILDROOT ├── RPMS ├── SOURCES │ ├── 69-sync-inotify.conf │ ├── ownCloud-2.10.1.7389.tar.xz │ ├── owncloud.appdata.xml │ ├── owncloud-client-2.10.1.7389-gcc12.patch │ ├── owncloud-client-2.9.0-syslibs.patch │ └── ownCloud.conf ├── SPECS │ └── owncloud-client.spec └── SRPMS └── owncloud-client-2.10.1-1.el8.src.rpm 6 directories, 8 files
Je me rends dans le répertoire SRPMS
:
$ cd ../SRPMS
Le répertoire /etc/mock
contient les configurations respectives de toutes les cibles possibles. Voyons quels sont les profils disponibles pour la distribution que j’utilise :
$ ls -1 /etc/mock/rocky* /etc/mock/rocky-8-aarch64.cfg /etc/mock/rocky-8-x86_64.cfg /etc/mock/rocky-9-aarch64.cfg /etc/mock/rocky-9-ppc64le.cfg /etc/mock/rocky-9-s390x.cfg /etc/mock/rocky-9-x86_64.cfg /etc/mock/rocky+epel-8-aarch64.cfg /etc/mock/rocky+epel-8-x86_64.cfg /etc/mock/rocky+epel-9-aarch64.cfg /etc/mock/rocky+epel-9-ppc64le.cfg /etc/mock/rocky+epel-9-s390x.cfg /etc/mock/rocky+epel-9-x86_64.cfg
Je souhaite construire un paquet pour Rocky Linux 8 sur une plateforme x86_64
. Je sais que mon paquet présente quelques dépendances disponibles dans le dépôt EPEL, je vais donc lancer la construction de mon paquet en optant pour le profil rocky+epel-8-x86_64
:
$ mock -r rocky+epel-8-x86_64 --rebuild owncloud-client-2.10.1-1.el8.src.rpm
INFO: mock.py version 3.0 starting (python version = 3.6.8, NVR = mock-3.0-1.el8)...
Start(bootstrap): init plugins
INFO: selinux enabled
Finish(bootstrap): init plugins
Start: init plugins
INFO: selinux enabled
Finish: init plugins
INFO: Signal handler active
Start: run
INFO: Start(owncloud-client-2.10.1-1.el8.src.rpm) Config(rocky+epel-8-x86_64)
Start: clean chroot
Finish: clean chroot
Start(bootstrap): chroot init
INFO: calling preinit hooks
INFO: enabled root cache
INFO: enabled package manager cache
Start(bootstrap): cleaning package manager metadata
Finish(bootstrap): cleaning package manager metadata
INFO: enabled HW Info plugin
Mock Version: 3.0
INFO: Mock Version: 3.0
Start(bootstrap): dnf install
...
La commande mock
se charge de deux choses ici :
- Télécharger et installer un environnement de construction cohérent
- Construire le paquet à l’intérieur de cet environnement isolé du système
Au bout d’une bonne dizaine de minutes, j’obtiens une série de paquets RPM proprement rangés dans l’arborescence /var/lib/mock
, dans le répertoire qui correspond à ma cible :
$ cd /var/lib/mock/rocky+epel-8-x86_64/result/ $ ls -1 *.rpm owncloud-client-2.10.1-1.el8.src.rpm owncloud-client-2.10.1-1.el8.x86_64.rpm owncloud-client-caja-2.10.1-1.el8.x86_64.rpm owncloud-client-debuginfo-2.10.1-1.el8.x86_64.rpm owncloud-client-debugsource-2.10.1-1.el8.x86_64.rpm owncloud-client-devel-2.10.1-1.el8.x86_64.rpm owncloud-client-dolphin-2.10.1-1.el8.x86_64.rpm owncloud-client-dolphin-debuginfo-2.10.1-1.el8.x86_64.rpm owncloud-client-libs-2.10.1-1.el8.x86_64.rpm owncloud-client-libs-debuginfo-2.10.1-1.el8.x86_64.rpm owncloud-client-nautilus-2.10.1-1.el8.x86_64.rpm owncloud-client-nemo-2.10.1-1.el8.x86_64.rpm
Ce répertoire contient également tous les logs de construction :
$ ls *.log build.log hw_info.log installed_pkgs.log root.log state.log
Pour installer ces paquets localement, utilisez dnf
avec l’option localinstall
plutôt que la commande de bas niveau rpm -ivh
. Cette manière de procéder facilitera de façon significative la gestion des dépendances :
# dnf localinstall ./owncloud-client-libs-2.10.1-1.el8.x86_64.rpm
# dnf localinstall ./owncloud-client-2.10.1-1.el8.x86_64.rpm
# dnf localinstall ./owncloud-client-dolphin-2.10.1-1.el8.x86_64.rpm
...
Dans notre prochain article, nous nous intéresserons de plus près à la mise en place d’un dépôt de paquets personnalisé dans le but de pouvoir installer les paquets RPM construits par nos propres soins sur un grand nombre de machines.
La rédaction de cette documentation demande du temps et des quantités significatives de café espresso. Vous appréciez ce blog ? Offrez un café au rédacteur en cliquant sur la tasse.
0 commentaire