Пакет Debian является не только архивом файлов, предназначенных для установки. Он является частью системы, и в нём описаны взаимоотношения с другими пакетами Debian (зависимости, конфликты, предложения). Он также содержит сценарии, которые выполняются на различных этапах жизненного цикла пакета (при установке, удалении, обновлении). Эти данные, используемые инструментами управления пакетами, не являются частью упакованного программного обеспечения, но содержатся внутри пакета и называются «метаинформацией» (информацией о другой информации).
5.2.1. Описание: файл control
This file uses a structure similar to email headers (as defined by RFC 2822). For example, for apt, the control
file looks like the following:
$
apt-cache show apt
Package: apt
Version: 0.9.7.9+deb7u1
Installed-Size: 3271
Maintainer: APT Development Team <deity@lists.debian.org>
Architecture: amd64
Replaces: manpages-pl (<< 20060617-3~)
Depends: libapt-pkg4.12 (>= 0.9.7.9), libc6 (>= 2.4), libgcc1 (>= 1:4.1.1), libstdc++6 (>= 4.6), debian-archive-keyring, gnupg
Suggests: aptitude | synaptic | wajig, dpkg-dev, apt-doc, xz-utils, python-apt
Conflicts: python-apt (<< 0.7.93.2~)
Description-ru: менеджер пакетов с интерфейсом командной строки
Этот пакет содержит инструменты командной строки для поиска и
управления пакетами, а также запроса информации о пакетах путём
низкоуровневого доступа ко всем возможностям библиотеки
libapt-pkg.
.
Включены следующие инструменты:
* apt-get для получения пакетов и информации о них из
достоверных источников и для установки, обновления и удаления
пакетов вместе с их зависимостями
* apt-cache для запроса доступной информации об установленных и
доступных для установки пакетов
* apt-cdrom для использования внешних носителей информации в
качестве источников пакетов
* apt-config в качестве интерфейса для настройки параметров
* apt-key в качестве интерфейса для управления ключами для
проверки ключей аутентификации
Description-md5: 9fb97a88cb7383934ef963352b53b4a7
Tag: admin::package-management, hardware::storage, hardware::storage:cd,
implemented-in::c++, interface::commandline, network::client,
protocol::ftp, protocol::http, protocol::ipv6, role::program,
suite::debian, use::downloading, use::searching,
works-with::software:package
Section: admin
Priority: important
Filename: pool/main/a/apt/apt_0.9.7.9+deb7u1_amd64.deb
Size: 1258056
MD5sum: f403a84515c37e3232b7fcf9664c3e30
SHA1: abe3610c4c619eccacc8bc985369c780189e9958
SHA256: 8f2ada8ed29831ae97264d5ce51410755b25f940c277eacacfe6803cc3ae7540
5.2.1.1. Зависимости: поле Depends
Зависимости определяются в поле Depends
в заголовке пакета. Это список условий, выполнение которых необходимо для коректной работы пакета. Данная информация используется такими инструментами, как apt
, чтобы установить правильные версии необходимых библиотек, от которых зависит устанавливаемый пакет. Для каждой зависимости диапазон версий, соответствующих этому условию, может быть ограничен. Другими словами, можно сказать, что нам требуется пакет libc6 версии не ниже чем «2.3.4» (пишется «libc6 (>= 2.3.4)
»). Операторы сравнения версий следующие:
В списке условий запятая играет роль разделителя. Её следует интерпретировать как логическое «и». Внутри условий вертикальная черта («|») означает логическое «или» (включающее «или», а не исключающее «строго одно из»). Поскольку оно имеет более высокий приоритет, чем «и», его можно использовать столько раз, сколько потребуется. Так, зависимость «(A или B) и C» записывается в виде
A | B, C
. Напротив, выражение «A или (B и C)» следует записывать как «(A или B) и (A или C)», поскольку поле
Depends
не допускает использования скобок, меняющих порядок приоритетов между логическими операторами «или» и «и». То есть должно писаться
A | B, A | C
.
The dependencies system is a good mechanism for guaranteeing the operation of a program, but it has another use with “meta-packages”. These are empty packages that only describe dependencies. They facilitate the installation of a consistent group of programs preselected by the meta-package maintainer; as such, apt install meta-package
will automatically install all of these programs using the meta-package's dependencies. The gnome, kde-full and linux-image-amd64 packages are examples of meta-packages.
5.2.1.2. Конфликты: поле Conflicts
Поле Conflicts
указывает на то, что пакет не может быть установлен, если уже установлен другой пакет. Наиболее распространенными причинами для этого является включение обоими пакетами файлов с одинаковыми именами, или предоставление сервисов на одном и том же порту TCP, или мешающих работе друг друга.
dpkg
will refuse to install a package if it triggers a conflict with an already installed package, except if the new package specifies that it will “replace” the installed package, in which case dpkg
will choose to replace the old package with the new one. apt
always follows your instructions: if you choose to install a new package, it will automatically offer to uninstall the package that poses a problem.
5.2.1.3. Несовместимость: поле Breaks
По своему действию поля Breaks
похоже на поле Conflicts
, но оно несёт особый смысл. Оно сообщает, что установка пакета «поломает» другой пакет (или конкретные его версии). Как правило, такая несовместимость между пакетами имеет временный характер, и Breaks
указывает на конкретные несовместимые версии.
dpkg
will refuse to install a package that breaks an already installed package, and apt
will try to resolve the problem by updating the package that would be broken to a newer version (which is assumed to be fixed and, thus, compatible again).
Подобные ситуации могут возникнуть в случае обновления без обратной совместимости: это происходит, если новая версия работает не так, как старая, что приводит к сбою в другой программе, если не принять должных мер. Поле Breaks
помогает пользователю не сталкиваться с такими проблемами.
5.2.1.4. Предоставляемое пакетом: поле Provides
Это поле вводит очень интересную концепцию «виртуального пакета». Она имеет много применений, два из которых особенно важны. Первое состоит в использовании виртуального пакета, чтобы привязать к нему общее название сервиса (пакет «предоставляет» сервис). Вторая показывает, что пакет полностью заменяет другой, и что при этом он может удовлетворять зависимости, которые удовлетворил бы другой. Таким образом, можно создать замену пакета без необходимости использовать то же самое имя пакета.
5.2.1.4.1. Предоставление «сервиса»
Давайте рассмотрим первый случай более подробно на примере: все почтовые серверы, такие как postfix или sendmail, «предоставляют» виртуальный пакет mail-transport-agent. Поэтому в любом пакете, для работы которого нужен этот сервис (например менеджере списков рассылки вроде smartlist или sympa), просто указывается зависимость от mail-transport-agent вместо того, чтобы указывать большой, и при этом всё равно неполный список возможных решений (то есть postfix | sendmail | exim4 | …
). Кроме того, бесполезно установливать два почтовых сервера на одной машине, поэтому каждый из этих пакетов сообщит о конфликте с виртуальным пакетом mail-transport-agent. Конфликт с самим собой игнорируется системой, но эта техника не допустит установки двух почтовых серверов.
5.2.1.4.2. Взаимозаменяемость другим пакетом
Поле Provides
также полезно в случаях, когда содержание пакета включается в состав другого, более крупного пакета. Например модуль Perl libdigest-md5-perl был необязательным в Perl 5.6, но стал стандартным в Perl 5.8 (и более поздних версиях, в частности 5.14, входящей в Wheezy). Поэтому в пакете perl, начиная с версии 5.8, указывается Provides: libdigest-md5-perl
, чтобы зависимости от этого пакета были удовлетворены при установке Perl версии 5.8 (или новее). Сам пакет libdigest-md5-perl в конечном итоге был удален, поскольку после удаления старых версий Perl в нём не стало смысла.
Эта функция очень полезна, поскольку никогда нельзя предвидеть превратности процесса разработки, и важно иметь возможность подстроиться к переименованию устаревшего ПО или другим автоматическим заменам.
5.2.1.4.3. Текущие ограничения
Virtual packages used to suffer from some limitations, the most significant of which was the absence of a version number. To return to the previous example, a dependency such as Depends: libdigest-md5-perl (>= 1.6)
, despite the presence of Perl 5.10, would never be considered as satisfied by the packaging system — while in fact it most likely is satisfied. Unaware of this, the package system chose the least risky option, assuming that the versions do not match.
This limitation has been lifted in dpkg 1.17.11, and is no longer relevant in Jessie. Packages can assign a version to the virtual packages they provide with a dependency such as Provides: libdigest-md5-perl (= 1.8)
.
5.2.1.5. Замена файлов: поле Replaces
The Replaces
field indicates that the package contains files that are also present in another package, but that the package is legitimately entitled to replace them. Without this specification, dpkg
fails, stating that it can not overwrite the files of another package (technically, it is possible to force it to do so with the --force-overwrite
option, but that is not considered standard operation). This allows identification of potential problems and requires the maintainer to study the matter prior to choosing whether to add such a field.
Это поле используется при изменении имени пакета, или когда один пакет включается в состав другого. Это также происходит в случае, если сопровождающий решает распределить файлы по-другому между двоичными пакетами, полученными из одного и того же исходного: заменённый файл больше не принадлежит старому пакету, а только новому.
Если все файлы в установленном пакете были заменены, принимается решение об удалении пакета. Наконец, это поле также указывает dpkg
удалить заменённый пакет в случае конфликта.
5.2.2. Сценарии настройки
Кроме файла control
архив control.tar.gz
в каждом пакете Debian может содержать несколько сценариев, вызываемых dpkg
на разных этапах обработки пакета. В Политике Debian подробно описаны все возможные случаи, в которых вызываются сценарии, и какие аргументы они при этом получают. Эти последовательности могут быть довольно сложными, поскольку если один из сценариев завершается с ошибкой, dpkg
будет пытаться вернуться к нормальному состоянию (насколько это возможно) путём отмены текущей установки или удаления.
Если вкратце, сценарий preinst
вызывается перед установкой пакета, а postinst
после неё. Аналогично, prerm
запускается перед удалением пакета, а postrm
— после. Обновление пакета эквивалентно удалению предыдущей версии и установке более новой. Все возможные ситуации описать здесь не получится, но мы рассмотрим две, встречающиеся чаще всего: установку/обновление и удаление.
5.2.2.1. Установка и обновление
Вот что происходит во время установки пакета (или его обновления):
Для обновления dpkg
запускает old-prerm upgrade новая-версия
.
Также для обновления dpkg
запускает new-preinst upgrade старая-версия
; при установке запускается new-preinst install
. Последним параметром может быть добавлена старая версия, если пакет уже устанавливался раньше, но был удалён (но не вычищен, то есть конфигурационные файлы сохранились).
После этого распаковываются файлы нового пакета. Если файл уже существует, он заменяется, но создаётся временная резервная копия.
При обновлении dpkg
вызывает old-postrm upgrade новая-версия
.
dpkg
обновляет все внутренние данные (список файлов, сценарии настройки и т. п.) и удаляет резервные копии заменённых файлов. Теперь обратного пути нет: dpkg
более недоступны все элементы, необходимые для отката к предыдущему состоянию.
Наконец, dpkg
настраивает пакет, запуская new-postinst configure последняя-настроенная-версия
.
Вот что происходит во время удаления пакета:
dpkg
запускает prerm remove
.
dpkg
удаляет все файлы пакета за исключением конфигурационных файлов и сценариев настройки.
dpkg
запускает postrm remove
. Все сценарии настройки, за исключением postrm
, удаляются. Если пользователь не использует опцию «purge», процесс удаления заканчивается на этом шаге.
Для полного удаления пакета (в случае использования команды dpkg --purge
или dpkg -P
) также удаляются конфигурационные файлы и их копии (*.dpkg-tmp
, *.dpkg-old
, *.dpkg-new
) и временные файлы; после этого dpkg
запускает postrm purge
.
Четыре сценария, описанные выше, дополняются сценарием config
, предоставляемым пакетами, которые используют debconf
для запроса у пользователя информации для настройки. Этот сценарий определяет вопросы, которые будут заданы debconf
во время установки. Ответы заносятся в базу данных debconf
для дальнейшего использования. Эти сценарии обычно выполняются apt
до установки пакетов, последовательно, чтобы сгруппировать вопросы и задать их пользовтелю в начале процесса. Пред- и послеустановочные сценарии могут впоследствии использовать эту информацию, чтобы действовать в соответствии с пожеланиями пользователей.
5.2.3. Контрольные суммы, список конфигурационных файлов
In addition to the maintainer scripts and control data already mentioned in the previous sections, the
control.tar.gz
archive of a Debian package may contain other interesting files. The first,
md5sums
, contains the MD5 checksums for all of the package's files. Its main advantage is that it allows
dpkg --verify
(which we will study in
Раздел 14.3.3.1, «Auditing Packages with dpkg --verify
») to check if these files have been modified since their installation. Note that when this file doesn't exist,
dpkg
will generate it dynamically at installation time (and store it in the dpkg database just like other control files).
В conffiles
содержится список файлов, которые должны быть обработаны как конфигурационные файлы. Конфигурационные файлы могут быть изменены администратором, и dpkg
постарается сохранить эти изменения во время обновления пакета.
Действительно, в этой ситуации dpkg
ведёт себя настолько интеллектуально, насколько это возможно: если стандартный конфигурационный файл не изменился между двумя версиями, она ничего не делает. Если, однако, файл был изменен, она будет пытаться обновить его. Возможны два варианта развития событий: если администратор не трогал конфигурационный файл, dpkg
автоматически установит новую версию; если же файл был изменен, dpkg
спросит администратора, какую версию он хочет использовать (старую с изменениями или новую из пакета). Для помощи в принятии решения dpkg
показывает «diff
», то есть различия между двумя версиями. Если пользователь предпочтёт оставить старую версию, новая будет храниться в том же месте, в файле с суффиксом .dpkg-dist
. Если же пользователь выбирает новую версию, старая сохраняется в файле с суффиксом .dpkg-old
. Другой вариант заключается в том, чтобы немедленно прервать dpkg
и отредактировать файл, попытавшись внести нужные изменения (ранее обнаруженные с помощью diff
).