Comment exécuter un script uniquement lors de la première installation d'un package et lors des mises à niveau?

14

J'ai récemment commencé à emballer certains de mes logiciels et à les publier sur Launchpad. L'installation et la suppression fonctionnent correctement, mais la mise à niveau du package d'une version vers la version suivante est problématique.

Le problème est qu'il existe certains scripts qui n'ont besoin d'être exécutés que lors de la première installation du package. Ces scripts remplissent la base de données, créent un utilisateur, etc. Ils sont actuellement appelés dans la configure)section package.postinst . Cependant, cela entraîne leur appel lors d'une mise à niveau ainsi que le montre le diagramme .

Existe-t-il un moyen d'inclure un script de responsable dans un package .deb qui ne s'exécute que lors de la première installation du package et non lors d'une mise à niveau? Ou quelle serait une manière élégante d'inclure des scripts de configuration initiale dans un package .deb?

Jeroen
la source

Réponses:

15

Avec un debian/preinstfichier, vous pouvez effectuer des actions sur l'installation mais pas la mise à niveau.

#!/bin/sh
set -e

case "$1" in
    install)
        # do some magic
        ;;

    upgrade|abort-upgrade)
        ;;

    *)
        echo "postinst called with unknown argument \`$1'" >&2
        exit 0
        ;;
esac

#DEBHELPER#

exit 0

Bien que, comme son nom l'indique, ceci est exécuté avant l'installation de votre package. Donc, vous ne pourrez peut-être pas faire ce dont vous avez besoin ici. La plupart des packages testent simplement à l'étape de configuration de postinstsi l'utilisateur a déjà été créé. Voicicolord

$ cat  /var/lib/dpkg/info/colord.postinst
#!/bin/sh

set -e

case "$1" in
    configure)

# create colord group if it isn't already there
    if ! getent group colord >/dev/null; then
            addgroup --quiet --system colord
    fi

# create the scanner group if it isn't already there
    if ! getent group scanner >/dev/null; then
        addgroup --quiet --system scanner
    fi

# create colord user if it isn't already there
    if ! getent passwd colord >/dev/null; then
            adduser --system --ingroup colord --home /var/lib/colord colord \
        --gecos "colord colour management daemon"
        # Add colord user to scanner group
        adduser --quiet colord scanner
    fi

# ensure /var/lib/colord has appropriate permissions
    chown -R colord:colord /var/lib/colord

    ;;
esac    



exit 0
andrewsomething
la source
28

Consultez ce diagramme du wiki Debian sur la façon dont les scripts du responsable sont appelés: Organigramme du script du responsable Debian

Si vous suivez le côté gauche (le chemin «tout va bien»), vous verrez que le postinstscript est appelé avec la version la plus récemment configurée. Cela vous permet de faire la distinction entre une mise à niveau et une nouvelle installation - dans le cas de la mise à niveau, votre postinst sera appelé comme

postinst configure 1.23-0ubuntu1

1.23-0ubuntu1est la version précédemment installée de votre package, alors que pour une nouvelle installation, elle sera appelée comme

postinst configure

Cela vous permet également de gérer le cas lorsque vous devez effectuer une action lors de la mise à niveau à partir d'une version particulière - vous pouvez archiver la postinstpour cette version.

Cela permet de vérifier facilement si le script est exécuté lors d'une «installation» ou d'une «mise à niveau». Si $ 2 est nul, alors c'est une installation. donc:

if [ -z "$2" ]; then
  do install stuff
else
  do upgrade stuff
fi
RAOF
la source
1
Notez que le paramètre supplémentaire est également transmis dans le cas où vous avez supprimé le package (mais ne l'avez pas purgé) et l'installez à nouveau.
skyking
3

Vous pourrez peut-être utiliser un script debian / preinst en combinaison avec postinst.

Dans le script preinst, recherchez un fichier que votre paquet installe définitivement. S'il est présent, ne faites rien (car votre package a été installé précédemment), sinon, effectuez vos étapes de configuration.

Si vos étapes de configuration nécessitent l'installation de votre package (dans ce cas, ce qui précède ne fonctionnera pas car la pré-exécution s'exécute avant l'installation), votre script de pré-installation peut écrire un fichier, par exemple: / tmp / setupmypkg. Votre script postinst pourrait simplement tester si ce fichier est présent et si c'est le cas, faites deux choses:

  • vos étapes de configuration initiale
  • supprimez le fichier / tmp / setupmypkg
kyleN
la source
1
Oui, cela fonctionnerait et je fais actuellement quelque chose de similaire. Mais ça a toujours l'air un peu hacky ... J'espérais une façon plus native de le faire. Cela ne semble pas être une demande aussi exotique, non?
Jeroen
1

J'ai trouvé que le test de 2 $ dans votre script "postinst configure" ne fonctionne pas correctement si vous avez déjà installé votre package une fois auparavant, puis l'a désinstallé (mais sans purger), puis essayez de réinstaller à nouveau. Dans ce cas, le script postinst obtient toujours un argument de version pour l'étape "postinst configure".

Cependant, si vous avez déjà installé le package, puis supprimez ET purgez-le, puis réinstallez-le à nouveau, le script "postinst configure" n'obtiendra PAS d'argument de version dans $ 2

robvdl
la source
0

Je ne pense pas, mais vous pouvez facilement modifier les scripts preinst / postinst pour vérifier si le package est installé pour la première fois et prendre des mesures standard.

Peut être quelque chose comme ça,

en préinst.

if not is_package_istalled():
    export MY_PACKAGE_FIRST_INSTALL

en postinst,

if MY_PACKAGE_FIRST_INSTALL:
    Do First Install Setup 

Éditer

Hmm, peut-être que vous pouvez simplement vérifier tout cela directement dans postinst parce que je pense que dpkg ne définirait pas le statut du paquet tel qu'installé avant d'exécuter postinst mais je ne suis pas sûr. Donc, ce qui précède pourrait venir,

en postinst,

if not is_package_istalled():
    Do First Install Setup 

Où, is_package_installed peut être votre fonction pour détecter l'état de l'installation. Peut être quelque chose comme «dpkg --status packagename»

OU

Pourquoi ne pas simplement vérifier si les modifications que vous souhaitez apporter sont déjà là et ne procéder que si elles ne le sont pas.

Owais Lone
la source
Je ne comprends pas. D'où vient IS_INSTALLED?
Jeroen
Il n'y a pas IS_INSTALLED, c'est juste un pseudo code. Juste un exemple. IS_INSTALLED pourrait être la sortie d'une commande comme 'dpkg --status package_name'. Ce que je voulais dire, c'était que vous pouviez vérifier si le package était installé en préinstauration, définir un état var puis en fonction de cet état var prendre des mesures en postinst.
Owais Lone