Le manuel de programmation de dpkg - chapitre 6
Script de maintenance de paquet et procédure d'installation


6.1 Introduction aux scripts de gestion de paquet

Il est possible de fournir des scripts avec le paquet que dpkg exécutera pour toi quand ton paquet est installé, mis à jour ou enlevé.

Ces scripts s'appellent preinst, postinst, prerm et postrm dans la zone de contrôle du paquet. Ce sont des fichiers exécutables propres; si ce sont des scripts (ce qui est recommandé), ils doivent commencer par la convention habituelle #!. Ils doivent être lisible et exécutable par n'importe qui, et non modifiable.

dpkg teste le statut de sortie de ces scripts. Il est important qu'ils se terminent avec un statut différent de zéro, s'il y a une erreur, afin que dpkg puisse arrêter son traitement. Pour les scripts shell, ceci signifie que tu as presque toujours besoin d'utiliser set -e (ce qui est généralement vrai quand on écrit des scripts shell, en fait). Il est aussi important, bien sûr, qu'ils ne se terminent pas avec un statut différent de zéro si tout se passe bien.

Il est nécessaire pour les procédures de recouvrement d'erreurs que les scripts soient idempotents; c'est à dire, appeler le même script plusieurs fois dans la même situation ne doit pas provoquer de problèmes. Si le premier appel échoue, ou s'arrête au milieu du chemin pour une raison ou une autre, le second appel devrait faire les choses qui n'ont pas été faites la première fois, s'il y en a, et sortir avec succès.

Quand un paquet est mis à jour, une combinaison des scripts du vieux et du nouveau paquet est appelée dans presque toutes les autres étapes de la procédure de mise à jour. Si tes scripts sont devenus plus compliqués, tu dois faire attention à cela, et peut être vérifier les arguments de tes scripts.

Techniquement parlant, le script preinst est appelé avant d'installer (une version particulière de) un paquet, et postinst après; le script prerm avant d'effacer (une version de) un paquet et postrm après.

Les programmes appelés à partir des scripts ne devraient pas normalement avoir de chemin préfixé. Avant que l'installation démarre, dpkg vérifie pour voir si les programmes ldconfig, start-stop-daemon, install-info et update-rc.d peuvent être trouvés via la variable d'environnement PATH. Ces programmes, et n'importe quel autre programme qu'on s'attend à trouver dans le PATH, devraient donc être appelés sans nom de chemins absolu. Les scripts de maintenance ne devraient pas non plus réinitialiser le PATH, bien qu'ils peuvent choisir de le modifier en ajoutant devant ou à la fin un répertoire spécifique à un paquet. Ces considérations s'appliquent vraiment à tous les scripts shell.


6.2 Résumé des façons dont les scripts de maintenance sont appelés


6.3 Détails des phases d'installation et de mise à jour

La procédure sur installation/mis à jour/écrasement/effacement (c'est à dire en exécutant dpkg --unpack, ou l'étape unpack de dpkg -- install) est la suivante. Dans chaque cas, si un erreur se produit, les actions sont généralement exécuter en arrière - ce qui signifie que les scripts de maintenance sont exécutés avec des arguments différents dans l'ordre inverse. Ce sont les appels 'recouvrement d'erreur' listés ci- dessous.
    1. Si une version du paquet est déjà installée, appel
      		vieux-prerm upgrade nouvelle-version
      	   

    2. Si cela donne une erreur (c'est à dire un status de fin différent de zéro), dpkg essayera plutôt:
      		nouveau-prerm failed-upgrade vieille-version
      	   
      Recouvrement d'erreurs, dans les deux cas ci-dessus:
      	vieux-postinst abort-upgrade nouvelle-version
      	   

  1. Si un paquet conflictuel est enlevé en même temps:
    1. Si n'importe quels paquets dépend de ce paquet conflictuel et --auto-deconfigure est spécifié, appel pour chaque paquet:
      	prerm-déconfiguré deconfigure in-favour
      	paquet-installé version
      	removing paquet-conflictuel version
              
      Recouvrement d'erreurs:
      	postrm-déconfiguré abort-deconfigure in-favour
      	paquet-échoué-installé version
      	removing paquet-conflictuel version
              
      Les paquets déconfigurés sont indiqués comme nécessitant une configuration, afin que si --install est utilisé, ils seront configurés de nouveau, si possible.

    2. Pour préparer, l'effacement du paquet conflictuel, appel:
      	prerm-conflictuel remove in-favour
      	 paquet nouvelle-version
      	
      Recouvrement d'erreurs:
      	postinst-conflictuel abort-remove in-favour
      	 paquet nouvelle-version
              

    1. Si le paquet est mis à jour, appel:
      	nouvelle-preinst upgrade vieille-version
              

    2. Autrement si le paquet a des fichiers de configuration d'une version précédemment installée (c'est à dire, il ne reste plus que les fichiers de configuration):
      	nouveau-preinst install vieille-version
      	

    3. Autrement (c'est à dire, le paquet a été complètement effacé):
      	nouveau-preinst install
      	
      Les versions de recouvrement d'erreurs, respectivement:
      	nouveau-postrm abort-upgrade vieille-version
      	nouveau-postrm abort-install vieille-version
      	nouveau-postrm abort-install
      	

  2. Les nouveaux fichiers du paquet sont installé, écrasant ceux qui peuvent déjà être sur le système, par exemple, les fichiers d'une vieille version du même paquet ou d'un autre paquet (les sauvegardes des vieux fichiers sont là, et si quelque chose se passe mal, dpkg essayera de les remettre à leur place dans la partie de recouvrement d'erreurs).

    C'est une erreur pour un paquet de contenir des fichiers qui sont sur le système dans d'autre paquet, à moins que Replaces soit utilisé (voir Replaces - écraser les fichiers et remplacer les paquets, section 8.5). Pour l'instant l'option --force-overwriting est disponible, le dégradant en un avertissement, mais ce ne sera pas toujours le cas.

    C'est une erreur beaucoup plus grave pour un paquet de contenir un fichier ou autre chose qu'un répertoire où un autre paquet a un répertoire (de nouveau, à moins que Replaces ne soit utilisé). Cette erreur peut être éviter si c'est l'effet recherché, en utilisant --force-overwrite-dir, mais ce n'est pas conseillé.

    Les paquets qui s'écrasent mutuellement des fichiers produisent des comportements qui bien que déterministe est difficile à comprendre pour un administrateur système. Cela nous amène à des programmes "manquants" si par exemple, un paquet est installé qui écrase un fichier d'un autre paquet, et puis est effacé de nouveau[20].

    Un répertoire ne sera jamais remplacé par un lien symbolique vers un répertoire et vice versa; à la place, l'état existant (lien symbolique ou non) est conservé et dpkg suivra les liens s'il y en a.

    1. Si le paquet est mis à jour, appel:
      	vieux-postrm upgrade nouvelle-version
      	

    2. Si cela échoue, dpkg essayera:
      	nouveau-postrm failed-upgrade vieille-version
      	
      Les recouvrements d'erreur, dans les deux cas:
      	vieux-preinst abort-upgrade nouvelle-version
      	
      C'est le point de non retour - si dpkg atteint ce point, il ne reviendra pas en arrière de ce point, si une erreur survient. Ceci laissera le paquet dans un mauvais état, qui nécessitera une réinstallation réussie pour remettre en état, mais c'est quand dpkg commence à faire des choses irréversibles.

  3. Tous les fichiers qui étaient dans la version précédent du paquet, mais pas dans le nouveau, sont effacés.

  4. La nouvelle liste de fichiers remplace la précédente.

  5. Les nouveaux scripts de maintenance remplacent les anciens.

  6. Les paquets dont les fichiers ont été écrasés pendant l'installation, et qui ne sont pas nécessaires pour les dépendances, sont considérés comme effacés. Pour ce paquets:
    1. dpkg appelle:
                    postrm-disparu disappear ecraseur version-ecraseur
      	      

    2. Les scripts de maintenance du paquet son effacés.

    3. Il est inscrit dans la base de données des statuts comme étant dans un état incorrect, non installé (ses fichiers de config sont ignorés plutôt que d'être enlevé par dpkg). Remarque que ce paquet disparu n'a pas appelé son script prerm, car dpkg ne sait pas à l'avance que le paquet est écrasé.

  7. Les fichiers du paquet qui sont aussi listés dans les listes de fichiers des autres paquets sont enlevés de ces listes (ce qui lobotomisera la liste de fichiers du paquet conflictuel, s'il y en a un).

  8. Les fichiers de sauvegarde faits pendant l'installation, ci- dessus, sont effacés.

  9. Le nouveau statuts du paquet est correct et enregistré comme installé. C'est un autre point de non retour - si l'effacement d'un paquet conflictuel échoue, nous ne pouvons pas défaire le reste de l'installation; le paquet conflictuel est dans un état à moitié enlevé.

  10. S'il y avait un paquet conflictuel, nous avons utilisé les actions d'effacement (décrites ci-dessus), en commençant par l'effacement des fichiers conflictuels du paquet (les fichiers qui sont aussi dans le paquet installé ont déjà été effacés de la liste des fichiers conflictuels du paquet, et ne doivent pas être enlevés maintenant).


6.4 Détails de la configuration

Quand nous configurons un paquet (ceci arrive avec dpkg -- install, ou avec --configure), nous mettons à jour d'abord les fichiers de configuration (conffiles) et ensuite appelons:
posinst configure version-configurée-la-plus-récente
Aucune actions n'est tenté pour défaire les erreurs pendant la configuration.

S'il n'y a pas de version configurée plus récente, dpkg passera un argument nul; les vieilles versions de dpkg peuvent passer <unknow> (avec les signes supérieur et inférieur) dans ce cas. Même les plus vieux ne passent pas de second argument du tout, dans n'importe quelles circonstances.


6.5 Détails de l'effacement et/ou de la configuration de purge

  1. prerm remove

  2. Les fichiers du paquet sont effacés (sauf conffiles).

  3. postrm remove

  4. Tous les scripts de maintenance sont effacés sauf postrm. Si nous n'effaçons pas le paquet, la procédure s'arrête là. Remarque que les paquets qui n'ont pas de postrm et conffiles sont automatiquement purgés pendant l'effacement, comme il n'y pas de différence, sauf pour le statut de dpkg.

  5. Le conffiles et les fichiers de sauvegarde (-files, #*#files, %-files, .dpkg-{old, new, tmp}, etc.) sont effacés.

  6. postrm purge

  7. La liste des fichiers du paquet est effacée.

Aucune tentative n'est faite pour défaire les erreurs durant l'effacement.


Le manuel de programmation de dpkg - Copyright ©1996 Ian Jackson Copyright ©1997 David Curé et Christian Jacolot pour la version française.
Table des matières; résumé; suivant; précédent.
15 octobre 1998
D. Cure cure@cnam.fr
C. Jacolot jacolot@ubolib.univ-brest.fr