четверг, 3 февраля 2011 г.

rpm - использование (ньюансы)

1). Верификация
# rpm -V util-linux-2.12q-26
S.5....T /bin/arch
В строке вывода перед названием файла пакета появляются некие символы (если верификация успешна и повреждений нет, вывода не будет), которые указывают на характер неисправностей. В данном случае 
s означает изменение размера файла,
5 – нарушение сигнатуры md5 файла,
T – изменение времени последней модификации (то есть времени копирования файла в систему в нашем случае).
2). В режимах установки-удаления довольно часто возникает необходимость воспользоваться опциями --nodeps или --force. Первая позволяет установить (удалить) пакет независимо от того, удовлетворяются ли все его зависимости, вторая – установить пакет даже в том случае, если в системе имеются файлы более свежих версий. Некоторый интерес представляют опции --aid, которая автоматически удовлетворит возникающие зависимости и --test, которая и означает тестирование операций, то есть весь вывод о возникающих проблемах будет осуществлен, но реальных операций не производится. Очень удобно моделировать поломку системы в результате каких-либо действий.
3). # rpm -q --queryformat %{DESCRIPTION} <имя пакета>
выведет описание пакета, а команда
# rpm -q --queryformat %{DISTRIBUTION} <имя пакета>
– название дистрибутива, в составе которого находится пакет.
Причем замена -q на -qp позволит ту же самую информацию получить от rpm-файла не установленного в систему пакета. Можно получить список только конфигурационных файлов пакета, или только файлов документации, или только файлов, содержащих в имени регулярное выражение, то есть в принципе что угодно.
4). Формат rpm-пакета.
Формат пакета состоит из бинарного заголовка и cpio-архива, который содержит бинарные файлы в таком дереве каталогов, в каком они будут находится в системе после установки пакета. Файловый менеджер mc понимает множество всяких архивов, и в том числе – упаковку rpm. Если в панели mc выделить rpm-пакет и нажать ввод, мы увидим псевдофайловую систему, состоящую из следующих компонентов: каталога INFO, архива CONTENTS.cpio, того самого, содержащего бинарные файлы, файла HEADER и псевдоскриптов INSTALL и UPGRADE. В каталоге INFO содержатся файлы, имена которых соответствуют именам полей spec-файла, содержимое – значениям полей. Файл HEADER – по сути то же самое, только в одном файле. Ссылки INSTALL и UPGRADE соответствуют командам rpm -ih <имя пакета> и rpm -Uh <имя пакета>. То есть, если на них нажать, эти действия и произойдут.
В реальном формате никакой файловой системы нет. Просто mc умеет по-своему интерпретировать бинарный заголовок пакета, за что его разработчикам большой респект.
При желании можно выделить cpio-архив из всего пакета. Для этого существует утилита rpm2cpio.
5). Соберем пакет.
В rpm версии v.4 режим сборки пакета оформлен в виде отдельной утилиты – rpmbuild. Воспользуемся самым эффективным методом изучения технологии, то есть, соберем модельный rpm-пакет. Нет и вопроса, что должна делать программа, которую мы упакуем в rpm. Она должна говорить: «Hello, world!»!
В rpm-based дистрибутивах существует специальное дерево каталогов, предназначенное исключительно для сборки пакетов. Оно лежит в /usr/src (в Suse Linux – в /usr/src/packages) и содержит каталоги BUILD, RPMS, SOURCES, SPECS, SRPMS. Предназначены они соответственно для хранения временных каталогов сборки, собранных бинарных rpm, исходного кода, хранения файлов спецификации, собранных src.rpm-пакетов. Src.rpm содержат исходный код и spec-файлы и предназначены для пересборки на целевых машинах с целью лучшей адаптации к архитектуре и системному окружению этих машин. Для сборки нам потребуется исходный код программы, который традиционно упаковывается в tar.gz или в tar.bz2 и spec-файл. Spec-файл для rpm примерно то же, что Makefile для утилиты make. Это подробнейший сценарий того, что должно происходить при сборке со всеми необходимыми определениями и служебными полями. Итак, за дело.
Создадим текст программы на С. Файл назовем hi.c и поместим его в каталог SOURCES. Отредактируем содержание файла в любимом текстовом редакторе следующим образом:
#include
int main(int argc, char **argv)
{
fprintf(stdout,"Hello, World!\n");
return 0;
}
Не забудем пустую строку в конце файла. Запакуем исходный код в tar.gz (команду отдаем, находясь в каталоге /usr/src/packages/SOURCES):
# tar cvfz ./hi-0.1.tar.gz ./hi.c
Далее spec-файл. По сути дела, умение создавать хорошо пересобираемые rpm-пакеты – это умение писать spec-файлы. Они имеют сложную структуру, подробности которой рассмотреть не представляется возможным в журнальной статье, поэтому обсудим главное. Файл делится на секции, каждая секция отвечает за свою часть работы. Создадим файл под именем hi.spec в каталоге SPECS и наполним его следующим содержанием:
Summary: Приветствующая утилита.
Name: hi
Version: 0.1
Release: 1
Copyright: GPL v.2
Group: Tests
Source:%{name}-%{version}.tar.gz
BuildRoot: /tmp/hi
%description
Тестовая программка для вывода приветствия.
%prep
%setup -c hi
%build
gcc -o hi hi.c

%install
mkdir -p $RPM_BUILD_ROOT/usr/local/bin
cp hi $RPM_BUILD_ROOT/usr/local/bin
%clean
rm -rf $RPM_BUILD_ROOT
%files
/usr/local/bin/hi
Проанализируем функции отдельных секций spec-файла.
Все, что написано до строки %prep, составляет секцию introduction. Она содержит описания, определения версий и релизов, корень сборки и другую служебную информацию. Значения всех этих полей используются через имена полей в качестве переменных при сборке и включаются в одноименные поля бинарного заголовка rpm-пакета.
Секция prep отвечает за подготовку исходного кода к сборке. В нашем примере секция содержит строку %setup -c hi, которая вызывает макрос RPM. Макрос, в свою очередь, распаковывает исходный текст Си из архива.
Секция build содержит инструкции по сборке. В данном случае мы указали имя выходного бинарного файла – hi. Если проект большой, как правило должен быть сгенерирован Makefile, поэтому секция может содержать нечто подобное:
./configure CXXFLAGS=-03 –prefix=$RPM_BUILD_ROOT/usr
make
Секция install включает операции по установке программы в систему. В развитых проектах она может содержать весьма обширные списки действий. Или, например:
rm -fr $RPM_BUILD_ROOT
make install
В нашем проекте нет Makefile, поэтому мы указали все непосредственно.
Секция clean содержит команды удаления каталогов сборки.
Секция files – список файлов проекта.
Итак, у нас имеется исходный код в виде tar.gz-архива и spec-файл. Больше для сборки пакета ничего не требуется. Естественно, в системе должны быть установлены средства разработки.
Для сборки пакета вызываем утилиту rpmbuild с ключом -b. Второй символ набора ключей означает цель сборки. Опция -a указывает на необходимость собрать как rpm-пакет, так и src.rpm. Укажем также целевую архитектуру. Находясь в каталоге SPECS, отдадим следующую команду:
rpmbuild -ba --target i586 ./hi.spec
Если в последней строке консольного вывода Вы увидите: + exit 0, значит все прошло как надо. В каталоге RPMS/i586 должен обнаружиться файл
hi-0.1-1.i586.rpm, в каталоге SRPMS – файл hi-0.1-1.src.rpm. Воспользуемся уже имеющимися знаниями, и установим пакет hi в систему:
# cd /usr/src/packages/RPMS/i586
# rpm -Uhv ./hi-0.1-1.i586.rpm
Теперь, если Вы скажете в консоли:
$ hi
получите ответ: Hello, World!
Для установки src.rpm-пакета воспользуйтесь командой:
# rpm -i /путь к каталогу/hi-0.1-1.src.rpm
При этом в систему скопируются исходный код и spec-файл (в то самое дерево каталогов для rpm-сборки). Если нужно просто собрать бинарный пакет, достаточно сказать:
# rpmbuild --rebuild /путь к каталогу/hi-0.1-1.src.rpm