Differences between revisions 14 and 15
Revision 14 as of 2008-07-30 12:11:39
Size: 25552
Comment:
Revision 15 as of 2008-07-30 22:39:42
Size: 25247
Comment:
Deletions are marked like this. Additions are marked like this.
Line 84: Line 84:
Осталась рассмотреть проблему конфликтов. Может получиться, что два разных пакета содержат один и тот же файл (т.е. тот, который будет помещён в одну и ту же директорию под одним и тем же названием). Этот конфликт паразитный - было бы неплохо, чтобы два ментейнера договорились, как они будут разруливать эту ситуацию. Наиболее частый пример --- cdrecord. Это утилита для записи лазерных дисков с командной строки. Он существует в двух вариантах: тот, который пишет Йорг Шиллинг, и тот, который пишет сообщество, которое в какой-то момент взяло исходный код и начало модифицировать его самостоятельно (потому, что Йорг боится патентных преследований и отказывается распространять под свободной лицензией версию cdrecord'а, которая может писать на dvd, который в некоторых странах как таковой защищён патентом). Поэтому есть два варианта cdrecord'а: один называется cdrecord classic, а другой - dvdrecord. Проблема в том, что у этих программ разный синтаксис ключей, и вы можете захотеть, чтобы у вас был cdrecord classic, чтобы работали какие-то штуки, которые используют его ключи. Осталось только выяснить, кто из них называется cdrecord. Если в системе стоят оба пакета, то в /usr/bin лежит символьная ссылка, которая всегда смотрит на один из двух вариантов, а специальная утилита alternatives позволяет переключать либо туда, либо сюда. Осталась рассмотреть проблему конфликтов. Может получиться, что два разных пакета содержат один и тот же файл (т.е. тот, который будет помещён в одну и ту же директорию под одним и тем же названием). Этот конфликт паразитный - было бы неплохо, чтобы два ментейнера договорились, как они будут разруливать эту ситуацию. Наиболее частый пример --- cdrecord. Это утилита для записи лазерных дисков с командной строки. Он существует в двух вариантах: тот, который пишет Йорг Шиллинг, и тот, который пишет сообщество, которое в какой-то момент взяло исходный код и начало модифицировать его самостоятельно (потому, что Йорг боится патентных преследований и отказывается распространять под свободной лицензией версию cdrecord'а, которая может писать на dvd, который в некоторых странах как таковой защищён патентом). Поэтому есть два варианта cdrecord'а: один называется cdrecord classic, а другой - dvdrecord. Проблема в том, что у этих программ разный синтаксис ключей, и вы можете захотеть, чтобы у вас был cdrecord classic, чтобы работали какие-то штуки, которые используют его ключи. Осталось только выяснить, кто из них называется cdrecord. Если в системе стоят оба пакета, то в /usr/bin лежит символьная ссылка, которая всегда ведет в один из двух вариантов, а специальная утилита alternatives позволяет переключаться между ними.
Line 86: Line 86:
Чтобы добить тему конфликтов. Бывает, что конфликт необходимо обеспечить. Например, у вас есть два почтовых сервера, и вы оба хотите установить. По-хорошему, этого делать не надо, поскольку тот и другой будут пытаться принимать соединения по двадцать пятому порту, и первый из них, который запустится, будет это делать, а второй не сможет это сделать и будет выдавать ошибку. При этом, предположим ситуацию, что конфликта по файлам между этими пакетами не существует. Было бы неплохо этот конфликт вписать в пакеты заранее. Это делается следующим образом: каждый пакет объявляет, какие функции он обеспечивает. Если вы попытаетесь установить два пакета, которые обеспечивают одинаковую функциональность, то есть у них поле provides где-то пересекается, вам ничего не дадут сделать, даже если конфликта по файлам нет, потому что так изначально было задумано, ибо эти два пакета изначально не функционируют в системе. Так что конфликт может быть не только результатом недосмотра двух мейнтейнеров, но и сознательно сделанной мейнтейнерами штукой, не позволяющей вам убить или наполнить мусором систему.  Бывает так, что конфликт необходимо обеспечить. Например, у вас есть два почтовых сервера, и вы оба хотите установить. В прицнипе, этого делать не надо, поскольку оба они будут пытаться принимать соединения по двадцать пятому порту, и первый из них, который запустится, будет это делать, а второй не сможет это сделать и будет выдавать ошибку. При этом, предположим ситуацию, что конфликта по файлам между этими пакетами не существует. Однако рационально этот конфликт вписать в пакеты заранее. Это делается следующим образом: каждый пакет объявляет, какие функции он обеспечивает. Если вы попытаетесь установить два пакета, которые обеспечивают одинаковую функциональность, то есть у них поле provides в чем-то совпадает, вам ничего не дадут сделать, даже если конфликта по файлам нет. Таким образом, конфликт может быть не только результатом недосмотра двух мейнтейнеров, но и сознательно введенным механизмом, оптимизирующим работу системы.
Line 94: Line 94:
|| 42 || 1 || 1 || 1 || || 1 || ConstantinYershow, ОльгаТочилкина, MaximByshevskiKonopko || || || || 45 || 1 || 1 || 1 || || 1 || ConstantinYershow, ОльгаТочилкина, MaximByshevskiKonopko || || ||

Пакет

Переходим к пакетам. Обратимся сначала к истории их появления. Итак, в подавляющем большинстве случаев Вы скачиваете пакет не с сайта продукта, а берёте из хранилища, которое поддерживается сообществом. В хранилище пакет появился благодаря ментейнеру, который скачал исходные тексты, оформил их в соответствии с дисциплиной сборки программных продуктов в хранилище, собрал, т.е. получил бинарный продукт. В результате в хранилище появились: пакет с исходным кодом, src.rpm (авторские исходники + инструкция по сборке + так называемые патчи, т.е. модификации, накладываемые на авторские исходники + некие дополнительные файлы, которые мейнтейнер посчитал нужным вставить в результирующий программный продукт) и пакет с бинарными файлами.

Пакет, который Вы нашли в хранилище, адаптирован к использованию в семействе операционных систем, сделанных на основе соответствующей ветки. Это означает, что люди, планирующие пакет, могут воспользоваться тем, что в Вашем GNU/Linux дистрибутиве все каталоги стандартизированы согласно Filesystem Hierarchy Standard (FHS) --- стандарту, описывающему, какого рода файлы должны находиться в том или ином каталоге. Таким образом, для того, чтобы установить заранее протестированный и адаптированный программный продукт, достаточно его распаковать архив. В отличие от операционной системы Windows, где программный продукт --- это инсталлятор, т.е. программа, которую вы запускаете, и она делает нечто малопонятное, в нашем случае пакет --- это архив типа rpm, и для того, чтобы его установить, достаточно его просто распаковать:

[george@class305 ~]$ rpm2cpio zip-2.32-alt2.S40.1.i586.rpm | cpio -itv
-rwxr-xr-x   1 root     root        66808 Jun 25 17:16 ./usr/bin/zip
-rwxr-xr-x   1 root     root        26616 Jun 25 17:16 ./usr/bin/zipcloak
-rwxr-xr-x   1 root     root        22548 Jun 25 17:16 ./usr/bin/zipnote
-rwxr-xr-x   1 root     root        26580 Jun 25 17:16 ./usr/bin/zipsplit
drwxr-xr-x   2 root     root            0 Jun 25 17:16 ./usr/share/doc/zip-2.32
-rw-r--r--   1 root     root          401 May 18  2006 ./usr/share/doc/zip-2.32/BUGS
-rw-r--r--   1 root     root        77392 Jun 20  2006 ./usr/share/doc/zip-2.32/CHANGES
-rw-r--r--   1 root     root         2692 Apr 10  2000 ./usr/share/doc/zip-2.32/LICENSE
-rw-r--r--   1 root     root        42404 Jun 20  2006 ./usr/share/doc/zip-2.32/MANUAL
-rw-r--r--   1 root     root         8674 Apr 14  2006 ./usr/share/doc/zip-2.32/README
-rw-r--r--   1 root     root         3149 Feb 21  2005 ./usr/share/doc/zip-2.32/TODO
-rw-r--r--   1 root     root         3382 Jun 20  2006 ./usr/share/doc/zip-2.32/WHATSNEW
-rw-r--r--   1 root     root        19032 Apr 19  2000 ./usr/share/doc/zip-2.32/WHERE
-rw-r--r--   1 root     root        12398 Jun 20  2006 ./usr/share/man/man1/zip.1.bz2
614 blocks

Итак, мы скачали пакет и применили к нему утилиту rpm2cpio, которая превратила его в cpio-архив. Во-первых, она его распаковывает, а во-вторых, удаляет дополнительную информацию. Как уже было сказано выше, пакет представляет собой просто архив. Обратите внимание, что внутри пакета также соблюдаются требования стандарта FHS: в /usr/bin/ находятся бинарные файлы, в /usr/share/doc/ --- документация, в /usr/share/man/ --- страница помощи. Обратите внимание, что в начале пути стоит точка: если бы мы его сейчас разархивировали, он бы разархивировался в текущий каталог, а не в корень, и не прибил бы наш зип. Для того, чтобы установить программный продукт, его надо только разархивировать. Это за нас сделает установщик. Так что ничего тайного здесь нет; всё стандартизовано. Отметим, что в Slackware пакет представляет собой обычный tar-архив, что делает процесс установки еще более простым. Однако возникает вопрос: что делать, если есть ещё один пакет, в котором тоже есть файл /usr/bin/zip? Необходимо понять, как такое могло произойти. У нас есть хранилище, в котором все пакеты лежат одновременно. Чтобы сделать так, чтобы в нем находились два конфликтующих по файлам (устанавливающих файл с одним и тем же именем) пакета, надо осознанно принять такое решение, потому что отследить, что два программных продукта направляют в одно и то же место два файла с одинаковыми именами, легко. Более того, есть ситуации, когда такой конфликт предпочтителен, чтобы нельзя было поставить два программных продукта, которые делают одни и те же операции.

Регистрация

Однако установка програмного продукта включается в себя не только распаковку архива. При установке пакетов нельзя забывать о том, что, возможно, нам придется их в будущем удалить. Что такое удаление? Это удаление собственно разархивированных файлов. Это значит, что при установке происходит регистрация собственно факта установки и создается список установленных файлов. Таким образом, если мы захотим удалить программный продукт, мы обратимся к базе данных, где содержится информация о том, какие файлы тому или иному пакету принадлежат. Эту функцию выполняет программа rpm:

$ rpmquery -f /usr/bin/zip
zip-2.32-alt1.0

Обратите внимание, что здесь присутствуют разные пакеты: в системе установлен zip-2.32-alt1.0, а в апдейтах (откуда был скачан пакет из предыдущего примера) лежит zip-2.32-alt2.S40.1. Куда rpm смотрит? В некую базу данных установленных пакетов.

Контрольная сумма

При регистрации происходят еще два важных процесса. Во-первых, для каждого файла запоминается (или берётся из пакета) контрольная сумма. Это необходимо, чтобы определить, изменился ли файл, входящий в пакет, или нет. Зачем это нужно? Допустим, у Вас есть программа pswd, с её помощью Вы меняете пароли, и в какой-то момент Вы запускаете утилиту, которая проверяет, не изменилась ли контрольная сумма программы pswd и выясняется, что она изменилась. Это серьёзный повод для беспокойства и переустановки операционной системы, потому что если кто-то подменил вам программу pswd, безопасность Вашего компьютера под угрозой. Это, правда, отдельный разговор, потому что умный человек подменит ещё и запись в базе данных относительно контрольной суммы... Вторая идея проверки контрольной суммы файла и вообще всякой информации файла состоит в следующем: предположим, что файл конфигурационный, то есть такой, который (предполагается) вы будете менять. В этом случае внутри пакета он помечается как конфигурационный, при регистрации считается его контрольная сумма, и если при удалении пакета выясняется, что этот файл был модифицирован, то он не удаляется, а переименовывается. Почему? Например, Вы поставили Web-сервер, долго его настраивали, редактируя конфигурационный файл, после чего пришлось его удалить. Потом вы снова поставили Web-сервер. Было бы неплохо, чтобы в момент удаления конфигурационный файл, который вы так долго редактировали, никуда не делся. Он никуда и не денется, а переименуется в *.rpmsafe. Обратная ситуация: вы поставили пакет, редактируете конфигурационный файл, а потом этот пакет обновили. Было бы неплохо, чтобы тот конфигурационный файл, который вы редактируете, остался с тем же именем, а тот, который входит в пакет, записался отдельно. Такое тоже есть: такой конфигурационный файл записывается с именем *.rpmnew. Это в случае с ALTLinux, где используется установщик rpm. В случае, скажем, c Debian всё сложнее, есть специальный конфигурационный скрипт, после того, как вы производите обновление, данные автоматически переписываются из старого конфигурационного файла в новый.

Сценарии

На самом деле, этого ещё не всё, поскольку часто бывает, что при установке и удалении пакета надо выполнять не только разархивацию, но и дополнительные действия с системой. Например, вы устанавливаете Web-сервер, и к нему --- модуль его настроек, например, mod_php. Было бы неплохо не только его установить, но и модифицировать конфигурационные файлы, если это нужно, и перезапустить Web-сервер. Или при установке Web-сервера процесс должен выполняться от лица специального пользователя apache, и этого пользователя надо добавить в систему, а когда вы удаляете этот Web-сервер, непонятно, нужно ли этого пользователя удалять. Так или иначе, действий, описанных выше, недостаточно. Бывает, что при установке или удалении пакета надо выполнить специфические для этого пакета действия. Это называется сценарии (например, предустановочные). В дистрибутивах ALTLinux их 4 (перед установкой пакета, после установки пакета, перед удалением пакета, после удаления пакета), в Debian --- 7. Пример:

[george@class305 ~]$ rpmquery --scripts dhcp-server
preinstall scriptlet (through /bin/sh):
/usr/sbin/useradd -r -n -g dhcp -d /var/lib/dhcp/dhcpd -s /dev/null -c 'The ISC DHCP server daemon' dhcpd >/dev/null 2>&1 ||:
/bin/rm -f /var/run/dhcpd.restart
# stop _old_ dhcpd if running
if [ $1 -eq 1 ] && [ -x /etc/rc.d/init.d/dhcpd ] && /etc/rc.d/init.d/dhcpd status >/dev/null 2>&1; then
        /etc/rc.d/init.d/dhcpd condstop && touch /var/run/dhcpd.restart ||:
fi

# relocate dhcpd.conf
if [ ! -f /etc/dhcp/dhcpd.conf -a -f /etc/dhcpd.conf ]; then
        /bin/mkdir -p /etc/dhcp
        /bin/mv -v /etc/dhcpd.conf /etc/dhcp/
fi

# relocate dhcpd.leases
if [ ! -f /var/lib/dhcp/dhcpd/state/dhcpd.leases -a -f /var/lib/dhcp/dhcpd.leases ]; then
        /bin/mkdir -p /var/lib/dhcp/dhcpd/state
        /bin/mv -v /var/lib/dhcp/dhcpd.leases /var/lib/dhcp/dhcpd/state/
fi

if [ $1 = 0 ]; then
        /bin/rm -f /var/lib/dhcp/dhcpd/lib/* /var/lib/dhcp/dhcpd/var/yp/binding/*
fi
postinstall scriptlet (through /bin/sh):
/etc/chroot.d/dhcpd.all
/usr/sbin/post_service dhcpd
if [ -f /var/run/dhcpd.restart ]; then
        /bin/rm -f /var/run/dhcpd.restart
        /etc/rc.d/init.d/dhcpd start ||:
fi
preuninstall scriptlet (through /bin/sh):
/usr/sbin/preun_service dhcpd

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

Зависимости

Как уже неоднократно говорилось выше, использование динамической библиотеки повышает удобство для разрабтчика. Во-первых, исполняемый файл, собранный с динамической библиотекой, занимает меньше места, во-вторых, n исполняемых файлов тоже занимают меньше места, поскольку библиотеки не входят в состав этих n файлов, в-третьих, все они пользуются одной и той же библиотекой, соответственно, можно рассчитывать на то, что любая программа, скажем, вычисляющая синус, вычисляет его правильно. Это, кстати, имеет обратное свойство: если в одной библиотеке есть ошибка, а ею пользуются 20 программ, вероятность возникновения ошибки в процессе работы в 20 раз выше, однако в некоторой степени это хорошо, потому что вероятность того, что вы эту ошибку вовремя исправите тоже в 20 раз выше. Однако возникает вопрос: в какой пакет должна входить динамическая библитека, которой пользуются много программных продуктов, находящихся в разных пакетах? Есть два варианта ответа. С одной стороны, поскольку мы можем поставить то один програмный продукт, то другой, то логично включить свою копию динамической библиотеки внутрь каждого пакета. В таком случае мы теряем все преимущества динамической библиотеки, возвращаясь, по сути, к статической сборке, только файлов становится еще больше. С каждым пакетом будут поставляться собственные динамические библиотеки, их версии могут быть несогласованы, так что это неприемлемо, особенно, если мы заранее знаем, что нет никаких ограничений к информационному доступу к пакетам. Поэтому в качестве основного варианта нужно принимать второй: если некая разделяемая библиотека или группа однотипных разделяемых библиотек используется несколькими програмными продуктами, то она находится в отдельном пакете. Таким образом, не каждый пакет сам по себе является программным продуктом в обычном смысле.

Итак, вот у нас несколько тысяч пакетов в сизифе, несколько тысяч в большом дистрибутиве, несколько сотен в малом. Всё это замечательно, но как же быть с установкой? Ведь чтобы установить, например, графический редактор GIMP, надо установить ещё несколько пакетов, которые он требует, а им в свою очередь тоже нужны какие-то другие пакеты и так далее. Ответ на этот вопрос простой: есть такое понятие как зависимость пакетов, и пакет, содержащий зависимости на другие, не может быть установлен, пока другие пакеты тоже не установлены.

Конфликты

Осталась рассмотреть проблему конфликтов. Может получиться, что два разных пакета содержат один и тот же файл (т.е. тот, который будет помещён в одну и ту же директорию под одним и тем же названием). Этот конфликт паразитный - было бы неплохо, чтобы два ментейнера договорились, как они будут разруливать эту ситуацию. Наиболее частый пример --- cdrecord. Это утилита для записи лазерных дисков с командной строки. Он существует в двух вариантах: тот, который пишет Йорг Шиллинг, и тот, который пишет сообщество, которое в какой-то момент взяло исходный код и начало модифицировать его самостоятельно (потому, что Йорг боится патентных преследований и отказывается распространять под свободной лицензией версию cdrecord'а, которая может писать на dvd, который в некоторых странах как таковой защищён патентом). Поэтому есть два варианта cdrecord'а: один называется cdrecord classic, а другой - dvdrecord. Проблема в том, что у этих программ разный синтаксис ключей, и вы можете захотеть, чтобы у вас был cdrecord classic, чтобы работали какие-то штуки, которые используют его ключи. Осталось только выяснить, кто из них называется cdrecord. Если в системе стоят оба пакета, то в /usr/bin лежит символьная ссылка, которая всегда ведет в один из двух вариантов, а специальная утилита alternatives позволяет переключаться между ними.

  • Бывает так, что конфликт необходимо обеспечить. Например, у вас есть два почтовых сервера, и вы оба хотите установить. В прицнипе, этого делать не надо, поскольку оба они будут пытаться принимать соединения по двадцать пятому порту, и первый из них, который запустится, будет это делать, а второй не сможет это сделать и будет выдавать ошибку. При этом, предположим ситуацию, что конфликта по файлам между этими пакетами не существует. Однако рационально этот конфликт вписать в пакеты заранее. Это делается следующим образом: каждый пакет объявляет, какие функции он обеспечивает. Если вы попытаетесь установить два пакета, которые обеспечивают одинаковую функциональность, то есть у них поле provides в чем-то совпадает, вам ничего не дадут сделать, даже если конфликта по файлам нет. Таким образом, конфликт может быть не только результатом недосмотра двух мейнтейнеров, но и сознательно введенным механизмом, оптимизирующим работу системы.


Сведения о ресурсах

Готовность (%)

Продолжительность (ак. ч.)

Подготовка (календ. ч.)

Полный текст (раб. д.)

Предварительные знания

Level

Maintainer

Start date

End date

45

1

1

1

1

ConstantinYershow, ОльгаТочилкина, MaximByshevskiKonopko


CategoryLectures CategoryPspo CategoryMpgu CategoryUneex

PspoClasses/080720/02Package (last edited 2008-10-09 21:49:05 by MaximByshevskiKonopko)