8.2. Управление пакетами

Управление пакетами — часто спрашиваемое дополнение к книге LFS. Менеджер пакетов позволяет отслеживать установку файлов, что упрощает удаление и обновление пакетов. Помимо бинарных файлов и библиотек, менеджер пакетов будет выполнять установку файлов конфигурации. Прежде чем вы начнете задаваться вопросом, НЕТ—в этом разделе не будет ни говориться, ни рекомендоваться какой-либо конкретный менеджер пакетов. То, что здесь предоставлено, — это обзор наиболее популярных методов и того, как они работают. Идеальным менеджером пакетов для вас может быть один из этих методов или комбинация двух или более методов. В этом разделе кратко упоминаются проблемы, которые могут возникнуть при обновлении пакетов.

Некоторые причины, по которым менеджер пакетов не упоминается в LFS или BLFS представлены ниже:

Есть несколько советов, написанных на тему управления пакетами. Посетите проект Советы возможно вы найдете решение, которое соответствует вашим потребностям.

8.2.1. Проблемы с обновлением

Менеджер пакетов упрощает обновление до более новых версий после их выпуска. Как правило, инструкции в книгах LFS и BLFS можно использовать для обновления до более новых версий. Вот некоторые моменты, о которых следует помнить при обновлении пакетов, особенно в работающей системе.

  • Если нужно обновить ядро Linux (например, с 5.10.17 до 5.10.18 или 5.11.1), дополнительно пересобирать ничего не нужно. Система продолжит нормально работать благодаря четко определенной границе между ядром и пользовательским пространством. В частности, заголовки Linux API не нужно (и не следует, см. следующий пункт) обновлять вместе с ядром. Вам потребуется перезагрузить систему, чтобы использовать обновленное ядро.

  • Если необходимо обновить заголовочные файлы Linux API или Glibc до более новой версии (например, с glibc-2.31 до glibc-2.32), безопаснее заново собрать LFS. Хотя вы можете пересобрать все пакеты с их зависимостями, мы не рекомендуем этого делать.

  • Если пакет, содержащий общую библиотеку, обновляется и имя библиотеки изменилось, то любые пакеты, динамически связанные с библиотекой, необходимо перекомпилировать, чтобы связать с более новой библиотекой. (Обратите внимание, что между версией пакета и именем библиотеки нет никакой связи.) Например, рассмотрим пакет foo-1.2.3, который устанавливает общую библиотеку с именем libfoo.so.1. Если вы обновите пакет до более новой версии foo-1.2.4, которая устанавливает общую библиотеку с именем libfoo.so.2, все пакеты, которые динамически связаны с libfoo.so.1, должны быть перекомпилированы для связи с libfoo.so.2, чтобы использовать новую версию библиотеки. Вы не должны удалять предыдущие библиотеки, пока все зависимые пакеты не будут перекомпилированы.

  • Если пакет, содержащий общую библиотеку, обновляется, а имя библиотеки не меняется, но уменьшается номер версии файла библиотеки (например, имя библиотеки сохраняется с именем libfoo.so.1, но имя файла библиотеки изменилось с libfoo.so.1.25 на libfoo.so.1.24), следует удалить файл библиотеки из ранее установленной версии (в данном случае libfoo.so.1.25). Или запуск ldconfig (самостоятельно с помощью командной строки или путем установки какого-либо пакета) приведёт к сбросу символической ссылки libfoo.so.1, которая будет указывать на старый файл библиотеки, потому что кажется, что он имеет «более новую» версию, поскольку его номер версии больше. Такая ситуация может произойти, если вам нужно понизить версию пакета или пакет внезапно меняет схему управления версиями файлов библиотеки.

  • Если пакет, содержащий общую библиотеку, обновляется, а имя библиотеки не меняется, но устраняется серьезная проблема (особенно уязвимость в системе безопасности), необходимо перезапустить все работающие программы, связанные с общей библиотекой. Следующая команда, запущенная от имени пользователя root после обновления, выведет список программ, которые использует старые версии этих библиотек (замените libfoo именем библиотеки):

    grep -l -e 'libfoo.*deleted' /proc/*/maps |
       tr -cd 0-9\\n | xargs -r ps u

    Если для доступа к системе используется OpenSSH и он связан с обновленной библиотекой, вам необходимо перезапустить службу sshd, затем выйти из системы, снова войти в систему и повторно запустить эту команду, чтобы убедиться, что удаленные библиотеки более не используются.

    Если демон systemd (работающий как PID 1) связан с обновленной библиотекой, вы можете перезапустить его без перезагрузки, запустив systemctl daemon-reexec от имени пользователя root.

  • Если бинарный файл или библиотека перезаписаны, процессы, использующие код или данные из них, могут завершиться сбоем. Правильный способ обновить бинарный файл или общую библиотеку, не вызывая сбоя процесса, - это сначала удалить его, а затем установить новую версию. Команда install, предоставляемая Coreutils, уже реализовала это, и большинство пакетов используют ее для установки бинарных файлов и библиотек. Это означает, что большую часть времени вас не будет беспокоить эта проблема. Однако процесс установки некоторых пакетов (в частности, Mozilla JS в BLFS) просто перезаписывает файл, если он существует, и вызывает сбой, поэтому безопаснее сохранить вашу работу и закрыть ненужные запущенные программы перед обновлением пакета.

8.2.2. Методы управления пакетами

Ниже приведены некоторые распространенные методы управления пакетами. Прежде чем принять решение о менеджере пакетов, изучите различные методы, особенно их недостатки.

8.2.2.1. Всё у меня в голове!

Да, это метод управления пакетами. Некоторым людям не нужен менеджер пакетов, потому что они хорошо знакомы с пакетами и знают, какие файлы устанавливаются каждым пакетом. Некоторым пользователям также не требуется какое-либо управление пакетами, поскольку они планируют пересобрать всю систему при изменении пакета.

8.2.2.2. Установка в отдельные каталоги

Это упрощенное управление пакетами, которое не требует дополнительных пакетов для управления установками. Каждый пакет устанавливается в отдельный каталог. Например, пакет foo-1.1 устанавливается в /usr/pkg/foo-1.1, а символическая ссылка создается из /usr/pkg/foo в /usr/pkg/foo-1.1. При установке новой версии foo-1.2 она устанавливается в /usr/pkg/foo-1.2 и предыдущая символическая ссылка заменяется символической ссылкой на новую версию.

Переменные окружения, такие как PATH, LD_LIBRARY_PATH, MANPATH, INFOPATH и CPPFLAGS необходимо расширить, включив каталог /usr/pkg/foo. Для большого количества пакетов, такая схема становится неуправляемой.

8.2.2.3. Управление пакетами с использованием символических ссылок

Это разновидность предыдущей техники.Каждый пакет устанавливается аналогично, но вместо создания символической ссылки, каждому файлу создаётся символическая ссылка в иерархию каталогов /usr. Это исключает необходимость модификации значений переменных окружения. Хотя такие ссылки могут быть созданы пользователям, который может автоматизировать их создания, многие менеджеры пакетов были созданы с использованием именной такого подхода. Наиболее популярные из них - Stow, Epkg, Graft, и Depot.

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

./configure --prefix=/usr/pkg/libfoo/1.1
make
make install

Установка будет выполнена, но зависимые пакеты не смогут ссылаться на libfoo. Если вы скомпилируете пакет, который ссылается на libfoo, вы заметите, что он связан с /usr/pkg/libfoo/1.1/lib/libfoo.so.1 вместо /usr/lib/libfoo.so.1, как вы ожидаете. Правильный подход — использовать стратегию DESTDIR для имитации установки пакета. Этот подход работает следующим образом:

./configure --prefix=/usr
make
make DESTDIR=/usr/pkg/libfoo/1.1 install

Большинство пакетов поддерживают этот подход, но есть и такие, которые этого не делают. Для несовместимых пакетов вам может потребоваться либо установить пакет вручную, либо вы можете решить, что некоторые проблемные пакеты проще установить в /opt.

8.2.2.4. На основе временной метки

В этом методе файлу присваивается временная метка перед установкой пакета. После установки простое использование команды find с соответствующими параметрами может создать журнал всех файлов, установленных после создания файла с временной метки. Менеджер пакетов, написанный с использованием этого подхода, называетсяs install-log.

Хотя преимущество этой схемы в том, что она проста, у нее есть два недостатка. Если во время установки, файлы устанавливаются с отметкой времени, отличной от текущего времени, эти файлы не будут отслеживаться менеджером пакетов. Кроме того, эта схема может использоваться только при установке одного пакета за раз. Журналы ненадежны, если два пакета устанавливаются на двух разных консолях.

8.2.2.5. Отслеживание сценариев установки

При таком подходе, записываются команды, выполняемые сценариями установки. Есть два метода, которые можно использовать:

Переменная среды LD_PRELOAD может быть установлена так, чтобы она указывала на библиотеку, которую нужно предварительно загрузить перед установкой. Во время установки эта библиотека отслеживает устанавливаемые пакеты, присоединяясь к различным исполняемым файлам, таким как cp, install, mv, и отслеживая системные вызовы, изменяющие файловую систему. Чтобы этот подход работал, все исполняемые файлы должны быть динамически связаны без битов suid или sgid. Предварительная загрузка библиотеки может вызвать некоторые нежелательные побочные эффекты во время установки. Поэтому рекомендуется выполнить некоторые тесты, чтобы убедиться, что менеджер пакетов ничего не сломает и зарегистрирует все соответствующие файлы.

Второй метод заключается в использовании strace, который регистрирует все системные вызовы, сделанные во время выполнения сценариев установки.

8.2.2.6. Создание архивов пакетов

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

Этот подход используется большинством менеджеров пакетов, имеющихся в коммерческих дистрибутивах. Примерами менеджеров пакетов, которые следуют этому подходу, являются RPM (который, кстати, требуется согласно спецификации Linux Standard Base Specification), pkg-utils, apt Debian и система Portage Gentoo. Описание того, как использовать этот стиль управления пакетами для систем LFS, находится по адресу https://mirror.linuxfromscratch.ru/hints/downloads/files/fakeroot.txt.

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

Slackware использует систему на основе tar для архивов пакетов. Эта система намеренно не обрабатывает зависимости пакетов, как это делают более сложные менеджеры пакетов. Подробнее об управлении пакетами Slackware см. https://www.slackbook.org/html/package-management.html.

8.2.2.7. Пользовательское управление пакетами

Эта схема, уникальная для LFS, была разработана Маттиасом Бенкманом и доступна в проекте Hints. В этой схеме каждый пакет устанавливается отдельным пользователем в стандартные папки. Файлы, принадлежащие пакету, легко идентифицируются путем проверки идентификатора пользователя. Особенности и недостатки этого подхода слишком сложны, чтобы описывать их в этом разделе. Для получения более подробной информации, пожалуйста, ознакомьтесь с советами по адресу https://mirror.linuxfromscratch.ru/hints/downloads/files/more_control_and_pkg_man.txt.

8.2.3. Развертывание LFS на нескольких системах

Одним из преимуществ системы LFS является отсутствие файлов, зависящих от положения файлов на диске. Клонировать сборку LFS на другой компьютер с той же архитектурой, что и у базовой системы, так же просто, как использовать tar для архивации раздела LFS, содержащем корневой каталог (около 250 МБ в несжатом виде для базовой сборки LFS), скопировать этот файл по сети или с помощью компакт-диска в новую систему и распаковать его. Далее, необходимо будет изменить несколько файлов конфигурации. Файлы конфигурации, которые, возможно, потребуется изменить, включают: /etc/hosts, /etc/fstab, /etc/passwd, /etc/group, /etc/shadow, и /etc/ld.so.conf.

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

[Примечание]

Примечание

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

Наконец, новую систему необходимо сделать загрузочной так, как это описано в Раздел 10.4, «Использование GRUB для настройки процесса загрузки».