Сборка своего RPM-пакета на примере NGINX

Thank you for reading this post, don't forget to subscribe!

Если нам нуж­но часто уста­нав­ли­вать свои паке­ты, у нас может ухо­дить мно­го вре­ме­ни на их кон­фи­гу­ри­ро­ва­ние и сбор­ку. Мы рас­смот­рим про­цесс того, как сде­лать RPM-пакет для уста­нов­ки на дис­три­бу­тив Linux одно­имен­но­го семей­ства (напри­мер, CentOS или Red Hat). В каче­стве при­ме­ра мы собе­рем NGINX с моду­лем SPNEGO. Это будет сде­ла­но поэтап­но — сна­ча­ла мы собе­рем про­стой пакет, потом доба­вим в него модуль и вне­сем изме­не­ния в кон­фи­гу­ра­ци­он­ный файл.

Подготовка системы

1. Уста­нав­ли­ва­ем необ­хо­ди­мые пакеты:

yum install wget rpm-build rpmdevtools

* где:

  • wget — ути­ли­та для загруз­ки фай­лов по сети.
  • rpm-build — вклю­ча­ет в себя ути­ли­ту rpmbuild, с помо­щью кото­рой будет выпол­нять­ся сама сбор­ка уста­но­воч­но­го пакета.
  • rpmdevtools — поз­во­лит нам исполь­зо­вать ути­ли­ту rpmdev-setuptree, с помо­щью кото­рой мы смо­жем создать рабо­чую сре­ду в виде ката­ло­гов для сборки.

2. Уста­нав­ли­ва­ем зависимости:

yum install openssl-devel zlib-devel pcre-devel

* дан­ные паке­ты необ­хо­ди­мы имен­но для наше­го вари­ан­та сбор­ки. Имей­те вви­ду, что в вашем слу­чае может пона­до­бить­ся боль­ше зави­си­мо­стей. Так или ина­че, если в систе­ме не будет хва­тать необ­хо­ди­мых паке­тов, мы полу­чим ошиб­ку при попыт­ке выпол­нить сбор­ку RPM.

3. Созда­ем пользователя.

Делать гото­вые уста­но­воч­ные сбор­ки паке­тов очень опас­но от поль­зо­ва­те­ля root. Если мы допу­стим ошиб­ку с путя­ми, фай­лы могут пере­те­реть или уда­лить важ­ные для рабо­ты дирек­то­рии. Сто­ит создать отдель­но­го поль­зо­ва­те­ля и рабо­тать под ним.

Выпол­ня­ем команду:

useradd builder -m

* в дан­ном при­ме­ре мы созда­дим поль­зо­ва­те­ля builder. Опция -m сра­зу создаст домаш­ний ката­лог для пользователя.

Теперь захо­дим под дан­ным поль­зо­ва­те­лем — после­ду­ю­щие коман­ды мы будем выпол­нять от него:

su - builder

Подготовка среды

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

$ pwd

Мы долж­ны уви­деть что-то на подобие:

/home/builder

Перей­ти в домаш­ний ката­лог поль­зо­ва­те­ля мож­но командой:

$ cd ~

Созда­дим струк­ту­ру ката­ло­гов для сборки:

$ rpmdev-setuptree

В нашей теку­щем ката­ло­ге долж­на появить­ся пап­ка rpmbuild — а в ней:

  1. BUILD содер­жит все фай­лы, кото­рые появ­ля­ют­ся при созда­нии пакета.
  2. RPMS сюда будут скла­ды­вать­ся гото­вые пакеты.
  3. SOURCES для исход­ни­ков, из кото­рых и будут соби­рать­ся RPM-пакеты.
  4. SPECS для фай­лов с опи­са­ни­ем про­цес­са сборки.
  5. SRPMS — для исход­ни­ков RPM-файлов.

Мы гото­вы к загруз­ке исход­ни­ка и его подготовке.

Загрузка исходника и сборка RPM

На стра­ни­це загруз­ки паке­тов NGINX мы можем най­ти паке­ты для нуж­ной нам опе­ра­ци­он­ной систе­мы. Так как в нашем при­ме­ре соби­ра­ет­ся пакет для CentOS (я выбрал 7), то мож­но перей­ти сра­зу в соот­вет­ству­ю­щий ката­лог.

Нахо­дим исход­ник вида nginx-<версия>.<отметка вер­сии linux>.ngx.src.rpm и копи­ру­ем на него ссылку:

* в моем при­ме­ре мне нужен nginx вер­сии 1.19.3.

С помо­щью ско­пи­ро­ван­ной ссыл­ки загру­жа­ем исходник:

$ wget https://nginx.org/packages/mainline/centos/7/SRPMS/nginx-1.19.3-1.el7.ngx.src.rpm

Уста­но­вим ска­чан­ный исход­ник командой:

$ rpm -Uvh nginx-1.19.3-1.el7.ngx.src.rpm

В ката­ло­ге rpmbuild/SOURCES появят­ся исход­ни­ки для сбор­ки нуж­ной нам вер­сии NGINX.

Соби­ра­ем уста­но­воч­ный RPM-пакет:

$ rpmbuild -bb rpmbuild/SPECS/nginx.spec

В ката­ло­ге rpmbuild/RPMS, в зави­си­мо­сти от архи­тек­ту­ры паке­та создаст­ся ката­лог. В моем при­ме­ре пол­ный путь до создан­но­го паке­та — rpmbuild/RPMS/x86_64. В нем мы долж­ны най­ти 2 файла:

  1. nginx-1.19.3-1.el7.ngx.x86_64.rpm: пакет для установки.
  2. nginx-debuginfo-1.19.3-1.el7.ngx.x86_64.rpm: пакет для уста­нов­ки с отла­доч­ной информацией.

Пакет создан и готов к установке.

Установка, запуск и удаление

1. Для уста­нов­ки собран­но­го паке­та вво­дим команду:

rpm -Uvh <путь до собран­но­го пакета>

* где rpm вво­дит­ся с ключами:

  • U — обно­вить, если пакет уже уста­нов­лен в системе.
  • v — вывод инфор­ма­ции о ходе процесса.
  • h — пока­зы­вать ста­тус установки.

Спи­сок всех клю­чей мож­но посмот­реть коман­дой rpm --help или man rpm.

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

В нашем слу­чае коман­да будет такой:

rpm -Uvh nginx-1.19.3-1.el7.ngx.x86_64.rpm

* при этом мы долж­ны нахо­дить­ся в ката­ло­ге, в кото­ром раз­ме­сти­ли пакет RPM.

2. Для запус­ка nginx вво­дим команды:

systemctl enable nginx

systemctl start nginx

* Пер­вая коман­да поз­во­лит наше­му веб-сер­ве­ру запус­кать­ся авто­ма­ти­че­ски. Вто­рая запу­стит сервис.

Для про­вер­ки состо­я­ния сер­ви­са вво­дим команду:

systemctl status nginx

Я столк­нул­ся с 2-я раз­ны­ми про­бле­ма при запус­ке сервиса.
1) служ­ба не стар­то­ва­ла, выда­вая ошиб­ку. В логе гово­ри­лось, что нет досту­па к фай­лу /var/run/nginx.pid. Повтор­ный запуск служ­бы решил проблемы.
2) систе­ма выда­ва­ла ошиб­ку «Unit nginx.service could not be found», кото­рая гово­рит, что сер­ви­са nginx не суще­ству­ет. Про­бле­ма реша­ет­ся вво­дом коман­ды systemctl daemon-reload, кото­рая пере­чи­ты­ва­ем кон­фи­гу­ра­ци­он­ные фай­лы для systemd.

3. Что­бы уда­лить пакет сна­ча­ла запре­тив авто­за­пуск сер­ви­са и оста­но­вим его:

systemctl disable nginx

systemctl stop nginx

Смот­рим пол­ное назва­ние уста­нов­лен­но­го в систе­ме пакета:

rpm -qa | grep nginx

В моем слу­чае это было:

nginx-1.19.3-1.el7.ngx.x86_64

Для уда­ле­ния паке­та вводим:

rpm -e nginx-1.19.3-1.el7.ngx.x86_64

Добавление модуля

Как гово­ри­лось выше, мы доба­вим модуль SPNEGO в нашу сбор­ку. Для при­ме­ра, мы будем исполь­зо­вать дина­ми­че­ское под­клю­че­ние дан­но­го модуля.

В моем при­ме­ре необ­хо­ди­мо кло­ни­ро­вать про­ект из GIT-репо­зи­то­рия. Для это­го необ­хо­ди­мо уста­но­вить одно­имен­ную утилиту:

yum install git

Теперь захо­дим под ранее создан­ным поль­зо­ва­те­лем builder:

su - builder

Пере­хо­дим в ката­лог для сбор­ки. В нашем слу­чае, это домаш­няя директория:

$ cd ~

Кло­ни­ру­ем исход­ник моду­ля в дирек­то­рию /tmp:

$ git clone https://github.com/stnoonan/spnego-http-auth-nginx-module.git /tmp/spnego-http-auth-nginx-module

Ранее мы уже ска­чи­ва­ли исход­ни­ки nginx, поэто­му сра­зу откры­ва­ем файл nginx.spec:

$ vi rpmbuild/SPECS/nginx.spec

Нахо­дим:

%define BASE_CONFIGURE_ARGS

После послед­не­го --with-… добавим:

--add-dynamic-module=/tmp/spnego-http-auth-nginx-module

Нахо­дим

%description

После него добавляем:

%package module-spnego
Group: %{_group}
Requires: nginx = %{?epoch:%{epoch}:}%{main_version}-%{main_release}
Summary: nginx spnego module
%description module-spnego
Dynamic Spnego module for nginx.

 

После:

%build

… добав­ля­ем:

echo 'load_module "%{_libdir}/nginx/modules/ngx_http_auth_spnego_module.so";' \
> %{buildroot}%{_sysconfdir}/nginx/modules/spnego-http-auth-nginx-module.conf

Нахо­дим раз­де­лы %files и после них добавим:

%files module-spnego
%{_libdir}/nginx/modules/spnego-http-auth-nginx-module.conf
%{_libdir}/nginx/modules/ngx_http_auth_spnego_module.so

Запус­ка­ем сборку:

$ rpmbuild -bb rpmbuild/SPECS/nginx.spec

Для уста­нов­ки нам пона­до­бит­ся 2 RPM-пакета:

  1. nginx-1.19.3-1.el7.ngx.x86_64.rpm
  2. nginx-module-spnego-1.19.3-1.el7.ngx.x86_64.rpm

Оба эти паке­та будут нахо­дить­ся в ката­ло­ге RPMS.

После уста­нов­ки паке­та выпол­ня­ем команду:

nginx -V

Сре­ди полу­чен­ных опций сбор­ки мы долж­ны уви­деть нашу:

… --add-dynamic-module=/tmp/spnego-http-auth-nginx-module …

Так­же мы долж­ны будем отре­дак­ти­ро­вать кон­фи­гу­ра­ци­он­ный файл NGINX, что­бы наши моду­ли подгружались:

vi /etc/nginx/nginx.conf

В кор­не­вой сек­ции добавим:

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

Изменение конфигурационного файла NGINX

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

Откры­ва­ем файл:

$ vi rpmbuild/SOURCES/nginx.conf

Вне­сем сле­ду­ю­щие изменения:

* в нашем при­ме­ре вне­се­но все­го 2 изменения:

  1. worker_processes, кото­рый отве­ча­ет за рас­пре­де­ле­ние нагруз­ки по ядрам уже дав­но реко­мен­ду­ет­ся выстав­лять в зна­че­ние auto.
  2. Так­же мы допи­са­ли стро­ку include /etc/nginx/modules/*.conf, кото­рая ука­жет наше­му веб-сер­ве­ру под­гру­жать все кон­фи­гу­ра­ци­он­ные фай­лы из ката­ло­га modules.

Так­же акти­ви­ру­ем для сай­та по умол­ча­нию опцию для моду­ля spnego. Откры­ва­ем файл:

$ vi rpmbuild/SOURCES/nginx.vh.default.conf

Это файл, кото­рый будет нахо­дить­ся по пути /etc/nginx/conf.d/default.conf. Вне­сем в него изменения:

Пере­со­би­ра­ем RPM:

$ rpmbuild -bb rpmbuild/SPECS/nginx.spec

Выпол­ня­ем уста­нов­ку новых паке­тов на целе­вом сер­ве­ре. В нашем при­ме­ре мы можем пере­уста­но­вить паке­ты командами:

rpm -Uvh --force nginx-1.19.3-1.el7.ngx.x86_64.rpm

rpm -Uvh --force nginx-module-spnego-1.19.3-1.el7.ngx.x86_64.rpm

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

Мы долж­ны уви­деть изме­не­ния в кон­фи­гах, кото­рые сде­ла­ли до сборки.