Aller au contenu

Administration Unix - CM séance 15

15. La gestion des packages

15.1. Introduction

Les systèmes Unix et les logiciels sont distribués par de nombreuses entités différentes :

  • sociétés commerciales (Redhat, Canonical, Suse, Oracle Solaris, MacOS,...) ;
  • associations ou fondations (Debian, Apache, GNU Project, FreeBSD, Mozilla, ...) ;
  • des contributeurs salariés (Intel, Microsoft,...) ou bénévoles.

Il existe différentes architectures, différentes versions des systèmes, des programmes, des librairies, des langages, etc

Pour permettre aux utilisateurs d'installer plus simplement des logiciels sur leur système sans tout recompiler entièrement, les distributeurs proposent des versions packagées qui permettent :

  • d'installer facilement les logiciels, et en toute sécurité ;
  • de choisir la version d'un logiciel, voire d'en faire cohabiter plusieurs ;
  • de gérer les "dépendances" :

    tel logiciel dépend de telles librairies, de tels autres programmes, dans telle versions. Il est donc nécessaire de les installer au préalable ;

  • de proposer un ensemble cohérent en fonction

    • d'une intention (installation minimale, complète, avec les sources, ...),
    • et des versions des composants du système à un instant t.

Un paquet (package) est un format de fichier, qui contient

  • un "entête" qui décrit ses propriétés (nom, version, dépendances,...) ;
  • une hiérarchie de fichiers à installer (exécutables, librairies, sources, icones, documentation,...) ;
  • des scripts de pré- et post-installation, pré- et post-suppression ;
  • etc.

Il existe des paquets d'un type spécial :

  • les méta-paquets, qui ne contiennent pas de fichiers, mais des dépendances (exemples : gnome, gnome-core, gnome-games) ;
  • des paquets virtuels : ce sont des noms génériques correspondant à un service offert (par exemple, les paquets firefox et chromium fournissent le paquet virtuel www-browser).

Le fonctionnement d'un système de package repose sur :

  • des dépôts de paquets (repositories) : ce sont des serveurs de fichier (http, ftp, P2P, ...) qui stockent

    • une base des entêtes des paquets disponibles dans le dépôt ;
    • des multitudes de paquets, organisés par système, architecture, version,...

    Ces dépôts sont répliqués sur des serveurs miroirs. Il existe aussi des dépôts personnels qui complètent les dépôts officiels (mais peuvent poser des problèmes de sécurité et de cohérence).

  • Au niveau de l'ordinateur local, cela nécessite :

    • une liste de dépôts ;
    • des clés pour vérifier les signatures des dépôts et paquets ;
    • une base locale d'entêtes de paquets disponibles dans les dépôts ;
    • une base locale des paquets installés ;
    • les fichiers effectivement installés dans le système de fichiers.

    La gestion est faite par un gestionnaire de paquets, qui se présente souvent comme une collection de commandes spécialisées.

Le gestionnaire de paquets sait comment

  • mettre à jour sa base locale d'entêtes ;
  • installer, mettre à jour ou supprimer un paquet ;
  • gérer les dépendances ;
  • configurer un paquet ;
  • mettre à jour tous les paquets installés ;
  • etc.

Il est également possible de créer des paquets, ou d'extraire des informations d'un paquet.

Il reste toujours possible d'installer manuellement des programmes à partir des sources ; mais ces programmes n'étant pas gérés par le gestionnaires de paquet, celui-ci ne pourra pas les mettre à jour ou les désinstaller.

Enfin, plusieurs systèmes de paquets peuvent cohabiter, ou s'imbriquer.

15.2. Système de paquets Debian

Debian est une distribution GNU/Linux créée par Ian Murdock en 1993. De nombreuses autres distributions son basée sur Debian et son système de paquets (Ubuntu, Linux Mint, Pure OS, Raspbian, Nakedeb, Kali, Tails, ...).

Il y a 2 sortes de paquets :

  • les paquets binaires .deb, contenant les exécutables, les fichiers de configuration, la documentation... (man deb).

  • les paquets sources, répartis sur 3 fichiers : (man dpkg-source)

    • un fichier .dsc qui décrit le paquet,
    • un fichier .orig.tar.gz contenant les sources originels non modifiés ;
    • un fichier .diff.gz contenant les modifications spécifiques à Debian par rapport aux sources d'origine.

Exemple avec les paquets pour bash : http://ftp.fr.debian.org/debian/pool/main/b/bash/

Documentation :

Recherche de paquets :

15.2.1. Structure des fichiers .deb

Un paquet binaire .deb est une archive ar.

(différence entre ar et tar : ar enregistre une liste de fichiers "à plat", c-à-d pas la structure de répertoires, contrairement à tar).

Exemple :

$ wget http://ftp.fr.debian.org/debian/pool/main/b/bash/bash_5.0-4_amd64.deb
$ ar t bash_5.0-4_amd64.deb 
debian-binary
control.tar.xz
data.tar.xz

$ ar x bash_5.0-4_amd64.deb 
$ file *
bash_5.0-4_amd64.deb: Debian binary package (format 2.0)
control.tar.xz:       XZ compressed data
data.tar.xz:          XZ compressed data
debian-binary:        ASCII text

Le fichier debian-binary est la version du format :

$ cat debian-binary
2.0

L'archive control.tar.xz contient les fichiers de contrôle du paquet :

  • l'entête du paquet (fichier control),
  • des scripts (ici postint, prerm, postrm) ou binaires (ici preinst),
  • les sommes de contrôle MD5 des fichiers (man md5sum).
$ tar tvfJ control.tar.xz 
drwxr-xr-x root/root         0 2019-04-18 06:12 ./
-rw-r--r-- root/root        77 2019-04-18 06:12 ./conffiles
-rw-r--r-- root/root      1006 2019-04-18 06:12 ./control
-rw-r--r-- root/root      4358 2019-04-18 06:12 ./md5sums
-rwxr-xr-x root/root       603 2019-04-18 06:12 ./postinst
-rwxr-xr-x root/root       500 2019-04-18 06:12 ./postrm
-rwxr-xr-x root/root     14536 2019-04-18 06:12 ./preinst
-rwxr-xr-x root/root       289 2019-04-18 06:12 ./prerm

L'archive data.tar.xz contient tous les fichiers à installer :

$ tar tvfJ data.tar.xz | wc -l
160
$ tar tvfJ data.tar.xz | head -5
drwxr-xr-x root/root         0 2019-04-18 06:12 ./
drwxr-xr-x root/root         0 2019-04-18 06:12 ./bin/
-rwxr-xr-x root/root   1168776 2019-04-18 06:12 ./bin/bash
drwxr-xr-x root/root         0 2019-04-18 06:12 ./etc/
-rw-r--r-- root/root      1994 2019-04-18 06:12 ./etc/bash.bashrc

Voici le fichier control :

$ cat control
Package: bash
Version: 5.0-4
Architecture: amd64
Essential: yes
Maintainer: Matthias Klose <doko@debian.org>
Installed-Size: 6439
Pre-Depends: libc6 (>= 2.15), libtinfo6 (>= 6)
Depends: base-files (>= 2.1.12), debianutils (>= 2.15)
Recommends: bash-completion (>= 20060301-0)
Suggests: bash-doc
Conflicts: bash-completion (<< 20060301-0)
Replaces: bash-completion (<< 20060301-0), bash-doc (<= 2.05-1)
Section: shells
Priority: required
Multi-Arch: foreign
Homepage: http://tiswww.case.edu/php/chet/bash/bashtop.html
Description: GNU Bourne Again SHell
 ...

Les dépendances, conflits, etc sont donnés avec des numéros de version.

Le champ Priority est une aide pour les outils de gestion de package ; les valeurs possibles sont :

Essential, Required, Important, Standard, Optional, Extra

Après installation :

  • les fichiers control sont concaténés dans /var/lib/dpkg/status :

    $ grep "Package:" /var/lib/dpkg/status | wc -l
    2740
    $ grep -A 20 "^Package: bash$" /var/lib/dpkg/status
    Package: bash
    Essential: yes
    Status: install ok installed        # rajouté
    Priority: required
    Section: shells
    ...
    
  • les autres fichiers de contrôle sont recopiés dans /var/lib/dpkg/info/ :

    $ ls /var/lib/dpkg/info/ | wc -l
    14163
    $ ls -1 /var/lib/dpkg/info/bash.*
    /var/lib/dpkg/info/bash.conffiles
    /var/lib/dpkg/info/bash.list        # généré
    /var/lib/dpkg/info/bash.md5sums
    /var/lib/dpkg/info/bash.postinst*
    /var/lib/dpkg/info/bash.postrm*
    /var/lib/dpkg/info/bash.preinst*
    /var/lib/dpkg/info/bash.prerm*
    

    Le fichier .list est la liste des fichiers installés (à partir de data.tar.xz).

15.2.2. Gestion des paquets

Il existe de nombreux outils de gestion, réunis en familles :

Famille dpkg
dpkg                     dpkg-genchanges          dpkg-reconfigure
dpkg-architecture        dpkg-gencontrol          dpkg-scanpackages
dpkg-buildflags          dpkg-gensymbols          dpkg-scansources
dpkg-buildpackage        dpkg-maintscript-helper  dpkg-shlibdeps
dpkg-checkbuilddeps      dpkg-mergechangelogs     dpkg-source
dpkg-deb                 dpkg-name                dpkg-split
dpkg-distaddfile         dpkg-parsechangelog      dpkg-statoverride
dpkg-divert              dpkg-preconfigure        dpkg-trigger
dpkg-genbuildinfo        dpkg-query               dpkg-vendor

La commande dpkg permet de manipuler un paquet, à partir du fichier .deb ou du nom du paquet ; c'est aussi un front-end qui peut appeler certaines des commandes ci-dessus.

Parmi les nombreuses possibilités on peut citer :

dpkg --help                     Affiche l'aide
dpkg -i fichier.deb             installe le paquet fichier.deb
dpkg -p nom_paquet              affiche l'entête du paquet
dpkg -r nom_paquet              supprime le paquet
dpkg -P nom_paquet              purge : supprime le paquet et les fichiers
                                de configuration éventuels

dpkg --configure nom_paquet     configure le paquet (ex : un serveur de base
                                de données demandant le mot de passe admin)
dpkg-reconfigure nom_paquet     re-configure le paquet

dpkg -C                         teste l'intégrité des paquets installés

dpkg -l                         affiche tous les paquets et leur état
dpkg -l "motif_paquet"          cherche les paquets correspondant au motif
                                parmi ceux connus localement, affiche l'état

dpkg -L nom_paquet              affiche la liste des fichiers installés
                                (mais pas les fichiers créés par les scripts
                                 d'installation, cf exemple suivant).
dpkg -S "motif_fichier"         cherche les paquets installés contenant les
                                fichiers du motif.

Exemple :

$ type vim vimtutor             # Où sont ces commandes ?
vim est /usr/bin/vim
vimtutor est /usr/bin/vimtutor

$ dpkg -S "/usr/bin/vim*"       # Dans quels paquets installés ?
vim-gtk: /usr/bin/vim.gtk
vim: /usr/bin/vim.basic
vim-tiny: /usr/bin/vim.tiny
vim-runtime: /usr/bin/vimtutor

$ dpkg -l vim                   # cherche vim et affiche son état

Souhait=inconnU/Installé/suppRimé/Purgé/H=à garder
État=Non/Installé/fichier-Config/dépaqUeté/échec-conFig/...
    Nom   Version          Architecture   Description
+++-=====-================-==============-=================
ii  vim   2:7.4.1689-3ub   amd64          Vi IMproved

Les deux premières lettres sont Souhait et État :

ii = Installé, Installé
un = inconnU, Non installé
...
$ dpkg -L vim                   # Il y a quoi dans le paquet vim ?
/.
/usr
/usr/share
/usr/share/bug
/usr/share/bug/vim
/usr/share/bug/vim/script
/usr/share/bug/vim/presubj
/usr/share/doc
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/vim
/usr/bin
/usr/bin/vim.basic              # l'éxécutable
/usr/share/doc/vim

On voit qu'il ne contient pas vi (ni vim), pourtant

$ vi --version | head -1
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Oct 13 2020 16:04:38)

En fait, vi est un lien qui est créé lors de l'installation de vim :

$ grep -B 2 -A 3 " vi " /var/lib/dpkg/info/vim.postinst 
  # Since other packages provide these commands, we'll setup alternatives for
  # their manpages, too.
  for i in vi view ex editor ; do
    update-alternatives \
      --install /usr/bin/$i $i /usr/bin/vim.$variant $1 \
      --slave $mandir/fr/man1/$i.1.gz $i.fr.1.gz $mandir/fr/man1/vim.1.gz \
update-alternatives

La commande update-alternatives du projet Debian permet de gérer un système de liens vers les commandes, lorsque plusieurs paquets installés la proposent, avec un système de priorités.

$ ls -gG /usr/bin/vi
lrwxrwxrwx 1 20 nov.  14  2013 /usr/bin/vi -> /etc/alternatives/vi*
$ ls -gG /etc/alternatives/vi
lrwxrwxrwx 1 16 août  18 13:40 /etc/alternatives/vi -> /usr/bin/vim.basic*

On peut aussi gérer les alternatives à la main, par exemple lorsqu'il y a plusieurs versions installées :

$ update-alternatives --list python3
/usr/bin/python3.5
/usr/bin/python3.6

$ update-alternatives --config python3

Il existe 2 choix pour l'alternative python3 (qui fournit /usr/bin/python3).

  Sélection   Chemin              Priorité  État
------------------------------------------------------------
  0            /usr/bin/python3.6   2         mode automatique
* 1            /usr/bin/python3.5   1         mode manuel
  2            /usr/bin/python3.6   2         mode manuel

Appuyez sur <Entrée> pour conserver la valeur par défaut[*] ou choisissez le 
numéro sélectionné :2
update-alternatives: erreur: erreur pendant la création du lien symbolique 
« /etc/alternatives/python3.dpkg-tmp »: Permission non accordée

(échec car il fallait être root).

Famille apt
apt(8)          apt-cdrom     aptdcon     apt-get      apt-add-repository
apt-sortpkgs    apt-config    apt-key     apturl       apt-extracttemplates
apt-cache       aptd          apt-mark    apturl-gtk   apt-ftparchive

Les commandes de la famille apt constituent une interface de plus haut niveau pour la gestion des packages ; en particulier, elles permettent le téléchargement des paquets depuis les dépôts. La commande apt est aussi un front-end pour certaines des commandes ci-dessus.

Parmi les nombreuses possibilités on peut citer :

apt --help                      affiche les options principales
apt update                      télécharge les entêtes depuis les dépôts
apt upgrade                     télécharge et met à jour tous les paquets

apt install nom_paquet          télécharge et installe le paquet
apt remove|purge nom_paquet     supprime le paquet (purge : configuration)

apt autoremove                  supprime les paquets devenus inutiles
apt clean                       vide le cache local des fichiers .deb
                                /var/cache/apt/archives/

apt show nom_paquet             télécharge et affiche l'entête du paquet
apt search "motif"              cherche dans les dépôts les paquets dont
                                la description contient le motif
Exemple :

Recherche d'un paquet inconnu :

$ dpkg -p qtcreator
dpkg-query: le paquet « qtcreator » n'est pas disponible

On n'obtient rien (puisqu'il n'est pas installé). En revanche avec apt :

$ apt search qtcreator
En train de trier... Fait
Recherche en texte intégral... Fait
qtcreator/stable 4.8.2-1 amd64
  integrated development environment (IDE) for Qt
qtcreator-data/stable 4.8.2-1 all
  application data for Qt Creator IDE
qtcreator-doc/stable 4.8.2-1 all
  documentation pour l'EDI Qt Creator.

$ apt show qtcreator
Package: qtcreator
Version: 4.8.2-1
Priority: optional
Section: devel
...

$ sudo apt install qtcreator    # télécharge et installe le paquet et ses
                                # dépendances.
Autres commandes
dselect :

front-end interactif de dpkg dans le terminal ; historique, peu intuitif...

aptitude :

interface en mode texte avec des menus à la souris ; les paquets sont rangés par catégories.

synaptic :

interface graphique, très complet.

software-center :

sur Ubuntu ; très simple, mais installe 1 logiciel à la fois. Gère plusieurs formats de package : deb, snap, charms.

15.2.3. Configuration

Voir :

Choix des dépôts

Les dépôts (repositories) sont listés dans le fichier /etc/apt/sources.list et les fichiers /etc/apt/source.liste.d/*.list sous la forme :

deb     url distribution composant1 composant2 ...
deb-src url distribution composant1 composant2 ...
  • deb ou deb-src : paquets binaires ou paquets source.

  • url : URL du dépôt.

  • distribution :

    • Debian : bullseye, buster, stretch, jessie, wheezy,...
    • Ubuntu : focal, bionic, xenial, trusty, ...

    Il peut y avoir un suffixe : -updates, -security, -backports

  • composants : indique le type de licences.

    • Debian :
      • main : logiciels libres
      • contrib : logiciels utilisant des composants non libres
      • non-free : logiciels non libres
    • Ubuntu :
      • main : logiciels libres, maintenus par Ubuntu
      • restricted : non libres, idem
      • universe : logiciels libres maintenus par la "communauté"
      • multiverse : non libres, idem
      • partner : logiciels non libres de sociétés partenaires

Après avoir modifié ces fichiers, il faut faire :

apt update

On peut voir aussi voir la liste des dépôts en faisant :

apt policy

Voir encore : software-properties-gtk

Choix des versions

Lorsqu'un paquet est disponible dans plusieurs dépôts listés, c'est le premier dans sources.list qui gagne.

Si un paquet d'une version plus récente que celle de votre distribution a été recompilé pour votre distribution, c'est un backport. Pour l'installer il faut donc préciser :

apt install <nom_paquet>/<votre_distribution>-backports

ou de manière générique :

apt install <nom_paquet>/$(lsb_release -sc)-backports

On peut préciser de manière permanente la version que l'on veut pour un paquet ou un ensemble de paquets dans /etc/apt/preferences ou /etc/apt/preferences.d avec un score de priorité, voir : man 5 apt_preferences

On peut aussi interdire la mise à jour d'un paquet :

apt-mark hold <nom_paquet>

re-autoriser :

apt-mark unhold <nom_paquet>

Liste les paquets :

apt-mark showhold

On peut marquer un paquet installé manuellement comme paquet installé automatiquement, en faisant :

apt-mark auto <nom_paquet>

de la sorte, lorsque plus aucun paquet ne dépendra de lui, il sera supprimé par : apt autoremove

On peut configurer finement le comportement de apt : man apt.conf ; fichiers de configuration dans /etc/apt/apt.conf.d/.

Personnal Package Archive

Les PPA sont de petits dépôts qui permettent de rajouter des paquets non présents sur les dépots officiels, ou avec des versions plus récentes.

Problèmes : sécurité, conflits, paquets mal configurés...

Rajouter un PPA :

add-apt-repository ppa:<nom_depot_ppa>
apt update
apt install <nom_paquet>

Supprimer un PPA :

add-apt-repository --remove ppa:<nom_depot_ppa>

(ça ne supprimera pas les paquets installés depuis le PPA).

add-apt-repository s'occupe aussi de télécharger les clés GPG et les stocker dans /etc/apt/trusted.gpg.d/. Pour une installation manuelle des clés, voir man apt-key.

Voir : exercice 1 du TP 15 ; comment installer Firefox sans snap.

15.3. Autres systèmes de paquets

  • Redhat : RHEL, Fedora, CentOS, SUSE, Mandriva, Mageia, ...

    Paquets .rpm ; gestion des dépendances
    Outils : dnf, rpm, yum, ...
    voir https://en.wikipedia.org/wiki/RPM_Package_Manager

  • ArchLinux :

    Tarball .tar.gz, .tar.bz2, .tar.xz ; gestion des dépendances
    Outils : pacman
    voir https://en.wikipedia.org/wiki/Arch_Linux#Package_management

  • Slackware :

    Tarball .tar.gz, .tar.bz2, .tar.xz ; sans dépendances
    Outils : pkgtool

  • Python :

    Le langage python vient avec des gestionnaires de paquets, qui peuvent faire une installation : dans le système, au niveau de l'utilisateur, ou dans un "environnement virtuel".
    Outils et formats : pip, wheel, virtualenv.
    voir lien1, lien2