Jak uruchomić skrypt tylko podczas pierwszej instalacji pakietu i aktualizacji?

14

Niedawno zacząłem pakować część mojego oprogramowania i publikować je na Launchpad. Instalacja i usuwanie działa dobrze, ale aktualizacja pakietu z jednej wersji do następnej jest problematyczna.

Problem polega na tym, że niektóre skrypty muszą zostać uruchomione tylko podczas pierwszej instalacji pakietu. Skrypty te wypełniają bazę danych, tworzą użytkownika itp. Obecnie są wywoływane w configure)sekcji package.postinst . Jednak powoduje to, że są one wywoływane podczas aktualizacji, a także pokazane na schemacie .

Czy istnieje sposób na dołączenie skryptu opiekuna do pakietu .deb, który jest wykonywany tylko podczas pierwszej instalacji pakietu, a nie podczas aktualizacji? Lub jaki byłby elegancki sposób na włączenie niektórych skryptów konfiguracji początkowej do pakietu .deb?

Jeroen
źródło

Odpowiedzi:

15

Za pomocą debian/preinstpliku można wykonywać czynności podczas instalacji, ale nie można aktualizować.

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

Jak sama nazwa wskazuje, jest to uruchamiane przed zainstalowaniem pakietu. Więc możesz nie być w stanie zrobić tego, czego potrzebujesz tutaj. Większość pakietów po prostu testuje na etapie konfiguracji, postinstczy użytkownik został już utworzony. Otocolord

$ 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
andrews coś
źródło
28

Sprawdź ten diagram z wiki Debiana, jak nazywane są skrypty opiekuna: Schemat blokowy skryptu opiekuna Debiana

Jeśli podążysz po lewej stronie (ścieżka „wszystko idzie dobrze”), zobaczysz, że postinstskrypt jest wywoływany z ostatnio skonfigurowaną wersją. Daje to szansę na rozróżnienie między aktualizacją a świeżą instalacją - w przypadku aktualizacji twoja postinst będzie nazywana jak

postinst configure 1.23-0ubuntu1

gdzie 1.23-0ubuntu1jest poprzednio zainstalowana wersja twojego pakietu, podczas gdy dla nowej instalacji będzie się nazywać jak

postinst configure

Pozwala to również na obsługę przypadku, gdy trzeba wykonać akcję podczas aktualizacji z określonej wersji - możesz sprawdzić w postinsttej wersji.

Ułatwia to sprawdzenie, czy skrypt jest wykonywany podczas instalacji lub aktualizacji. Jeśli 2 USD to zero, oznacza to instalację. więc:

if [ -z "$2" ]; then
  do install stuff
else
  do upgrade stuff
fi
RAOF
źródło
1
Zauważ, że dodatkowy parametr jest również przekazywany w przypadku, gdy usunąłeś pakiet (ale go nie wyczyściłeś) i ponownie go zainstalowałeś.
skyking
3

Możesz być w stanie użyć skryptu debian / preinst w połączeniu z postinst.

W skrypcie wstępnym sprawdź, czy plik, który zdecydowanie instaluje pkg. Jeśli jest obecny, nie rób nic (ponieważ pakiet był wcześniej zainstalowany), w przeciwnym razie wykonaj kroki instalacji.

Jeśli kroki instalacji wymagają zainstalowania pakietu pkg (w takim przypadku powyższe nie zadziała, ponieważ preinstalacja jest uruchamiana przed instalacją), wówczas skrypt preinst może zapisać plik, na przykład: / tmp / setupmypkg. Twój skrypt postinst może po prostu przetestować, czy ten plik jest obecny, a jeśli tak, wykonaj dwie czynności:

  • twoje początkowe kroki konfiguracji
  • usuń plik / tmp / setupmypkg
kyleN
źródło
1
Tak, to zadziałałoby i obecnie robię coś podobnego. Ale wciąż wygląda trochę pospiesznie ... Miałem nadzieję na bardziej rodzimy sposób na zrobienie tego. To nie wydaje się taka egzotyczna prośba, prawda?
Jeroen
1

Odkryłem, że testowanie za 2 USD w skrypcie „postinst config” nie działa poprawnie, jeśli już wcześniej zainstalowałeś swój pakiet, a następnie odinstalowałeś go (ale bez czyszczenia), a następnie spróbuj ponownie zainstalować. W takim przypadku skrypt postinst nadal otrzymuje argument wersji dla kroku „konfiguracja postinst”.

Jednak jeśli wcześniej zainstalowałeś pakiet, usuń ORAZ wyczyść go, a następnie zainstaluj ponownie, skrypt „postinst config” NIE dostanie argumentu wersji w 2 $

robvdl
źródło
0

Nie sądzę, ale możesz łatwo zmodyfikować skrypty preinst / postinst, aby sprawdzić, czy pakiet jest instalowany po raz pierwszy i podjąć standardowe działania.

Może być coś takiego

na wstępie.

if not is_package_istalled():
    export MY_PACKAGE_FIRST_INSTALL

w postinst,

if MY_PACKAGE_FIRST_INSTALL:
    Do First Install Setup 

Edytować

Hmm, być może możesz to wszystko sprawdzić bezpośrednio w postinst, ponieważ myślę, że dpkg nie ustawiłby statusu pakietu jako zainstalowany przed uruchomieniem postinst, ale nie jestem pewien. Aby powyższe mogło przyjść,

w postinst,

if not is_package_istalled():
    Do First Install Setup 

Gdzie is_package_installed może być funkcją wykrywania stanu instalacji. Może być coś w stylu „dpkg --status nazwa_pakietu”

LUB

Dlaczego nie po prostu sprawdzić, czy zmiany, które chcesz wprowadzić, już istnieją, i postępuj tylko, jeśli ich nie ma.

Owais Lone
źródło
Nie rozumiem. Skąd pochodzi IS_INSTALLED?
Jeroen,
Nie ma IS_INSTALLED, to tylko pseudo kod. Tylko przykład. IS_INSTALLED może być wynikiem polecenia takiego jak „dpkg --status nazwa_pakietu”. Chciałem przez to sprawdzić, czy pakiet jest zainstalowany w preinst, ustawić stan var, a następnie na podstawie tego stanu var podjąć działanie w postinst.
Owais Lone