Создать rpm пакет из исходников. Сборка rpm пакетов и настройка своего репозитория

В данной статье будет подробно описан процесс создание rpm пакетов и организация репозитория. Прошу всех, кому интересна данная тема, пройти под кат.


Я взялся писать крайне подробно, так что Вы можете пролистать очевидные для Вас вещи.

  • Установка системы
  • Преднастройка
  • Подготовка площадки сборки
  • Собираем Tmux
  • Собираем fbida
  • Настройка доступа по ftp
  • Заключение

Установка системы

Театр начинается с вешалки

Наш сервис начинается с момента установки на него операционной системы. Естественно, что для сборки rpm пакетов мы выбираем rhel дистрибутив. В данном случае, был выбран CentOS 7 .

Скачать CentOS

Создадим директорию, где будет лежать образ и перейдем в нее:


mkdir ~/centos && cd $_

wget https://mirror.yandex.ru/centos/7/isos/x86_64/CentOS-7-x86_64-Everything-1708.iso wget https://mirror.yandex.ru/centos/7/isos/x86_64/sha256sum.txt.asc

или посредством torrent`а с помощью программы aria2 , которую для начала установим:


sudo yum install -y epel-release sudo yum install -y aria2 aria2c https://mirror.yandex.ru/centos/7/isos/x86_64/CentOS-7-x86_64-Everything-1708.torrent cd ~/centos/CentOS-7-x86_64-Everything-1708

Проверить образ

Скачать образ мало, нужно проверить его целостность и достоверность, что мы и сделаем.


Скачаем ключ для CentOS 7:


wget http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7

Посмотрим на ключ и импортируем его:


gpg --quiet --with-fingerprint RPM-GPG-KEY-CentOS-7 pub 4096R/F4A80EB5 2014-06-23 CentOS-7 Key (CentOS 7 Official Signing Key) Key fingerprint = 6341 AB27 53D7 8A78 A7C2 7BB1 24C6 A8A7 F4A8 0EB5 gpg --import RPM-GPG-KEY-CentOS-7 gpg: key F4A80EB5: public key "CentOS-7 Key (CentOS 7 Official Signing Key) " imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1)

Проверим подпись файла, с контрольной суммой образа:


gpg --verify sha256sum.txt.asc 2>&1 | grep "Good signature" gpg: Good signature from "CentOS-7 Key (CentOS 7 Official Signing Key) "

Как мы видим - все отлично и теперь можем проверить сам образ на целостность:


sha256sum -c sha256sum.txt.asc 2>&1 | grep OK CentOS-7-x86_64-Everything-1708.iso: OK

Запись образа на носитель

После того как мы убедились в целостности образа и его достоверности, неплохо было бы его уже записать и установить! Так сделаем это, но вначале определимся, на что записывать будем.

Запись образа на диск

Для записи данного образа, нам понадобится двухсторонний DVD. Допустим мы его нашли и записываем, установив предварительно wodim:


sudo yum install -y wodim sudo wodim dev=/dev/cdrom -eject -v CentOS-7-x86_64-Everything-1708.iso

Запись образа на флешку

Двухсторонний DVD это как то архаично, так что возьмем флешку на 16 гб и запишем образ на нее, но прежде /dev/sda тут - это флешка, а у Вас она может быть другой. Смотри команду fdisk:


sudo dd if=CentOS-7-x86_64-Everything-1708.iso of=/dev/sda bs=1M status=progress; sync eject /dev/sda

Если status=progress не поддерживается, то по старинке:


watch -n 10 "sudo kill -USR1 $(pgrep ^dd)"

или вот так:


watch -n 10 "sudo pkill -usr1 dd"

а можно воспользоваться pv:


sudo yum install -y epel-release sudo yum install -y pv sudo su dd if=CentOS-7-x86_64-Everything-1708.iso | pv | dd of=/dev/sda

Установка

Как поставить Centos 7, решать Вам, тут и за RAID подумать можно и за LVM и много чего еще,
я ставил минимальный пакет.


Процесс установки можно посмотреть в этом ролике .

Преднастройка

После установки системы, нам необходимо настроить наш сервер.

Обновление и установка пакетов

В начале мы обновим все установленные пакеты, далее установим репозиторий epel, в котором есть много что полезного для нас:


sudo yum update -y sudo yum install -y epel-release

Следующим шагом установим группу пакетов, которые понадобятся нам для сборки, а так же ряд пакетов необходимые для развёртывания репозитория.


sudo yum groupinstall -y "Development Tools" sudo yum install -y glibc-static tree wget vim createrepo sudo yum install -y httpd httpd-devel mod_ssl python2-certbot-apache vsftpd

SSH

Для того чтобы комфортно и безопасно управлять сервером настроим SSH.


Безопаснее пользоваться ключами, по этому мы и создадим себе ключи для доступа к серверу на своем рабочем компьютере:


ssh-keygen

и добавим ключ на сервер:


ssh-copy-id chelaxe@rpmbuild

или ручками:


mkdir ~/.ssh chmod 700 ~/.ssh vim ~/.ssh/authorized_keys ssh-rsa AAAA...tzU= ChelAxe (D.F.H.) chmod 600 ~/.ssh/authorized_keys

Необходимо еще закрутить гайки в самой службе. Создадим копию файла конфигурации и приступим к редактированию:


sudo cp /etc/ssh/sshd_config{,.bak} sudo vim /etc/ssh/sshd_config

В файле стоит добавить/изменить/раскомментировать следующие строки:


# Слушать будем на интерфейсе с адресом 192.168.0.2 ListenAddress 192.168.0.2 # Для авторизации хватит и 30 секунд LoginGraceTime 30 # Запретим подключение root пользователю PermitRootLogin no # Три неудачных попытки хватит MaxAuthTries 3 # Запретить авторизацию по паролю PasswordAuthentication no # Через 10 минут простоя разорвем сессию ClientAliveInterval 600 ClientAliveCountMax 0 # Разрешим вход только пользователю chelaxe AllowUsers chelaxe # Разрешим вход только пользователям из группы chelaxe AllowGroups chelaxe # Заставить sshd работать только с протоколом SSH2 Protocol 2

Перезапускаем службу:


sudo systemctl restart sshd

Межсетевой экран

Важно ограничить доступ к нашему серверу. По этой причине настроим межсетевой экран:


sudo firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client sudo firewall-cmd --permanent --zone=public --remove-service=ssh sudo firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.0.0/28" service name="ssh" accept" sudo firewall-cmd --permanent --zone=public --add-service=http sudo firewall-cmd --permanent --zone=public --add-service=https sudo firewall-cmd --permanent --zone=public --add-service=ftp sudo firewall-cmd --permanent --list-all public target: default icmp-block-inversion: no interfaces: sources: services: http https ftp ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="192.168.0.0/28" service name="ssh" accept sudo firewall-cmd --reload

Подготовка площадки сборки

Подготовим саму площадку для сборки. Стоит отметить, что вернее всего сборку производить на отдельном виртуальном хосте, активно используя технологию snapshot"ов, но тут я опишу все в едином целом. Так же для сборки нужно выделить отдельного пользователя, не являющемся администратором (т.е. sudo ему недоступно).

Создание директорий

Создаем необходимые директории:


mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} sudo mkdir /var/www/repo sudo chown -R chelaxe:chelaxe /var/www/repo ln -s /var/www/repo ~/rpmbuild/REPO tree ~/rpmbuild/ /home/chelaxe/rpmbuild/ ├── BUILD ├── BUILDROOT ├── REPO -> /var/www/repo ├── RPMS ├── SOURCES ├── SPECS └── SRPMS 7 directories, 0 files

Настройка PGP подписи

Наши пакеты, которые мы соберем, необходимо подписать, что будет обеспечивать целостность и достоверность.


Ключ будем использовать свой или если его нет, то создадим. Создавать ключ стоит на своем рабочем компьютере.


Создадим ключ, если его у нас нет:


gpg --gen-key

Нас попросят ответить на ряд вопросов:
тип ключа, выбираем (1) RSA and RSA (default), размер ключа: 4096, срок действия: 6m, наше имя: Alexander F. Mikhaylov, Email: [email protected], комментарий, тут можно указать для чего нам ключ: repo и ждем...


Если вдруг после ответов на все вопросы получим это gpg: cancelled by user , то запускаем команду:


script /dev/null

и повторяем.


Посмотреть ключ:


gpg --fingerprint [email protected] pub 2048R/E6D53D4D 2014-05-07 Key fingerprint = EE2A FF9A 2BE3 318E 9346 A675 8440 3961 E6D5 3D4D uid ChelAxe (D.F.H.)

Сохраняем наш приватный ключ:


gpg --export-secret-keys --armor [email protected] > chelaxe-privkey.asc

Создадим ключ для отзыва:


gpg --output chelaxe-revoke.asc --gen-revoke [email protected]

Экспорт открытого ключа на keyserver:


gpg --keyserver pgp.mit.edu --send-keys E6D53D4D

Теперь ключ можно и импортировать на наш сервер:


gpg --import ~/chelaxe-privkey.asc rm -rf ~/chelaxe-privkey.asc

Смотрим где находится gpg утилита:


which gpg /usr/bin/gpg

и настроем файл для подписи пакетов:


vim ~/.rpmmacros %_signature gpg %_gpg_path /home/chelaxe/.gnupg %_gpg_name ChelAxe %_gpgbin /usr/bin/gpg

Создаем репозиторий

Теперь организуем сам репозиторий.


Создадим директорию, где будем хранить пакеты:


mkdir ~/rpmbuild/REPO/Packages

Экспортируем ключ в репозиторий:


gpg --export -a "ChelAxe" > ~/rpmbuild/REPO/RPM-GPG-KEY-chelaxe

Создаем сам репозиторий и подписываем метаданные:


createrepo ~/rpmbuild/REPO

Пакет для репозитория

Собираем пакет для автоматической установки репозитория в систему.


cd ~/rpmbuild/SOURCES mkdir chelaxe-release && cd $_

Файл репозитория для yum:


vim ~/rpmbuild/SOURCES/chelaxe-release/chelaxe.repo name=ChelAxe Official Repository - $basearch baseurl=https://repo.chelaxe.ru/ enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-chelaxe

Экспортируем ключ для пакета:


gpg --export -a "ChelAxe" > ~/rpmbuild/SOURCES/chelaxe-release/RPM-GPG-KEY-chelaxe

Собираем все в архив:


cd ~/rpmbuild/SOURCES tar -czf chelaxe-release.tar.gz chelaxe-release/

Создаем SPECS файл для пакета:


cd ~/rpmbuild/SPECS vim ~/rpmbuild/SPECS/chelaxe-release.spec Name: chelaxe-release Version: 1.0 Release: 1%{?dist} Summary: ChelAxe repository configuration Vendor: D.F.H. Packager: ChelAxe Group: System Environment/Base License: GPL URL: https://repo.chelaxe.ru Source0: https://repo.chelaxe.ru/%{name}.tar.gz BuildArch: noarch %description This package contains the ChelAxe official repository GPG key as well as configuration for yum. %prep %setup -q -n %{name} %install %__rm -rf %{buildroot} install -d -m 755 %{buildroot}%{_sysconfdir}/yum.repos.d install -p -m 644 chelaxe.repo %{buildroot}%{_sysconfdir}/yum.repos.d/chelaxe.repo install -d -m 755 %{buildroot}%{_sysconfdir}/pki/rpm-gpg install -p -m 644 RPM-GPG-KEY-chelaxe %{buildroot}%{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-chelaxe %post rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-chelaxe %clean %__rm -rf %{buildroot} %files %defattr(-,root,root,-) %{_sysconfdir}/yum.repos.d/chelaxe.repo %{_sysconfdir}/pki/rpm-gpg/RPM-GPG-KEY-chelaxe %changelog * Tue May 1 2018 ChelAxe (D.F.H.) - 1.0-1%{?dist} - Initial package.

Собираем пакет:


rpmbuild -ba --sign ~/rpmbuild/SPECS/chelaxe-release.spec

На этом этапе нас спросят пароль от нашего PGP ключа.


Копируем созданный пакет в репозиторий и обновляем его:


cp ~/rpmbuild/RPMS/noarch/chelaxe-release-1.0-1.el7.centos.noarch.rpm ~/rpmbuild/REPO/ createrepo --update ~/rpmbuild/REPO

gpg --detach-sign --armor ~/rpmbuild/REPO/repodata/repomd.xml

Теперь установим наш репозиторий в систему:


sudo yum install -y ~/rpmbuild/REPO/chelaxe-release-1.0-1.el7.centos.noarch.rpm

В дальнейшем данный пакет будет доступен по адресу: https://repo.chelaxe.ru/chelaxe-release-1.0-1.el7.centos.noarch.rpm


После установки должен появиться репозиторий chelaxe и PGP ключ:


rpm -q gpg-pubkey --qf "%{name}-%{version}-%{release} --> %{summary}\n" | grep ChelAxe gpg-pubkey-e6d53d4d-5369c520 --> gpg(ChelAxe (D.F.H.) )

Самое важное тут это SPEC файлы, расписывать о них не стану, но предоставлю ряд ссылок:

и одна полезная команда:


rpm --showrc

она отобразит готовые макросы для сборки.

Собираем Tmux

Теперь соберем, для примера, что нибудь полезное. Собирать будем tmux - терминальный мультиплексор, без которого работать мне не комфортно. Стоит отметить tmux есть в base репозитории CentOS 7, но версия там 1.8, а мы соберем 2.7. Так же у пакета из base репозитория есть зависимость libevent, мы же соберем tmux со статическими библиотеками последних версий.

Готовим исходники

Скачиваем исходники tmux и необходимых библиотек:


cd ~/rpmbuild/SOURCES wget https://github.com/tmux/tmux/releases/download/2.7/tmux-2.7.tar.gz wget https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz wget https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz.asc wget ftp://ftp.gnu.org/gnu/ncurses/ncurses-6.1.tar.gz wget ftp://ftp.gnu.org/gnu/ncurses/ncurses-6.1.tar.gz.sig

gpg --recv-keys 8EF8686D gpg --recv-keys F7E48EDB

Проверяем файлы:


gpg --verify libevent-2.1.8-stable.tar.gz.asc libevent-2.1.8-stable.tar.gz 2>&1 | grep "Good signature" gpg: Good signature from "Azat Khuzhin " gpg --verify ncurses-6.1.tar.gz.sig ncurses-6.1.tar.gz 2>&1 | grep "Good signature" gpg: Good signature from "Thomas Dickey "

Подготовим файл конфигурации tmux:


vim ~/rpmbuild/SOURCES/tmux.conf # Доступные параметры сервера: # Количество буферов set-option -g buffer-limit 50 # Массив пользовательских псевдонимов для команд set-option -g command-alias zoom="resize-pane -Z" # Терминал по умолчанию set-option -g default-terminal "screen-256color" # Ожидание после ввода escape set-option -g escape-time 500 # Отключать сервер без активности set-option -g exit-empty off # Отключать сервер без клиентов set-option -g exit-unattached off # Запрос фокусировки у терминала set-option -g focus-events off # Файл в котором хранится история команд set-option -g history-file ~/.tmux_history # Количество сообщений в журнале для каждого клиента set-option -g message-limit 100 # Устанавливать содержимое терминального буфера обмена с помощью escape set-option -g set-clipboard on # Массив описаний терминалов set-option -g terminal-overrides "xterm:colors=256" set-option -g terminal-overrides "xterm*:colors=256" set-option -g terminal-overrides "screen:colors=256" set-option -g terminal-overrides "screen*:colors=256" # Пользовательские сочетания клавиш # set-option -g user-keys "\e#{?session_many_attached,*,} #{version} # # " # Размер левой части строки состояния set-option -g status-left-length 20 # Стиль левой части строки состояния # Заменяет параметры: status-left-attr status-left-bg status-left-fg set-option -g status-left-style "default" # Позиция строки состояния set-option -g status-position bottom # Формат правой части строки состояния set-option -g status-right " # # %a %d %b %Y %H:%M:%S [%V/%j] " # Размер правой части строки состояния set-option -g status-right-length 40 # Стиль правой части строки состояния # Заменяет параметры: status-right-attr status-right-bg status-right-fg set-option -g status-right-style "default" # Стиль строки состояния # Заменяет параметры: status-attr status-bg status-fg set-option -g status-style "bg=green,fg=black" # Массив переменных окружения которые необходимо обновлять set-option -g update-environment "TERMINFO" # Массив пользовательских клавиш # set-option -g user-keys "\e,#{pane_current_command}}#{?pane_dead,,}" # Цвет отображения времени set-option -gw clock-mode-colour "green" # Формат отображения времени set-option -gw clock-mode-style 24 # Предотвращение изменениея размера окна до высоты set-option -gw force-height 0 # Предотвращение изменениея размера окна до ширины set-option -gw force-width 0 # Высота основной панели set-option -gw main-pane-height 24 # Ширина основной панели set-option -gw main-pane-width 80 # Стиль сочетаний клавиш в режиме копирования set-option -gw mode-keys vi # Стиль окона в режиме копирования # Заменяет параметры: mode-attr mode-bg mode-fg set-option -gw mode-style "bg=yellow,fg=black" # Мониторинг активности в окне set-option -gw monitor-activity on # Мониторинг "звонка" в окне set-option -gw monitor-bell on # Мониторинг "тишины" в окне. Время срабатывания. set-option -gw monitor-silence 0 # Высота других панелей set-option -gw other-pane-height 0 # Ширина других панелей set-option -gw other-pane-width 0 # Стиль рамки активной панели # Заменяет параметры: pane-active-border-attr pane-active-border-bg pane-active-border-fg set-option -gw pane-active-border-style "fg=green" # Начало нумерации панелей set-option -gw pane-base-index 1 # Формат строк состояния панелей set-option -gw pane-border-format "#{?pane_active,#,}#{?window_zoomed_flag,#,} #{pane_index}:#{=6:pane_current_command} #" # Положение строк состояния панелей set-option -gw pane-border-status top # Стиль рамки панели # Заменяет параметры: pane-border-attr pane-border-bg pane-border-fg set-option -gw pane-border-style "fg=green" # Не уничтожать окно по завершению программы set-option -gw remain-on-exit off # Синхронизация панелей на ввод с клавиатуры set-option -gw synchronize-panes off # Стиль активной панели set-option -gw window-active-style "default" # Стиль вкладки окна с активностью в строке состояния # Заменяет параметры: window-status-activity-attr window-status-activity-bg window-status-activity-fg set-option -gw window-status-activity-style "fg=red" # Стиль вкладки окна с "звуком" в строке состояния # Заменяет параметры: window-status-bell-attr window-status-bell-bg window-status-bell-fg set-option -gw window-status-bell-style "fg=red" # Формат вкладки текущего окна в строке состояния set-option -gw window-status-current-format " #{window_index}:#{window_name} " # Стиль вкладки текущего окна в строке состояния # Заменяет параметры: window-status-current-attr window-status-current-bg window-status-current-fg set-option -gw window-status-current-style "reverse" # Формат вкладок окон в строке состояния set-option -gw window-status-format " #{window_index}:#{window_name}#{?window_activity_flag,#,}#{?window_bell_flag,!,}#{?window_silence_flag,~,} " # Стиль вкладки предыдущего окна в строке состояния # Заменяет параметры: window-status-last-attr window-status-last-bg window-status-last-fg set-option -gw window-status-last-style "default" # Строка разделяющая вкладки окон в строке состояния set-option -gw window-status-separator "" # Стиль вкладок окон в строке состояния set-option -gw window-status-style "default" # Стиль панелей set-option -gw window-style "default" # Поиск внутри панели set-option -gw wrap-search on # Генерировать сочетания клавиш set-option -gw xterm-keys on # Настройк сочетаний клавиш # Выбор панелей по Alt + стрелки bind-key -rT root M-Up select-pane -U bind-key -rT root M-Down select-pane -D bind-key -rT root M-Left select-pane -L bind-key -rT root M-Right select-pane -R # Переход в режим копирования bind-key -T root M-PageUp copy-mode -eu # Включение синхронизации ввода с клавиатуры bind-key -T prefix M-s set-option -gw synchronize-panes\; display-message "Синхронизация ввода: #{?synchronize-panes,on,off}" # Блокировка сеанса bind-key -T prefix M-l lock-session # Обновление конфигурации bind-key -T prefix M-r source-file /etc/tmux.conf\; display-message "Обновление конфигурации" # Редактирование конфигурации # bind-key -T prefix M-e # Настройка сеанса # Создать сеанс new-session -s "work"

Готовим SPEC файл

Этот файл будет интереснее предыдущего SPEC файла:


cd ~/rpmbuild/SPECS vim ~/rpmbuild/SPECS/tmux.spec %define libevent 2.1.8 %define ncurses 6.1 Name: tmux Version: 2.7 Release: 1%{?dist} Summary: A terminal multiplexer Vendor: D.F.H. Packager: ChelAxe Group: Applications/System License: ISC and BSD URL: https://github.com/%{name}/%{name} Source0: https://github.com/%{name}/%{name}/releases/download/%{version}/%{name}-%{version}.tar.gz Source1: https://github.com/libevent/libevent/releases/download/release-%{libevent}-stable/libevent-%{libevent}-stable.tar.gz Source2: ftp://ftp.gnu.org/gnu/ncurses/ncurses-%{ncurses}.tar.gz Source3: tmux.conf BuildRequires: gcc, gcc-c++, make, glibc-static %description tmux is a "terminal multiplexer", it enables a number of terminals (or windows) to be accessed and controlled from a single terminal. tmux is intended to be a simple, modern, BSD-licensed alternative to programs such as GNU screen. %prep %setup -q -a1 -a2 %build %__mkdir "libs" pushd "libevent-%{libevent}-stable" %_configure \ --prefix="$(pwd)/../libs" \ --disable-shared %__make install popd pushd "ncurses-%{ncurses}" %_configure \ --prefix="$(pwd)/../libs" \ --with-default-terminfo-dir="/usr/share/terminfo" \ --with-terminfo-dirs="/etc/terminfo:/lib/terminfo:/usr/share/terminfo:$HOME/.terminfo" %__make install popd %_configure \ --enable-static \ --prefix="/usr" \ CFLAGS="-Ilibs/include -Ilibs/include/ncurses" \ LDFLAGS="-Llibs/lib -Llibs/include -Llibs/include/ncurses" \ LIBEVENT_CFLAGS="-Ilibs/include" \ LIBEVENT_LIBS="-Llibs/lib -levent" \ LIBNCURSES_CFLAGS="-Ilibs/include" \ LIBNCURSES_LIBS="-Llibs/lib -lncurses" %__make %install %__rm -rf %{buildroot} %make_install install -d -m 755 %{buildroot}%{_sysconfdir} install -p -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/tmux.conf %clean %__rm -rf %{buildroot} %files %defattr(-,root,root,-) %doc README TODO CHANGES example_tmux.conf %config(noreplace) %{_sysconfdir}/tmux.conf %{_bindir}/tmux %{_mandir}/man1/tmux.1.gz %changelog * Fri Jun 29 2018 ChelAxe (D.F.H.) - 2.7-1%{?dist} - Rebuild for new version tmux. * Tue May 1 2018 ChelAxe (D.F.H.) - 2.6-1%{?dist} - Initial package.

Сборка


rpmbuild -ba --sign ~/rpmbuild/SPECS/tmux.spec cp ~/rpmbuild/RPMS/x86_64/tmux-2.7-1.el7.centos.x86_64.rpm ~/rpmbuild/REPO/Packages/ createrepo --update ~/rpmbuild/REPO

Не забываем подписать метаданные:


gpg --detach-sign --armor ~/rpmbuild/REPO/repodata/repomd.xml

Смотри что и как получилось:


tree ~/rpmbuild/ -L 2 /home/chelaxe/rpmbuild/ ├── BUILD │ ├── chelaxe-release │ └── tmux-2.7 ├── BUILDROOT ├── REPO -> /var/www/repo ├── RPMS │ ├── noarch │ └── x86_64 ├── SOURCES │ ├── chelaxe-release │ ├── chelaxe-release.tar.gz │ ├── libevent-2.1.8-stable.tar.gz │ ├── libevent-2.1.8-stable.tar.gz.asc │ ├── ncurses-6.1.tar.gz │ ├── ncurses-6.1.tar.gz.sig │ ├── tmux-2.7.tar.gz │ └── tmux.conf ├── SPECS │ ├── chelaxe-release.spec │ └── tmux.spec └── SRPMS ├── chelaxe-release-1.0-1.el7.centos.src.rpm └── tmux-2.7-1.el7.centos.src.rpm

Установка и запуск

Устанавливаем наш пакет:


sudo yum clean all sudo yum install -y tmux

Запускаем tmux и радуемся:


tmux attach-session

Собираем fbida

Собирать будем fbida - комплект приложений для просмотра изображений в консоли. Данный пакет не нашел под Centos 7.

Готовим исходники

Скачиваем исходники fbida:


cd ~/rpmbuild/SOURCES wget https://www.kraxel.org/releases/fbida/fbida-2.14.tar.gz wget https://www.kraxel.org/releases/fbida/fbida-2.14.tar.gz.asc

Экспортируем GPG ключи для проверки исходников:


gpg --recv-keys D3E87138

Проверяем файлы:


gpg --verify fbida-2.14.tar.gz.asc fbida-2.14.tar.gz 2>&1 | grep "Good signature" gpg: Good signature from "Gerd Hoffmann (work) "

Готовим SPEC файл

В этом SPEC файле будет больше зависимостей:


cd ~/rpmbuild/SPECS vim ~/rpmbuild/SPECS/fbida.spec Name: fbida Version: 2.14 Release: 1%{?dist} Summary: FrameBuffer Imageviewer Vendor: D.F.H. Packager: ChelAxe Group: Applications/Multimedia License: GPLv2+ URL: https://www.kraxel.org/blog/linux/fbida/ Source: https://www.kraxel.org/releases/fbida/fbida-%{version}.tar.gz BuildRequires: libexif-devel fontconfig-devel libjpeg-turbo-devel BuildRequires: libpng-devel libtiff-devel pkgconfig BuildRequires: giflib-devel libcurl-devel libXpm-devel BuildRequires: pixman-devel libepoxy-devel libdrm-devel BuildRequires: mesa-libEGL-devel poppler-devel poppler-glib-devel BuildRequires: freetype-devel mesa-libgbm-devel Requires: libexif fontconfig libjpeg-turbo Requires: libpng libtiff giflib Requires: libcurl libXpm pixman Requires: libepoxy libdrm mesa-libEGL Requires: poppler poppler-glib freetype Requires: mesa-libgbm ImageMagick dejavu-sans-mono-fonts %description fbi displays the specified file(s) on the linux console using the framebuffer device. PhotoCD, jpeg, ppm, gif, tiff, xwd, bmp and png are supported directly. For other formats fbi tries to use ImageMagick"s convert. %prep %setup -q %{__sed} -i -e "s,/X11R6,g" GNUmakefile %install %__rm -rf %{buildroot} %make_install PREFIX=/usr %clean %__rm -rf %{buildroot} %files %defattr(-,root,root,-) %doc Changes COPYING INSTALL README TODO VERSION %{_prefix}/* %changelog * Tue May 1 2018 ChelAxe (D.F.H.) - 2.14-1%{?dist} - Initial package.

Сборка

Собираем пакет и добавляем его в репозиторий:


sudo yum install -y libexif-devel fontconfig-devel libjpeg-turbo-devel libpng-devel libtiff-devel pkgconfig giflib-devel libcurl-devel libXpm-devel ImageMagick dejavu-sans-mono-fonts pixman-devel libepoxy-devel libdrm-devel mesa-libEGL-devel poppler-devel poppler-glib-devel mesa-libgbm-devel rpmbuild -ba --sign ~/rpmbuild/SPECS/fbida.spec cp ~/rpmbuild/RPMS/x86_64/fbida-2.14-1.el7.centos.x86_64.rpm ~/rpmbuild/REPO/Packages/ createrepo --update ~/rpmbuild/REPO

Не забываем подписать метаданные:


gpg --detach-sign --armor ~/rpmbuild/REPO/repodata/repomd.xml

Установка и запуск

Устанавливаем наш пакет:


sudo yum clean all sudo yum install -y fbida

Настройка доступа по http/https

Теперь обеспечим доступ к нашему репозиторию по http/https.

Настройка

Первым делом настроем наш Apache:


sudo mv /etc/httpd/conf.d/welcome{.conf,.bak} sudo cp /etc/httpd/conf/httpd{.conf,.bak}

sudo vim /etc/httpd/conf/httpd.conf # Слушать на определенном интерфейсе и порте Listen 192.168.0.2:80 # Email адрес и имя сервера ServerAdmin [email protected] ServerName repo.chelaxe.ru # Не светить версию Apache ServerSignature Off ServerTokens Prod sudo cp /etc/httpd/conf.d/ssl{.conf,.bak} sudo vim /etc/httpd/conf.d/ssl.conf # Слушать на определенном интерфейсе и порте Listen 192.168.0.2:443 https # OCSP (Online Certificate Status Protocol) SSLStaplingCache "shmcb:logs/stapling-cache(128000)"

Проверим конфигурацию:


sudo apachectl configtest Syntax OK

sudo systemctl start httpd sudo systemctl enable httpd

Настраиваем наш репозиторий:


# Создадим свой файл с параметрами Диффи-Хеллмана cd /etc/ssl/certs sudo openssl dhparam -out dhparam.pem 4096 # Готовим публичный ключ для HKPK (HTTP Public Key Pinning) sudo openssl x509 -noout -in /etc/pki/tls/certs/localhost.crt -pubkey | openssl asn1parse -noout -inform pem -out /tmp/public.key # Получаем отпечаток публичного ключа для HKPK (HTTP Public Key Pinning) openssl dgst -sha256 -binary /tmp/public.key | openssl enc -base64 aQxRkBUlhfQjidLUovOlxdZe/4ygObbDG7l+RgwzSWA= rm -rf /tmp/public.key

Настройка VirtualHost:


sudo vim /etc/httpd/conf.d/repo.conf ServerAdmin "[email protected]" ServerName "repo.chelaxe.ru" DocumentRoot "/var/www/repo" AllowOverride None Options Indexes SSLEngine on # HSTS (HTTP Strict Transport Security) Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" # HKPK (HTTP Public Key Pinning) Header set Public-Key-Pins "pin-sha256=\"aQxRkBUlhfQjidLUovOlxdZe/4ygObbDG7l+RgwzSWA=\"; max-age=2592000; includeSubDomains" # Гнать поисковых роботов Header set X-Robots-Tag "none" # Защита от некоторых XSS-атак Header set X-XSS-Protection "1; mode=block" # Защита от кликджекинг-атак Header always append X-Frame-Options DENY # Защита от подмены MIME типов Header set X-Content-Type-Options nosniff # Защита от XSS-атак Header set Content-Security-Policy "default-src "self";" # OCSP (Online Certificate Status Protocol) SSLUseStapling on # Отключаем сжатие SSL (защита от атаки CRIME) SSLCompression off # Отключаем SSLv2 и SSLv3 SSLProtocol all -SSLv2 -SSLv3 # Набор шифров SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH # Предпочтения сервера при согласовании шифров SSLHonorCipherOrder on # Используем свой файл с параметрами Диффи-Хеллмана # cat /etc/ssl/certs/dhparam.pem >> /etc/pki/tls/certs/localhost.crt # для 2.4.8 и старше # SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem" SSLOptions +StrictRequire SSLCertificateFile "/etc/pki/tls/certs/localhost.crt" SSLCertificateKeyFile "/etc/pki/tls/private/localhost.key"

Т.к. в Centos 7 у нас Apache 2.4.6, а не 2.4.8, то параметры Диффи-Хеллмана необходимо вшить в сертификат:


sudo bash -c "cat /etc/ssl/certs/dhparam.pem >> /etc/pki/tls/certs/localhost.crt"

По этой же причине с HTTP/2 у нас ничего не получится, но теперь вы можете собрать сами свежий Apache и воспользоваться HTTP/2.



Сертификат от Let"s Encrypt

Пока у нас свой сертификат и это не красиво, так что получим сертификат от Let"s Encrypt:


sudo certbot --apache --agree-tos --email [email protected] -d repo.chelaxe.ru

При ответе на вопросы, выбираем использование rewrite для перенаправления всех на https. В результате в файле изменяться строки у VirtualHost для http:


RewriteEngine on RewriteCond %{SERVER_NAME} =repo.chelaxe.ru RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI}

и у VirtualHost для https:


Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/repo.chelaxe.ru/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/repo.chelaxe.ru/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/repo.chelaxe.ru/chain.pem

Строку Include /etc/letsencrypt/options-ssl-apache.conf закомментируем.


Тут стоит напомнить о необходимости добавить файл с параметрами Диффи-Хеллмана в конец сертификата:


sudo bash -c "cat /etc/ssl/certs/dhparam.pem >> /etc/letsencrypt/live/repo.chelaxe.ru/cert.pem"

И изменить заголовок HKPK (HTTP Public Key Pinning):


# Готовим публичный ключ для HKPK (HTTP Public Key Pinning) sudo openssl x509 -noout -in /etc/letsencrypt/live/repo.chelaxe.ru/cert.pem -pubkey | openssl asn1parse -noout -inform pem -out /tmp/public.key # Получаем отпечаток публичного ключа для HKPK (HTTP Public Key Pinning) openssl dgst -sha256 -binary /tmp/public.key | openssl enc -base64 aidlhfQjoxRkbvOlxdZLBUe/4ygOUDG7l+RgwzQbSWA= rm -rf /tmp/public.key

И изменим соответственно строку в конфигурации:


# HKPK (HTTP Public Key Pinning) Header set Public-Key-Pins "pin-sha256=\"aidlhfQjoxRkbvOlxdZLBUe/4ygOUDG7l+RgwzQbSWA=\"; max-age=2592000; includeSubDomains"

Проверим конфигурацию и перечитаем конфигурацию:


sudo apachectl configtest Syntax OK sudo systemctl reload httpd

Есть еще одна проблема. Для обновления сертификата добавим запись в крон:


sudo crontab -e SHELL=/bin/bash [email protected] @daily certbot renew >> /var/log/certbot-renew.log

Но этого не достаточно, нужно еще дописать автоматическое добавление файла с параметрами Диффи-Хеллмана и параметры HKPK (HTTP Public Key Pinning).

Файлы.htaccess

Настройка через.htaccess лучше избежать в данном случае, если Вы все же решили его использовать, то сделайте следующее:


sudo chown apache:apache ~/rpmbuild/REPO/.htaccess sudo chmod 600 ~/rpmbuild/REPO/.htaccess sudo chcon -R -t httpd_sys_content_t ~/rpmbuild/REPO/.htaccess

и AllowOverride смените на All . Так же добавьте:


IndexIgnore .htaccess

для исключения в отображении на сайте.


Для vsftpd можно использовать опции:


hide_file={.htaccess} deny_file={.htaccess}

А вообще смените стандартное имя.htaccess на другое с помощью параметра AccessFileName:


AccessFileName .acl

Тут можно используя модуль mod_autoindex Apache настроить внешний вид. Завернуть в noscript тег и используя html5, css3, javascript, jquery, bootstrap, backbone, awesome сделать конфетку, как это сделал я:



Вот что будет при использовании в браузере без поддержки javascript или с отключенным:



Сами файлы web интерфейса нужно будет скрыть как от vsftpd так и от демонстрации на сайте, делается аналогичными способами что и для сокрытия.htaccess файла.


Настроить внешний вид листинга через mod_autoindex или в nginx:

Настройка доступа по ftp

Запускаем службу и прописываем ее в автозапуск:


sudo systemctl start vsftpd sudo systemctl enable vsftpd

Настройка службы:


sudo cp /etc/vsftpd/vsftpd{.conf,.bak} sudo vim /etc/vsftpd/vsftpd.conf anonymous_enable=YES local_enable=NO write_enable=NO local_umask=022 dirmessage_enable=YES xferlog_enable=YES connect_from_port_20=YES xferlog_std_format=YES listen=NO pam_service_name=vsftpd userlist_enable=YES tcp_wrappers=YES force_dot_files=NO anon_root=/var/www/repo no_anon_password=YES hide_ids=YES sudo usermod -d /var/www/repo ftp

Настроем SeLinux:


sudo semanage fcontext -a -t public_content_t "/var/www/repo(/.*)?" sudo restorecon -Rv "/var/www/repo"

Перезапустим службу:


sudo systemctl restart vsftpd

В случае использования.htaccess файла - продублируйте, чтобы файл был надежно защищен от доступа по ftp:


sudo chcon -R -t httpd_sys_content_t ~/rpmbuild/REPO/.htaccess

Заключение

Собственно на этом все. Надеюсь, данный мануал будет Вам полезен.

Сперва давайте разберёмся, что должно быть в системе для сборки rpm-пакета. Обязательно должен быть установлен пакет rpm-build . Без него не будет доступна команда rpmbuild. Наряду с ним, по зависимостям поставится еще ряд пакетов, используемых при сборке. В зависимостях для сборки пакета в РОСЕ обычно не принято прописывать компилятор C/C++, по этому поводу рано или поздно вам понадобятся пакеты gcc и gcc-c++ Все остальные зависимости должен попросить сам пакет. Конечно бывают промахи, и в процессе сборки вы понимаете, что что-то упустили, но это обычно бывает довольно редко и не критично.

А что собственно из себя представляет RPM пакет? RPM-пакеты делятся на пакеты с исходниками - src.rpm и пакеты, готовые к установке - %{arch}.rpm . В src.rpm пакетах содержится исходный тарболл (исходник программы), какие-либо другие исходники, пачти и самый главный spec-файл, который управляет процессом сборки. Все эти файлы упакованы в cpio архив. Когда вы пытаетесь войти в src.rpm пакет при помощи файлового менеджера mc , вы его увидите. Также в пакете присутствует некоторые файлы с информацией.

В %{arch}.rpm-пакетах содержится cpio-архив с файлами, которые после установки разложатся по соответствующим каталогам, файлы информации и установочные скрипты.

Также вы можете встретить без исходного кода. Обычно их создают для проприетарных программ, которые нельзя включать в дистрибутив (исходников нет, а бинарник каким-то образом нужно переделать либо просто запрещено размещать на зеркалах дистрибутива лицензией). Внутри этого пакета находится обычно только spec-файл, а бинарник скачивается и, при необходимости, модифицируется, в процессе установки пакета (например, в post-скрипте, о котором речь пойдет ниже).

Собирать пакеты можно из-под любого пользователя. Делать это из-под root"а не рекомендуется, т.к. есть вероятность, что корнем для секции инсталляции окажется каталог / и тогда команда rm -rf %{buildroot} уничтожит все на свете. Также бывает, что «кривые» пакеты не правильно выполняют инсталляцию, и ставятся не во временный каталог, а прямо куда-нибудь в %{_prefix} (/usr ). Часть файлов будет потеряна, хотя на работоспособности пакета на этой машине понятное дело это не скажется.

Что нужно сделать, чтобы можно было собирать пакеты из-под обычного пользователя? Первым делом нужно создать в своём домашнем каталоге файл директорию rpmbuild со следующей структурой:

~/rpmbuild |-- BUILD |-- BUILDROOT |-- RPMS | |-- i586 | |-- x86_64 | `-- noarch |-- SOURCES |-- SPECS `-- SRPMS

Каталоги BUILD , RPMS , SOURCES , SPECS , SRPMS вам необходимо создать вручную, подкаталоги каталога RPMS должны создаться автоматически во время сборки в зависимости от архитектуры.

В РОСЕ не принято писать сборщика пакета и вендора в spec-файлах; эти значения выставляются автоматически системой сборки ABF. Также ABF автоматически подписывает собранные пакеты ключом соответствующего репозитория. Поэтому эти вопросы мы здесь затрагивать не будем.

Теперь давайте посмотрим что из себя представляет самый главный файл rpm-пакета, spec-файл. Для примера возьмём его из пакета stardict . Этот пакет хорошо подходит для обучения, так как в нем есть несколько тарболов (исходник программы, упакованный tar ’ом), получается несколько пакетов и есть такая вещь, как схемы. Обычно spec-файл имеет такое же имя, как и сам пакет (stardict.spec ). Однако вы можете добавить версию пакета (stardict-2.spec ), удобно если вы пытаетесь поддерживать несколько веток программ. Можно даже дать какое-нибудь другое название, однако это мягко говоря не удобно.

Итак, содержимое файла stardict.spec приведено ниже. Мы сразу будем вставлять комментарии после определенных секций, но если вы соедините все блоки в один и тот же файл, то получите полноценный stardict.spec .

Spec-файл состоит из секций и шапки:

Summary: StarDict dictionary Name: stardict Version: 2.4.8 Release: 4 License: GPL URL: Group: User Interface/Desktops Source0: %{name}-%{version}.tar.bz2 Source1: %{name}-tools-%{version}.tar.bz2 Patch0: %{name}-2.4.8-desktop.patch

Summary - краткое описание пакета, Name - название, Version - версия, Release - релиз. Последним трем тегам соответствуют макроопределения %{name} , %{version} , %{release} . Их часто используют в дальнейшем. Name и Version обычно совпадает с название тарбола. Если же они отличаются, то в принципе ничего страшного, но придётся в некоторых местах spec-файла действовать нестандартными методами. Если вы собираете пакет из cvs, svn и т. д., то рекомендуется в самом начале файла сделать макроопределение %define date 20070422 (именно в таком формате, сами догадайтесь почему) и тег Release определить следующим образом:

Release: 0.git%{date}.4

Source* - исходные тексты, тарболы, просто файлы. В данном примере идут два тарбола с разными программами, что делает сборку намного сложнее. Обычные файлы, например, конфигурации, могут просто копироваться в секции %%install при помощи команды install . У нее простой синтаксис, install -m маска_как_у_chmod что куда . При помощи нее можно также создавать каталоги. В нашем примере она не используется, но подробнее про неё можно почитать в man.

Patch - патчи, исправления, которые вы или кто-то другой выпустили для данного пакета. Не принято изменять исходный текст самой программы, а затем завертывать ее в тарбол. Принято накладывать заплатки. Делать их можно следующим образом. Распаковываете исходный тарбол, у нас это будет stardict-2.4.8, далее копируете stardict-2.4.8 в stardict-2.4.8.orig. После этого изменяете код в каталоге stardict-2.4.8, выходите из него и отдаете команду diff -ur stardict-2.4.8.orig stardict-2.4.8 > stardict-2.4.8-название_патча.patch. Как видно, до навания патча идёт %{name}-%{version} пакета. В самом spec-файле обязательно следует писать название патча без макроопределений. По крайней мере версию, точно. Иначе при обновлении версии пакета, у вас и обновится версия патча, определённая макросом %{version} , а патч может быть подойдёт к новой версии программы и без каких либо изменений. Если же во время самой сборки патч не смог наложиться, то его следует либо переделать под данную версию программы, либо отключить в секции %setup .

В spec-файлах пакетов многих дистрибутивов вы также можете в заголовке встретить определение BuildRoot - каталога, в котором осуществляется сборка. В РОСЕ в этом определении нет необходимости, имя BuildRoot формируется автоматически.

BuildRequires: libgnomeui-devel >= 2.2.0 BuildRequires: scrollkeeper BuildRequires: gettext Requires(post): GConf2 Requires(post): scrollkeeper Requires(postun): scrollkeeper

BuildRequires - секция, в которую через запятую или через пробел прописываются пакеты, которые требуются для сборки нашей программы. Почерпнуть их можно из каких-нибудь файлов README и INSTALL (хотя там редко бывает что-то полезное по этому поводу), из процесса конфигурации (на данный момент обычно это скрипт configure ) и из самого процесса сборки (иногда configure что-нибудь пропустит и сборка остановится).

Requires - в эту секцию записываются пакеты или файлы(!), которые будет требовать данный пакет при установке. При сборке в зависимости автоматически пропишутся все библиотеки, которые наш пакет потребует, но вы также можете указать пакеты вручную. Rpm также автоматически прописывает зависимости perl, python, mono и некоторые другие (все эти зависимости прописываются не в spec-файл разумеется, а в сам пакет). Если вам не нужно, чтобы зависимости прописывались автоматически, следует прописать в spec-файл новый тег AutoReq: no. Обычно его прописывают при сборки проприетарных программ, так как rpm добавляет внутренние зависимости из собираемой программы.

В нашем примере используются конструкции Requires(post) и Requires(postun) для зависимостей в скриптах установки и удаления. В принципе достаточно и простого Requires . Здесь особенно нечего комментировать. Просто самому StarDict в процессе работы эти зависимости не нужны. Нужны они только при инсталляции и удалении.

Есть ещё несколько полезных тегов, которые здесь не используются.

Provides: название1, название2

Другие названия, помимо %{name} , на которые будет откликаться данный пакет. Удобно указывать, если вы сменили название пакета, а другие пакеты продолжают зависеть от старого названия.

Obsoletes: название1, название2

Удаление указанных пакетов при установки текущего пакета. Как бы говорится, что данный пакет замещает собой указанные (по функциональности, по набору файлов и т. п.). Можно использовать конструкцию название < . Тут вы должны сами понимать, что к чему.

Conflicts: название1, название2

Перечисляются пакеты, которые конфликтуют с текущим. Подразумевается что указанные пакеты нужно вручную удалить, перед установкой нашего. Также используются конструкции со знаками сравнения и версиями (см. выше).

Suggests: название1, название2

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

Epoch: число

Обычно или не указывается совсем или равняется 0. Суть этого параметра вот в чем. Пусть всё наш же пакет stardict имеет версию 2.4.8 , а также есть более старый 2.4.5 . Так вот если %{epoch} у stardict 2.4.5 будет 1 , а у 2.4.8 - 0 , то пакет 2.4.5 будет всегда новее, чем 2.4.8 . О чём при установки вам RPM и скажет. Этот параметр удобен, если вы хотите откатиться на предыдущую версию (разумеется, если вы это все выкладываете в публичный репозиторий и хватаете все через urpmi или rpmdrake . Для «домашних» нужд подойдёт параметр к rpm --force ). Если определён тег Epoch: 0 , то пакет будет иметь приоритет перед пакетом с непоределённым тегом Epoch .

BuildArch: архитектура

Архитектура, под которую будет собираться наш пакет. Если эта опция не указана, то пакет соберётся под текущую архитектуру. Обычно эту опцию указывают для того, чтобы собирать пакет архитектуры noarch , то есть пакет, в котором нет бинарников.

ExclusiveArch: архитектура1 архитектура2

Архитектуры, под которые данный пакет может быть собран. Обычно используется при сборки модулей к ядру.

На этом шапка заканчивается и начинаются отдельные секции.

%description StarDict is an international dictionary written for the GNOME environment. It has powerful features such as "Glob-style pattern matching," "Scan seletion word," "Fuzzy search," etc.

Описание главного пакета, того, у которого будет имя %{name}

%package tools Summary: StarDict-Editor Requires: %{name} = %{version}-%{release} Group: User Interface/Desktops

Здесь мы создаём новый пакет, название которого будет %{name}-tools . Если нужно обозвать пакет совсем по другому, то следует сделать, например, так: %package -n tools-stardict . Версия нового пакета берётся из заданного тега Version . Обратите внимание на Requires . В нём прописана зависимость на главный пакет stardict . Если бы он имел %{epoch} , то необходимо было бы обязательно указать Requires: %{name}-%{epoch}:%{version}-%{release} . Иначе вам просто не удастся установить это пакет.

%description tools A simple tool for StarDict.

Описание второго пакета

%prep %setup -q -a1 %patch0 -p1

Секция %prep в ней начинается подготовка к сборке. %setup распаковывает исходники. Опция -q не показывает вывод распаковывания архива. Опция -a1 используется для распаковки %{SOURCE1} , второго тарбола внутрь(!) каталога первого тарбола. Соответственно цифра указывает на номер SOURCE. Ещё иногда используется параметр -b , тогда второй тарбол распаковывается в тот же каталог, что и первый. Соответственно если у нас один тарбол, то опции -a , -b не используются.

Если у вас первый каталог в тарболе имеет отличное от %{name}-%{version} название, то rpm не сможет войти автоматом в этот каталог. В таком случае следует немного изменить %setup . Если в архиве stardict-2.4.8.tar.bz2 первый каталог имеет название, например, просто stardict , то выглядеть это будет так:

%setup -q -n %{name} -a1

Сразу после распаковки пакета, перед %patch , если нужно, можно скопировать файлы, или запустить какие либо программы для изменения исходников. Допустим скопировать файл русификации, или подправить sed’ом какой-нибудь исходник. Просто вызываете здесь cp , sed или ещё что-то. В качестве корня здесь выступает каталог, в который распаковался первый тарболл (за него отвечает переменная $RPM_BUILD_DIR, но она крайне редко используется).

При помощи %patch накладываются патчи. Если вы делали патч, как мы писали выше, то у вас всегда будет параметр -p1 . Также часто используют параметр -b .название_патча , для создания резервной копии.

%build pushd %{name}-tools-%{version} %configure %make popd %configure %make

Секция %build , именно здесь происходит сборка пакета. Обратите внимание на pushd и popd . Этими командами мы переходим и выходим из каталога второго тарбола. Именно он будет корневым каталогом после pushd . После команды popd мы вернёмся в каталог первого тарбола. Соответственно если у вас один исходник, то не нужно использовать эти команды.

Так как у нас две программы в одном пакете, то мы выполняем два раза концигурацию %configure и два раза make . Если пакет конфигурируется при помощи autotools , то макросом %configure запускается скрипт configure из корня распакованного тарбола. У него обычно бывает много параметров, их можно посмотреть из командной строки при помощи ./configure --help . После %configure вы можете указать нужные вам параметры. Заметьте, что вызов %configure и ./configure отличаются. В первом случае конфигуратору будут переданы правильные каталоги для инсталляции (а также стандартные параметры), во втором - каталоги по умолчанию.

После успешной конфигурации идет сборка, а именно макрос %make , вызывающий одноименную команду с некоторыми дополнтельными параметрами (в частности, на многопроцессорных машинах используется параллельная сборка - опиця -j ).

Если пакет не использует autotools , то %configure , а может и %make использовтаь не нужно, для сборки прочтите файл README и INSTALL. В РОСЕ есть макросы и на другие случаи жизни - например, %cmake для одноименного инструмента сборки.

Когда сборка успешна закончена, в действие вступает секция %install .

%install pushd %{name}-tools-%{version} %makeinstall_std popd %makeinstall_std %find_lang %{name}

%%find_lang , поиск файлов локализации. Параметром у неё является название файлов, которые будут лежать после установки в каталоге %{buildroot}/usr/share/locale/*/LC_MESSAGES/*.mo . Обычно оно соответствует %{name} . Если это не так, пишите другое имя.

Во многих spec-файлах вы можете заметить выполнение команды rm -rf %{buildroot} или rm -rf $RPM_BUILD_ROOT в самом начале секции %install , а также секцию %clean с такими же строками. В современной РОСЕ в этом нет необходимости, такая зачистка выполняется автоматически.

%preun %preun_uninstall_gconf_schemas %{name}

Секции для установочных скриптов. Вообще их бывает несколько. %pre - выполняется перед установкой, %post - после установки, %preun - перед удалением, %postun - после удаления. В нашем примере при удалении удаляются схемы Gconf. Здесь мы предполагаем, что в пакете только одна схема и ее имя совпадает с именем пакета. Обратите внимание, что для удаления схем мы вызываем специальный макрос; этот макрос раскрывается rpmbuild РОСЫ в набор необходимых команд оболочки Shell, которые, собственно, и удаляют схему. Установка схем при установке пакета выполняется автоматически за счет файловых триггеров RPM .

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

В секциях %files мы должны указать какие файлы должны быть упакованы в пакеты. Все файлы должны быть оговорены, в противном случае rpmbuild выдаст сообщение о неупакованных файлах.

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

Для определения каталогов используются специальные макроопределения.

  • %{_prefix} - /usr
  • %{_sysconfdir} - /etc
  • %{_bindir} - /usr/bin
  • %{_datadir} - /usr/share
  • %{_libdir} - /usr/lib или /usr/lib64 в зависимости от разрядности системы
  • %{_lib} - соответственно /lib или /lib64
  • %{_libexecdir} - /usr/libexec
  • %{_includedir} - /usr/unclude
  • %{_mandir} - /usr/share/man
  • %{_sbindir} - /usr/sbin
  • %{_localstatedir} - /var .
  • %{systemd_libdir} - /usr/lib/systemd
%files -f %{name}.lang %defattr(-, root, root) %doc AUTHORS COPYING INSTALL README NEWS %{_sysconfdir}/gconf/schemas/stardict.schemas %{_bindir}/stardict %{_bindir}/stardict-editor %{_libdir}/bonobo/servers/GNOME_Stardict.server %{_datadir}/applications/*.desktop %{_datadir}/stardict %{_datadir}/locale/*/LC_MESSAGES/* %{_datadir}/pixmaps/stardict.png %{_datadir}/gnome/help/%{name}/* %{_datadir}/idl/GNOME_Stardict.idl %{_datadir}/omf/* %doc %{_mandir}/man?/*

%doc помечает файлы как документацию. Третья строка копирует указанные файлы в каталог %{_datadir}/doc/%{name}-%{version} . По умолчанию файлы в rpm пакете будут иметь владельцем root’а, а права доступа у низ будут такие же, как и в процессе установки. Если это необходимо поменять, то воспользуйтсь конструкцией %defattr .

%files tools %{_bindir}/stardict-editor

Тоже самое для пакета stardict-tools . Если бы он назывался tools-stardict , то %files выглядел бы так:

%files -n tools-%{name}.

Последнее, что идёт в spec-файле, это %changelog . В changelog’е вы указывает изменения в пакете по сравнению с предыдущей версией. Синтаксис его примерно следующий.

%changelog * Sun Apr 22 2007 Your Name - 2.4.8-4 - update desktop patch

Макроопределения

Теперь пора познакомиться поближе с макросами и переменными. Допустим, мы собираем пакет из SVN, в данном случае в релиз обычно включается дата ревизии. В самом начале spec-файла нужно определить переменную date:

%define date 20070612

Как мы видим, за определение переменных отвечает макроопределение %define . Теперь в любом месте spec-файла мы можем использовать нашу переменную в виде %{date} (скобки не обязательны, но в РОСЕ принято брать в скобки переменные, и не брать - макроопределения; так их проще различать). Например, определение основных параметров будет выглядеть примерно так:

Version: 0.5 Release: 0.svn%{date}.3

Обратите внимание, что перед датой стоит 0. , а после даты - число, которое и увеличивается при необходимости поднять релиз. Зачем так сделано? Когда наконец выйдет окончательная версия (в нашем случае - 0.5 ), ревизию можно будет убрать, а в релиз прописать просто 1 . При этом литерально 1 больше, чем любая строка, начинающаяся на 0 , и пакет будет считаться более новым, чем предварительные пакеты, собиравшиеся на основе ревизий SVN.

Крайне популярным макроопределением является конструкция

%if условие действие1 %else действие2 %endif

или просто %if без %else . Суть проста, если условие стоящее при %if истина, то выполняется действие1 , в противном случае выполняется действие2 .

Допустим, мы опять же собираем что-нибудь из SVN. Обычно внутри архива, если он из SVN, вместо каталога %{name}-%{version} указывают просто %{name} (архив sim-0.9.5.tar.bz2 внутри имеет каталог sim , так как финального релиза sim 0.9.5 не существует. Конечный же релиз будет иметь первым каталогом sim-0.9.5 ). Чтобы всякий раз не переписывать spec-файл, можно сделать следующие макроопределения:

%define svn 1 ... %prep %if %{svn} %setup -q -n %{name} %else %setup -q %endif

Если переменная svn не определена, то будет выполняться часть сценария после %else . Можно также использовать более строгое условие (не забудьте про кавычки):

%define svn 1 ... %prep %if "%{svn}" == "1" %setup -q -n %{name} %else %setup -q %endif

Внутри всех секций spec-файла мы можем использовать любые команды Linux, без каких либо «наворотов», а вот в шапке файла не всё так просто. Например, нам нужно определить версию firefox для пакета (допустим epiphany) и прописать ее в секцию Requires: . Выглядеть это будет следующим образом:

Requires: firefox = %(rpm -q firefox --qf "%%{version}")

Обратите внимание на то, что внешняя команда выполняется в %() (почти, как в bash - $() ) и в spec-файле необходимо ставить два знака % в параметрах. Таким образом можно вызывать любые команды Linux, например, для определения версии ядра.

Ещё одним популярным макроопределение является конструкция %ifarch .. %endif . Если архитектура соответствует указанной после %ifarch , то выполняется какое либо действие. Архитектуры бывают i386, i486, i586, i686, i?86, x86_64, и понятное дело некоторые другие, с которыми вы наверно не столкнётесь.

Как уже отмечалось выше во всех секциях spec-файла вы можете использовать любые команды Shell, включая for, while, if и др.

Сборка пакета

Теперь перейдём непосредственно к сборке пакета. Исходники и патчи должны лежать в каталоге SOURCES , а spec файл в каталог SPECS . После этого нужно отдать команду:

Rpmbuild -ba spec-файл

После этого пакет соберётся (или не соберётся, а вывалится с ошибками), и в подкаталогах каталога RPMS появятся бинарные пакеты, а в каталоге SRPMS появится исходник.

Очень часто, перед самым завершением сборки, rpmbuild выдаёт сообщение о найденных, но неупакованных файлах. Это означает, что вы просто не указали их в секции %files . Необходимо просто добавить их туда. Если же вы не хотите чтобы эти файлы попадали в пакет, то можно воспользоваться одним из следующих способов:

  • Добавить в секцию %files макроопределение
%exclude путь_к_файлу/файл
  • Добавить в начало spec-файла макроопределение
%define _unpackaged_files_terminate_build 0

Если необходимо собрать только бинарник или только исходник, то вместо -ba следует использовать -bb и -bs соответственно. Из полезных параметров rpmbuild можно отметить -clean (удалить весь мусор), -rmsource (удалить исходники из каталога SOURCE ) и -target=архитектура (собрать пакет под конкретную архитектуру).

Можно также выполнять сценарии только в определённой секции. Описывать подобные параметры мы здесь не будем, см. man rpmbuild .

Сборка RPM пакета из уже установленного в системе

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

Для решения этой проблемы следует воспользоваться утилитой rpmrebuild. Эта написанная на bash утилита доступна в contrib-репозитории РОСЫ.

Работать с ней крайне просто. Нужно отдать всего лишь команду:

Rpmrebuild название_установленного_пакета

Если какой-либо файл был изменён, то вам об этом сообщат, но процесс сборки не прервётся.

Rpmrebuild обладает огромным количеством параметров, например, вы можете изменять release пакета, changelog, скрипты, секции Requires, описания пакета и многое другое. Можете даже просто напросто изменить spec-файл, который скрипт сгенерирует сам. Он правда будет немного страшный, но это все же лучше, чем ничего.

Все параметры можно посмотреть при помощи

Rpmrebuild --help

Все найденные мною в интернете мануалы в большинстве случаев сводятся к двум видам:
— перевод документации (с которым я всё-таки советую ознакомиться, тк в моей статье будет освещена лишь часть информации, которая вам в дальнейшем понадобится)
— краткие инструкции, как запустить rpmbuild когда у нас уже есть всё.
Лично я столкнулся с необходимость собрать пакет из исходника, вместе с которым небыло ничего, а главное spec-файла, по которому необходимо собрать пакет. В итоге мы напишем собственный spec-файл для сборки пакета и добавим туда сразу собственные конфиги (этот вопрос тоже не сильно освящён).

Я буду собирать пакет из исходников ffmpeg для AirVideoServer, который я уже рассказывал как . Я сторонник того, что бы в дистрибутиве, который использует пакетный менеджер, приложения ставились именно через него, по этому на CentOS я не люблю собирать ПО из исходников. По этой причине я решил собрать себе всё в пакеты. Сборка так же необходимых lame (он идёт уже со spec-файлов в комплекте) и x264 (под него вы сможете написать spec-файл сами, после прочтения этой статьи) не должна вызвать у вас проблем в будущем.

И так, для начала нам нужно настроить «среду» в которой мы будет собирать пакет. Не рекомендуется производить сборку пакетов из под root`а, по этому мы заведём отдельного пользователя, но а пока поставим всё необходимое ПО:

Yum install gcc gcc-c++ automake autoconf libtool yasm nasm ncurses-devel git ftp rpmdevtools

а теперь заведём специального пользователя

Useradd rpmbuild

и войдём под ним

Su - rpmbuild

выполним команду

Rpmdev-setuptree

что бы она развернула нам необходимую структуру директорий для сборки
И теперь мы можем приступать непосредственно к сборке.
Нам понадобится сам исходник

Wget http://inmethod.com/airvideo/download/ffmpeg-for-2.4.5-beta7.tar.bz2

разворачиваем его

Tar -xjf ffmpeg-for-2.4.5-beta7.tar.bz2

Положим рядом конфигурационный файл с содержимым:

Nano airvideoserver.conf path.ffmpeg = /usr/bin/ffmpeg password = subtitles.encoding = utf-8 subtitles.font = Verdana folders = Movies:/home/share/films

Сюда же скачаем файл сервера:

Wget http://inmethod.com/airvideo/download/linux/alpha6/AirVideoServerLinux.jar

И init-скрипт:

Nano AirVideoServer #!/bin/bash #chkconfig: - 80 20 #description: AirVideo server # Source function library. . /etc/rc.d/init.d/functions PREFIX_DIR=/usr/local/AirVideo case "$1" in start) echo -n "Starting AirVideo server: " daemon java -jar ${PREFIX_DIR}/AirVideoServerLinux.jar ${PREFIX_DIR}/properties.conf > /dev/null 2>&1 & [ $? -eq 0 ] && success || failure echo ;; stop) echo -n "Stopping AirVideo server: " killproc java echo ;; status) status java ;; restart | reload) $0 stop ; $0 start ;; *) echo "Usage: airvideo {start|stop|status|reload|restart" exit 1 ;; esac

Теперь можно переходить к написанию нашего spec-файла для сборки.
Сначала у нас идут различные заголовки. Имя пакета, версия и релиз — имеют значение, от них будет зависеть в какую директорию будет разворачиваться исходник перед сборкой. В Source1 , Source2 и Source3 мы указываем наши 3 дополнительных файл, конфиг, сервер и init-скрипт, которые необходимо добавить в пакет при сборке.

Name: ffmpeg Version: 2.4.5 Release: beta7 Summary: ffmpeg for AirVideoServer License: GPL URL: http://inmethod.com/airvideo/ Source: http://inmethod.com/airvideo/download/ffmpeg-for-2.4.5-beta7.tar.bz2 Source1: airvideoserver.conf Source2: AirVideoServer Source3: AirVideoServerLinux.jar BuildRoot: %{_tmppath}/%{name}-for-%{version}-%{release}

%description Utility and library for encoding H264/AVC video streams for AirVideoServer.

Секция %prep отвечает за команды, необходимые для начала сборки, что бы мне не мучится с переименованием директории под формат -, я просто ключом -n указываю где лежат распакованные исходники

%prep %setup -n /home/rpmbuild/rpmbuild/BUILD/ffmpeg/

Секция %build отвечает за непосредственную сборку исходника, ключи вы можете менять на необходимые вам, как при обычной сборке и установке из исходников:

%build ./configure \ --prefix="%{_prefix}" \ --bindir="%{_bindir}" \ --libdir="%{_libdir}" \ --enable-pthreads \ --disable-shared \ --enable-static \ --enable-gpl \ --enable-libx264 \ --enable-libmp3lame

Секция %install содержит команды установки файлов пакета в систему, здесь нам необходимо дополнительно указать, куда инсталлировать наши файл конфига, сервер и init-скрипт

%install %{__rm} -rf %{buildroot} %{__make} install DESTDIR="%{buildroot}" mkdir -p $RPM_BUILD_ROOT/usr/local mkdir -p $RPM_BUILD_ROOT/usr/local/AirVideo/ install -m 644 %{SOURCE1} $RPM_BUILD_ROOT/usr/local/AirVideo/ install -m 644 %{SOURCE2} $RPM_BUILD_ROOT/etc/init.d install -m 644 %{SOURCE3} $RPM_BUILD_ROOT/usr/local/AirVideo/

Уберём за собой мусор и выполним ldconfig

%clean %{__rm} -rf %{buildroot} %post -p /sbin/ldconfig %postun -p /sbin/ldconfig

Команды в секции %files задают списки файлов и каталогов, которые с соответствующими атрибутами должны быть скопированы из дерева сборки в rpm-пакет и затем будут копироваться в целевую систему при установке этого пакета.

%files %defattr(-,root,root,-) %doc COPYING* CREDITS README* %{_bindir}/avconv %{_bindir}/avprobe %{_bindir}/avserver %{_bindir}/ffmpeg /usr/include/* /usr/lib64/* /usr/share/avconv/* /usr/local/AirVideo/airvideoserver.conf /etc/init.d/AirVideoServer /usr/local/AirVideo/AirVideoServerLinux.jar

Макрос %doc отмечает файлы документации, копирайты и прочие вещи.
На этом наш spec-файл готов, теперь нам необходимо запустить саму сборку

Rpmbuild -bb ffmpeg/ffmpeg.spec

При успешной сборке пакета, после завершения, в директории RPMS/_архитектура_/ у нас появится наш пакет ffmpeg-2.4.5-beta7.x86_64.rpm который теперь можно выложить и развернуть на любой машине.

Надеюсь данный небольшой мануал, поможет вам собирать собственные пакеты для установки, с собственными конфигурационными файлами, что впоследствии облегчит вам жизнь.

Во многих наших проектах используются open-source библиотеки. Когда разработка ведется под одну конкретную платформу, нет смысла собирать одни и те же библиотеки из исходников каждый раз, когда к проекту подключается новый разработчик. Кроме того, установка библиотек а-ля make && sudo make install считается плохим тоном, поскольку система засоряется «бесхозными» файлами, о которых нет информации в базе данных менеджера пакетов RPM.

В качестве решения предлагается из скомпилированных библиотек собирать RPM-пакеты и хранить их в едином репозитории, доступном для всех разработчиков. Ниже приводится инструкция и некоторые советы по сборке пакетов.

Инструкция будет основываться на примере Red Hat Enterprise Linux 6, но с небольшими изменениями ее можно будет адаптировать и для других дистрибутивов. Для примера будем собирать пакет из библиотеки zeromq.

Перед сборкой пакета

Первое, что нужно сделать перед сборкой - убедиться, что нужный вам пакет не собрал кто-то до вас. Часто на таких ресурсах, как rpmfind.net и rpm.pbone.net можно найти то, что вам нужно. Но если не нашлось необходимой версии библиотеки или нет сборки под вашу платформу, то придется собирать пакет самому.

rpmbuild

Сборка пакетов осуществляется с помощью утилиты rpmbuild . Перед ее использованием необходимо сконфигурировать окружение сборки. Создадим необходимое дерево каталогов, например, в директории ~/rpmbuild:

$ mkdir ~/rpmbuild $ mkdir ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}

Создаем файл конфигурации утилиты rpmbuild, чтобы она узнала, где находится созданное дерево каталогов:

$ echo "%_topdir %(echo $HOME)/rpmbuild" >~/.rpmmacros

rpmbuild при запуске будет искать файлы пакета в директории ~/rpmbuild/BUILDROOT/<имя_пакета>. Разберемся, как именуются RPM-пакеты, на примере zeromq:

zeromq-3.2.4-1.rhel6.x86_64.rpm

  • zeromq - собственно, имя пакетируемого ПО;
  • 3.2.4 - версия ПО;
  • 1.rhel6 - номер сборки пакета (release number) - сколько раз данная версия ПО собиралась в rpm-пакет. Суффиксом rhel6 или el6 обычно обладают пакеты для Red Hat Enterprise Linux 6;
  • x86_64 - процессорная архитектура, под которую скомпилировано ПО.

Обратите внимание на знаки, разделяющие поля имени пакета. Они должны быть именно такими, как в примере.

Итак, создаем директорию для zeromq в BUILDROOT:

$ mkdir ~/rpmbuild/BUILDROOT/zeromq-3.2.4-1.rhel6.x86_64

Сборка библиотеки

Само собой, перед сборкой бинарного пакета, нужно скомпилировать саму библиотеку. Если библиотека использует систему сборки GNU Autotools, то обычно это делается командами:

$ ./configure $ make

Теперь устанавливаем библиотеку в созданную нами директорию в BUILDROOT:

$ make install DESTDIR="$HOME/rpmbuild/BUILDROOT/zeromq-3.2.4-1.rhel6.x86_64"

Параметр DESTDIR не всегда обрабатывается в мейкфайлах. Например, qmake генерирует мейкфайлы, которые игнорируют этот параметр. Если библиотека использует систему сборки, отличную от GNU Autotools, то прочитайте в соответствующем руководстве, какие параметры нужно передать при сборке, чтобы установить библиотеку в указанную директорию.

spec-файл для сборки пакета

В RPM-пакетах помимо заархивированного дерева файлов хранится метаинформация об этом пакете. При сборке она должна задаваться в spec-файле, который находится в папке ~/rpmbuild/SPECS. Рассмотрим пример файла zmq.spec для библиотеки zeromq:

Name: zeromq Version: 3.2.4 Release: 1.rhel6 Summary: Software library for fast, message-based applications Packager: My organization Group: System Environment/libraries License: LGPLv3+ with exceptions %description The 0MQ lightweight messaging kernel is a library which extends the standard socket interfaces with features traditionally provided by specialized messaging middle-ware products. 0MQ sockets provide an abstraction of asynchronous message queues, multiple messaging patterns, message filtering (subscriptions), seamless access to multiple transport protocols and more. This package contains the ZeroMQ shared library for versions 3.x. %post /sbin/ldconfig %postun /sbin/ldconfig %files %defattr(-,root,root) /usr/lib64/libzmq.so.3 /usr/lib64/libzmq.so.3.0.0 %package devel Summary: Development files for zeromq3 Group: Development/Libraries Requires: %{name} = %{version}-%{release} %description devel The zeromq3-devel package contains libraries and header files for developing applications that use zeromq3 3.x. %files devel %defattr(-,root,root) /usr/include /usr/share /usr/lib64/pkgconfig /usr/lib64/libzmq.so /usr/lib64/libzmq.a /usr/lib64/libzmq.la

В начале файла указывается минимальный набор полей с информацией о пакете. Из значений первых трех полей (Name , Version , Release ) формируется имя пакета, поэтому важно, чтобы там были указаны правильные значения. Если значения не будут соответствовать имени каталога с деревом файлов собираемого пакета, rpmbuild выдаст ошибку. Поле License также является обязательным - без него rpmbuild откажется собирать пакет.

Назначение секции %description очевидно. Секции %post и %postun содержат скрипты, выполняющиеся после установки файлов пакета в систему и после удаления файлов пакета из системы, соответственно. Это полезно, если пакет устанавливает динамические библиотеки (.so) в нестандартные директории (т. е. не в /lib, /usr/lib, /lib64 или /usr/lib64). В этом случае пакет должен предоставлять файл конфигурации для ldconfig и устанавливать его в /etc/ld.so.conf.d. Команда ldconfig обновляет кэш динамического загрузчика, добавляя в него все библиотеки, найденные в директориях, указанных в конфигурационных файлах.

В секции %files указывается список файлов, которые пакуются в rpm. Директива %defattr указывает атрибуты файлов по умолчанию в формате:

%defattr (, , ,

)

указывается в восьмеричном виде, например, «644» для rw-r--r--. Атрибут

может быть опущен. Вместо атрибутов, которые не должны меняться для устанавливаемых файлов, можно указать дефис. Директории, указанные в секции %files , будут внесены в пакет вместе со всем их содержимым.

Дальше самое интересное. Фактически существует два типа RPM-пакетов библиотек. В одних находятся собственно сами файлы динамических библиотек, необходимые для работы программ, которые скомпонованы с этими библиотеками. Например, пакет zeromq-3.2.4-1.rhel6.x86_64.rpm предоставляет только два файла: /usr/lib64/libzmq.so.3.0.0 и символьную ссылку на него, /usr/lib64/libzmq.so.3. Другой тип пакетов содержит файлы, необходимые для разработки приложений с использованием предоставляемой библиотеки. К имени таких пакетов добавляется суффикс "-devel", например, zeromq-devel-3.2.4-1.el6.x86_64.rpm. В таких пакетах обычно содержатся заголовочные файлы C/C++, документация, статические библиотеки (.a), и эти пакеты являются зависимыми от пакетов первого типа.

В приведенном выше spec-файле директива %package позволяет собрать «дочерний» пакет одним запуском rpmbuild. Значения полей заголовков дочернего пакета наследуются от родительского, но их можно переопределить. Поле Requires задает дополнительную зависимость от родительского пакета. Заметьте, что секция %files пакета zeromq-devel содержит файл /usr/lib64/libzmq.so. Это символьная ссылка на настоящий файл с динамической библиотекой. Он необходим компоновщику ld на этапе сборки приложения с использованием библиотеки, поскольку он ищет файлы динамических библиотек, начинающиеся на «lib» и заканчивающиеся на ".so".

Сборка

Перед сборкой нужно иметь в виду две вещи.
Первое: при успешной сборке пакета rpmbuild очистит директорию BUILDROOT. Так что на всякий случай сделайте резервную копию пакетируемых файлов.
Второе: никогда не собирайте пакеты с правами root. объясняется, почему так нельзя делать.

Теперь все готово для сборки пакета. Запускаем rpmbuild:

$ cd ~/rpmbuild/SPECS $ rpmbuild -bb zmq.spec

Параметр -bb означает «build binary», то есть, собрать бинарный пакет. Помимо бинарных пакетов есть еще пакеты исходных кодов, но они здесь не обсуждаются.

В случае успеха полученный rpm-пакет будет сохранен в папке RPMS.

Если не знаете, что писать в полях заголовка spec-файла для пакетируемой библиотеки, можно взять RPM-пакет для другого дистрибутива c указанных выше ресурсов и посмотреть, что пишут там:

$ rpm -qip package.rpm

Здесь «q» означает «режим запросов (query)», «i» - получение информации о пакете, «p» - получение информации об указанном файле пакета (без этой опции будет получена информация о пакете, установленном в системе, если он установлен).

Если не знаете, какие файлы принадлежат пакету devel, а какие - пакету с библиотеками, но у вас есть оба пакета для другого дисрибутива, можно распаковать дерево файлов, предоставляемых данным пакетом, в текущую директорию:

$ rpm2cpio package.rpm | cpio -di

Утилита rpm2cpio пишет в стандартный вывод cpio-архив, хранящийся в rpm-пакете; утилита cpio распаковывает архив, принятый из стандартного ввода. Параметр «i» включает режим распаковки, а «d» создает нужные директории.

Посмотреть, какие файлы предоставляет пакет, можно и не распаковывая его, с помощью опции «f»:

$ rpm -qfp package.rpm

Итого

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

Внимание! Действия пунктов 1 и 4 настоящей инструкции выполняются с административными правами (root)!

1. Установка необходимых пакетов для процесса сборки

# apt-get install rpm-build

2. Установка src.rpm пакета нужного ПО, которое требуется собрать

Находим и качаем src.rpm пакет нужного ПО, которое будем собирать, и устанавливаем его (от пользователя!):

$ rpm -i название_пакета_с_версией.src.rpm

При этом исходники (исходный код) пакета разместятся в ~/RPM/SOURCES , а спек - в ~/RPM/SPECS .
Наличие исходного кода программного обеспечения и спека, т.е. описания процесса сборки, является необходимым и достаточным условием для сборки rpm пакета (или пересборки, например, пакета из более нового бранча для более старого).

3. Сборка пакета

Приступаем к сборке, делается это командой:

$ rpm -ba --target (i586|x86_64) ~/RPM/SPECS/имя_спека_нужного_пакета_для_сборки.spec

При этом необходимо раскрыть скобки в зависимости от архитектуры, под которую происходит сборка пакета.

Собранные пакеты разместятся в ~/RPM/RPMS .

Примечание:

Пересобрать пакет без его установки (распаковки) можно и так:

$ rpmbuild --rebuild --target (i586/x86_64) название_пакета_с_версией.src.rpm

При этом необходимо также раскрыть скобки в зависимости от архитектуры, под которую происходит сборка пакета.

Примечание: Что касается процессоров, не относящихся к семейству x86_64, то само по себе указание "--target i586" опционально (сборка отработает и без него, но при этом компилятор соберет пакет, точно заточенный под Ваш тип процессора и наименование пакета будет отличаться от наименования пакетов бранчей, к примеру, xxx.athlon.rpm или xxx.pentium4.rpm). Отсутствие параметра "--target i586" при сборке совершенно не гарантирует устанавливаемость собранного таким образом пакета на другом компьютере с другим процессором. Если же сборка совершается под 64-битную систему (на 64-битном процессоре с установленной 64-битной системой), то ключ "--target x86_64" теряет свой смысл и ставить его совершенно не обязательно.

Примечание: Если rpm ругается на не найденные макросы примерно так: "ошибка: Macro %groupadd not found" или "ошибка: Macro %license not found", то помочь в дальнейшей сборке пакета должна установка в систему одного из пакетов rpm-build-* , который, фактически, является дополнительной зависимостью для сборки (пересборки) вашего пакета и отвечает за присвоение требуемых значений этим самым не найденным макросам.

4. Установка сборочных зависимостей

Если имеется srpm пакет, для сборки которого необходимо установить зависимости, то это можно сделать, выполнив следующую команду:

# apt-get build-dep название_пакета_с_версией.src.rpm

Если srpm пакета нет и имеется отдельно спек и исходный код, то почти 100% сборка сразу не пойдёт - в самом начале вывода в консоли будут показаны пакеты, которые должны быть установлены в систему, прежде чем сборка сможет пойти далее. Вы их (эти выведенные в консоль зависимости сборки) установите

# apt-get install пакет1 пакет2 пакет3 ...

а после повторите сборку (возврат к шагу 3).

5. Автоматический поиск зависимостей для вновь собираемого пакета

Если вы собираете новый пакет, а не пересобираете уже существующий srpm, то хорошим подспорьем в рамках оформления (поиска и прописывания) нужных зависимостей в спек вам послужит утилита buildreq из пакета rpm-utils :

$ buildreq имя_спек_файла.spec