Внутреннее устройство пакетов Debian
Введение
Несмотря на то что большинство пакетов создается с использованием debhelper, понимание того как устроен deb-пакет "изнутри" даст возможность разобраться зачем нужна та или иная утилита dh_ или что делать когда возникает задача создать "нестандартный" src-пакет итд. Лишние знания, как известно не отягощают голову, а, напротив, облегчают ей работу когда перед ней наконец появляется задача, требующая решения
Что представляет собой deb-пакет?
Deb-пакет это обычный архив файлов, содержащий файлы, предназначенные для установки в систему, а так же некоторые служебные файлы, необходимые для того чтобы эту установку сделать гибкой. При помощи программы ar упаковано в один файл:
Архив control.tar.gz, содержащий скрипты, написанные майнтенером пакета, использующиеся при установке/удалении пакета, а так же другие служебные файлы;
Архив data.tar.gz, содержащий двоичные файлы программы, ради которой создан пакет;
Файл debian-binary.
Поскольку содержимое пакета может в будущем измениться (будет новый номер версии в debian-binary), то собирать deb-пакет при помощи программ tar, gzip, ar не рекомендуется и этот вариант в статье рассматриваться не будет.
Собирается пакет программой dpkg из специально подготовленной структуры каталогов:
- DEBIAN/
- .. path/to/dir/file1
- .. path/to/dirX/fileX
то есть:
Файлы и каталоги, предназначенные для установки в систему. Их расположение в архиве соответствует положению их в файловой системе если считать от корня. Например файл usr/share/doc/package/copyright в deb-архиве после установки будет находиться в /usr/share/doc/package/copyright (все они будут упакованы в архив data.tar.gz);
Каталог DEBIAN/, содержащий служебную информацию о пакете (о ней пойдет речь ниже). Содержимое этого каталога при сборке будет упаковано в архив control.tar.gz;
Низкоуровневые функции работы с deb-пакетом
Программа dpkg
Представляет наиболее низкоуровневый интерфейс для создания/установки/распаковки пакетов.
Основные команды, которые выполняет данная программа общеизвестны, нас же будет интересовать команда dpkg -build.
Если Вы создали в некотором каталоге нужную для создания пакета иерархию файлов/каталогов, то превратить ее в deb-пакет можно дав команду:
- dpkg -build Directory package.deb
при этом из каталог Directory будет упакован в пакет.
То есть все что нам нужно чтобы создать пакет для Debian, это сложить файлы в нужные директории и упаковать. Фактически это почти тоже самое что и простой архив tgz дистрибутива slackware, только информационные файлы располагаются в каталоге с другим именем и видов этих файлов несколько больше.
Ну а теперь, когда мы уяснили базовое устройство пакета, можем перейти к описанию того что должно или может находиться внутри каталога DEBIAN/.
Обязательное содержимое DEBIAN/
Файл control
Этот файл содержит всю описательную информацию на пакет, как то:
- Короткое описание пакета (одна строка);
- Полное описание пакета (один или несколько абзацев);
- Имя и координаты майнтенера, создавшего пакет;
- Номер версии программы (пакета);
- Имя раздела которому принадлежит пакет;
- Перечень пакетов от которых зависит пакет (несколько видов зависимостей: строгие, нестрогие, конфликты итп);
- Уровень важности пакета;
- Имя и версию src-пакета из которого собран данный deb-пакет (если есть таковой);
- Архитектуру для которой данный пакет собран;
и некоторые другие параметры.
Короткое описание содержимого этого файла на русском языке Вы можете найти здесь, а полное описание на английском языке в Debian-policy. Смотрите так же man deb-control.
Необходимо отметить: в src-пакетах как правило лежит файл debian/control, который является лишь шаблоном для того файла contol, который будет упакован в deb-пакет. Скрипты сборки пакета добавят несколько полей в этот шаблон, вычислят зависимости от библиотек, проставят версию пакета (взяв ее из changelog), разобьют общий control нескольких пакетов на несколько control-файлов, если из одного src-пакета производится сборка нескольких deb-пакетов.
Опциональное содержимое DEBIAN/
Файл md5sums
Содержит md5 хеши для всех файлов кроме файлов находящихся в каталоге DEBIAN/. Данный файл необязателен для deb-пакета, однако программы верификации пакетов считают пакеты, несодержащие этот файл ошибочными. Может использоваться некоторыми программами администрирования системы для верификации изменений в файловой системе.
Скрипты для установки/удаления пакета
Пакет может содержать несколько скриптов (или программ), которые будут вызываться при установке/удалении пакета. Эти скрипты позволяют майнтенеру выполнять некоторые действия при установке/удалении. Например этими скриптами могут создаваться/удаляться каталоги в которых программа будет хранить свои временные данные, может производиться добавление/удаление программы в меню вашего оконного менеджера, первичное конфигурирование программы и так далее.
Виды скриптов:
preinst - скрипт, вызывающийся перед распаковкой пакета в файловую систему. Обычно при помощи этого скрипта пользователю задаются вопросы, позволяющие позже сконфигурировать программу. Так же возможно производится сбор информации, которая потребуется позже для конфигурирования программы. Если скрипт завершится с кодом ошибки, то пакет не будет установлен в систему;
postinst - скрипт, вызывающийся после распаковки пакета. При помощи этого скрипта производится конфигурирование уже установленной программы. Конфигурирование происходит с использованием информации полученной на предыдущем этапе от пользователя. Задавать вопросы пользователю из скрипта postinst не принято.;
prerm - скрипт, вызывающийся перед удалением пакета. Может задать пользователю некоторые вопросы, связанные с удалением. Например вопрос что делать с лог-файлами итп. Если скрипт завершится с кодом ошибки, пакет останется установленным в систему;
postrm - скрипт, вызывающийся после удаления пакета;
config - скрипт, вызывающийся на стадии конфигурирования и переконфигурирования пакета. Это дополнительный скрипт, который используется системой Debconf. Вызывается перед скриптом postinst, используется для того чтобы задать пользователю вопросы в системе диалогов debconf.
В разных ситуациях эти скрипты вызываются с разными опциями. В общем виде пакет может:
- Устанавливаться в систему (первичная установка);
- Устанавливаться новая версия пакета (upgrade);
- Устанавливаться старая версия пакета (downgrade);
- Удаляться из системы.
Соответственно порядок вызова скриптов и опции их вызова может быть разный. Скрипты могут вызываться со следующими параметрами (полный перечень можно найти в Debian-policy):
Параметр |
Доп-параметры |
Описание |
preinst |
||
install |
Номер версии* |
Вызывается перед распаковкой пакета. Номер версии указывает на пакет, который стоял ранее, но был удален без ключа --purge, то есть конфигурационные файлы сохранены. С данным параметром скрипт вызывается если в системе пакет не установлен. |
upgrade |
Номер версии |
Вызывается перед распаковкой пакета. Номер версии указывает на пакет, который стоял ранее. Выполняется upgrade или downgrade для пакета. Зная текущую версию пакета и сравнив её с передаваемым здесь значением мы можем определить что происходит upgrade или downgrade |
abort-upgrade |
Номер версии |
Вызывается если preinst upgrade вызванное для нового пакета завершилось неудачей. Номер версии соответствует номеру версии нового пакета, который пытались установить. Таким вызовом установленный пакет информируется о том что его попытались неудачно проапгрейдить. |
postinst |
||
configure |
Номер версии* |
Вызывается после распаковки пакета. Номер версии содержит версию пакета корректно сконфигурированного ранее. То есть того для которого данный вызов завершился без ошибки. По номеру версии скрипт конфигурации может принять решение о том каким образом необходимо производить апгрейд конфигурационных файлов программы |
reconfigure |
Номер версии |
Вызывается системой Debconf после переконфигурации пакета. Выполняет все необходимые действия по переконфигурации. |
abort-upgrade |
Номер версии |
Вызывается если preinstall upgrade нового пакета завершился неудачей. Новый пакет не устанавливается, а старый при этом может провести собственную переконфигурацию для того чтобы сохранить работоспособность. |
prerm |
||
remove |
|
Вызывается перед удалением пакета. |
upgrade |
Номер версии |
Вызывается перед удалением пакета при его апгрейде. Номер версии указывает на версию устанавливаемого пакета. |
failed-upgrade |
Номер версии |
Вызывается для устанавливаемого пакета, если prerm upgrade удаляемого пакета завершился с кодом ошибки. Номер версии указывает на удаляемый пакет |
postrm |
||
remove |
|
Вызывается после удаления пакета |
purge |
|
Вызывается после удаления пакета. Если вызван dpkg --purge |
upgrade |
Номер версии |
Вызывается после удаления пакета при его апгрейде. Номер версии указывает на новый пакет. |
failed-upgrade |
Номер версии |
Вызывается после удаления пакета при его апгрейде. Вызывается в случае если postrm upgrade вернул код ошибки. Номер версии указывает на удаляемый пакет. Вызов скрипта происходит во вновь устанавливаемом пакете. |
abort-install |
Номер версии* |
Вызывается если preinst install вернул код ошибки. Номер версии соответствует номеру версии передаваемому preinst install |
config |
||
configure |
Номер версии |
Вызывается во время предварительной настройки пакета из dpkg-preconfigure. Этот вызов проходит во время установки/апгрейда пакета. Номер версии указывает на версию установленного на данный момент пакета. |
reconfigure |
Номер версии |
Вызывается при повторной настройке пакета. Номер версии - номер установленной версии пакета. Инициировать вызов можно дав команду dpkg-reconfigure package из командной строки. После этого вызова системой Debconf будет вызван сценарий postinst reconfigure |
* Необязательный параметр |
Файл templates
Если используется возможность конфигурации/реконфигурации пакета в системе Debconf (скрипт config), то этот файл содержит шаблоны диалогов с пользователем.
Файл conffiles
Содержит перечень файлов пакета, которые являются конфигурационными. По одному файлу на одну строку. Эти файлы при апгрейдах пакета заменяться не будут (или же будут задаваться вопросы с предложением о замене). Подробнее о содержимом см. man debconf-devel
Утилиты для работы/генерации содержимого DEBIAN/
Утилита dpkg-gencontrol
Осуществляет генерацию файла control на базе шаблона этого файла, составляемого майнтенером, а так же дополнительных параметров, передаваемых из командной строки. В частности, устанавливает номер версии пакета, архитектуру итп. Номер версии обычно берется из файла changelog, однако иногда бывает необходимо из одного src-пакета собрать несколько deb-пакетов с разными номерами версий. Опция -v поможет Вам в этом.
Утилита dpkg-shlibdeps
Вычисляет зависимости для исполняемых файлов и библиотек. Майнтенер обычно указывает Build-зависимости (зависимости сборки), а Depend-зависимости (зависимости необходимые для работы) вычисляются с помощью этой (или подобных) утилит. Такой подход дает возможность не привлекать майнтенера при смене имен библиотек от которых зависит пакет.
Утилита dpkg-parsechangelog
Позволяет извлекать из changelog-файла некоторые параметры, вроде номера версии, координат и имени майнтенера итп. Результаты работы этой утилиты могут использоваться как входные параметры для утилит вроде dpkg-gencontrol.
Утилита dpkg-architecture
Позволяет извлекать информацию (манипулировать ей) об архитектуре системы для которой собирается пакет или на которой собирается пакет. Выходные данные так же могут использоваться для использования в других утилитах. Например при генерации файла control утилитой dpkg-gencontrol.
Проверка соответствия пакета современным требованиям Debian
После того как пакет создан, можно получить информацию о его содержимом с помощью вышеупомянутой утилиты dpkg.
dpkg -I package.deb - выведет общую информацию о пакете, включая содержимое control-файла; dpkg -c package.deb - выведет полный перечень файлов пакета.
После этих двух проверок (все файлы на месте, информация в финальном control корректна), можно запустить одну из двух проверки пакета на соответствие текущему полиси.
Такие проверки осуществляются при помощи программы lintian. Проверяются такие параметры, как правильность расположения двоичных файлов, наличие man-страниц, проверяется на наличие ошибок описание пакета в control-файле, просматривается файл copyright и так далее. Идеальный вариант - добиться от создаваемого пакета такого состояния, что lintian не выводит предупреждений/сообщений об ошибках.
- lintian -is package.deb
покажет подробную информацию о проблемах в пакете.