У цій статті буде докладно описано процес створення 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 http://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)
Перевіримо підпис файлу з контрольною сумою образу:
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.)
Потрібно ще закрутити гайки у самій службі. Створимо копію файлу конфігурації та приступимо до редагування:
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 # 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: 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 ~/rpmbuild/REPO tree ~/rpmbuild/ /home/chelaxe/rpmbuild/ ├── BUILD ├── BUILDROOT ├── REPO -> /var/www/repo ├── RPMS ├── SOURCES ├── ── 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 Назви: chelaxe-release Version: 1.0 Release: 1%(?dist) Packager: ChelAxe Group: System Environment/Base License: GPL URL: https://repo.chelaxe.ru Source0: https://repo.chelaxe.ru/%(name).tar.gz BuildArch: noarch %description Цей пакет contains the ChelAxe офіційний репозиторій GPG key як добре як 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.)
Збираємо пакет:
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
Підготуємо файл конфігурації 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 " # Не знищувати вікно після завершення програми 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 =red" # Стиль вкладки вікна з "звуком" у рядку стану # Замінює параметри: window-status-bell-attr window-status-bell-bg window-status-bell-fg set-option -gw 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) Сума: A terminal multiplexer Ven. 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 є "terminal multiplexer", це дає змогу числу terminals (або windows) для доступу і контролюється з одного 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 %(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.)
Складання
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 -> ── RPMS │ ├── noarch │ └── x86_64 ├── SOURCES │ ├── chelaxe-release │ ├── chelaxe-release.tar.gz │ │ . │ ├── libevent-2.1.8-stable.tar.gz.asc │ ├── ncurses-6.1.tar.gz │ ├── ncurses-6.1.tar.gz.sig │ ├── tmux-2. .gz │ └── tmux.conf ├── SPECS │ ├── chelaxe-release.spec │ └── tmux.spec └── SRPMS ├── chelaxe-release-1.0-1.0-1.0. 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 Назви: fbida Version: 2.14 Release: 1%(?dist) Сума: 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 : mesa-libEGL-devel poppler-devel poppler-glib-devel BuildRequires: freetype-devel mesa-libgbm-devel Requires: libexif fontconfig libjpeg-turbo libpng libtiff giflib Requires: libcurl libXpm pixman poppler poppler-glib freetype Requires: mesa-libgbm ImageMagick dejavu-sans-mono-fonts %description fbi відтворює конкретний файл(s) на лінзовому контролі з використанням framebuffer device. PhotoCD, jpeg, ppm, gif, tiff, xwd, bmp і png є supported безпосередньо. Для інших форматів fbi tries для використання ImageMagick"s convert. %prep %setup -q %(__sed) -i -e "s,/X11R6,g" usr %clean %__rm -rf %(buildroot) %files %defattr(-,root,root,-) %doc Відмінності COPYING INSTALL README TODO VERSION %(_prefix)/* %changelog * Tue May 1 2018 ChelAxe (D.F.H.)
Складання
Збираємо пакет і додаємо його до репозиторію:
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 -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 /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
Т.к. у 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 /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 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 t=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-файл, а бінарник скачується і, при необхідності, модифікується, в процесі установки пакета (наприклад, у скрипті, про який мова піде нижче).
Збирати пакети можна з будь-якого користувача. Робити це з-під 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 international dictionary written for GNOME environment. Це має потужні особливості, як "Глоб-стиль 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 Додаткові інструменти для 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 - після встановлення, %pren - перед видаленням, %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
%doc позначає файли як документацію. Третій рядок копіює зазначені файли до каталогу %(_datadir)/doc/%(name)-%(version). За замовчуванням файли в rpm пакеті будуть мати власника root'а, а права доступу вниз будуть такі ж, як і в процесі установки. Якщо це необхідно змінити, то скористайтеся конструкцією %defattr .
%files tools %(_bindir)/stardict-editor
Теж саме для пакету stardict-tools. Якби він називався tools-stardict, то %files виглядав би так:
%files -n інструменти-%(name).
Останнє, що йде в spec-файлі, це %changelog. У changelog'і ви вказуєте зміни в пакеті порівняно з попередньою версією. Синтаксис приблизно такий.
%changelog * Sun Apr 22 2007 Your Name
Макровизначення
Тепер настав час познайомитися ближче з макросами і змінними. Припустимо, ми збираємо пакет із 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 макровизначення
- Додати до початку spec-файлу макровизначення
Якщо необхідно зібрати тільки бінарник або лише вихідник, то замість -baслід використовувати -bbі -bsвідповідно. З корисних параметрів можна відзначити rpmbuild -clean(Видалити все сміття), -rmsource(Видалити вихідники з каталогу SOURCE) та -target=архітектура(Зібрати пакет під конкретну архітектуру).
Можна також виконувати сценарії лише у певній секції. Описувати подібні параметри ми не будемо, див. man rpmbuild.
Складання RPM пакета з вже встановленого в системі
Іноді трапляється ситуація, що якийсь пакет уже встановлений у системі (може бути в дуже старій системі) і дуже хочеться отримати rpm'ку з ним, а вона якраз і не збереглася. Також може захотітися зібрати по швидкому пакет із зміненими під ваші потреби конфігураційними файлами.
Для вирішення цієї проблеми слід скористатися утилітою rpmrebuild. Ця написана на bash утиліта доступна в contrib-репозиторії РОСИ.
Працювати з нею дуже просто. Потрібно віддати лише команду:
Rpmrebuild назва_встановленого_пакета
Якщо якийсь файл був змінений, то вам про це повідомлять, але процес збирання не перерветься.
Rpmrebuild має величезну кількість параметрів, наприклад, ви можете змінювати release пакета, changelog, скрипти, секції Requires, описи пакета та багато іншого. Можете навіть просто змінити spec-файл, який скрипт згенерує сам. Він правда буде трохи страшний, але це все ж таки краще, ніж нічого.
Усі параметри можна переглянути за допомогою
Rpmrebuild --help
Багато наших проектів використовуються 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 Загальна: Software library for fast, message-based applications Packager: My organization Group: System Environment/libraries License: LGPLv3+ with exceptions extends the standard socket interfaces with features traditionally provided by specialized messaging middle-ware products. 0MQ sockets надає abstraction of asynchronous message queues, multiple messaging patterns, message filtering (subscriptions), seamless access to multiple transport protocols and more. Цей пакет містить 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: Розробка файлів для 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 видасть помилку. Поле Ліцензіятакож є обов'язковим – без нього rpmbuild відмовиться збирати пакет.
Призначення секції %descriptionочевидно. Секції %postі %postunмістять скрипти, що виконуються після встановлення файлів пакета в систему і після видалення файлів пакета із системи відповідно. Це корисно, якщо пакет встановлює динамічні бібліотеки (.so) в нестандартні директорії (тобто не /lib, /usr/lib, /lib64 або /usr/lib64). У цьому випадку пакет повинен надавати файл конфігурації для ldconfig та встановлювати його у /etc/ld.so.conf.d. Команда ldconfigоновлює кеш динамічного завантажувача, додаючи до нього всі бібліотеки, знайдені в каталогах, вказаних у конфігураційних файлах.
У секції %filesвказується список файлів, які пакуються в rpm. Директива %defattrвказує атрибути файлів за промовчанням у форматі:
%defattr(
Далі найцікавіше. Фактично є два типи 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-пакет для іншого дистрибутива з вказаних вище ресурсів і подивитися, що пишуть там:
$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-файлів (як, наприклад, поділ файлів конфігурації, документації тощо), але для збирання пакетів бібліотек це, за великим рахунком, і не потрібно.
Програма RPM призначена для виконання всіх видів операцій із програмним забезпеченням, у тому числі і для створення пакетів для встановлення (RPM-пакетів).
Перш ніж описати багато сухих фактів, взятих із документації, розглянемо простий приклад створення невеликого RPM-пакету. Я створив цей пакет для своєї програми, яка контролює стан вказаного послідовного порту.
Вважатимемо, що програма вже відкомпільована і всі файли, необхідні для її роботи, вже підготовлені. Нам потрібні такі файли:
port - відкомпільований бінарний файл
README - файл
port.1 - файл для довідкової системи man
Усі ці файли я помістив у каталог /root/port. Звичайно, це не зовсім коректно, але про це буде сказано трохи згодом.
Для створення пакету потрібно створити файл специфікацій. У файлі специфікацій вказується вся інформація про пакет, що створюється: назва, версія, файли програм, файли документації, дії, що виконуються при встановленні пакета і при його видаленні.
Ось мій файл специфікацій для port
Лістинг 1.
# /root/port/port.spec # Файл специфікацій для програми port # Загальний описпрограми Summary: Program to control your serial device # Назва пакету Name: port # Його версія Version: 1.0 # Реліз Release: 99 # Група програмного забезпечення. Групи (або категорії) використовуються багатьма програмами для маніпуляції пакетами, наприклад gnorpm, яка будує дерево категорій встановленого програмного забезпечення Group: Monitoring # Якщо хочете, можете вказати своє ім'я, але зазвичай вказується GPL License: GPL # Можна також вказати і copyleft # Copyright: GPL # Наш пакет ні з чим не конфліктує # Conflicts: # Менеджер сам заповнить це поле при необхідності # (тільки для створення двійкових пакетів!) # Require: # Інформація про творця пакету Packager: Denis Kolisnichenko URL: http://dkws .narod.ru # Теги Summary, Name, Version, Release, Group, License є обов'язковими # З вищевказаної інформації видно, що буде створено пакет: # port-1.0-99.i686.rpm # Архітектура у вас може відрізнятися # Повний опис пакета %description Програма port призначена для моніторингу стану послідовного порту. При отриманні сигналу (1) на якийсь контакт зазначеного порту, port відправляє повідомлення користувачу, що запустив її, на вказаний email # Файли, які будуть поміщені в пакет %files %doc /root/port/README /root/port/port /root/ port/port.1
Для побудови пакета необхідно ввести команду:
# rpm -bb /root/port/port.spec
Якщо ви не припустилися жодних помилок при створенні файлу специфікацій, на екрані ви побачите приблизно таке повідомлення:
Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.33439 Processing files: port-1.0-99 Finding Provides (using /usr/lib/rpm/find-provides)... Finding Requires: (using /usr/lib/rpm/find-requires)... Requires: ld-linux.so.2 libc.so.6 libc.so.6(GLIBC_2.0) Записано: /usr/src/RPM /RPMS/i686/port-1.0-99.i686.rpm
При цьому буде створено пакет port-1.0-99.i686.rpm. Цей пакет буде поміщений у каталог /usr/src/RPM/RPMS/i686
Проведемо невеликий експеримент. Запустіть Midhight Commander (mc), перейдіть у каталог /usr/src/RPM/RPMS/i686/ і "увійдіть" у пакет port-1.0-99.i686.rpm як у звичайний каталог. У ньому буде "підкаталог" INFO, в якому міститься вся інформація про пакет.
Що ж, ми успішно розібралися із побудовою простого пакету, але для створення реальних пакетів встановлення наших знань досі не вистачає. Тепер настала черга тієї сухої теорії, про яку я згадав на початку статті.
Традиційно процедура створення RPM-пакетів складається з наступних етапів:
- Вилучення вихідних текстів програми з архіву
- Компілювання програми із вихідних текстів
- Створення RPM-пакету
Перші два етапи можна пропустити, що ми зробили під час створення нашого пакета. Це можна зробити лише у випадку, якщо програму вже відкомпілювали з вихідних текстів.
Програма RPM використовує конфігураційний файл rpmrc. Пошук цього файлу відбувається у каталогах /usr/lib/rpm, /etc, $HOME. Переглянути цей файл можна за допомогою команди:
# rpm --showrc
Запис topdir файлу конфігурації rpmrc містить назву каталогу, в якому знаходиться дерево підкаталогів, яке використовується менеджером RPM для побудови пакетів. Введіть команду:
# rpm --showrc | grep topdir -14: _builddir %(_topdir)/BUILD -14: _rpmdir %(_topdir)/RPMS -14: _sourcedir %(_topdir)/SOURCES -14: _specdir %(_topdir)/SPECS -14: _srcrpmdir %(_topdir) /SRPMS -14: _topdir %(_usrsrc)/RPM
У мене ці підкаталоги знаходяться у каталозі /usr/src/RPM. Як ви бачите, у цьому каталозі знаходяться підкаталоги BUILD, RPMS, SOURCES, SPECS, SRPMS.
В каталозі BUILD створюється пакет RPM. У каталозі SOURCES є стислі вихідні тексти програми. До каталогу RPMS розміщуються створені пакети. Точніше, вони поміщаються в один із його підкаталогів, у якому саме - це залежить від архітектури. У каталог SRPMS розміщуються пакети, що містять вихідні тексти програми.
У каталозі SPECS є файли специфікацій. Зазвичай файл специфікації називається назва_програми-версія-реліз.spec.
Наприклад, якщо у вас є вихідний текст програми в архіві, з якого ви хочете створити пакет RPM, скопіюйте його до каталогу SOURCES
# cp source_code-1.0.tar.gz /usr/src/RPM/SOURCES
За замовчуванням менеджер RPM працює з пакетами, розташованими в каталозі з ім'ям, що збігається з назвою пакета та його версією. Для нашого пакету port це буде каталог port-1.0-99. Менеджер пакетів компілюватиме наш пакет у каталозі /usr/src/RPM/port-1.0-99
Думаю, вже достатньо інформації про каталоги RPM. Тепер перейдемо файл специфікацій. Файл специфікацій складається із чотирьох сегментів: заголовка, підготовчого, файлового, настановного.
У заголовку вказується Загальна інформаціяпро пакет. У лістингу 1 до сегменту заголовка відносяться теги Summary, Name, Version, Release, Group та Licese. На них ми зупинятися не будемо, оскільки їхнє призначення зрозуміле з лістингу 1.
Є ще дуже корисний мітка: BuildRoot. Він змінює розташування дерева BUILD. Стандартним значенням є /usr/src/RPM або інший каталог, що задається змінною оточення $RPM_BUILD_ROOT. З метою економії дискового простору корисно після встановлення видалити дерево %RPM_BUILD_ROOT. Але дерево за промовчанням може містити інші файли, які стосуються інших пакетів. Тому спочатку за допомогою тега BuildRoot потрібно задати якийсь тимчасовий каталог, а після встановлення видалити його.
У кожному сегменті є макрокоманди. З деякими ми вже знайомі - %description, %files, %doc, %install. У таблиці 1 наведено повний опис макрокоманд.
Таблиця 1.
Макрокоманда | Опис |
%description | Повний опис пакету |
%prep | Підготовка архіву Тут задаються команди для отримання вихідного тексту програми та його розпакування, додаткова підготовка вихідного тексту. Після макрокоманди %prep задаються стандартні команди shell. |
%setup | Макрокоманда вилучення файлів із архівів. Опція -n дозволяє вказати каталог, у якому буде створюватись новий пакет. Зазвичай розпаковується архів, розташований у каталозі SOURCES у каталог BUILD |
%build | Макрокоманда компілювання. Зазвичай тут запускається програма make із необхідними параметрами |
%files | Задає список файлів, які входять до складу пакета. При вказівці імен файлів має бути вказаний повний, а чи не відносний шлях. Для вказівки повного шляху можна використовувати змінну оточення $RPM_BUILD_ROOT. Необхідні файливже мають бути поміщені до каталогу BUILD. Цього можна досягти за допомогою макрокоманди %setup або за допомогою %pre (див. нижче) |
%config список | Задає список файлів, які будуть розміщені в каталогі / etc |
%doc список | Задає список файлів, які будуть розміщені в каталогі /usr/doc/--. |
%install | Етап встановлення програмного забезпечення. Тут потрібно записати команди, які встановлюватимуть файли, що входять до складу пакета. Зручніше використовувати команду install, яку я використав у лістингу. |
%pre | Дії, які будуть виконані до інсталяції пакета |
%post | Дії, які будуть виконані після інсталяції пакету |
%preun | Дії, які будуть виконані перед видаленням пакету |
%postun | Дії, які будуть виконані після видалення пакету |
%clean | Видалення дерева BUILD. Використовується замість опції --clean програми rpm. Зазвичай містить одну команду: rm -rf $RPM_BUILD_ROOT |
Потрібно зробити невелике зауваження щодо макрокоманд %config та %doc. У цьому випадку список задається не так, як у макрокоманді %files. Якщо після макрокоманди %files можна було просто вказати по одному файлу в кожному рядку, то макрокоманді %doc кожному файлу (або кожному списку) повинна передувати команда %doc. Наприклад,
%doc README TODO Changes %doc Install, а не %doc README TODO Changes Install
Ще раз зазначу, що наявність всіх макрокоманд у файлі специфікацій не є обов'язковою.
Під час створення пакета ми використовували опцію -bb програми rpm. При вказанні цієї опції створюється тільки двійковий RPM-пакет, якщо ви хочете створити пакет, що містить вихідний текст програми, використовуйте опцію -ba. Створений пакет міститься в каталогі SRPMS і матиме ім'я port-1.0-99.src.rpm. Тобто замість назви архітектури буде зазначено, що пакет містить вихідний текст програми. Для створення такого пакета у каталозі SOURCES мають бути вихідні тексти програми.
Для повноти картини залишилося розглянути налаштування менеджера rpm, які використовуються для створення пакетів.
Таблиця 2.
-ba | Створюються два пакети: двійковий і вихідний текст. При цьому не пропускається жоден етап установки, вказаний у файлі специфікацій |
-bb | Створюється лише двійковий пакет. Не пропускається жоден етап установки, вказаний у файлі специфікацій |
-bc | Виконуються етапи %pre та %build. При цьому пакет розпаковується та компілюється |
-bi | Виконуються етапи %pre, %build, %install |
-bl | Перевірка списку файлів, вказаних у макрокоманді %files |
-bp | Виконується лише етап %pre, тобто розпаковується архів |
--recompile package.src.rpm | Зазначений пакет, що містить вихідні тексти, спочатку встановлюється, а потім компілюється |
--rebuild package.src.rpm | Встановлює та компілюється пакет вихідних текстів, а потім створюється новий двійковий пакет |
--test | Перевірка файлу специфікацій |
--clean | Видалення дерева каталогів BUILD після створення пакету |
--showrc | Виводить файл конфігурації |
Linux-сервер своїми руками Колісниченко Денис Миколайович
19.5. Створення RPM-пакетів
19.5. Створення RPM-пакетів
Програма RPM призначена для виконання всіх видів операцій із програмним забезпеченням, у тому числі і для створення пакетів для встановлення (RPM-пакетів).
Перш ніж описати багато сухих фактів, взятих із документації, розглянемо простий приклад створення невеликого RPM-пакету. Я створив цей пакет для своєї програми, яка контролює стан вказаного послідовного порту.
port – відкомпільований бінарний файл.
README – файл, який буде поміщений у каталог /usr/doc/port-1.0-99.
port.1 – файл для довідкової системи man.
Усі ці файли я помістив у каталог /root/port. Звичайно, це не зовсім коректно, але про це буде сказано трохи згодом.
Для створення пакета необхідно створити файл специфікацій. У файлі специфікацій вказується вся інформація про пакет, що створюється: назва, версія, файли програм, файли документації, дії, що виконуються при встановленні пакета і при його видаленні. Мій файл специфікацій для програми port представлений у лістингу 19.1
Лістинг 19.1. Файл специфікації для port
Summary: Program для управління вашим серіальним пристроєм
Group: Monitoring
Packager: Denis Kolisnichenko
URL: http://dkws.narod.ru
Програма port призначена для моніторингу стану послідовного
порту. При отриманні сигналу (1) на якийсь контакт зазначеного порту,
port відправляє повідомлення користувачу, що її запустив, на вказаний email
%doc /root/port/README
/root/port/port.1
Для побудови пакета необхідно ввести команду:
# rpm –bb /root/port/port.spec
Якщо ви не припустилися жодних помилок при створенні файлу специфікацій, на екрані ви побачите приблизно таке повідомлення:
Executing(%install): /bin/sh –e /var/tmp/rpm-tmp.33439
Processing files: port-1.0-99
Finding Provides: (за допомогою /usr/lib/rpm/find-provides)…
Finding Requires: (за допомогою /usr/lib/rpm/find-requires)…
Requires: ld-linux.so.2 libc.so.6 libc.so.6(GLIBC_2.0)
Записано: /usr/src/RPM/RPMS/i686/port-1.0-99.i686.rpm
При цьому буде створено пакет port-1.0-99.i686.rpm. Цей пакет буде поміщений у каталог /usr/src/RPM/RPMS/i686.
При видаленні такого пакета він буде видалений з бази RPM, але видалення файлів не відбудеться. Дії, які потрібно виконати до та після видалення пакета з бази RPM, можна визначити в макрокомандах %preun і %postun відповідно. Наприклад
rm –f /usr/bin/port
rm -f /usr/man/man1/port.1
Такий підхід - найпростіший вихід зі становища, проте він не дуже коректний. Вирішення цієї проблеми залишаю вам як домашнє завдання.
А зараз проведемо невеликий експеримент. Запустіть Midnight Commander (mc), перейдіть у каталог /usr/src/RPM/RPMS/i686/ і «увійдіть» у пакет port-1.0-99.i686.rpm як у звичайний каталог. У ньому буде «підкаталог» INFO, в якому міститься вся інформація про пакет.
Що ж, ви успішно розібралися з побудовою простого пакета, але для створення реальних пакетів встановлення ваших знань досі не вистачає. Тепер настала черга тієї сухої теорії, про яку я згадав на початку цього пункту. Традиційно процедура створення RPM-пакетів складається з наступних етапів:
1. Вилучення вихідних текстів програми з архіву.
2. Компілювання програми із вихідних текстів.
3. Створення RPM-пакету.
Перші два етапи можна пропустити, що ми зробили під час створення пакета. Таке можна зробити лише у випадку, якщо програму вже відкомпілювали з вихідних текстів.
Програма RPM використовує конфігураційний файл rpmrc. Пошук цього файлу здійснюється у каталогах /usr/lib/rpm, /etc, $HOME. Переглянути цей файл можна за допомогою команди:
Запис topdir файлу конфігурації rpmrc містить назву каталогу, де знаходиться дерево підкаталогів, яке використовується менеджером RPM для побудови пакетів. Введіть команду:
# rpm --showrc | grep topdir
14 _builddir %(_topdir)/BUILD
14 _rpmdir %(_topdir)/RPMS
14 _sourcedir %(_topdir)/SOURCES
–14 _specdir %(_topdir)/SPECS
–14 _srcrpmdir %(_topdir)/SRPMS
–14 _topdir %(usrsrc)/RPM
У мене ці підкаталоги знаходяться у каталозі /usr/src/RPM. Як ви бачите, у цьому каталозі знаходяться підкаталоги BUILD, RPMS, SOURCES, SPECS, SRPMS.
В каталозі BUILD створюється пакет RPM. У каталозі SOURCES є стислі вихідні тексти програми. До каталогу RPMS розміщуються створені пакети. Точніше, вони поміщаються в один із його підкаталогів, у якому саме - це залежить від архітектури. У каталог SRPMS розміщуються пакети, що містять вихідні тексти програми. У каталозі SPECS є файли специфікацій. Зазвичай файл специфікації називається назва-програми-версія-реліз.8рес.
Наприклад, якщо у вас є вихідний текст програми в архіві, з якого потрібно створити пакет RPM, скопіюйте його в каталог SOURCES:
# СР source_code-1.0.tar.gz /usr/src/RPM/SOURCES.
За замовчуванням менеджер RPM працює з пакетами, розташованими в каталозі з ім'ям, що збігається з назвою пакета та його версією. Для нашого пакету port це буде каталог port-1.0-99. Менеджер пакетів буде компілювати наш пакет у каталог /usr/src/RPM/port-1.0-99.
Думаю, вже достатньо інформації про каталоги RPM. Тепер перейдемо файл специфікацій. Файл специфікацій складається із чотирьох сегментів: заголовка, підготовчого, файлового, настановного. У заголовку вказується загальна інформація про пакет. У лістингу 19.1 до сегменту заголовка належать теги Summary, Name, Version, Release, Group та License. На них ми зупинятися не будемо, оскільки їхнє призначення зрозуміле з лістингу 19.1.
Є ще дуже корисний мітка: BuildRoot. Він змінює розташування дерева BUILD. Стандартним значенням є /usr/src/RPM або інший каталог, що задається змінною оточення $RPM_BUILD_ROOT. З метою економії дискового простору корисно після встановлення видалити дерево %RPM_BUILD_ROOT. Але це дерево за промовчанням може містити інші файли, які стосуються інших пакетів. Тому спочатку за допомогою тега BuildRoot потрібно задати якийсь тимчасовий каталог, а після встановлення видалити його.
У кожному сегменті є макрокоманди. З деякими ми вже знайомі - %description, %files, %doc, %install. У табл. 19.34 наведено повний опис макрокоманд.
Макрокоманди Таблиця 19.34
Макрокоманда | Опис |
---|---|
%description | Повний опис пакету |
%prep | Підготовка архіву Тут задаються команди для отримання вихідного тексту програми та його розпакування, додаткова підготовка вихідного тексту. Після макрокоманди %prep задаються звичайні команди shell |
%setup | Макрокоманда вилучення файлів із архівів. Опція –n дозволяє вказати каталог, у якому створюватиметься новий пакет. Зазвичай розпаковується архів, розташований у каталозі SOURCES, у каталог BUILD |
%build | Макрокоманда компілювання. Зазвичай тут запускається програма make із необхідними параметрами |
%files | Задає список файлів, які входять до складу пакета. При вказівці імен файлів має бути вказаний повний, а чи не відносний шлях. Для вказівки повного шляху можна використовувати змінну оточення $RPM_BUILD_ROOT. Необхідні файли вже мають бути поміщені до каталогу BUILD. Цього можна досягти за допомогою макрокоманди %setup або за допомогою макрокоманди %pre (див. нижче) |
%config список | Задає список файлів, які будуть розміщені в каталогі / etc |
%doc список | Задає список файлів, які будуть розміщені в каталогі /usr/doc/–– |
%install | Етап встановлення програмного забезпечення. Тут потрібно записати команди, які встановлюватимуть файли, що входять до складу пакета. Найзручніше використовувати команду install яку я використав у лістингу 19.1 |
%pre | Дії, які будуть виконані до інсталяції пакета |
%post | Дії, які будуть виконані після інсталяції пакету |
%preun | Дії, які будуть виконані перед видаленням пакету |
%postun | Дії, які будуть виконані після видалення пакету |
%clean | Видалення дерева BUILD. Використовується замість опції – clean програми rpm. Зазвичай містить одну команду: rm –rf $RPM_BUILD_ROOT |
Потрібно зробити невелике зауваження щодо макрокоманд %config та %doc. У цьому випадку список задається не так, як у макрокоманді %files. Якщо після макрокоманди %files можна було просто вказати по одному файлу в кожному рядку, то макрокоманді %doc кожному файлу (або кожному списку) повинна передувати команда %doc. Наприклад:
%doc README TODO Changes
Ще раз зазначу, що наявність всіх макрокоманд у файлі специфікацій не є обов'язковою.
Під час створення пакета ми використовували опцію –bb програми rpm. При вказанні цієї опції створюється лише двійковий RPM-пакет, якщо ви хочете створити пакет, що містить вихідний текст програми, використовуйте опцію –ba. Створений пакет міститься в каталогі SRPMS і матиме ім'я port-1.0-99.src.rpm. Тобто замість назви архітектури буде вказано, що цей пакет містить вихідний текст програми. Для створення такого пакета у каталозі SOURCES мають бути вихідні тексти програми.
Для повноти картини залишилося розглянути налаштування менеджера rpm, які використовуються для створення пакетів (див. табл. 19.35).
Опції менеджера пакетів rpm Таблиця 19.35
Опція | Опис |
---|---|
-ba | Створюються два пакети: двійковий і вихідний текст. При цьому не пропускається жоден етап установки, вказаний у файлі специфікацій |
-bb | Створюється лише двійковий пакет. Не пропускається жоден етап установки, вказаний у файлі специфікацій |
-be | Виконуються етапи %pre та %build. При цьому пакет розпаковується та компілюється |
-bi | Виконуються етапи %pre, %build, %install |
-bl | Перевірка списку файлів, зазначених у макрокоманді. |
-bp | Виконується лише етап %pre, тобто розпаковується архів |
--recompile package.src.rpm | Зазначений пакет, що містить вихідні тексти, спочатку встановлюється, а потім компілюється |
--rebuild package.src.rpm | Встановлюється та компілюється пакет вихідних текстів, а потім створюється новий двійковий пакет |
--test | Перевірка файлу специфікацій |
--clean | Видалення дерева каталогів BUILD після створення пакету |
--showrc | Виводить файл конфігурації |
3.1. Менеджер пакунків yum 3.1.1. Основні поняття про пакети Давайте спочатку розглянемо процес інсталяції програм у Windows. Як правило, дистрибутив Windows-програми складається з та інсталяційного файлу (зазвичай називається setup.exe або install.exe) і декількох допоміжних файлів (наприклад,
З книги 200 найкращих програмдля Linux автора Яремчук Сергій Якимович3.2.4. Створення власного сервера пакетів Цей параграф більше розрахований на адміністраторів мереж, які розуміють, що вони роблять. Звичайним користувачамйого можна прочитати хіба що для "загального розвитку", хоча наведений спосіб можна вдало використати не лише
З книги Skype: безкоштовні дзвінкичерез Інтернет. Почали! автора Гольцман Віктор Йосипович3.3.3.1. Установка пакетів Для встановлення пакета (або пакетів - у командному рядку можна вказати кілька пакетів) використовується опція -i:rpm - i пакетЯкщо ви хочете спостерігати за процесом установки (це дуже корисно, якщо встановлюється великий пакет або ж виконується
З книги Linux-сервер своїми руками автора Колісниченко Денис Миколайович3.3.3.2. Видалення пакетів Для видалення пакета використовується опція -е. При видаленні не потрібно задавати повне ім'я файлу пакета, достатньо назви програми. Наприклад, якщо спочатку пакет називався program-base-0.94-2.i386.rpm, то для його видалення достатньо ввести команду: rpm -e
З книги UNIX: взаємодія процесів автора Стівенс Вільям РічардКонвертери пакетів Окремо хотілося б відзначити наявність утиліт, що дозволяють конвертувати пакети з одного формату до іншого. Їхні можливості застосування обмежені, оскільки з пакета одного типу отримати повноцінний інший тип пакета неможливо. Крім того, додатки,
З книги Програмування мовою Ruby [Ідеологія мови, теорія та практика застосування] автора Фултон ХелПередача пакетів Наступний етап – це передача пакетів. Транспортування цифрового трафіку здійснюється через Інтернет за допомогою технології TCP/IP. Термін TCP/IP означає цілий набір технологій та прикладних програм, пов'язаних із передачею даних через Інтернет. Сюди
З книги Linux: Повне керівництво автора Колісниченко Денис Миколайович1.7.7. Структура пакетів IP та TCP Ось тепер можна сміливо перейти до розгляду структури пакетів IP та TCP. Протокол IP не орієнтований на з'єднання, тому забезпечує надійну доставку даних. Поля, опис яких наведено у табл. 1.6, являють собою IP-заголовки та
З книги Linux очима хакера автора Фльонов Михайло Євгенович14.3.2. Фрагментація пакетів Іноді пакет, що передається, занадто великий, щоб його можна було передавати за один раз. Якщо таке відбувається, пакет ділиться на фрагменти, і ці фрагменти пересилаються. Комп'ютер, якому цей пакет призначений, збирає ці фрагменти в
Із книги Linux Mintта його Cinnamon. Нариси застосування автора19 Корисні команди та програми. Створення RPM-пакетів
З книги Священні війни світу FOSS автора Федорчук Олексій Вікторович16.9. Формати пакетів RPC На рис. 16.5 наведено формат запиту RPC в пакеті TCP. Оскільки TCP передає потік байтів і не передбачає меж повідомлень, програма повинна передбачати спосіб розмежування повідомлень. Sun RPC визначає запис як запит або відповідь, і кожен запис
З книги автораРозділ 17. Створення пакетів та розповсюдження програм Все більше і більше продуктів - і в першу чергу аспірин - випускається в упаковці, захищеній настільки, що споживач вже й скористатися ними не може. Дейв Беррі Цей розділ присвячений питанню про те, як
З книги автора27.1.2. Структура пакетів IP і TCP Протокол IP не орієнтований з'єднання, тому забезпечує надійну доставку даних. Поля, опис яких наведено в таблиці 27.4, є IP-заголовком і додаються до пакета при його отриманні з транспортного
З книги автора4.10.1. Фільтрування пакетів Отже, основним, але не єдиним завданням мережного екрану є фільтрація пакетів. У Linux вже вбудовано Firewall, і вам його не потрібно встановлювати окремо. Точніше сказати, їх навіть два: iptables та ipchains. Вони дозволяють контролювати трафік, що проходить
З книги автора14.12.1. Дефрагментація пакетів За допомогою фрагментованих пакетів хакери роблять дуже багато атак на сервери. У Linux можна зробити так, щоб ОС об'єднувала пакети, що приходять. Якщо у вас монолітне ядро (без підтримки модулів), необхідно прописати 1 у файл
З книги автораФормат пакетів Як було зазначено, у дистрибутиві Mint прийнято deb-формат пакетів. Будучи розроблений ще в минулому тисячолітті для дистрибутива Debian, цей формат був успадкований від нього Ubuntu, багато в чому визначивши успіх останньої. А слідом за нею - і вдачливість нашого