Créer un package RPM

De Le wiki de Fred sur gantzer.eu

Sommaire

Préambule

Ce document décrit la façon simple de générer un package rpm (Red-Hat Package Manager).

On va traiter deux méthodes:

  • En créant le rpm à partir de sources que l'on va compiler à travers rpmbuild. L'exemple se base sur la création d'un package de l'outil GNU cfengine en version 2.2.8.
  • En créant un rpm à partir d'un ficher tar.gz. L'exemple se base sur un tar.gz contenant un shellscript et son fichier de configuration.

Création du rpm en compilant les sources

Pré-requis

  • Installer le package rpm-build (vérifier par rpm -q rpm-build)
  • Créer l'arborescence /usr/src/redhat/SOURCES . C'est dans ce répertoire que l'on va déposer les sources qui une fois compilées constitueront le package.


Définition et création du package

La création du package se fait en 4 phases:


  1. créer le fichier nom_software.spec .Il contient la définition du package. Il peut être placé n'importe où
  1. se connecter UID 0 (nécessaire pour l'installaltion)
  1. Copier le fichier tar.gz contenant les sources dans /usr/src/redhat/SOURCES
  2. Exécuter rpmbuild -ba nom_software.spec pour compiler et créer le package


Le fichier .spec

Ce fichier contient simplement les attributs de génération du rpm

   # pwd
   /root
   # cat cfengine.spec
   Summary: GNU CFEngine
   Name: cfengine
   Version: 2.2.8
   Release: 1
   Source0: %{name}-%{version}.tar.gz
   License: GPL
   Group: Applications/System
   %description
   Le programme CFEngine qui permet d'administrer
   des groupes heterogenes de machines
   %prep
   %setup -q
   %build
   ./configure --prefix=/usr/local/cfengine
   make
   %install
   make install
   %files
   %defattr(-,root,root)
   /usr/local/cfengine

Les éléments du fichier .spec:

  • L'entête correspond à la description du package (nom, version, etc). A noter que Source0: %{name}-%{version}.tar.gz doit correspondre exactement à la syntaxe du fichier source dans /usr/src/redhat/SOURCES (dans notre exemple /usr/src/redhat/SOURCES/cfengine-2.2.8.tar.gz).Il peut y avoir plusieurs sources --> Source0,Source1... Une liste des groupes existants sont dans /usr/share/doc/rpm-4.x.x/GROUPS, mais on peut choisir ce que l'on veut.
  • %prep et %setup -q indiquent qu'il faut préparer le package source (extraction gz et dé-tar)
  • %build, correspond à la partie buid des sources avec le ./configure.
  • %install installe le package compilé sur le système.
  • %files et %defattr définit les fichiers ou répertoires à intégrer dans le package avec les droits par défaut.


La création du package

La commande rpmbuild -ba fichier.spec va compiler,installer et créer le package cfengine

   # rpmbuild -ba /root/cfengine.spec
   ...
   ....
   .....
   make[2]: Leaving directory `/usr/src/redhat/BUILD/cfengine-2.2.8'
   make[1]: Leaving directory `/usr/src/redhat/BUILD/cfengine-2.2.8'
   Processing files: cfengine-2.2.8-1
   Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
   Requires: /bin/sh /usr/bin/perl libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) ...
   Wrote: /usr/src/redhat/SRPMS/cfengine-2.2.8-1.src.rpm
   Wrote: /usr/src/redhat/RPMS/x86_64/cfengine-2.2.8-1.x86_64.rpm
  • Le rpm binaire est générés sous /usr/src/redhat/RPMS/x86_64/cfengine-2.2.8-1.x86_64.rpm
  • Le source RPM est sous /usr/src/redhat/SRPMS/cfengine-2.2.8-1.src.rpm (c'est un fichier contenant le tar.gz des sources et le fichier .spec).


Installation du package

Il faut au préalable supprimer ce qui a été installé pendant la génération du package.

   # rm -rf /usr/local/cfengine
   # rpm -ivh /usr/src/redhat/RPMS/x86_64/cfengine-2.2.8-1.x86_64.rpm
   Preparing...                ########################################### [100%]
   # rpm -qi cfengine-2.2.8-1
   Name        : cfengine                     Relocations: (not relocatable)
   Version     : 2.2.8                             Vendor: (none)
   Release     : 1                             Build Date: Tue 16 Sep 2008 10:55:02 AM CEST
   Install Date: Tue 16 Sep 2008 10:59:51 AM CEST      Build Host: prssis1t.e-i.net
   Group       : Applications/System           Source RPM: cfengine-2.2.8-1.src.rpm
   Size        : 16505409                         License: GPL
   Signature   : (none)
   Summary     : GNU CFEngine
   Description :
   Le programme CFEngine qui permet d'administrer
   des groupes heterogenes de machines


Création du rpm à partir d'un fichier tar.gz

Principe

  1. on va générer le fichier .spec à partir du tar.gz. Le plus simple est d'utiliser l'utilitaire autospec disponible ici: http://www.npsnet.com/danf/software/ (c'est un rpm à installer :) )
  2. Ensuite, il va falloir modifier le fichier spec génère, pour y ajouter quelques informations, que le générateur ne peut inventer (description, résumé ...).
  3. Finalement, on procède de la même façon qu'à partir de fichiers sources avec rpmbuild.

Exemple

On veut générer un rpm contenant les deux fichiers suivants:

  /usr/local/bin/sys_sauve_mondo.sh
  /usr/local/etc/exclude_mondo.conf
  • On génère le fichier tgz:
  cd /tmp
  tar cvPf sys_sauve_mondo.tar /usr/local/bin/sys_sauve_mondo.sh /usr/local/etc/exclude_mondo.conf
  gzip sys_sauve_mondo.tar
  
  • On créé le specfile avec autospec:
  tar tfz /tmp/sys_sauve_mondo.tar.gz | autospec -b > sys_sauve_mondo.spec
  • On édite le fichier spec en :
    • décommentant et modifiant la valeur "unknown" des "tags" suivants (obligatoires) : Group, Licence(Copyright), summary, description
    • supprimant certains "attributs" de fichiers : %readme ou %license, générés par certaines version d'autospec, mais que rpm ne comprends pas.
    • Le fichier .spec doit avoir cet aspect:
  # Initial spec file created by autospec ver. 0.8 with rpm 3 compatibility
  Summary: Script "mksysb-like" qui declenche une sauvegarde mondorescue
  # The Summary: line should be expanded to about here -----^
  Name: sys_sauve_mondo
  Version: 1
  Release: 1
  Group: Applications/Archiving
  License: GPL
  Source: sys_sauve_mondo.tar.gz
  #NoSource: 0
  BuildRoot: %{_tmppath}/%{name}
  Vendor: MOI
  # Following are optional fields
  #URL: http://www.example.net/tmp/
  #Distribution: Red Hat Contrib-Net
  #Patch: tmp-%{version}.patch
  #Prefix: /usr/local
  BuildArch: noarch
  Requires: mondo >= 2.2.7
  #Obsoletes:
  #BuildRequires:
  
  %description
  sys_sauve_mondo.sh encapsule mondorescue pour verfier que les prerequis sont corrects.
  Le fichier de configuration contient les filesystems a exclure de la sauvegarde.
  
  %prep
  %setup -c tmp
  #%patch
  
  %install
  %__cp -a . "${RPM_BUILD_ROOT-/}"
  
  %clean
  [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
  
  %files
  %defattr(-,root,root)
  /usr/local/bin/sys_sauve_mondo.sh
  %config /usr/local/etc/exclude_mondo.conf
  
  %changelog
  * Thu Oct 23 2008 root <root@vrssi01t>
  - Initial spec file created by autospec ver. 0.8 with rpm 3 compatibility
  
  • On finit par générer le fichier rpm (en tant que root):
    • Copier le ficher tar à sa place:
  cp sys_sauve_mondo.tar.gz /usr/src/redhat/SOURCES/sys_sauve_mondo.tar.gz
    • Un petit coup de rpmbuild:
  rpmbuild -bb sys_sauve_mondo.spec

Le fichier rpm est généré dans /usr/src/redhat/RPMS/noarch (car on avait spécifié dans le fichier .spec que c'était du noarch). On aurait aussi pu choisir x86_64 ou i386 en fonction de l'architecture choisie.

  # rpm -qip /usr/src/redhat/RPMS/noarch/sys_sauve_mondo-1-1.noarch.rpm
  
  Name        : sys_sauve_mondo              Relocations: (not relocatable)
  Version     : 1                                 Vendor: MOI
  Release     : 1                             Build Date: Thu 23 Oct 2008 04:57:05 PM CEST
  Install Date: (not installed)               Build Host: vrssi01t
  Group       : Applications/Archiving        Source RPM: sys_sauve_mondo-1-1.src.rpm
  Size        : 11020                            License: GPL
  Signature   : (none)
  Summary     : Script "mksysb-like" qui declenche une sauvegarde mondorescue
  Description :
  sys_sauve_mondo.sh encapsule mondorescue pour verfier que les prerequis sont corrects.
  Le fichier de configuration contient les filesystems a exclure de la sauvegarde.
  
  # rpm -qlp /usr/src/redhat/RPMS/noarch/sys_sauve_mondo-1-1.noarch.rpm
  /usr/local/bin/sys_sauve_mondo.sh
  /usr/local/etc/exclude_mondo.conf
  

Howto

Eviter la verification sur les prérequis

rpmbuild va verifier les libs dynamiques dans les binaires. Il se peut que ces libs soient dans le package lui-même, donc problèmes !

Ajouter dans le fichier spec:

  AutoReq: 0

Passer des variables au RPM

Il est possible d'utiliser des variables d'environnement dans le fichier .spec !

  rpmbuild -bb package-1.12.i386.spec --define "VAR1 $VAR1" --define "VAR2 $VAR2"

On pourra donc faire:

  export VAR1=valeur1
  export VAR2=valeur2
  rpm -ivh package-1.12.i386.rpm


Lister les caractéristiques spec d'un RPM

Pour voir les dépendances du package

  rpm -qpR fichier_rpm.rpm

Pour voir les scripts pre/post contenus dans le rpm

  rpm -qp --scripts fichier_rpm.rpm

Forcer la desinstall d'un rpm même si un script de pre/post plante

  rpm -ev --noscripts

Tester dans le spec si install initiale ou upgrade

  %post
  #--------------------------------------------------
  # Perform some custumization at first installation
  #--------------------------------------------------
  if [ "$1" = "1" ]; then
  ...
  ...
  fi


  %postun
  #------------------------------------------------
  # Undo some custumization at last uninstallation
  #------------------------------------------------
  if [ "$1" = "0" ]; then
  ...
  perl -i -ne 'print if ($_!~m/(|toto.*iso)/)' file
  ...
  fi

Annexes

Le format du fichier spec

Les tags

Dans la terminologie rpm, un mot-clé s'appelle un "tag".

Il y a deux formats possibles :

  • pour les champs qui tiennent sur une ligne : tag: valeur
  • pour les autres :
    • on commence par %tag
    • suivent les lignes du champ
    • il se termine par une ligne vide


Les tags obligatoires

  • Name : nom du package
  • Version : version du logiciel
  • Release : release
  • Summary : description en une ligne du package
  • Group : pour classer le package
  • Copyright : le type de licence
  • %description : description détaillée en quelques lignes
  • %file : la liste des fichiers contenus dans le package
  • %config : fichier contenu dans le package mais non écrasé s'il existe (renommé). Ca aide si on fait un update...
  • Avec %defattr(0755, root, bin) pour définir les droits sur un fichier


Les tags optionnels

  • Packager : nom et adresse mail de celui qui a fait le package
  • URL : site ftp/web où trouver le logiciel
  • Distribution : pour quelle distribution ?
  • %changelog : décrit les changements du logiciel
  • BuildRoot : permet de fabriquer le package "dans un coin", sans interférer avec le reste de la machine
  • patch : pour appliquer un patch a la compilation
  • %pre, %post, %preun et %postun : scripts de pré et postinstallation
  • Requires et Provide : gestion des dépendances
Outils personnels
Navigation