Como executar um script apenas durante a primeira instalação de um pacote e durante as atualizações?

14

Recentemente, comecei a empacotar alguns dos meus softwares e publicá-los no Launchpad. A instalação e remoção funcionam bem, mas a atualização do pacote de uma versão para a próxima é problemática.

O problema é que existem alguns scripts que só precisam ser executados durante a primeira instalação do pacote. Esses scripts preenchem o banco de dados, criam um usuário etc. Eles são chamados atualmente na configure)seção package.postinst . No entanto, isso resulta em serem chamados durante uma atualização, bem como mostrado no diagrama .

Existe uma maneira de incluir um script de mantenedor em um pacote .deb que é executado apenas durante a primeira instalação do pacote e não durante uma atualização? Ou qual seria uma maneira elegante de incluir alguns scripts de configuração inicial em um pacote .deb?

Jeroen
fonte

Respostas:

15

Com um debian/preinstarquivo, você pode executar ações na instalação, mas não na atualização.

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

Embora, como o nome indica, isso seja executado antes da instalação do seu pacote. Portanto, talvez você não consiga fazer o que precisa aqui. A maioria dos pacotes simplesmente testa no estágio de configuração postinstse o usuário já foi criado. Aqui estácolord

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

Confira este diagrama no wiki do Debian sobre como os scripts de manutenção são chamados: Fluxograma de script do mantenedor Debian

Se você seguir o lado esquerdo (o caminho "tudo dá certo"), verá que o postinstscript é chamado com a versão configurada mais recentemente. Isso dá a você a chance de distinguir entre uma atualização e uma nova instalação - no caso da atualização, seu postinst será chamado como

postinst configure 1.23-0ubuntu1

onde 1.23-0ubuntu1está a versão instalada anteriormente do seu pacote, enquanto que para uma nova instalação será chamada como

postinst configure

Isso também permite que você lide com o caso quando precisar executar uma ação ao atualizar a partir de uma versão específica - você pode verificar postinst dessa versão.

Isso facilita verificar se o script está sendo executado em uma 'instalação' ou 'atualização'. Se $ 2 for nulo, será uma instalação. assim:

if [ -z "$2" ]; then
  do install stuff
else
  do upgrade stuff
fi
RAOF
fonte
Observe que o parâmetro extra também é passado no caso de você remover o pacote (mas não o limpar) e instalá-lo novamente.
SkyKing
3

Você pode usar um script debian / preinst em combinação com o postinst.

No script preinst, verifique se há um arquivo que seu pkg definitivamente instala. Se estiver presente, não faça nada (porque seu pacote foi instalado anteriormente); caso contrário, execute as etapas de instalação.

Se as etapas de configuração exigirem que o seu pkg esteja instalado (nesse caso, o acima descrito não funcionará porque o preinst é executado antes da instalação), o script do preinst poderá gravar um arquivo, por exemplo: / tmp / setupmypkg. Seu script postinst pode simplesmente testar se esse arquivo está presente e, em caso afirmativo, fazer duas coisas:

  • suas etapas de configuração inicial
  • exclua o arquivo / tmp / setupmypkg
kyleN
fonte
1
Sim, isso funcionaria e atualmente estou fazendo algo semelhante. Mas ainda parece um pouco hacky ... Eu esperava uma maneira mais nativa de fazê-lo. Não parece um pedido tão exótico, certo?
Jeroen
1

Descobri que o teste de US $ 2 no script "postinst configure" não funcionará corretamente se você já instalou o pacote uma vez antes, desinstalou-o (mas sem limpar) e tente reinstalar novamente. Nesse caso, o script postinst ainda recebe um argumento de versão para a etapa "postinst configure".

No entanto, se você instalou o pacote antes, remova-o E limpe-o e reinstale-o novamente, o script "postinst configure" NÃO receberá um argumento de versão em $ 2

robvdl
fonte
0

Acho que não, mas você pode modificar facilmente os scripts preinst / postinst para verificar se o pacote está sendo instalado pela primeira vez e executar uma ação padrão.

Pode ser algo assim,

em preinst.

if not is_package_istalled():
    export MY_PACKAGE_FIRST_INSTALL

no postinst,

if MY_PACKAGE_FIRST_INSTALL:
    Do First Install Setup 

Editar

Hmm, pode ser que você possa verificar tudo isso diretamente no postinst porque acho que o dpkg não definiria o status do pacote como instalado antes de executar o postinst, mas não tenho certeza. Então, o que foi dito acima pode vir,

no postinst,

if not is_package_istalled():
    Do First Install Setup 

Onde is_package_installed pode ser sua função para detectar o status da instalação. Pode ser algo como 'dpkg --status packagename'

OU

Por que não simplesmente verificar se as alterações que você deseja fazer já estão lá e somente prosseguir se não estiverem?

Owais Lone
fonte
Eu não entendo De onde vem IS_INSTALLED?
Jeroen
Não existe IS_INSTALLED, é apenas pseudo-código. Apenas um exemplo. IS_INSTALLED pode ser a saída de um comando como 'dpkg --status package_name'. O que eu quis dizer foi que você pode verificar se o pacote está instalado no preinst, definir uma variável de estado e, com base nesse estado, executar ações no postinst.
Owais Lone