Несколько лет назад, когда Linux использовали на инфраструктурных серверах и компьютерах энтузиастов, было «модно» собирать ПО из исходных текстов. Плох тот линуксоид, который не может пройти книжку LFS и собрать свой дистрибутив.
Подобный путь, хотя поначалу и интересен, влечет за собой массу трудностей, когда речь заходит о поддержке сколько-нибудь масштабной инфраструктуры. Сборка ПО из исходных текстов чревата потерями времени, машинно-специфичными сборками, потерей стандартизации, а следовательно и контроля над ПО. Прямым следствием этого с технической точки зрения является возрастание расходов рабочего времени на управление ПО, а с экономической – удорожание обслуживания инфраструктуры.
Решение подобной проблемы – использование специального ПО и политики управления пакетами с целью стандартизации управления жизненным циклом ПО. Одним из решений для управления ПО является использование формата RPM, а также одноименного менеджера пакетов.
RPM – что это такое?
Что такое пакет? Прежде всего пакет – это единица управление ПО. Пакет состоит из:
- Файлов, исполняемых и конфигурационных
- Предустановочных действий.
- Постустановочных действий
- Действий, необходимых для удаления ПО.
- Различной служебной информации (списки и контрольные суммы файлов и т.д.)
Соответственно, пакет – это несколько больше, чем просто архив файлов. RPM-пакеты – основной способ управления ПО во многих дистрибутивах Linux. Разумно использовать его и для управления собственным ПО / ПО третьих лиц, которое не распространяется в виде RPM по умолчанию. Именно этим мы и займемся. Примеры из данной статьи разобраны и протестированы на RHEL5, хотя по аналогии будут работать и во многих других дистрибутивах.
Подготовка окружения для сборки RPM
В любой системе существует стандартная инфраструктура для сборки RPM. По умолчанию она расположена в /usr/src/redhat/. Если подобного каталога нет, установите пакет rpm-build. Его наличие позволяет собирать пакеты, имея административные привилегии, что не всегда безопасно. Мы будем использовать сборку под непривилегированным пользователем, которого назовем brewbuilder.
Для демонстрации нам потребуется пакет hello-1.0.tar.gz, который можно взять с сервера ftp://62.205.185.52/765591143807cc23efcfb4f1b436ebbc/hello-1.0.tar.gz
Для того, чтобы сделать пользовательско-специфичное окружение для сборки RPM, нам нужно всего лишь создать директории и переопределить один макрос.
$ mkdir -p ~/workspace/redhat/{RPMS,SRPMS,SPECS,SOURCES,BUILD}
$ echo '%_topdir /home/brewbuilder/workspace/redhat' > ~/.rpmmacros
Теперь мы готовы к сборке. Для сборки нам необходим единственный файл hello-1.0.tar.gz, который надо разместить в ~/workspace/redhat/SOURCES.
Часть основная – содержательная. SPEC-файл.
SPEC-файл – центральная часть процесса сборки. Написание корректного SPEC-файла и является целью нашей сегодняшней работы. Итак приступим.
Есть простой способ обеспечить себе шаблон для сборки – запустите emacs. =) Сложный – сделайте себе шаблон в вашем любимом редакторе (читай VIM) или запомните необходимые стадии. Мы приведем сразу весь SPEC-файл, позже разобрав его построчно. (Нумерация строк приведена только для удобства, в реальном SPEC-файле нумерация не нужна.)
- Name: hello
- Version: 1.0
- Release: 1
- Summary: A sample package, saying hello, world
- Group: Applications/Productivity
- License: GPL
- Source0: hello-1.0.tar.gz
- BuildArch: i386
- BuildRoot: %{_tmppath}/hello-root
- %description
- This package basically does nothing, but it potentially could
- do something useful.
- %prep
- %setup -q -n %{name}-%{version}
- %build
- make
- %install
- mkdir -p $RPM_BUILD_ROOT/usr/local/{bin,lib,share}
- mkdir -p $RPM_BUILD_ROOT/usr/local/share/man/man1
- install libhello.so.1.0 $RPM_BUILD_ROOT/usr/local/lib
- install hello $RPM_BUILD_ROOT/usr/local/bin
- gzip -9c hello.1 > hello.1.gz &&
- install hello.1.gz $RPM_BUILD_ROOT/usr/local/share/man/man1
- %files
- %defattr(-,root,root)
- /usr/local/lib/libhello.so.1.0
- /usr/local/bin/hello
- /usr/local/share/man/man1/hello.1.gz
- %clean
- make clean
- rm -rf $RPM_BUILD_ROOT
- %post
- echo "/usr/local/lib" >> /etc/ld.so.conf
- ldconfig
- %changelog
- * Tue Jul 17 2007 Andrey Meganov
- - Initial build
Итак, начнем. В строчках [1-6] находится стандартное описание пакета. Эти поля необходимы, но назначение их чисто описательное за исключением поля Source0, в котором указано имя архива с исходными текстами. Помимо поля Source0, могут быть и Source1, Patch0 и далее по аналогии.
Строчки [11-13] (секция %description) задают описание пакета. Это стандартное многострочное описание, выводимое командой rpm -qi.
Строки [16-17] (секция %prep) отвечаю за подготовку пакета к сборке. Единственная строчка в нашем случае – макрос %setup отвечает за «тихую» (флаг -q) распаковку исходников Source0 в каталог %{name}-%{version}. В этой секции полагается размещать подготовку исходников с сборке, применение патчей и т.п.
Строки [19-20] (секция %build) отвечают за сборку исходников. В нашем случае это делается просто командой make. В общем случае это почти всегда комманды ./configure –prefix=$RPM_BUILD_ROOT/usr; make.
Секция %install [22-28] отвечает за установку файлов в окружении сборки. В нашем случае стандартной цели make install нет, поэтому мы устанавливаем все вручную. В общем случае make install в этой секции почти всегда решит ваши проблемы. Заметьте, что все пути начинаются с $RPM_BUILD_ROOT. Это достаточно важно и это главная причина не собирать пакеты под пользователем root. В случае если вы – root и вы забудете $RPM_BUILD_ROOT в начале пути, то вместо установки в «песочнице» ваш файл будет установлен на вашей рабочей системе, чего вы вряд ли хотите. =)
Секция %files [30-34] – одна из наиболее важных частей нашего SPEC-файла. Она описывает файлы, входящие в RPM-пакет. В этой секции желательно определить макросом %defattr(-,root,root) атрибуты по умолчанию (владелец – root, группа root, доп. атрибутов нет.), иначе при установке RPM-пакета пользователь увидит жалобы на то, что пользователь brewbuilder не существует. При создании списка файлов можно использовать шаблоны с символами '*' и '?', но делать это следует осмотрительно, так как указание списка файлов как /* приведет к включению лишних файлов в пакет. Специально можно пометить конфигурационные файлы (%config), что приведет к специальному обращению с ними, например при обновлении пакета, документацию (%doc) и пустые директории, принадлежащие пакету (%dir). Подробнее об использовании этих и других опций вы сможете прочитать в отдельных статьях.
Секция %clean [36-38] описывает очистку временного окружения сборки и обычно ничего кроме двух указанных команд не содержит.
Секция %post [40-42] описывает постинсталляционный скрипт. В нашем случае мы добавляем /usr/local/lib к пути, по которым доступны разделяемые библиотеки и успокаиваемся на этом. При написании данной секции мы сделали очевидную ошибку. Ошибка заключается в том, что мы не выдержали транзакционность. При удалении пакета мы не можем просто убрать строчку /usr/local/lib из файла /etc/ld.so.conf, потому что мы не можем рассчитывать, что никто другой не проверял наличие там этой строчки. С другой стороны, если мы – последний пакет, которому эта строчка нужна – неплохо было бы все таки иметь возможность удалить ее – для чистоты процесса. Для этого придумали директории, вроде /etc/ld.so.conf.d/. Чтобы добавить путь к библиотекам корректно, нам просто необходимо создать свой файл со строчкой /usr/local/lib в этой директории, а при удалении пакета (например, в неописанной в данной статье секции %preun) удалить этот файл.
И последняя секция %changelog содержит историю пакета. История пишется записями с фиксированным форматом даты, имени и адреса электронной почты. Формат дальнейших заметок произволен. Рекомендуется серьезно отнестись к changelog'ам, дабы избежать проблем в будущем.
Сборка пакета
Сборка пакета осуществляется одной командой
rpmbuild -ba [путь к SPEC-файлу]
После чего вы можете исследовать директории %_topdir/RPMS и %_topdir/SRPMS, найти там собранные пакеты и исследовать их командами rpm -q ...., установить и удалить соответственно.
Заключение
Вот мы и собрали наш первый RPM-пакет. Если вы хотите узнать более тонкие моменты сборки RPM, то рекомендуем прочесть книгу RPM Guide, доступную по адресу http://docs.fedoraproject.org/drafts/rpm-guide-en/. В дальнейшем мы обязательно расскажем о подписи RPM-пакетов и создании собственных репозитариев для yum.
1 комментарий:
За это время, ссылка:
http://docs.fedoraproject.org/drafts/rpm-guide-en/
переехала на новый адрес:
https://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/
Отправить комментарий