web-dev-qa-db-fra.com

Installation conditionnelle de fichiers et de répertoires dans les paquets `.deb`

Est-il possible de créer un package binaire .deb avec une installation conditionnelle de fichiers et de répertoires (par exemple, installation d'un script init dans /etc/init.d/ après avoir été confirmé par l'utilisateur)?

3
KaBa

Pour poser des questions de manière interactive lors de l'installation du paquet, vous devez utiliser debconf . Pour créer et gérer dynamiquement des fichiers de configuration (les fichiers de /etc/init.d/ sont considérés comme des fichiers de configuration) cf peut être utilisé.

Un tutoriel sur l'utilisation de debconf est disponible ici:
http://www.fifi.org/doc/debconf-doc/tutorial.html

Exemple minimal

debconf template

Mettez ceci dans le fichier debian/templates. Il contient le texte affiché à l'utilisateur lors de l'installation. Assurez-vous simplement de remplacer demo-pkg par votre nom de paquet!

Template: demo-pkg/install-init.d
Type: boolean
Default: false
Description: Would you like to install a service for this package?
 Services are really cool! They allow stuff to be started in the
 background without you having to start them manually!!!

Script de configuration du paquet

C’est là que vous interrogez (de manière interactive) l’utilisateur sur les choses que vous devez savoir. Ce script est spécial car, lors de l'installation de plusieurs packages, tous ces fichiers sont exécutés avant que dpkg ne commence le processus d'installation. Cela signifie que, si plusieurs packages veulent demander quelque chose à l'utilisateur, toutes les questions sont posées au début de l'installation pour tous les packages, et non plus tard pour chaque package individuellement.

Il suffit de placer les éléments suivants dans un fichier nommé debian/config et de le marquer comme exécutable (n'oubliez pas de remplacer demo-pkg par le nom de package correct):

#!/bin/sh

# Make sure this script fails if any unexpected errors happen
set -e

# Load debconf library
. /usr/share/debconf/confmodule

# Should an init job be installed?
db_input high demo-pkg/install-init.d || true
db_go

# You can also act upon the user's answers using `db_get`
#db_get demo-pkg/install-init.d
#[ "${RET}" = "false"] && echo "I don't think that was a wise decision..."

Scripts de maintenance (postinst, prerm et postrm)

Ici, nous faisons la magie et ajoutons et supprimons dynamiquement le fichier de configuration/script init. Pour que cela fonctionne, vous devez installer votre script init sous forme de fichier normal avec votre paquet (j'ai supposé que /usr/share/demo-pkg/init-service dans cet exemple).

Le fichier debian/postinst (appelé après l'extraction de tous les fichiers par dpkg):

#!/bin/sh

# Make sure this script fails if any unexpected errors happen
set -e

# Load debconf library
. /usr/share/debconf/confmodule

if [ "$1" = "configure" ];
then
    # Check if the user decided the enable the service using `db_get`
    db_get demo-pkg/install-init.d
    if [ "${RET}" != "false" ];
    then
        # Install init script using `ucf`
        ucf /usr/share/demo-pkg/init-service /etc/init.d/demo-service

        # Register init script as service
        update-rc.d demo-service defaults

        # Start service
        invoke-rc.d demo-service start
    fi
fi

Le fichier debian/prerm (appelé avant que les fichiers ne soient supprimés par dpkg ou le package mis à niveau vers une version plus récente):

#!/bin/sh

# Make sure this script fails if any unexpected errors happen
set -e

# Load debconf library
. /usr/share/debconf/confmodule

# Check if the user decided the enable the service using `db_get`
db_get demo-pkg/install-init.d
if [ "${RET}" != "false" ];
then
    # Stop the service before upgrade or removal
    invoke-rc.d demo-service stop

    if [ "$1" = "remove" ] || [ "$1" = "deconfigure" ];
    then
        # Unregister service prior to removal
        update-rc.d -f demo-service remove
    fi
fi

Le fichier debian/postrm (appelé après que tous les fichiers ont été supprimés par dpkg):

#!/bin/sh

# Make sure this script fails if any unexpected errors happen
set -e

if [ "$1" = "purge" ];
then
    # Remove service file using `ucf` (checking whether `ucf` is still available first)
    if type ucf >/dev/null 2>&1;
    then
        ucf --purge "/etc/init.d/demo-service"
    fi

    # Remove service file by hand (in case the above failed somehow)
    rm -f "/etc/init.d/demo-service"
fi

Étapes finales

  1. Ajouter une dépendance Pre-Depends: sur debconf dans le fichier debian/control
  2. Ajouter une dépendance normale Depends: sur ucf dans le fichier debian/control
  3. Assurez-vous que le fichier /usr/share/demo-pkg/init-service (ou le nom que vous appelez) est correctement installé.
3
ntninja