[ précédent ] [ Table des matières ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ suivant ]
Il est possible de fournir des scripts qui seront exécutés par le système de gestion des paquets lors d'une installation, d'une mise à jour ou d'une suppression du paquet.
Ces scripts sont les fichiers preinst
, postinst
,
prerm
et postrm
contenus dans le répertoire de
contrôle du paquet. Ils doivent être des fichiers exécutables corrects ;
quand ce sont des scripts (ce qui est recommandé), ils doivent commencer par la
convention habituelle : #!. Ils seront lisibles et
exécutables par tout le monde mais ils ne doivent pas être modifiables par tout
le monde.
Le système de gestion de paquets teste le code de sortie de ces scripts. Il est important que ce code soit différent de zéro quand il y a une erreur ; le système de gestion de paquets peut alors s'interrompre. Pour les scripts shell, cela signifie que l'on doit presque toujours utiliser set -e (et c'est généralement vrai pour tout script shell). Bien sûr, il est aussi important que ce code ne soit pas différent de zéro quand tout s'est bien passé.
De plus, les paquets interagissant avec les utilisateurs utilisant
debconf dans le script postinst
doivent installer un
script config
dans la zone de contrôle, voir Poser des questions via les
scripts du responsable, Section 3.9.1 pour plus de détails.
Quand un paquet est mis à jour, une combinaison des scripts de l'ancien et du nouveau paquet est appelée durant la procédure de mise à jour. Il faut faire attention quand les scripts se compliquent et il faut vérifier leurs arguments.
D'une manière générale, le script preinst
est appelé avant
d'installer (une version particulière d') un paquet, et le script
postinst
après ; le script prerm
avant d'effacer
(une version d') un paquet et postrm
après.
Normalement on ne doit pas préfixer le chemin des programmes appelés par les
scripts. Avant le début de l'installation, le système de gestion de paquet
vérifie que 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, seront donc appelés sans nom de
chemin absolu. Les scripts du responsable ne doivent pas non plus
réinitialiser la variable PATH, bien qu'ils puissent choisir de la
modifier en ajoutant au début ou à la fin un répertoire spécifique à un paquet.
Ces considérations s'appliquent vraiment à tous les scripts shell.
Il est nécessaire pour les procédures de gestion des erreurs que les scripts soient idempotents. Cela signifie qu'un script, appelé à nouveau après une exécution réussie, n'explose pas et ne fait pas de dégâts ; il s'assure simplement que chaque chose est à sa place. Si le premier appel échoue, ou s'arrête au milieu du chemin pour une raison ou une autre, le second appel fera, s'il y en a, les choses qui n'ont pas été faites la première fois et se terminera normalement si tout est correct [40].
Les scripts du responsable sont assurés de s'exécuter avec un terminal de contrôle et de pouvoir interagir avec l'utilisateur. Comme ces scripts peuvent rediriger leur sortie standard dans un tube à des fins d'enregistrement, les scripts Perl utiliseront un mode de sortie sans tampon mémoire en déclarant $|=1 de manière à ce que la sortie soit affichée immédiatement plutôt que d'être mise dans un tampon mémoire.
Chaque script retournera un code de sortie égal à zéro en cas de succès et un code différent de zéro en cas d'échec. Chaque script doit retourner un code de sortie égal à zéro en cas de succès et un code différent de zéro en cas d'échec car le système de gestion des paquets récupère le code de sortie de ces scripts et détermine l'action suivante en fonction de cette valeur.
preinst-du-nouveau-paquet install
preinst-du-nouveau-paquet install vieille-version
preinst-du-nouveau-paquet upgrade vieille-version
preinst-de-l'ancien-paquet abort-upgrade nouvelle-version
postinst configure version-la-plus-récemment-configurée
postinst-de-l'ancien-paquet abort-upgrade nouvelle-version
postinst-du-paquet-conflictuel abort-remove in-favour paquet nouvelle-version
postinst abort-remove
postinst-du-paquet-déconfiguré abort-deconfigure in-favour paquet-dont-installation-a-échoué version removing paquet-conflictuel version
prerm remove
prerm-de-l'ancien-paquet upgrade nouvelle-version
prerm-du-nouveau-paquet failed-upgrade vieille-version
prerm-du-paquet-conflictuel remove in-favour paquet nouvelle-version
prerm-du-paquet-déconfiguré deconfigure in-favour paquet-installé version removing paquet-conflictuel version
postrm remove
postrm purge
postrm-de-l'ancien-paquet upgrade nouvelle-version
postrm-du-nouveau-paquet failed-upgrade vieille-version
postrm-du-nouveau-paquet abort-install
postrm-du-nouveau-paquet abort-install vieille-version
postrm-du-nouveau-paquet abort-upgrade vieille-version
postrm-du-paquet-disparu disappear remplaçant version-du-remplaçant
La procédure lors d'une installation, d'une mise à jour, d'un remplacement ou d'une disparition (c'est-à-dire quand on exécute dpkg --unpack, ou bien l'étape unpack de dpkg --install) est la suivante. Dans chaque cas, si une erreur majeure se produit (à moins d'être listée ci-dessous), les actions sont généralement « rembobinées » -- ce qui signifie que les scripts du responsable sont exécutés dans l'ordre inverse avec des arguments différents. Ce sont les appels « correction d'erreur » listés ci-dessous.
Si une version du paquet est déjà installée, appel de
prerm-de-l'ancien-paquet upgrade nouvelle-version
Quand le script se termine avec un code de sortie différent de zéro,
dpkg
essaye :
prerm-du-nouveau-paquet failed-upgrade vieille-version
Si cela réussit, la mise à jour continue. Sinon, correction d'erreur :
postinst-de l'ancien-paquet abort-upgrade nouvelle-version
Si cela réussit, alors l'ancienne version est dans l'état « Installed ». Sinon, l'ancienne version est dans l'état « Failed-Config ».
Si un paquet conflictuel est enlevé en même temps :
Quand un paquet dépend de ce paquet conflictuel et si l'option --auto-deconfigure est spécifiée, appel pour chaque paquet :
prerm-du-paquet-déconfiguré deconfigure in-favour paquet-à-installer version removing paquet-conflictuel version
Correction d'erreurs :
postinst-du-paquet-déconfiguré abort-deconfigure in-favour paquet-dont-l'installation-a-échoué version removing paquet-conflictuel version
Les paquets déconfigurés sont indiqués comme nécessitant une configuration, afin que, si l'option --install est utilisée, ils soient, si possible, de nouveau configurés.
Pour préparer l'effacement du paquet conflictuel, appel de :
prerm-du-paquet-conflictuel remove in-favour paquet nouvelle-version
Correction d'erreurs :
postinst-du-paquet-conflictuel abort-remove in-favour paquet nouvelle-version
Si le paquet est mis à jour, appel de :
preinst-du-nouveau-paquet upgrade vieille-version
Si cela échoue, on appelle :
postrm-du-nouveau-paquet abort-upgrade vieille-version
Si cela fonctionne, alors
postinst-de-l'ancien-paquet abort-upgrade nouvelle-version
est appelé. Si cela fonctionne, alors l'ancienne version est dans un état « Installed », sinon elle est laissée dans un état « Unpacked ».
Si cela échoue, alors l'ancienne version est laissée dans un état « Half-Installed ».
Autrement, si le paquet a des fichiers de configuration d'une version précédemment installée (c'est-à-dire, s'il ne reste plus du paquet que les fichiers de configuration) :
preinst-du-nouveau-paquet install vieille-version
Correction d'erreur :
postrm-du-nouveau-paquet abort-install vieille-version
Si cela échoue, le paquet est laissé dans un état « Half-Installed » qui impose une réinstallation. Si cela réussit, le paquet est laissé dans un état « Config Files ».
Autrement (c'est-à-dire, le paquet a été complètement effacé) :
preinst-du-nouveau-paquet install
Correction d'erreurs
postrm-du-nouveau-paquet abort-install
Si la correction d'erreur échoue, le paquet est dans un état « Half Installed » et nécessite une réinstallation. Si elle réussit, le paquet n'est plus installé.
Les fichiers du nouveau paquet sont dépaquetés, remplaçant ceux qui peuvent déjà être sur le système, par exemple, les fichiers appartenant à la vieille version du même paquet ou ceux d'un autre paquet. Les sauvegardes des vieux fichiers sont laissées, et si quelque chose se passe mal, le système de gestion des paquets, dans sa partie « correction d'erreurs » essayera de les remettre en place.
C'est une erreur pour un paquet de contenir des fichiers qui sont sur le système dans un autre paquet, à moins que Replaces ne soit utilisé (voir le champ Replaces -- regénérer les fichiers et remplacer les paquets, Section 7.5).
C'est une erreur plus grave pour un paquet de contenir un simple fichier ou autre chose qu'un répertoire quand un autre paquet veut un répertoire (à moins que Replaces ne soit utilisé). Cette erreur peut être évitée si c'est l'effet recherché, en utilisant --force-overwrite-dir, mais ce n'est pas à conseiller.
Les paquets qui remplacent mutuellement leurs fichiers ont une démarche qui, bien que déterministe, est difficile à comprendre pour un administrateur système. Cela peut aisément conduire à des programmes annoncés comme « absent » quand, par exemple, un paquet remplaçant tel fichier d'un autre paquet est installé puis effacé [41].
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.
Si le paquet est mis à jour, appel de :
postrm-de l'ancien-paquet upgrade nouvelle-version
Si cela échoue, dpkg
essaye :
postrm-du-nouveau-paquet failed-upgrade vieille-version
Si cela réussit, l'installation continue. Sinon, correction d'erreur :
preinst-de-l'ancien-paquet abort-upgrade nouvelle-version
Si cela échoue, l'ancienne version est laissée dans un état « Half Installed ». Si cela réussit, dpkg appelle maintenant :
postrm-du-nouveau-paquet abort-upgrade vieille-version
Si cela échoue, l'ancienne version est laissée dans un état « Half Installed ». Si cela échoue, dpkg appelle maintenant :
postinst-de-l'ancien-paquet abort-upgrade nouvelle-version
Si cela échoue, l'ancienne version est dans un état « Unpacked ».
C'est le point de non-retour. Quand dpkg
atteint ce point, il ne
revient pas en arrière si une erreur se produit. Le paquet reste dans un très
mauvais état et demande une réinstallation réussie pour remettre tout en
place ; cela arrive quand dpkg
commence à faire des choses
irréversibles.
Tous les fichiers de la version précédente du paquet qui ne sont pas dans la nouvelle sont effacés.
La nouvelle liste de fichiers remplace la précédente.
Les nouveaux scripts du responsable remplacent les anciens.
Les paquets dont tous les fichiers ont été remplacés pendant l'installation, et qui ne sont pas nécessaires pour les dépendances, sont considérés comme effacés. Pour ces paquets :
dpkg
appelle :
postrm-du-paquet-effacé disappear remplaçant version-du-remplaçant
Les scripts du responsable de paquet sont effacés.
Le paquet est inscrit dans la base de données « status » comme étant
dans un état correct, à savoir non installé (ses conffiles sont
ignorés et non pas supprimés par dpkg
). Il faut remarquer que
dpkg
n'appelle pas le script prerm du paquet effacé, car il ne
sait pas à l'avance que le paquet va disparaître.
Les fichiers du paquet à installer qui sont aussi répertoriés par d'autres paquets sont enlevés des listes de ces paquets, ce qui lobotomisera la liste de fichiers du paquet « conflictuel », s'il y en a un.
Les fichiers de sauvegarde faits pendant la phase précédente d'installation sont effacés.
Le statut du nouveau paquet est correct et enregistré comme « dépaqueté ».
C'est un autre point de non-retour - si l'effacement d'un paquet conflictuel échoue, on ne « rembobine » pas le reste de l'installation ; le paquet conflictuel est laissé dans un état « enlevé à moitié ».
Au cas où existe un paquet conflictuel, on procède aux actions d'effacement (décrites ci-dessus), en commençant par l'effacement des fichiers du paquet conflictuel (les fichiers qui sont aussi dans le paquet installé ont déjà été effacés de la liste des fichiers du paquet conflictuel et ne sont pas enlevés maintenant).
Quand on configure un paquet (avec dpkg --install, ou avec --configure), on met à jour d'abord les conffiles et ensuite on appelle :
postinst configure version-la-plus-récemment-configurée
On n'essaye pas de « rembobiner » après une erreur pendant la configuration. Si la configuration échoue, le paquet est dans un état « Failed Config » et un message d'erreur est généré.
S'il n'existe pas de « version-la-plus-récemment-configurée »,
dpkg
passe un argument nul [42].
prerm remove
Si le script prerm échoue pendant le remplacement à cause d'un conflit
postinst-du-paquet-en-conflit abort-remove \ in-favour paquet nouvelle-version
Ou sinon on appelle :
postinst abort-remove
Si cela échoue, le paquet est dans un état « Failed-Config » ou sinon il reste « Installed ».
Les fichiers du paquet sont effacés (sauf les conffiles).
postrm remove
Si cela échoue, il n'y a pas de correction d'erreur et le paquet est dans un état « Half-Installed ».
Tous les scripts du responsable sont effacés sauf postrm
.
Si on n'efface pas le paquet, la procédure s'arrête là. Il faut remarquer que
les paquets qui n'ont pas de postrm
ni de conffiles
sont automatiquement purgés pendant l'effacement, puisqu'il n'y pas de
différence, sauf pour le fichier status de dpkg
.
Les conffiles et les fichiers de sauvegarde (fichiers ~, fichiers #*#, fichiers %, .dpkg-{old, new, tmp}, etc.) sont effacés.
postrm purge
Si cela échoue, le paquet reste dans un état « Config-Files ».
La liste des fichiers du paquet est effacée.
[ précédent ] [ Table des matières ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ suivant ]
La Charte Debian
version 3.7.2.2