Как запустить скрипт только при первой установке пакета и при обновлении?


14

Недавно я начал собирать часть своего программного обеспечения и публиковать его на Launchpad. Установка и удаление работают нормально, но обновление пакета с одной версии до следующей версии проблематично.

Проблема в том, что есть некоторые сценарии, которые нужно запускать только во время первой установки пакета. Эти сценарии заполняют БД, создают пользователя и т. Д. В настоящее время они называются в разделе package.postinst configure). Однако это приводит к их вызову во время обновления, а также показано на диаграмме .

Есть ли способ включить сценарий сопровождающего в пакет .deb, который выполняется только при первой установке пакета, а не при обновлении? Или какой изящный способ включить некоторые сценарии начальной установки в пакет .deb?

Ответы:


15

С debian/preinstфайлом вы можете выполнять действия по установке, но не обновлять.

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

Хотя, как следует из названия, он запускается до установки вашего пакета. Таким образом, вы не сможете делать то, что вам нужно здесь. Большинство пакетов просто тестируют на этапе настройки, postinstесли пользователь уже создан. Вот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

28

Проверьте эту диаграмму из вики Debian о том, как называются сценарии сопровождающего: Блок-схема сценария сопровождающего Debian

Если вы пойдете по левой стороне (путь «все идет хорошо»), вы увидите, что postinst скрипт вызывается с последней настроенной версией. Это дает вам возможность отличить обновление от новой установки - в случае обновления ваш postinst будет называться как

postinst configure 1.23-0ubuntu1

где 1.23-0ubuntu1 находится ранее установленная версия вашего пакета, тогда как для новой установки он будет называться как

postinst configure

Это также позволяет вам обрабатывать случай, когда вам нужно выполнить действие при обновлении с определенной версии - вы можете проверить postinstдля этой версии.

Это позволяет легко проверить, выполняется ли сценарий при «установке» или «обновлении». Если $ 2 ноль, то это установка. так:

if [ -z "$2" ]; then
  do install stuff
else
  do upgrade stuff
fi

1
Обратите внимание, что дополнительный параметр также передается в случае, если вы удалили пакет (но не удалили его) и установите его снова.
скайкинг

3

Вы можете использовать скрипт debian / preinst в сочетании с postinst.

В сценарии preinst проверьте наличие файла, который определенно устанавливает ваш pkg. Если он присутствует, ничего не делайте (поскольку ваш пакет был ранее установлен), в противном случае выполните шаги по настройке.

Если ваши шаги установки требуют, чтобы ваш pkg был установлен (в этом случае вышеописанное не будет работать, потому что preinst запускается перед установкой), тогда ваш скрипт preinst может записать файл, например: / tmp / setupmypkg. Ваш скрипт postinst может просто проверить, присутствует ли этот файл, и если это так, сделать две вещи:

  • ваши начальные шаги настройки
  • удалите файл / tmp / setupmypkg

1
Да, это будет работать, и я сейчас делаю что-то подобное. Но это все еще выглядит немного странно ... Я надеялся на более родной способ сделать это. Это не похоже на такой экзотический запрос, верно?
Jeroen

1

Я обнаружил, что тестирование на $ 2 в вашем скрипте «postinst configure» не работает должным образом, если вы уже установили свой пакет один раз, затем удалили его (но без очистки), а затем попробуйте переустановить снова. В этом случае сценарий postinst по-прежнему получает аргумент версии для шага «postinst configure».

Однако, если вы установили пакет раньше, затем удалите и очистите его, а затем переустановите заново, сценарий "postinst configure" НЕ получит аргумент версии в $ 2.


0

Я так не думаю, но вы можете легко изменить сценарии preinst / postinst, чтобы проверить, устанавливается ли пакет в первый раз, и выполнить стандартные действия.

Может быть что-то вроде этого,

в preinst.

if not is_package_istalled():
    export MY_PACKAGE_FIRST_INSTALL

в постинст,

if MY_PACKAGE_FIRST_INSTALL:
    Do First Install Setup 

редактировать

Хм, может быть, вы можете просто проверить все это непосредственно в postinst, потому что я думаю, что dpkg не установит статус пакета как установленного перед запуском postinst, но я не уверен. Таким образом, вышесказанное может прийти,

в постинст,

if not is_package_istalled():
    Do First Install Setup 

Где is_package_installed может быть вашей функцией для определения статуса установки. Может быть что-то вроде 'dpkg --status packagename'

ИЛИ

Почему бы просто не проверить, внесены ли изменения, которые вы хотите внести, и продолжить, только если их нет.


Я не понимаю Откуда исходит IS_INSTALLED?
Jeroen

IS_INSTALLED нет, это просто псевдокод. Просто пример. IS_INSTALLED может быть выводом команды типа 'dpkg --status package_name'. Я имел в виду, что вы можете проверить, установлен ли пакет в preinst, установить состояние var, а затем на основе этого состояния var выполнить действие в postinst.
Owais Lone
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.