¿Cómo ejecutar un script solo durante la primera instalación de un paquete y durante las actualizaciones?

14

Recientemente comencé a empaquetar parte de mi software y a publicarlo en Launchpad. La instalación y eliminación funciona bien, pero actualizar el paquete de una versión a la siguiente es problemático.

El problema es que hay algunos scripts que solo necesitan ejecutarse durante la primera instalación del paquete. Estos scripts pueblan la base de datos, crean un usuario, etc. Actualmente se los llama en la configure)sección package.postinst . Sin embargo, esto hace que se les llame durante una actualización, como se muestra en el diagrama .

¿Hay alguna manera de incluir un script de mantenedor en un paquete .deb que solo se ejecute durante la primera instalación del paquete y no durante una actualización? ¿O cuál sería una forma elegante de incluir algunos scripts de configuración inicial en un paquete .deb?

Jeroen
fuente

Respuestas:

15

Con un debian/preinstarchivo puede realizar acciones en la instalación pero no actualizar.

#!/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

Aunque, como su nombre lo indica, esto se ejecuta antes de instalar el paquete. Por lo tanto, es posible que no pueda hacer lo que necesita aquí. La mayoría de los paquetes simplemente prueban en la etapa de configuración de postinstsi el usuario ya ha sido creado. Aqui estacolord

$ 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
fuente
28

Consulte este diagrama de la wiki de Debian sobre cómo se llaman los scripts de mantenedor: Diagrama de flujo del script del mantenedor de Debian

Si sigue por el lado izquierdo (la ruta "todo va bien") verá que el postinstscript se llama con la versión configurada más recientemente. Esto le da la oportunidad de distinguir entre una actualización y una instalación nueva: en el caso de actualización, su postinst se llamará como

postinst configure 1.23-0ubuntu1

donde 1.23-0ubuntu1está la versión instalada previamente de su paquete, mientras que para una instalación nueva se llamará como

postinst configure

Esto también le permite manejar el caso cuando necesite realizar una acción al actualizar desde una versión en particular; puede verificar la postinstversión correspondiente.

Esto facilita verificar si el script se está realizando en una 'instalación' o una 'actualización'. Si $ 2 es nulo, entonces es una instalación. entonces:

if [ -z "$2" ]; then
  do install stuff
else
  do upgrade stuff
fi
RAOF
fuente
1
Tenga en cuenta que el parámetro adicional también se pasa en el caso de que haya eliminado el paquete (pero no lo haya purgado) y lo vuelva a instalar.
Skyking
3

Es posible que pueda utilizar un script debian / preinst en combinación con postinst.

En el script preinst, verifique si hay un archivo que su paquete definitivamente instala. Si está presente, no haga nada (porque su paquete se instaló previamente), de lo contrario, siga los pasos de configuración.

Si sus pasos de configuración requieren que su paquete esté instalado (en cuyo caso lo anterior no funcionará porque preinst se ejecuta antes de la instalación), entonces su script de preinst podría escribir un archivo, por ejemplo: / tmp / setupmypkg. Su secuencia de comandos postinst podría simplemente probar si ese archivo está presente y, de ser así, hacer dos cosas:

  • sus pasos iniciales de configuración
  • eliminar el archivo / tmp / setupmypkg
kyleN
fuente
1
Sí, esto funcionaría y actualmente estoy haciendo algo similar. Pero todavía parece un poco hacky ... Esperaba una forma más nativa de hacerlo. No parece una solicitud tan exótica ¿verdad?
Jeroen
1

Descubrí que la prueba de $ 2 en su secuencia de comandos "postinst configure" no funciona correctamente si ya instaló su paquete una vez antes, luego lo desinstaló (pero sin purgarlo), luego intente reinstalarlo nuevamente. En este caso, el script postinst todavía obtiene un argumento de versión para el paso "configurar postinst".

Sin embargo, si ha instalado el paquete anteriormente, luego retírelo y purguelo, luego vuelva a instalarlo, el script "postinst configure" NO obtendrá un argumento de versión en $ 2

robvdl
fuente
0

No lo creo, pero puede modificar fácilmente los scripts preinst / postinst para verificar si el paquete se está instalando por primera vez y tomar medidas estándar.

Puede ser algo como esto

en preinst.

if not is_package_istalled():
    export MY_PACKAGE_FIRST_INSTALL

en postinst,

if MY_PACKAGE_FIRST_INSTALL:
    Do First Install Setup 

Editar

Hmm, puede ser que puedas verificar todo esto directamente en postinst porque creo que dpkg no establecería el estado del paquete como instalado antes de ejecutar postinst, pero no estoy seguro. Entonces lo anterior podría venir,

en postinst,

if not is_package_istalled():
    Do First Install Setup 

Donde, is_package_installed puede funcionar para detectar el estado de la instalación. Puede ser algo así como 'dpkg --status packagename'

O

¿Por qué no simplemente verificar si los cambios que desea realizar ya están allí y continuar si no lo están?

Owais Lone
fuente
No entiendo. ¿De dónde viene IS_INSTALLED?
Jeroen
No hay IS_INSTALLED, solo es un pseudocódigo. Solo un ejemplo. IS_INSTALLED podría ser la salida de un comando como 'dpkg --status package_name'. Lo que quise decir es que podría verificar si el paquete está instalado en preinst, establecer un estado var y luego, basándose en este estado, var tomar medidas en postinst.
Owais Lone