lfs-ru/chapter08/pkgmgt.xml
2023-05-26 02:07:20 +05:00

336 lines
27 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % general-entities SYSTEM "../general.ent">
%general-entities;
]>
<sect1 id="ch-system-pkgmgt">
<?dbhtml filename="pkgmgt.html"?>
<title>Управление пакетами</title>
<para>Управление пакетами — часто спрашиваемое дополнение к книге LFS. Менеджер
пакетов позволяет отслеживать установку файлов, что упрощает удаление и обновление
пакетов. Помимо бинарных файлов и библиотек, менеджер пакетов будет выполнять
установку файлов конфигурации. Прежде чем вы начнете задаваться вопросом,
НЕТ&mdash;в этом разделе не будет ни говориться, ни рекомендоваться какой-либо
конкретный менеджер пакетов. То, что здесь предоставлено, — это обзор наиболее
популярных методов и того, как они работают. Идеальным менеджером пакетов для вас
может быть один из этих методов или комбинация двух или более методов.
В этом разделе кратко упоминаются проблемы, которые могут возникнуть при
обновлении пакетов.</para>
<para>Некоторые причины, по которым менеджер пакетов не упоминается в LFS или BLFS
представлены ниже:</para>
<itemizedlist>
<listitem>
<para>Рассмотрение управления пакетами отвлекает внимание от целей этих
книг&mdash;обучения тому, как строится система Linux</para>
</listitem>
<listitem>
<para>Существует множество решений для управления пакетами, каждое из
которых имеет свои сильные и слабые стороны. Трудно найти такое,
которое удовлетворит всех</para>
</listitem>
</itemizedlist>
<para>Есть несколько советов, написанных на тему управления пакетами. Посетите
проект <ulink url="&hints-root;">Советы</ulink> возможно вы найдете решение,
которое соответствует вашим потребностям.</para>
<sect2 id='pkgmgmt-upgrade-issues'>
<title>Проблемы с обновлением</title>
<para>Менеджер пакетов упрощает обновление до более новых версий после их
выпуска. Как правило, инструкции в книгах LFS и BLFS можно использовать для
обновления до более новых версий. Вот некоторые моменты, о которых следует
помнить при обновлении пакетов, особенно в работающей системе.</para>
<itemizedlist>
<listitem>
<para>Если нужно обновить ядро Linux (например, с 5.10.17 до 5.10.18 или
5.11.1), дополнительно пересобирать ничего не нужно. Система продолжит
нормально работать благодаря четко определенной границе между ядром и
пользовательским пространством. В частности, заголовки Linux API не нужно
(и не следует, см. следующий пункт) обновлять вместе с ядром. Вам потребуется
перезагрузить систему, чтобы использовать обновленное ядро.</para>
</listitem>
<listitem>
<para>Если необходимо обновить заголовочные файлы Linux API или Glibc до
более новой версии (например, с glibc-2.31 до glibc-2.32), безопаснее заново
собрать LFS. Хотя вы <emphasis>можете</emphasis> пересобрать все пакеты с их
зависимостями, мы не рекомендуем этого делать.</para>
</listitem>
<listitem> <para>Если пакет, содержащий общую библиотеку, обновляется и имя
библиотеки изменилось, то любые пакеты, динамически связанные с библиотекой,
необходимо перекомпилировать, чтобы связать с более новой библиотекой.
(Обратите внимание, что между версией пакета и именем библиотеки нет никакой
связи.) Например, рассмотрим пакет foo-1.2.3, который устанавливает общую
библиотеку с именем <filename class='libraryfile'>libfoo.so.1</filename>.
Если вы обновите пакет до более новой версии foo-1.2.4, которая устанавливает
общую библиотеку с именем <filename class='libraryfile'>libfoo.so.2</filename>,
все пакеты, которые динамически связаны с <filename class='libraryfile'>libfoo.so.1</filename>,
должны быть перекомпилированы для связи с <filename class='libraryfile'>libfoo.so.2</filename>,
чтобы использовать новую версию библиотеки. Вы не должны удалять предыдущие
библиотеки, пока все зависимые пакеты не будут перекомпилированы.</para>
</listitem>
<listitem> <para>Если пакет, содержащий общую библиотеку, обновляется, а имя
библиотеки не меняется, но уменьшается номер версии <emphasis role="bold">файла</emphasis>
библиотеки (например, имя библиотеки сохраняется с именем
<filename class='libraryfile'>libfoo.so.1</filename>, но имя файла библиотеки изменилось с
<filename class='libraryfile'>libfoo.so.1.25</filename> на
<filename class='libraryfile'>libfoo.so.1.24</filename>), следует удалить файл
библиотеки из ранее установленной версии (в данном случае
<filename class='libraryfile'>libfoo.so.1.25</filename>). Или запуск <command>ldconfig</command>
(самостоятельно с помощью командной строки или путем установки какого-либо пакета)
приведёт к сбросу символической ссылки <filename class='libraryfile'>libfoo.so.1</filename>,
которая будет указывать на старый файл библиотеки, потому что кажется, что он имеет
<quote>более новую</quote> версию, поскольку его номер версии больше. Такая ситуация
может произойти, если вам нужно понизить версию пакета или пакет внезапно меняет
схему управления версиями файлов библиотеки.</para></listitem>
<listitem><para>Если пакет, содержащий общую библиотеку, обновляется, а имя библиотеки
не меняется, но устраняется серьезная проблема (особенно уязвимость в системе безопасности),
необходимо перезапустить все работающие программы, связанные с общей библиотекой. Следующая
команда, запущенная от имени пользователя <systemitem class="username">root</systemitem> после
обновления, выведет список программ, которые использует старые версии этих библиотек
(замените <replaceable>libfoo</replaceable> именем библиотеки):</para>
<screen role="nodump"><userinput>grep -l -e '<replaceable>libfoo</replaceable>.*deleted' /proc/*/maps |
tr -cd 0-9\\n | xargs -r ps u</userinput></screen>
<para>
Если для доступа к системе используется <application>OpenSSH</application> и он
связан с обновленной библиотекой, вам необходимо перезапустить службу
<command>sshd</command>, затем выйти из системы, снова войти в систему и повторно
запустить эту команду, чтобы убедиться, что удаленные библиотеки более не используются.
</para>
<para revision='systemd'>
Если демон <command>systemd</command> (работающий как PID 1) связан с обновленной
библиотекой, вы можете перезапустить его без перезагрузки, запустив
<command>systemctl daemon-reexec</command> от имени пользователя
<systemitem class='username'>root</systemitem>.
</para></listitem>
<listitem>
<para>Если бинарный файл или библиотека перезаписаны, процессы, использующие код
или данные из них, могут завершиться сбоем. Правильный способ обновить бинарный
файл или общую библиотеку, не вызывая сбоя процесса, - это сначала удалить его,
а затем установить новую версию. Команда <command>install</command>,
предоставляемая <application>Coreutils</application>, уже реализовала это, и
большинство пакетов используют ее для установки бинарных файлов и библиотек.
Это означает, что большую часть времени вас не будет беспокоить эта проблема.
Однако процесс установки некоторых пакетов (в частности, Mozilla JS в BLFS)
просто перезаписывает файл, если он существует, и вызывает сбой, поэтому
безопаснее сохранить вашу работу и закрыть ненужные запущенные процессы перед
обновлением пакета.</para>
</listitem>
</itemizedlist>
</sect2>
<sect2>
<title>Методы управления пакетами</title>
<para>Ниже приведены некоторые распространенные методы управления пакетами. Прежде
чем принять решение о менеджере пакетов, изучите различные методы, особенно их недостатки.</para>
<sect3>
<title>Всё у меня в голове!</title>
<para>Да, это метод управления пакетами. Некоторым людям не нужен менеджер пакетов,
потому что они хорошо знакомы с пакетами и знают, какие файлы устанавливаются
каждым пакетом. Некоторым пользователям также не требуется какое-либо управление
пакетами, поскольку они планируют пересобрать всю систему при изменении пакета.</para>
</sect3>
<sect3>
<title>Установка в отдельные каталоги</title>
<para>Это упрощенное управление пакетами, которое не требует дополнительных
пакетов для управления установками. Каждый пакет устанавливается в отдельный
каталог. Например, пакет foo-1.1 устанавливается в
<filename class='directory'>/usr/pkg/foo-1.1</filename>, а символическая ссылка
создается из <filename>/usr/pkg/foo</filename> в
<filename class='directory'>/usr/pkg/foo-1.1</filename>. При установке новой
версии foo-1.2 она устанавливается в <filename class='directory'>/usr/pkg/foo-1.2</filename>
и предыдущая символическая ссылка заменяется символической ссылкой на новую версию.</para>
<para>Переменные окружения, такие как <envar>PATH</envar>,
<envar>LD_LIBRARY_PATH</envar>,<envar>MANPATH</envar>,<envar>INFOPATH</envar>
и <envar>CPPFLAGS</envar> необходимо расширить, включив каталог
<filename>/usr/pkg/foo</filename>. Для большого количества пакетов, такая
схема становится неуправляемой.</para>
</sect3>
<sect3>
<title>Управление пакетами с использованием символических ссылок</title>
<para>Это разновидность предыдущей техники.Каждый пакет устанавливается аналогично,
но вместо создания символической ссылки, каждому файлу создаётся
символическая ссылка в иерархию каталогов <filename class='directory'>/usr</filename>.
Это исключает необходимость модификации значений переменных окружения. Хотя такие
ссылки могут быть созданы пользователям, который может автоматизировать их создания,
многие менеджеры пакетов были созданы с использованием именной такого подхода.
Наиболее популярные из них - Stow, Epkg, Graft, и Depot.</para>
<para>Установку нужно сымитировать, чтобы пакет думал, что он установлен в
<filename class="directory">/usr</filename>, хотя на самом деле он установлен в
иерархии <filename class="directory">/usr/pkg</filename>. Установка таким
способом обычно является нетривиальной задачей. Например, предположим, что
вы устанавливаете пакет libfoo-1.1. Следующие инструкции могут привести к
неправильной установке пакета:</para>
<screen role="nodump"><userinput>./configure --prefix=/usr/pkg/libfoo/1.1
make
make install</userinput></screen>
<para>Установка будет выполнена, но зависимые пакеты не смогут ссылаться на libfoo.
Если вы скомпилируете пакет, который ссылается на libfoo, вы заметите, что он
связан с <filename class='libraryfile'>/usr/pkg/libfoo/1.1/lib/libfoo.so.1</filename>
вместо <filename class='libraryfile'>/usr/lib/libfoo.so.1</filename>, как вы
ожидаете. Правильный подход — использовать стратегию <envar>DESTDIR</envar> для
имитации установки пакета. Этот подход работает следующим образом:</para>
<screen role="nodump"><userinput>./configure --prefix=/usr
make
make DESTDIR=/usr/pkg/libfoo/1.1 install</userinput></screen>
<para>Большинство пакетов поддерживают этот подход, но есть и такие, которые
этого не делают. Для несовместимых пакетов вам может потребоваться либо установить
пакет вручную, либо вы можете решить, что некоторые проблемные пакеты проще
установить в <filename class='directory'>/opt</filename>.</para>
</sect3>
<sect3>
<title>На основе временной метки</title>
<para>В этом методе файлу присваивается временная метка перед установкой пакета.
После установки простое использование команды <command>find</command> с
соответствующими параметрами может создать журнал всех файлов, установленных
после создания файла с временной метки. Менеджер пакетов, написанный с
использованием этого подхода, называетсяs install-log.</para>
<para>Хотя преимущество этой схемы в том, что она проста, у нее есть два
недостатка. Если во время установки, файлы устанавливаются с отметкой времени,
отличной от текущего времени, эти файлы не будут отслеживаться менеджером пакетов.
Кроме того, эта схема может использоваться только при установке одного пакета
за раз. Журналы ненадежны, если два пакета устанавливаются на двух разных консолях.</para>
</sect3>
<sect3>
<title>Отслеживание сценариев установки</title>
<para>При таком подходе, записываются команды, выполняемые сценариями установки.
Есть два метода, которые можно использовать:</para>
<para>Переменная среды <envar>LD_PRELOAD</envar> может быть установлена так,
чтобы она указывала на библиотеку, которую нужно предварительно загрузить
перед установкой. Во время установки эта библиотека отслеживает устанавливаемые
пакеты, присоединяясь к различным исполняемым файлам, таким как <command>cp</command>,
<command>install</command>, <command>mv</command>, и отслеживая системные вызовы,
изменяющие файловую систему. Чтобы этот подход работал, все исполняемые файлы
должны быть динамически связаны без битов suid или sgid. Предварительная загрузка
библиотеки может вызвать некоторые нежелательные побочные эффекты во время
установки. Поэтому рекомендуется выполнить некоторые тесты, чтобы убедиться, что
менеджер пакетов ничего не сломает и зарегистрирует все соответствующие файлы.</para>
<para>Второй метод заключается в использовании <command>strace</command>, который
регистрирует все системные вызовы, сделанные во время выполнения сценариев установки.</para>
</sect3>
<sect3>
<title>Создание архивов пакетов</title>
<para>В этой схеме установка пакета осуществляется фиктивно в отдельное дерево так,
как описано в разделе управления пакета с использованием символических ссылок.
После установки из установленных файлов создается архив пакета. Затем этот архив
используется для установки пакетов либо на локальной машине, либо может быть
использован для установки пакета на других машинах.</para>
<para>Этот подход используется большинством менеджеров пакетов, имеющихся в
коммерческих дистрибутивах. Примерами менеджеров пакетов, которые следуют этому
подходу, являются RPM (который, кстати, требуется согласно спецификации <ulink
url="http://refspecs.linuxfoundation.org/lsb.shtml">Linux
Standard Base Specification</ulink>), pkg-utils, apt Debian и система Portage
Gentoo. Описание того, как использовать этот стиль управления пакетами для систем
LFS, находится по адресу <ulink url="&hints-root;fakeroot.txt"/>.</para>
<para>Создание файлов пакетов, содержащих информацию о зависимостях, является
сложной задачей и выходит за рамки LFS.</para>
<para>Slackware использует систему на основе <command>tar</command> для архивов
пакетов. Эта система намеренно не обрабатывает зависимости пакетов, как это
делают более сложные менеджеры пакетов. Подробнее об управлении пакетами Slackware
см. <ulink url="http://www.slackbook.org/html/package-management.html"/>.</para>
</sect3>
<sect3>
<title>Пользовательское управление пакетами</title>
<para>Эта схема, уникальная для LFS, была разработана Маттиасом Бенкманом и доступна
в проекте <ulink url="&hints-root;">Hints</ulink>. В этой схеме каждый пакет
устанавливается отдельным пользователем в стандартные папки. Файлы, принадлежащие
пакету, легко идентифицируются путем проверки идентификатора пользователя. Особенности
и недостатки этого подхода слишком сложны, чтобы описывать их в этом разделе. Для
получения более подробной информации, пожалуйста, ознакомьтесь с советами по адресу
<ulink url="&hints-root;more_control_and_pkg_man.txt"/>.</para>
</sect3>
</sect2>
<sect2>
<title>Развертывание LFS на нескольких системах</title>
<para>Одним из преимуществ системы LFS является отсутствие файлов, зависящих от
положения файлов на диске. Клонировать сборку LFS на другой компьютер с той же
архитектурой, что и у базовой системы, так же просто, как использовать
<command>tar</command> для архивации раздела LFS, содержащем корневой каталог
(около 250 МБ в несжатом виде для базовой сборки LFS), скопировать этот файл
по сети или с помощью компакт-диска в новую систему и распаковать его. Далее,
необходимо будет изменить несколько файлов конфигурации. Файлы конфигурации,
которые, возможно, потребуется изменить, включают:
<filename>/etc/hosts</filename>,
<filename>/etc/fstab</filename>,
<filename>/etc/passwd</filename>,
<filename>/etc/group</filename>,
<phrase revision="systemd">
<filename>/etc/shadow</filename>, и
<filename>/etc/ld.so.conf</filename>.
</phrase>
<phrase revision="sysv">
<filename>/etc/shadow</filename>,
<filename>/etc/ld.so.conf</filename>,
<filename>/etc/sysconfig/rc.site</filename>,
<filename>/etc/sysconfig/network</filename>, и
<filename>/etc/sysconfig/ifconfig.eth0</filename>.
</phrase>
</para>
<para>Возможно, потребуется собрать собственное ядро для новой системы в зависимости
от различий в системном оборудовании и исходной конфигурации ядра.</para>
<note><para>Поступали некоторые сообщения о проблемах при копировании между похожими,
но не идентичными архитектурами. Например, набор инструкций для Intel не идентичен
набору инструкций для процессора AMD, и более поздние версии некоторых процессоров
могут содержать инструкции, недоступные в более ранних версиях.</para></note>
<para>Наконец, новую систему необходимо сделать загрузочной так, как это описано в <xref
linkend="ch-bootable-grub"/>.</para>
</sect2>
</sect1>