Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

Automating UNIX and Linux Administration by Kirk Bauer

Red Hat Package Manager (RPM)
   Если вы не имеете понятия о создании дистрибутивов , то вы обычно поступаете так :
 вы компилируете какую-то программу на своей машине , затем собираете все в архив ,
 копируете этот архив на другую машину , извлекаете все из архива и запускаете там 
 make install . Через какое-то время вы удаляете инсталляционный каталог вместе с архивом ,
 а потом возникает необходимость установить его еще раз на новой удаленной машине ,
 и вы не знаете , что делать .
   Через некоторое время выходит новая версия программы , вам нужно опять все откомпилировать 
 у себя и разослать новый архив , и там опять делать make install . Если компиляция составляет 
 несколько часов и более , это может привести к серьезным проблемам .
  Эти проблемы решаются в RPM. Он обеспечивает гибкое управление пакетов и их версий .
 В RPM существует специальный файл-сценарий - SPEC - в котором фиксируются все изменения
 при генерации пакета .
  Перед тем как построить первый RPM , нужно подготовить систему . Начинать нужно с каталога
 исходников , в котором также будут присутствовать SPEC-файлы . 
 Базовым каталогом мы выберем ~/rpmroot. Внутри ~/rpmroot создадим подкаталоги :
 BUILD/, RPMS/, SOURCES/, SPECS/, и SRPMS/.
 Также необходим виртуальный инсталяционный каталог - пусть это будет ~/tmp/.
 Далее в своем домашнем каталоге ~/ создаем файл .rpmmacros . 
 В данном примере имеется ввиду , что пользователь не root , а build ,
 и его домашний каталог -  /home/build/. Надо сказать , что некоторые пакеты можно построить 
 только из-под рута .
 Содержание его может быть следующим :
 	%_topdir /home/build/rpmroot
 	%buildroot /home/build/tmp/build
 	%packager Kirk Bauer <kirk@kaybee.org>
 	%_tmppath /home/build/tmp
 На вашей системе должны стоять rpm , rpm-build , я уже не говорю про gcc и make .
  Начнем с создания простого пакета . Для начала создадим файл test.spec в подкаталоге /SPECS/.
 Для того , чтобы с его помощью построить пакет , нужно с этого подкаталога запустить :
 	rpmbuild -ba test.spec
 В случае успеха , в каталоге SRPMS/ будет создан source RPM , 
 в каталоге PMS/noarch/ - "binary" RPM .
 noarch - значит не конкретная архитектура .
 Вот содержание этого spec-файла :
 	Name: test
 	Version: 1.0
 	Release: 1
 	Summary: A test package
 	License: MIT
 	Group: Test
 	BuildArch: noarch
 	%description
 	This is just a test package
 	%files
 Если BuildArch не определить , система сама поставит i386 или что-то другое .
 Секция %files пуста ради простоты .
 Теперь строим пакет :
 	rpmbuild -ba test.spec
 	...
 	Wrote: /home/build/rpmroot/SRPMS/test-1.0-1.src.rpm
 	Wrote: /home/build/rpmroot/RPMS/noarch/test-1.0-1.noarch.rpm
 Создаются две RPM-ки.
 Теперь добавим в пакет один файл - /etc/hosts . Для этого в заголовок test.spec
 добавим 2 строки :
 	Buildroot: /var/tmp/test_build
 	Source: hosts
 При этом файл hosts должен лежать в нашем подкаталоге /SOURCES/.
 Его можно скопировать туда так :
 	%prep
 	cp /etc/hosts $RPM_SOURCE_DIR
 Следующей идет секция %install :
 	%install
 	rm -rf $RPM_BUILD_ROOT
 	mkdir -p $RPM_BUILD_ROOT/etc
 	cp $RPM_SOURCE_DIR/hosts $RPM_BUILD_ROOT/etc/hosts
 Секция %files будет выглядеть так :
 	%files
 	%attr(0644,root, root) /etc/hosts
 Запускаем еще раз 
 	rpmbuild -ba test.spec
 
 

Пример gzip-1.3-15.src.rpm

В качестве примера возьмем пакет gzip-1.3-15.src.rpm из редхатовского дистрибутива. Выполняем : % rpm -i gzip-1.3-15.src.rpm % cd ~/rpmroot/SPECS Рассмотрим подробнее gzip.spec из этого пакета : Summary: The GNU data compression program. Name: gzip Version: 1.3 Release: 15 License: GPL Group: Applications/File Source: ftp://alpha.gnu.org/gnu/gzip/gzip-%{version}.tar.gz Patch0: gzip-1.3-mktemp.patch Patch1: gzip-1.2.4-zforce.patch Patch2: gzip-1.2.4a-dirinfo.patch Patch3: gzip-1.3-stderr.patch Patch4: gzip-1.3-zgreppipe.patch Patch5: gzip-1.3-noppid.patch URL: http://www.gzip.org/ Prereq: /sbin/install-info Requires: mktemp Buildroot: %{_tmppath}/gzip-%{version}-root Интерес здесь представляют секции Prereq: и Requires: , которые показываю зависимости и указывают на пакеты , которые уже должны быть установлены . Buildroot: - каталог , необходимый при построении пакета . Рассмотрим секцию prep : %prep %setup -q %patch0 -p1 %patch1 -p1 %patch2 -p1 %patch3 -p1 %patch4 -p1 %patch5 -p1 Макрос %setup извлекает исходники из пакета , которые перечислены в поле Source , и ставит их в каталог /BUILD/ . Макрос %patch0 вызывает патч . Рассмотрим секцию build : %build export DEFS="-DNO_ASM" export CPPFLAGS="-DHAVE_LSTAT" %configure --bindir=/bin make make gzip.info С помощью export мы устанавливаем несколько переменных . Конфигурация устанавливает каталог /bin , в который лягут бинарники . Следующая секция - clean : %clean rm -rf $RPM_BUILD_ROOT Секция install : %install rm -rf $RPM_BUILD_ROOT %makeinstall bindir=$RPM_BUILD_ROOT/bin gzip.info mkdir -p $RPM_BUILD_ROOT/usr/bin ln -sf ../../bin/gzip $RPM_BUILD_ROOT/usr/bin/gzip ln -sf ../../bin/gunzip $RPM_BUILD_ROOT/usr/bin/gunzip for i in zcmp zegrep zforce zless znew gzexe zdiff zfgrep zgrep zmore ; do mv $RPM_BUILD_ROOT/bin/$i $RPM_BUILD_ROOT/usr/bin/$i done gzip -9nf $RPM_BUILD_ROOT%{_infodir}/gzip.info* cat > $RPM_BUILD_ROOT/usr/bin/zless <<EOF #!/bin/sh /bin/zcat "\$@" | /usr/bin/less EOF chmod 755 $RPM_BUILD_ROOT/usr/bin/zless Относительно нашего buil root создается каталог /usr/bin/ . Следующая секция - %post : %post /sbin/install-info %{_infodir}/gzip.info.gz %{_infodir}/dir Следующая секция %files : %files %defattr(-,root, root) %doc NEWS README AUTHORS ChangeLog THANKS TODO /bin/* /usr/bin/* %{_mandir}/*/* %{_infodir}/gzip.info* Команда %defattr автоматически меняет пермишины на рутовые .

Build Root

Начнем с того , что в ~/.rpmmacros добавляем строку : %buildroot /home/build/tmp/build Предположим , что пакет должен проинсталировать программу /usr/bin/program и конфиг /etc/program.conf . Процес будет таким . 1. Компилируем program 2. Ложим в $RPM_BUILD_ROOT/usr/bin/program и $RPM_BUILD_ROOT/etc/program.conf. 3. В секции files , добавляем /usr/bin/program и /etc/program.conf. Пример SPEC-файла :
%build
 	make -DCONFIG_FILE=/etc/program.conf program
 	%install
 	rm -rf $RPM_BUILD_ROOT
 	mkdir -p $RPM_BUILD_ROOT/etc
 	mkdir -p $RPM_BUILD_ROOT/usr/bin
 	cp program $RPM_BUILD_ROOT/usr/bin
 	chmod a+rx $RPM_BUILD_ROOT/usr/bin/program
 	cp program.conf $RPM_BUILD_ROOT/etc
 	chmod a+r $RPM_BUILD_ROOT/etc/program.conf
 	%clean
 	rm -rf $RPM_BUILD_ROOT
 	%files
 	%defattr(-,root, root)
 	/etc/program.conf
 	/usr/bin/program.conf
 
 

Патчи

Патч создается так : сначала тарбол test-1.0.tgz нужно разместить в каталог SOURCES/. Затем выполняем 2 команды : % tar -xzf test-1.0.tgz % cp -ar test-1.0 test-1.0-orig После этого заходим в каталог SOURCES/test-1.0/ и делаем изменения в исходниках . После чего создаем патч : % diff -uNr test-1.0-orig test-1.0 > test-patch1 % rm -rf test-1.0 test-1.0-orig Теперь мы имеем патч test-patch1. Нужно в SPEC сделать ссылку на исходник и на патч : Source: test-1.0.tgz Patch0: test-patch1 %prep %setup %patch0 -p1

RPM-зависимости

Зависимости не позволяют проинсталлировать пакет , если не установлены другие программы. Иногда это может привести к циклической зависимости , когда отсутствующая программа требует другую отсутствующую программу . Если пакет использует расшаренные библиотеки , RPM автоматически добавит их в пакет . Эту фичу можно отключить путем AutoProv: no . Можно использовать поле Provides . В полях Prereq и Requires можно просто перечислить все зависимости , необходимые для установки пакета . При указании пакета , который является предустановленной зависимостью , можно указать версию : Requires: bash Requires: bash = 2.05a Requires: bash >= 2.0, webserver, /bin/ls Если в SPEC имеется непустое поле Conflicts , то пакет может быть не усстановлен , если конфликт будет найден в системе . Опция –nodeps позволяет устанавливать пакет , что называется , невзирая на лица и зависимости .

Advanced RPM

Зависимости можно определить в полях BuildPrereqs, BuildRequires,BuildConflicts. Опции RPM можно задать из командной строки с помощью опции –with , для чего нужно использовать макрос %_with_option внутри SPEC . Переменную RPM можно использовать в любом месте SPEC . Можно определить свою собственную переменную : %define varname value Использование такой переменной - %{varname} . Директива %attr используется для раздачи прав на файлы : %files %attr(0644,root, root) /etc/* %attr(0755,root, root) /usr/bin/* Если в SPEC задается директива %config , то при инсталляции пакета , старые конфиги будут сохранены с расширением .rpmorig. Если файл , отмаркированный этой директивой , модифицировался после инсталляции , то после удаления пакета этот файл будет переименован с расширением .rpmsave . С помощью директивы %ghost можно указать файлы , которых не будет в пакете , но на них например могут быть созданы линки . Файлы для директивы %files можно сохранить в отдельном файле в каталоге /BUILD/ и затем вызвать в SPEC так : %files -f file.list. SPEC может включать несколько инсталяционных секций : %pre - скрипт в этой секции выполняется перед установкой файлов %post - скрипт в этой секции выполняется после установки файлов %preu - скрипт вызывается перед апгрэйдом или удалением %postun - скрипт вызывается после апгрэйда или удаления Наличие пакета в системе можно проверить с помощью команды rpm -V pkgname Файлы пакета можно вывести командой rpm -Va Триггеры-специальные скрипты,которые выполняются RPM при инсталяции или удалении . Существуют 3 типа триггеров : %triggerin: %triggerun: %triggerpostun: Триггер выполняется с 2-мя аргументами : первый - номер версии устанавливаемого пакета , второй - номер версии уже установленного пакета . В большинстве случаев это параметры 0,1 и 2. При апгрейде порядок выполнения скриптов следующий : 1. %pre 2. %files 3. %post 4. $triggerin из установленного ранее пакета 5. $triggerin из устанавливаемого пакета 6. %triggerun из установленного ранее пакета 7. %preun из установленного ранее пакета 8. %postun из установленного ранее пакета 9. %triggerpostun из установленного ранее пакета Работу триггеров можно рассмотреть на следующем примере : создадим 2 пакета - test1 и test2,и проинсталлируем их. Затем создадим новую версию пакета test1 и сделаем его апгрэйд . Пример SPEC для этого случая :
%define other_pkg test2
 	Name: test1
 	Summary: Package %{name}
 	Version: 1.0
 	Release: 1
 	License: MIT
 	Group: Test
 	BuildArch: noarch
 	BuildRoot: /var/tmp/%{name}
 	%description
 	Description for %{name}
 	%files
 	%pre
 	echo Executing pre in %{name}-%{version}-%{release}: arg=$1
 	%post
 	echo Executing post in %{name}-%{version}-%{release}: arg=$1
 	%preun
 	echo Executing preun in %{name}-%{version}-%{release}: arg=$1
 	%postun
 	echo Executing postun in %{name}-%{version}-%{release}: arg=$1
 	%triggerin -- %{other_pkg}
 	echo Executing triggerin in %{name}-%{version}-%{release}: args=$1 $2
 	%triggerun -- %{other_pkg}
 	echo Executing triggerun in %{name}-%{version}-%{release}: args=$1 $2
 	%triggerpostun -- %{other_pkg}
 	echo Executing triggerun in %{name}-%{version}-%{release}: args=$1 $2
 
 Если вы хотите установить пакет в какой-то конкретный каталог , 
 можно набрать :
 	rpm -i –prefix /some/path
 При этом в SPEC должно быть поле :
 	Prefix: /usr
 	...
 	%files
 	/usr/bin/program
 Другой вариант :
 	Prefix: /usr/local
 	...
 	%post
 	if [ ! "$RPM_INSTALL_PREFIX" == "/" ] ; then
 	ln -sf "$RPM_INSTALL_PREFIX/etc/program.conf" /etc/program.conf
 	fi
 	%postun
 	rm -f /etc/program.conf
 	%verifyscript
 	test -l /etc/program.conf
 	%files
 	%conf /usr/local/etc/program.conf
 	/usr/local/bin/program
 Возможен такой вариант :
 	% rpm -i --relocate /usr=/usr/local /etc=/usr/local/etc test.rpm
 
 
  

Основные опции команды rpm

КомандаДействие
rpm -i (package)Установка пакета
rpm -iv (package)Установка пакета с распечаткой результатов
rpm -ivh(package)Установка пакета с распечаткой результатов + текущий процент
rpm -ivv (package)Установка пакета с подробной распечаткой результатов
rpm -ivv --nodeps (package)Установка пакета , игнорируя все зависимости
rpm -qp (package)Распечатка имени пакета
rpm -qip (package) Вывод более подробной информации о пакете
rpm -qlp (package) Вывод списка файлов в пакете
rpm -qa Показывает все пакеты , установленные в системе
rpm -Va Вывод краткой информации о каждом пакете
rpm -U (package)Upgrade уже установленного пакета или инсталляция нового
rpm -F (package)Upgrade уже установленного пакета лишь в том случае , если он уже установлен
rpm -e (package)Удаление пакета вместе с зависимостями
rpm -e --nodeps (package)Удаление пакета игнорируя зависимости
Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье