Compilation de src.rpm sous CentOS / RedHat

Published: 01-02-2015

Updated: 30-01-2016

By: Maxime de Roucy

tags: centos redhat rpm

Comment compiler/modifier un paquet RedHat/CentOS. Ici je vais prendre l’exemple de firefox (monpaquet=firefox).

Environnement de compilation

rpmbuild

Si on utilise rpmbuild on peut fixer un certaines macros qui servirons durant la compilation, dans le fichier ~/.rpmmacros.

%vendor                 Craoc
%packager               Maxime de Roucy <maxime.deroucy@gmail.com>
%dist                   .el5

%_signature             gpg
%_gpg_path              %(echo $HOME)/.gnupg
%_gpg_name              6E715AB0
%__gpg_sign_cmd         %{__gpg} gpg --force-v3-sigs --digest-algo sha256 --batch --no-verbose --no-armor --passphrase-fd 3 --no-secmem-warning -u %{_gpg_name} -sbo %{__signature_filename} %{__plaintext_filename}

%_topdir        %(echo $HOME)/rpmbuild
%_smp_mflags        -j3
%__arch_install_post    /usr/lib/rpm/check-rpaths   /usr/lib/rpm/check-buildroot

mock

mock est un outil qui permet de compiler les rpm (il lance rpmbuild) dans un chroot, il permet d’être sure d’avoir un environement de compilation « propre ». Il ne fonctionne pas si on est déjà dans un chroot/nspawn…

installation

mock se trouve dans les dépôts EPEL. On peut facilement ajouter ces dépôts sous CentOS via la commande suivante.

root@testhost # yum install epel-release

On peut aussi installer EPEL manuellement :

root@testhost # cd /tmp
root@testhost # curl -O https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
root@testhost # rpm -Uvh epel*

Liens pour télécharger les paquets epel-release pour :

Ensuite un simple yum install mock suffit.

configuration

Chaque environment de compilation est géré par un fichier de configuration (.cfg) disponible dans /etc/mock. Les fichier commançant par « epel » sont ceux correspondant CentOS / RHEL. Je vous encourage à y jeter un œuil, ils sont généralement assez simple et intéressant pour comprendre ce que fait mock lorsqu’il compil un paquet. /etc/mock/site-defaults.cfg est un fichier de configuration global, les inscructions qu’il contient sont appliqué pour toutes les « targets ».

C’est dans ce fichier que nous allons indiquer les macros de compilation (cf. rpmbuild). Indiquer le « vendor » et le « packager » est généralement suffisant.

max@laptop % cat /etc/mock/site-defaults.cfg
…
config_opts['macros']['%vendor'] = "Craoc"
config_opts['macros']['%packager'] = "Votre Nom <vnom@mail.com>"

Récupération des sources

On peut télécharger le src.rpm « à la main » via un navigateur ou wget/curl ou avec yumdownloader (du paquet yum-utils).

max@laptop % yumdownloader --source $monpaquet

Extraction des

Je travail sur une CentOS 7 minimal.

Nous allons d’abord devoir générer un srpm rebrander que nous compilerons ensuite. Nous utilisons plusieurs outils que ne fonctionne pas dans un environnement chrooté, nous devons donc utiliser une machine virtuel.

Installation du dépots EPEL contenant mock.

root@testhost # cd /tmp
root@testhost # curl -O http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
root@testhost # rpm -Uvh epel*

Mise à jour et installation de mock, git et pyrpkg (dépendance de centpkg), personnellement j’en profite aussi pour installer vim.

root@testhost # yum update
root@testhost # yum install mock git pyrpkg

centpkg est un outil qui vas gérer le dépôts git sur lequels se trouve les sources. Il permet de lancer facilement les principales commandes relative à la création de paquets. J’ai essayé sans succès d’utiliser rpkg et fedpkg à la place de centpkg (centpkg est encore en alpha). Ce sont des outils prévue pour Fedora et ne sont pas adaptés au format des dépôt git CentOS.

Installation de centpkg

root@testhost # cd ~
root@testhost # git clone https://git.centos.org/git/centpkg.git
root@testhost # cd centpkg
root@testhost # python setup.py install

Le fichier de configuration de centpkg est /etc/rpkg/centpkg.conf. Nous n’avons pas besoins de le modifier pour l’instant étant donné que nous utilisons les dépôt git officiels de CentOS.

Création de l’utilisateur non privilégié qui nous servira pour manipuler les sources.

root@testhost # useradd -g users -G mock builder
root@testhost # su - builder

Configuration de git.

max@laptop % git config --global core.editor "vim"
max@laptop % git config --global user.name "Votre Nom"
max@laptop % git config --global user.email "vnom@mail.com"

Sources disponible sur git.centos.org

Récupération de la branch CentOS 6 de Firefox (soft qui va nous servir d’exemple).

max@laptop % cd ~
max@laptop % centpkg clone --branch c6 firefox

Ici nous n’avons pas récupéré les sources, elles n’ont pas encore été migrées dans git. En revanche elle sont présente pour CentOS 7.

max@laptop % cd ~/firefox
max@laptop % git log origin/c7

Pour télécharger les soruces on peut télécharger le srpm de firefox pour CentOS 6 et alimenter le git.

max@laptop % cd /tmp
max@laptop % curl -O http://vault.centos.org/centos/6/updates/Source/SPackages/firefox-31.4.0-1.el6.centos.src.rpm
max@laptop % cd ~/firefox
max@laptop % rpm -ivh --define="_topdir `pwd`" /tmp/firefox-31.4.0-1.el6.centos.src.rpm

--define="_topdirpwd" permet d’indiquer à rpm d’extraire le srpm dans le répertoire courant. Sinon, par défaut, il est extrait dans ~/rpmbuild.

Ou utiliser centpkg.

max@laptop % cd ~/firefox
max@laptop % centpkg sources

On doit créer un fichier de métadonnées contenant les sommes md5 des sources du logiciel et empécher le versionning de ces fichiers. En effet, les sources du logiciel sont dans un dépôt séparé des sources du paquets (même si le srpm contient les deux). Pour savoir quels sont ces fichier on peut prendre exemple sur la branch origin/c7 (correspondant à CentOS 7).

max@laptop % git show origin/c7:.firefox.metadata
32502debd0a207bb918ccf169757607ecb32b5e0 SOURCES/firefox-31.4.0esr.source.tar.bz2
d43b72d4814d8a7e6805de24d048136af1a085d0 SOURCES/firefox-langpacks-31.4.0esr-20150106.tar.bz2
max@laptop % md5sum \
	SOURCES/firefox-31.4.0esr.source.tar.bz2 \
	SOURCES/firefox-langpacks-31.4.0esr-20150106.tar.bz2 \
	> .firefox.metadata
max@laptop % cut -d ' ' -f 3 .firefox.metadata > .gitignore

Pour l’instant on ne supprime pas les fichiers listés dans .firefox.metadata car on utilise les dépôt officiels de CentOS, or ces fichiers sources ne s’y trouve pas. Si on les supprimés, lors de la gérénation du srpm centpkg essaierait de les télécharger depuis depuis ces dépôt officiel et échouerait.

On effectuer un commit initial avant le rebranding.

max@laptop % git add .
max@laptop % git commit -m "import firefox-31.4.0-1.el6.centos.src.rpm"

On peut maintenant rebrander les sources en prenant exemple sur ce qui est fait dans la branch origin/c7 (correspondant à CentOS 7).

max@laptop % git log --decorate=full origin/c7
max@laptop % git diff imports/c7/firefox-31.4.0-1.el7_0..origin/c7
max@laptop % git mv …
max@laptop % vim …
max@laptop % git add …
max@laptop % git commit -m 'brand craoc : firefox-31.4.0-1'

On doit maintenant spécifier quelques informations qui seront utilisées lors de la génération du srpm et du rpm.

max@laptop % cat /etc/mock/site-defaults.cfg
config_opts['macros']['%vendor'] = "Craoc"
config_opts['macros']['%packager'] = "Votre Nom <vnom@mail.com>"

Lancer la génération du srpm et rpm, pour RHEL 6 64 bits.

max@laptop % centpkg mockbuild --root epel-6-x86_64

Pour RHEL 6 32 bits.

max@laptop % centpkg mockbuild --root epel-6-i386

On peut aussi générer un srpm initial avec centpkg et générer les paquets (y compris le srpm final) avec mock.

max@laptop % cd ~/firefox
max@laptop % centpkg srpm
max@laptop % mock -r epel-6-x86_64 firefox-31.4.0-1.el6.src.rpm -D 'dist .el6.craoc'

Sources non disponible sur git.centos.org

Firefox est disponible dans les dépôt git officiels de CentOS. Ce n’est pas le cas de tous les logiciels, par exemple Thunderbird.

Ici je prendrais donc l’exemple de thunderbird.

On télécharge les srpm de RedHat et CentOS et on les extrait.

max@laptop % cd ~
max@laptop % curl -O ftp://ftp.redhat.com/redhat/linux/enterprise/6Server/en/os/SRPMS/thunderbird-31.4.0-1.el6_6.src.rpm
max@laptop % rpm -ivh thunderbird-31.4.0-1.el6.centos.src.rpm
max@laptop % mv rpmbuild thunderbird-rhel
max@laptop % curl -O http://vault.centos.org/centos/6/updates/Source/SPackages/thunderbird-31.4.0-1.el6.centos.src.rpm
max@laptop % rpm -ivh thunderbird-31.4.0-1.el6.centos.src.rpm
max@laptop % mv rpmbuild thunderbird-centos

On créer le répertoire git qui sera utilisé pour versionner les sources du rpm et on y copie les sources RedHat (on aurait pu prendre les sources CentOS).

max@laptop % cd ~
max@laptop % mkdir thunderbird
max@laptop % cp -r thunderbird-rhel/* thunderbird
max@laptop % cd thunderbird

On doit créer un fichier de métadonnées contenant les sommes md5 des sources du logiciel et empécher le versionning de ces fichiers. En effet, les sources du logiciel sont dans un dépôt séparé des sources du paquets (même si le srpm contient les deux). Je n’ai pas de solution pour déterminer la liste de ces fichier… généralement il s’agit des première sources inscrite dans le fichier SPEC/*.spec (grep '^Source' SPECS/thunderbird.spec).

max@laptop % md5sum \
	SOURCES/thunderbird-31.4.0.source.tar.bz2 \
	SOURCES/thunderbird-langpacks-31.4.0-20150110.tar.bz2 \
	> .thunderbird.metadata
max@laptop % cut -d ' ' -f 3 .thunderbird.metadata > .gitignore

On effectuer un commit initial avant le rebranding.

max@laptop % git init
max@laptop % git checkout -b c6
max@laptop % git add .
max@laptop % git commit -m 'import thunderbird-31.4.0-1.el6_6.src.rpm'

On peut maintenant rebrander les sources en prenant exemple sur les différences entre les sources RedHat et CentOS.

max@laptop % diff -r ~/thunderbird-rhel/ ~/thunderbird-centos/
max@laptop % git mv …
max@laptop % vim …
max@laptop % git add …
max@laptop % git commit -m 'brand craoc : thunderbird-31.4.0-1'

Génération d’un près srpm qui servira à lancer mock.

max@laptop % centpkg --dist el6 --module-name thunderbird srpm

Lancer la génération du srpm et rpm, pour RHEL 6 64 bits.

max@laptop % mock -r epel-6-x86_64 thunderbird-31.4.0-1.el6.src.rpm -D 'dist .el6.craoc'

Pour RHEL 6 32 bits.

max@laptop % mock -r epel-6-i386 thunderbird-31.4.0-1.el6.src.rpm -D 'dist .el6.craoc'

-D 'dist .el6.craoc' permet d’ajouter « .craoc » à la spécification de la version de la distribution « .el6 ». Les paquets créés seront de la forme « thunderbird-31.4.0-1.el6.craoc… » Ça permet de différentier nos paquets des originaux.

Vérification

Pour vérifier les métadonnées contenues dans un srpm.

max@laptop % rpm -qpi firefox-31.4.0-1.el6.craoc.src.rpm

Compiler plusieurs paquets à la fois

Il est possible de compiler plusieurs paquets à la fois avec mock.

max@laptop % mock -r epel-6-x86_64 firefox-31.4.0-1.el6.src.rpm thunderbird-31.4.0-1.el6.src.rpm -D 'dist .el6.craoc' --resultdir=/var/tmp/result

--resultdir=… est obligatoir si on veut compiler plusieurs paquets en même temps.

Signature des paquets

TODO

Liste des paquets rebrandés par CentOS

Les paquets qui ont été modifiés par CentOS ont un nom contenant la chaine de caractères « centos » (le paquet « kernel » est une exception) on peut donc les lister facilement avec la commande suivante (la deuxième ligne n’affiche que le nom du logiciel) :

max@laptop % version=6.6 ; curl -s "http://vault.centos.org/$version/os/Source/SPackages/" | sed -n 's@^.*href="\([^"]*\(\.centos\|kernel\)[^"]*rpm\)".*$@\1@p'
max@laptop % version=6.6 ; curl -s "http://vault.centos.org/$version/os/Source/SPackages/" | sed -n 's@^.*href="\([^"]*\(\.centos\|kernel\)[^"]*rpm\)".*$@\1@p' | sed -n 's/^\(.*\)-[^-]*-[^-]*$/\1/p'

Pour la dernière version majeur de CentOS, il ne faut pas utilisé le dépôt « vault » :

max@laptop % version=7 ; curl -s "http://mirror.centos.org/centos/$version/os/x86_64/Packages/" | sed -n 's@^.*href="\([^"]*\(\.centos\|kernel\)[^"]*rpm\)".*$@\1@p'
max@laptop % version=7 ; curl -s "http://mirror.centos.org/centos/$version/os/x86_64/Packages/" | sed -n 's@^.*href="\([^"]*\(\.centos\|kernel\)[^"]*rpm\)".*$@\1@p' | sed -n 's/^\(.*\)-[^-]*-[^-]*$/\1/p'

Pour n’afficher que le nom du logiciel ajouter via un « | » la commande sed -n 's/^\(.*\)-[^-]*-[^-]*$/\1/p'.