dpkg: как использовать триггер?
Я написал небольшой сервер cdn, который будет перестраивать его реестр пула, если в него будут установлены новые вещи (pool-content-packages).
Вместо того чтобы каждый пул-контент-пакет вызывал init.d cdn-сервера, я бы хотел использовать триггеры. Тогда он перезапустит сервер только один раз в конце установки после установки всех пакетов.
Что я должен сделать, чтобы использовать триггер в моих пакетах с поддержкой debhelper?
2 ответа
То, что вы ищете, это dpkg-триггеры.
Одно из решений с использованием debhelper для сборки пакетов debian:
Шаг 1)
Создать файл debian/<serverPackageName>.triggers
(заменить <serverPackageName>
с именем вашего серверного пакета).
Шаг 1а)
Определите триггер, который следит за каталогом вашего пула. Содержание файла будет:
interest /path/to/my/pool
Шаг 1б)
Но вы также можете определить именованный триггер, который должен быть запущен явно (см. Шаг 3).
содержание файла:
interest cdn-pool-changed
Имя триггера cdn-pool-change является свободным. Вы можете взять то, что вы хотите.
Шаг 2)
Добавить обработчик для триггера в файл debian/<serverPackageName>.postinst
(заменить <serverPackageName>
с именем вашего серверного пакета).
Пример:
#!/bin/sh
set -e
case "$1" in
configure)
;;
triggered)
#here is the handler
/etc/init.d/<serverPackageName> restart
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
#DEBHELPER#
exit 0
замещать <serverPackageName>
с именем вашего серверного пакета.
Шаг 3) (только для именованных триггеров, шаг 1b))
Добавьте в каждый пакет контента файл debian/<contentPackageName>.triggers
(заменить <contentPackageName>
с именами ваших пакетов контента).
содержание файла:
activate cdn-pool-changed
Используйте то же имя для триггера, который вы определили в шаге 1.
Более подробная информация
Лучшее описание для триггеров dpkg, которое я смог найти, это " Как использовать триггеры dpkg ". Соответствующий репозиторий git с примерами вы можете получить здесь:
git clone git://anonscm.debian.org/users/seanius/dpkg-triggers-example.git
У меня была потребность, и я много раз читал и перечитывал документы. Я думаю, что процесс не совсем понятно объяснить, вернее непонятно, что куда идет. Здесь я надеюсь прояснить использование триггеров пакетов Debian.
Служба с каталогом конфигурации
Служба, читающая свои настройки в определенном каталоге, может пометить этот каталог как принадлежащий .
Скажем, я создаю новую службу, которая считывает настройки из/usr/share/my-service/config/...
Этот сервис получает два дополнения:
В его каталог я добавляю
my-service.triggers
А вот и содержимое:
# my-service.triggers interest /usr/share/my-service/config
Это означает, что если какой-либо другой пакет устанавливает или удаляет файл из этого каталога, триггер переходит в состояние «необходимо выполнить».
В своем
debian
каталог я также добавляюmy-service.postinst
И у меня есть следующий сценарий, чтобы проверить, произошел ли триггер, и запустить процесс по мере необходимости:
# my-service.postinst if [ "$1" = "triggered" ] then if [ "$2" = "/usr/share/my-service/config" ] then # this may or may not be what you need to do, but this is often # how you handle a change in your service config files # systemctl restart my-service fi exit 0 fi
Вот и все.
Теперь пакеты, добавляющие расширения к вашей службе, могут добавлять свои собственные файлы конфигурации в (или каталог в/etc/my-service/my-service.d/...
или/var/lib/my-service/...
, хотя последний должен быть зарезервирован для динамических файлов, а не для файлов, установленных из пакета) и автоматически вызывает ваш скрипт с помощью:
postinst triggered /usr/share/my-service/config
# where /usr/share/my-service/config is your <interest-path>
Этот вызов происходит только один раз и после того, как все пакеты были установлены, отсюда и преимущество наличия триггера. Таким образом, каждому пакету не нужно знать, что он должен перезапуститься.my-service
и это не происходит более одного раза, что может вызвать всевозможные побочные эффекты (например, служба пытается прослушивать порт TCP и получает ошибку: адрес уже используется).
ВАЖНО: имейте в виду, что должен содержать строку с#DEBHELPER#
.
Таким образом, вам не нужно делать ничего особенного в других пакетах. Только убедитесь, что файлы конфигурации установлены в правильном каталоге и загружаются оттуда (т.е. в моем примере под/usr/share/my-service/config
).
У меня есть расширение для BIND9 под названием ipmgr , которое использует.ini
файлы, сохраненные в определенной папке. Он использует файлы для создания зон DNS (таким образом меньше ошибок! И он включает поддержку получения сертификатов letsencrypt и настроек для dmarc/dkim). Этот пакет использует этот случай: простой каталог, в который устанавливаются файлы конфигурации. Другим пакетам не нужно ничего делать, кроме как устанавливать файлы в нужное место (/usr/share/ipmgr/zones
, для этого пакета).
Сервис без папки конфигурации
В некоторых (редких?) случаях вам может потребоваться запустить что-то в службе, что не связано с установкой нового файла конфигурации.
В этом случае вы можете использовать произвольное имя (оно должно включать имя вашего пакета, чтобы убедиться, что оно уникально, поскольку это имя является глобальным для всей системы Debian/Ubuntu).
Чтобы этот работал, вам нужны три файла, один из которых является триггером в других пакетах.
Укажите интерес
Как и выше, у нас есть интерес. В этом случае интерес указывается как имя само по себе. Система различает имя и путь, потому что имя не может содержать косую черту (
/
) характер. Имена ограничены ASCII, за исключением управляющих символов и пробелов. Я бы посоветовал вам придерживаться az, 0-9 и тире (-
).# my-service.triggers interest my-service-settings
Это полезно, если вы не можете просто отслеживать папку. Например, настройки могут исходить из сетевого подключения, которое предлагает пакет после установки.
Прислушивайтесь к триггерам
Опять же, как и выше, вам нужен
postinst
скрипт в вашем пакете услуг. Это фиксирует триггер и позволяет вам запустить команду. Сценарий тот же, только вы проверяете имя, а не папку (обратите внимание, что у вас может быть любое количество триггеров, поэтому вы также можете иметь оба: папку, как указано выше, и специальное имя, как здесь).# my-service.postinst if [ "$1" = "triggered" ] then if [ "$2" = "my-service-settings" ] then # this may or may not what you need to do, but this is often # how you handle a change in your service config files # systemctl restart my-service fi exit 0 fi
Курок
Как было сказано выше, нам нужен третий файл. Произвольное имя не будет запускаться автоматически
dpkg
. Он не будет знать, должен ли ваш другой пакет инициировать что-то подобное (хотя он уже достаточно автоматизирован).Таким образом, в других пакетах вы создаете файл триггера, который выглядит так:
# other-package.triggers activate my-service-settings
Теперь мы узнаем имя, оно такое же, как
interest
указано выше.Другими словами, если триггер должен запускаться для чего-то другого, кроме установки файлов в заданном месте, используйте специальное имя и добавьте этот файл триггеров с
activate
ключевое слово.
Другие особенности
Я не проверял другие функцииdpkg-trigger(1)
инструмент. В файлах есть поддержка других ключевых слов:
interest
interest-await
interest-noawait
activate
activate-await
activate-noawait
На странице руководства deb-triggers есть дополнительная информация о них. Я не слишком уверен, чтоawait
/ подразумевает, что триггер может произойти в любое время , когдаnowait
используется.
Добавлен автоматический триггер
Система сборки в Ubuntu (вероятно, и в Debian) автоматически добавляетtriggers
файл со следующим, если ваш пакет включает библиотеку:
$ cat triggers
# Triggers added by dh_makeshlibs/11.1.6ubuntu2
activate-noawait ldconfig
Я предлагаю вам проявлять осторожность, если ваш пакет включает библиотеки. Если у вас есть свой файл триггеров, я не знаю, будет ли это добавление все еще происходить автоматически.
Это также показывает нам особый случай, когда он хочет использоватьnoawait
. Если я правильно понимаю, он должен запускатьldconfig
запускать как можно скорее, чтобы ваши команды работали должным образом послеunpack
. В противном случаеldd
ничего не будет знать о вашей недавно установленной библиотеке.