Могу ли я создать неинсталлируемый пакет Debian, который перезаписывает файлы другого пакета?
Я пытаюсь создать пакет Debian, который устанавливает пользовательскую раскладку клавиатуры. Для этого вам нужно изменить два файла в /usr/share/X11/xkb
, Так что мой пакет просто включает новые версии этих файлов. Когда я пытаюсь установить его, dpkg жалуется на конфликты с пакетом xkeyboard и не дает мне. Я знаю, что я мог бы использовать --force-overwrite
установить его в любом случае, но я беспокоюсь об удалении пакета позже. Я хотел бы создать пакет Debian со следующим поведением:
- При установке перезаписывает файлы, принадлежащие другому пакету.
- При удалении файлы возвращаются в состояние, в котором они находились до установки.
Это возможно?
1 ответ
Возможно, что dpkg не перезаписывает файл при переустановке пакета, к которому он принадлежит, и может вместо этого поместить файл из пакета в другое место.
Это может быть использовано локально для переопределения версии файла в пакете или одним пакетом для переопределения версии другого (или для создания оболочки).
Существует список переадресации, который читается dpkg и обновляется специальной программой dpkg-divert. Пожалуйста, смотрите dpkg-divert(8) для полной информации о его работе.
Когда пакет хочет перенаправить файл из другого, он должен вызвать dpkg-divert в своем preinst, чтобы добавить переадресацию и переименовать существующий файл. Например, предположим, что пакет smailwrapper желает установить оболочку вокруг /usr/sbin/smail:
dpkg-divert --package smailwrapper --add --rename \
--divert /usr/sbin/smail.real /usr/sbin/smail
--Package smailwrapper гарантирует, что копия / usr / sbin / smail smailwrapper может обойти переадресацию и будет установлена как истинная версия. Можно безоговорочно добавить переадресацию при обновлениях, поскольку она останется неизменной, если она уже существует, но dpkg-divert отобразит сообщение. Чтобы подавить это сообщение, сделайте команду условной для версии, с которой обновляется пакет:
if [ upgrade != "$1 || dpkg --compare-versions "$2" lt 1.0-2; then
dpkg-divert --package smailwrapper --add --rename \
--divert /usr/sbin/smail.real /usr/sbin/smail
fi
где 1.0-2 - версия, в которой диверсия была впервые добавлена в пакет. Выполнение команды во время abort-upgrade бессмысленно, но безвредно.
Postrm должен сделать обратное:
if [ remove = "$1" -o abort-install = "$1" -o disappear = "$1; then
dpkg-divert --package smailwrapper --remove --rename \
--divert /usr/sbin/smail.real /usr/sbin/smail
fi
Если переадресация была добавлена в определенной версии, postrm также должен обрабатывать случай сбоя при обновлении со старой версии (если только старая версия не настолько старая, что прямые обновления больше не поддерживаются):
if [ abort-upgrade = "$1 && dpkg --compare-versions "$2" lt 1.0-2; then
dpkg-divert --package smailwrapper --remove --rename \
--divert /usr/sbin/smail.real /usr/sbin/smail
fi
где 1.0-2 - версия, в которой диверсия была впервые добавлена в пакет. Функция postrm не должна устранять переадресацию при обновлениях, поскольку нет причин удалять переадресацию только для немедленного ее повторного добавления, а поскольку postrm старого пакета запускается после распаковки, поэтому удаление переадресации завершится неудачно.
Не пытайтесь перенаправить файл, который жизненно важен для работы системы - при использовании dpkg-divert есть время после его перенаправления, но до того, как dpkg установит новую версию, когда файл не существует.
Не пытайтесь отвлечь conffile, так как dpkg плохо с этим справляется.
Скопировано из вики Debian: https://www.debian.org/doc/debian-policy/ap-pkg-diversions.html