Pacman: управление пакетами в Archlinux

Автор: Алексей Федорчук
5 июля 2005 г

В этой заметке я постараюсь продемонстрировать тот самый цимес, который придаёт неповторимое своеобразие Archlinux — систему управления пакетами под именем pacman.

Краткое вступление

Подобно системе apt, зародившейся в недрах Debian и внедрённой затем… да куда только её не внедрили, — применение системы pacman далеко выходит за рамки родительского дистрибутива: pacman успешно прикручивается к Slackware — пример чему показал сначала Rubix, а затем Frugalware Linux. На Distrowatch я нашел даже сведения о том, что этот механизм управления пакетами используется в Ufficio Zero — итальянском дистриубутиве, основанном на Ubuntu, и использующем, следовательно, пакеты в deb-формате. Правда, проверить это мне пока не удалось — сайт их оказался на чистейшем языке Данте и Петрарки, на котором я только ругаться могу, а устанавливать его было влом. Может быть, кто из наших романистов может внести ясность?

Тем не менее очевидно, что pacman завоевал свое место под солнцем — и ему в немалой степени обязан своей популярностью Archlinux — дистрибутив, еще недавно широко известный в узких кругах собственных разработчиков и немногочисленных пользователей.

Pacman — базис пакетного менеджмента

Archlinux — не является в полном смысле слова дистрибутивом Source Based, подобно Gentoo или, тем более, Linux from Scratch. Ибо основная форма его дистрибуции — все же в виде набора прекомпилированных пакетов. Видом эти пакеты похожи на обычные архивы *tar.gz:

package##ver##rel.pkg.tar.gz

Здесь package — имя пакета, ##ver — номер его версии, присвоенный его разработчиком, ##rel — номер реализации, то есть сборки конкретного бинарника, даваемый уже майнтайнерами Archlinux, аббревиатура pkg свидетельствует, что мы имеем дело с прекомпилированным пакетом Archlinux, а не c абстрактным тарбаллом, ну а два последние суффикса понятны без комментариев…

При ближайшем рассмотрении оказывается, что пакеты Archlinux похожи на тарбаллы не только видом, но и нравом. Формат их — прост до предела, это именно чистое за-tar‘енное дерево, сжатое gzip‘ом, не содержащее никаких инсталляционных скриптов, и вообще никакой метаинформации: только сам исполняемый бинарник (бинарники), предназначенный для помещения в каталог /usr/bin (за исключением тех программ, которым резонно находиться в /bin, /sbin или /usr/sbin), сопровождаемый в необходимых случаях конфигами (для каталога /usr/etc) и библиотеками (для /usr/lib), а также man-документацией.

Средство для управления этими просто построенными пакетами также очень просто и носит название pacman (от packages manager, нужно полагать). Формат её вызова таков:

$ pacman <действие> [опции] имя_файла_пакета

Указание действия является обязательным, опций, в соответствие с названием — опциональным.

Действия, предусмотренные командой pacman, следующие:

  • -A, или --add — добавление (то есть установка) пакета в систему;
  • -U, --upgrade, и -F, --freshen, — обновление пакета; различие между ними в том, что во втором случае обновляется только ранее инсталлированный (посредством -A) пакет, в первом же — установка осуществляется и при отсутствии оного;
  • -S, --sync, — синхронизация локально установленных пакетов с репозиторием дистрибутива (ftp.archlinux.org) или его зеркалами;
  • -R, --remove, — удаление пакета, выполняемое без всяких предупреждений, вместе со всеми его конфигурационными файлами и прочим хозяйством (за исключением, разумеется, пользовательских конфигов из каталога $HOME);
  • -Q, --query, — запрос информации о пакете, установленном или не установленном;
  • -V, --version, — вывод номера версии pacman, сведений о копирайте и лицензии.

В качестве аргументов команды pacman при действиях -A, -U и -F должны выступать полные имена файлов пакетов, вида — pkg_name-version-release.pkg.tar.gz. Если пакет расположен в одном из предназначенных к тому мест (о них я скажу чуть позже), то достаточно приведённой формы, в противном случае потребуется указание полного пути. В одной строке можно перечислить несколько пакетов для единовременной установки или обновления. Действия -Q, -S и -R требуют только указания имени пакета, без прочей атрибутики.

Есть и ещё одно действие — -h, или --help, (внимание — только оно и в краткой форме задаётся в нижнем регистре), — вывод краткой справки, конкретно, списка действий. Если любое из них присоединить к действию -h, то можно получить более подробные сведения об опциях, которые могут это действие сопровождать. Так, команда

$ pacman -hA

даст список всех опций, которые доступны при действии --added:

usage:  pacman {-A --add} [options] 
options:
-d, --nodeps        отменить проверку зависимостей
-f, --force         принудительная установка
-v, --verbose       включение вывода сообщений о
ходе операции
-r, --root
   установка корня
пакета, отличного от "умолчального" /

Опции команды pacman довольно многочисленны, что компенсируется их обычной необязательностью. Важными могут быть -d, --nodeps, отменяющая проверку зависимостей, и -f, --force, — принудительная установка пакета, а также -r, --root, предписывающая отличный от умолчального исходный каталог (а им является корень файловой системы) и требующий, естественно, указания пути (например, /usr/local или /opt. Отмечу ещё опцию -c, --cascade, так как применение её требует особой осторожности: она предписывает рекурсивное удаление не только указанного пакета, но и всех, связанных с ним зависимостями. Обратим внимание, что опции, в отличие от действий, в краткой форме даются исключительно в нижнем регистре.

Наконец, самая интересная опция — -u, --sysupgrade. Используемая вместе в действиями -U или, ещё лучше, -S, она обеспечивает тотальное обновление всей системы:

$ pacman -Su

Очевидно, что в этом случае требуется подключение к Сети для синхронизации с репозиториями Archlinux.

Для ознакомления с прочими опциями предлагается обратиться к тёте Мане — man pacman.

Настройка pacman

Выше я вскользь обмолвился, что для упрощения установки пакетов их следует разместить в должном месте. А место это определяется в файле конфигурации pacman/etc/pacman.conf.

Как и все а Archlinux, файл этот устроен очень просто и состоит из двух секций — общих настроек установки пакетов и списка репозиториев оных. К общим настройкам относятся:

IgnorePkg = pkg1 pkg2 ...

которой определяется список пакетов, не затрагиваемых при тотальном обновлении посредством pacman -Su;

NoUpgrade = etc/passwd etc/group etc/shadow...

содержащая список файлов, которые не должны перезаписываться ни при каких установках и обновлениях пакетов (в том числе и при тотальном апдейте); по умолчанию здесь, кроме указанных, перечислены все основные общесистемные конфиги типа etc/fstab, etc/rc.conf, etc/rc.local, и т.д.;

DBPath = /path/to/db/dir

путь к базе данных пакетов (по умолчанию — /var/lib/pacman);

NoPassiveFtp

отключение пассивного режима ftp-соединения (по умолчанию используется именно он — и это, товарищи, правильно в большинстве случае).

В списке репозиториев Arch’а указан главный ftp-сервер проекта

Server = ftp://ftp.archlinux.org/current

и все его зеркала. Списки можно задать отдельно для текущей ветки, стабильной, включить в него репозитории неофициальных пакетов. Наконец, можно задать и локальный репозиторий пакетов, например:

Server = local:///home/arch/pkg

Именно нахождение пакета в одном из репозиториев, перечисленных в файле /etc/pacman.conf, избавляет от необходимости указывать полный путь к файлу пакета, о чем говорилось ранее. Понятно, что установка пакета с ftp-сервера требует подключения к Сети. Локальный же репозиторий, куда можно разместить пакеты, скачанные заблаговременно, избавляет от этой необходимости.

Проблема зависимостей

Установка пакетов посредством pacman происходит фантастически быстро. Что, в общем-то, понятно: ведь pacman просто распаковывает архив пакета и записывает его прекомпилированные компоненты куда следует. Поскольку никакой метаинформации в пакете не содержится, то и отслеживания зависимостей как бы не происходит.

Тем не менее контроль зависимостей в системе управления пакетам Archlinux существует. Эта функция возложена на внешнюю (по отношению к каждому пакету) базу данных, расположенную в каталоге /var/lib/pacman/. Она включает в себя два подкаталога — /var/lib/pacman/current/ и /var/lib/pacman/local. В первом — база всех пакетов, охваченных дистрибутивом Arch Linux (вернее, официальной его частью). Она образована каталогами вида pkg-ver-rel (например, bash-2.05b-6 — приводимые ниже примеры относятся к этому пакету), в каждом из которых имеется по два файла: desc — краткое описание пакета в форме

%NAME%
bash

%VERSION%
2.05b-6

%DESC%
The GNU Bourne Again shell

и depends — список пакетов, с которыми данный связан зависимостями, а также, возможно, конфликтующих пакетов:

%DEPENDS%
glibc
grep
readline
ncurses

%CONFLICTS%

В каталоге /var/lib/pacman/local/, как следует из его названия, содержится база пакетов, установленных на данной машине. Он образован точно также, как и /var/lib/pacman/current/, однако в каталоге каждого пакета — уже по три файла: desc, depends и files.

Описание пакета в файле desc включает, помимо краткой информации (аналогичной описанию из current), также даты построения и установки пакета, имя сборщика (для официальной части им выступает обобщённый archlinux), и суммарный размер:

%NAME%
bash

%VERSION%
2.05b-6

%DESC%
The GNU Bourne Again shell

%URL%

%BUILDDATE%
Mon Jan 06 22:49:26 2003

%INSTALLDATE%
Wed Oct 22 08:14:09 2003

%PACKAGER%
Arch Linux (http://www.archlinux.org)

%SIZE%
1318400

В файле depends, кроме списка пакетов, от которых зависит данный, приведён и список пакетов, которые зависят от него:

%DEPENDS%
glibc
grep
readline
ncurses

%REQUIREDBY%
m4
diffutils
autoconf
automake
...

Наконец, files — это просто список всех компонентов пакета с указанием путей, по которым они размещаются при инсталляции:

%FILES%
bin/
bin/sh
bin/bash
etc/
etc/profile
usr/
usr/man/
usr/man/man1/
usr/man/man1/bash.1

В необходимых случаях тут же можно обнаружить и список файлов, подвергнутых изменению при установке пакета (в первую очередь это относится к общесистемным конфигам), с указанием исходных контрольных сумм:

%BACKUP%
etc/profile db618b683dee3f98f72bbb666ab0963c

Эта информация понадобится при удалении пакета командой pacman -R — для восстановления первозданной конфигурации системы (именно благодаря ей pacman способен к «чистой» деинсталляции пакетов).

Из структуры базы пакетов легко понять принцип контроля зависимостей в Archlinux: при установке нового пакета программа pacman сначала проверяет каталог /var/lib/pacman/current/ на предмет выявления его зависимостей, а потом — каталог /var/lib/pacman/local/ на предмет того, установлены ли пакеты, от которых зависит данный. Если все в порядке — пакет успешно устанавливается. Если же нет — выдаётся список имён недостающих пакетов (в порядке, котором они должны инсталлироваться) и работа pacman‘а завершается сообщением об ошибке. Никаких попыток разрешить нарушение зависимостей автоматически он не делает, оставляя это на долю пользователя.

Так что при установке пакета, зависимости для которого не выполнены, пользователь, получив соответствующий список, должен самостоятельно установить все недостающие компоненты. Причём с каждым из них возможно повторение истории — то есть нарушение зависимостей, которые должны разрешаться вручную.

Такая система может показаться не очень удобной. Хотя это гораздо лучше, чем классический rpm, где при нарушении зависимостей выдаётся что-нибудь типа недостачи библиотеки имя_рек.so.1 — и давай вычисляй, в состав какого пакета она входит. В Archlinux же вывод команды pacman выглядит примерно следующим образом:

pacman -A gnome-desktop-2.4.0-1.pkg.tar.gz           11:01 pts/2
error: unsatisfied dependencies:
gnome-desktop: requires libgnome
gnome-desktop: requires gnome-vfs

после чего недостающие пакеты (вместе с требуемым) легко установить одной командой.

Руки против автоматики

Тем не менее, в сравнении с такими как-бы «продвинутыми» системами управления пакетами, как apt или даже yum, pacman выглядит весьма примитивно. Однако это а) не так (потому что он не более чем дополнение к ABS), и б) имеет свои преимущества.

Об ABS речь впереди, а вот о преимуществах «ручного» подхода pacman (в CRUX принята примерно такая же система, да и pkg-tools из Slackware не сильно от них отличается) перед системами типа apt я хотел бы поговорить подробнее ввиду их не полной очевидности.

Что происходит, когда мы прибегаем к услугам apt или yum? Система пакетного менеджмента определяет, что для установки данного пакета не хватает таких-то компонентов, связанных с ним зависимостями, отыскивает их (на локальном носителе или в Сети), скачивает, устанавливает (вместе со всеми уже их зависимостями), после чего благополучно инсталлирует запрошенный пакет. Красота, да и только — «и не думать ничего, фюрер мыслит за него» (пардон, майнтайнер, разумеется).

Однако вспомним, что зависимости пакетов бывают двух родов: обязательные, или жесткие, и не обязательные, так сказать, «мягкие». Первые — объективная реальность, определяющая непременность их исполнения: никакую программу невозможно заставить работать без glibc (о статической линковке здесь не говорим), никакое X-приложение не будет функционировать без xlib, ни одна KDE-софтина не встанет без Qt и kdelibs.

«Мягкие» же зависимости к исполнению не обязательны, так как лишь обеспечивают пакету некоторые дополнительные функции, полезные, бесполезные, а то и откровенно вредные — причем понятие пользы и вреда тут откровенно субъективны. Так, большинство сборщиков links или mc полагают непременным условием их юзабильности поддержку gpm, мне же использование мыши как указательного устройства в этих приложениях представляется однозначно вредным. Я уж не говорю о том, что разрешение необязательных зависимостей приводит к захламлению файловой системы компонентами, о которых пользователь подчас не имеет ни малейшего представления (да и иметь не желает).

Так вот, в Archlinux пользователь, получив предупреждение о том, что нужный ему пакет требует того-то и того-то, при минимальном опыте (и некотором представлении о зависимостях) может определить, относятся ли навязываемые ему зависимости к числу «жестких», объективных, или «мягких», обусловленных субъективными представлениями сборщика пакета. И во втором случае — осознанно сделать выбор:

  • простоты ради согласиться со сделанным ему предложением (что, правда, приведет к захламлению системы),
  • отказаться от удовлетворения зависимостей посредством опции nodeps (в этом случае есть некоторый риск того, что пакет не будет функционировать должным образом — впрочем, для «мягких» зависимостей риск этот не слишком велик),
  • или просто плюнуть и собрать требуемый пакет из исходников вручную — только с теми with/without и enable/disable, которые ему действительно нужны.

Конечно, ручная сборка тоже имеет свои минусы. Установленные помимо системы пакетов программы не попадут в базу данных. И соответственно, если в дальнейшем придется устанавливать пакеты, зависящие от такого «самосборника», через систему pacman‘а, то он не будет обнаружен последним.

Впрочем, если рассматривать Archlinux как фундамент для построения собственной системы, ограничившись только компонентами base и все остальное собирая вручную — такой путь вполне приемлем. Если все же ориентироваться на смешанное его использование — критически важные компоненты собираются вручную, все остальные — устанавливаются из прекомпилированных пакетов, — то выход все равно остается. Поскольку база данных, используемая pacman‘ом, очень проста, никто не запрещает внести в нее сведения о «самосборном» пакете вручную (правда, здесь нет такого средства автоматизации этого процесса, как inject в Gentoo).

Впрочем, все сказанное о зависимостях относится только к случаю установки пакетов с локального носителя. И если пользоваться репозиториями пакетов с ftp-сервера проекта или его зеркал — силы не имеет. Потому что, как уже было сказано, простая команда pacman -Su выполнит полное обновление системы с разрешением всех зависимостей

Однако у пользователя Arch’а есть и еще одна, более интересная, возможность. И это — использование ABS (Arch Build System), системы построения пакетов, о которой пойдёт речь в следующей заметке.