Сборка RPM-пакетов в ALT Linux: автоматизация с помощью GEAR

В первой части материала мы разобрали случай сборки простого rpm-пакета в ALT Linux. За пример брали набор файлов изображений и собирали стандартной утилитой rpmbuild.

В этом материале поговорим про сборку python-проекта специальным инструментом — GEAR. Этот инструмент разработала команда сообщества ALT Linux Team для автоматизации процесса сборки.

Общими словами, GEAR — это удобная обвязка вокруг Git и rpmbuild. В дополнение к spec-инструкции достаточно написать gear-правила формирования архива, полученного из git-репозитория.

Материал статьи может быть полезен при изучении темы сборки rpm-пакета инструментом gear-rpm в ОС «Альт».

443c3e2cf37bb196d335dbba79057dfe.png

Что делать по шагам:

  1. проверить работоспособность кода;

  2. установить набор инструментов для сборки;

  3. настроить Git;

  4. подготовить рабочее пространство сборки;

  5. составить spec-файл;

  6. написать правила gear;

  7. проверить сборку с подготовленным spec-файлом;

  8. собрать пакет инструментом gear-rpm.

b9c44a85c46e29aef12bf0f495e87062.png

Проверим работоспособность кода

Возьмём python-программу управления яркостью мониторов компьютера. Перед сборкой пакета убедимся, что программа вообще работает.

cc016f0adcfc58d0498d95456cabd6fa.png

Способ установки со всеми зависимостями указан в README проекта.

# apt-get update

# apt-get install ddcutil xrandr python3 python3-module-PyQt5 pip

# pip install brightness-controller-linux

# brightness-controller

$ brightness-controller

Если программа запустилась успешно, можно приступить к подготовке rpm-пакета.

Установим необходимые пакеты

# apt-get update

# apt-get install rpm-build rpmdevtools rpm-utils git gear

Настроим Git

Укажем имя и адрес электронной почты в конфигурационных файлах git — эта информация будет использоваться во всех проектах, склонированных или созданных и отправленных с помощью git; она включается в коммиты, передаваемые пользователем, и не может быть далее изменена.

$ git config --global user.name "FirstName SecondName"

$ git config --global user.email "user@altlinux.org"

Создадим рабочее пространство

$ rpmdev-setuptree

008ce68e6861428a82bff40549714b46.png

Утилита rpmdev-setuptree создаёт базовую структуру каталогов RPM и файл ~/.rpmmacros. Заполним данные в этом файле, которые пригодятся для журнала изменений.

Склонируем исходный проект

$ git clone https://github.com/LordAmit/Brightness

Подготовим spec-файл

Cоздадим инструкции проекта на основе шаблона.

$ rpmdev-newspec brightness.spec

Возьмём данные из pyproject.toml — файла инструкций python-проекта, чтобы заполнить заголовок файла инструкций будущего пакета (spec-файл). Для имени пакета оставим название brightness-controller.

Укажем лицензию через макрос.

$ cat /usr/lib/rpm/macros.d/license
<...>
%gpl3plus GPLv3+
<...>

Пропишем зависимости, указанные в pyproject.toml, в том числе модуль poetry. Добавим к ним пакет rpm-build-python3, который содержит готовые макросы для сборки программ. Также добавим rpm-build-licenses, так как макрос лицензии относится к этому пакету.

Зависимость сборки от python3

Учтём, что в ОС «Альт» пакет python3 установится по зависимостям от python-модулей qtpy и PyQt5.

Для работоспособности пакета в окружении ALT добавим зависимость python3-module-cx-freeze и отфильтруем модули brightness_controller_linux.util через макрос %add_python3_req_skip.

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

Requires: python3-module-cx-freeze
BuildRequires: python3-module-qtpy
BuildRequires: python3-module-PyQt5
BuildRequires: python3-module-poetry
BuildRequires: rpm-build-python3
BuildRequires: rpm-build-licenses

%description
You can control brightness of both primary and external displays.

%add_python3_req_skip brightness_controller_linux.util

ed6a2c8ea139adc4ce53a3eb39bc86b5.png

Опишем процесс сборки и установки в секциях тела spec-файла с помощью макросов. В нашем примере python-проект собирается по инструкции файла pyproject.toml через модуль poetry. Поэтому в секцию build поместим макрос %pyproject_build, а в секции %install %pyproject_install.

В конфигурационном файле pyproject.toml указано, как должен называться README-файл:

readme = "readme.md"

Так как в проекте этот файл назван заглавными буквами, добавим команду переименования.

%build
mv README.md readme.md
%pyproject_build

Поправим секцию %files также в соответствии с описаниями проекта. %python3_sitelibdir использует переменную name, значение которой не подходит. Определим переменную %oname в самом верху spec«а и исправим инструкции.

%define oname brightness_controller_linux
<...>
%files
%python3_sitelibdir/%oname
%python3_sitelibdir/%oname-%version.dist-info
%_bindir/brightness-controller

Утилита add_changelog поможет в оформлении журнала изменений.

$ add_changelog brightness.spec

Настроим GEAR-правила

Создадим инструкции GEAR в корне проекта. В справочном руководстве gear-rules указано, что файл может называться .gear-rules или .gear/rules. Сопровождающий пакета определяет структуру репозитория будущего пакета. Чаще можно встретить использование .gear/rules.

$ mkdir .gear

$ vim .gear/rules

В этом файле описаны правила сборки git-репозитория. А именно, какие файлы и по каким инструкциям собрать в архив, из которого затем соберётся приложение.

В случае, когда используются собственные наработки, архив создают из корня проекта. Знак [.] обозначает корень проекта.

$ cat .gear/rules
tar: .
spec: .gear/brightness.spec

Для нашего примера такая запись тоже будет работать. Но мы не будем упаковывать весь склонированный каталог и добавленные инструкции (.gear/rules и brightness.spec). Все файлы, необходимые для работы программы, уже находятся в директории brightness-controller-linux. Отделим разработки upstream от своих изменений и дополним правило в rules.

Имя архива должно совпадать с названием, указанным в файле спецификации. При использовании GEAR имя архива также должно совпадать с указаниями в .gear/rules. Название директории brightness-controller-linux, а по инструкциям в spec-файле имя архива формируется из тегов Name и Version: brightness-controller-2.4.tar.

Source: %name-%version.tar

Воспользуемся опциями утилиты gear-rules для переименования архива. Укажем, из какого каталога сформировать архив и дополним директиву tar: опцией name=@name@-@version@. То есть выберем каталог для создания архива и зададим имя архиву.

tar: brightness-controller-linux name=@name@-@version@
spec: .gear/brightness.spec

76d901e717a339c3e9aa0a9d5fc35342.png

В соответствии с записью переместим spec-файл в каталог .gear. Spec-файл можно расположить и в корне проекта — тогда в rules ничего не нужно указывать. GEAR автоматически найдёт файл спецификации в корне проекта, если он единственный соответствующий шаблону *.spec.

$ mv brightness.spec .gear/

Раскладывать файлы в каталоги RPM нет необходимости — этим займётся GEAR на этапе сборки.

Запустим сборку gear-rpm

Соберём пакет из внешнего источника с помощью gear-rpm. По сравнению с вариантом сборки через rpmbuild, утилита gear за счет автоматизации облегчает работу для сопровождающего пакета — при многократной сборке одной и той же программы.

Установим зависимости для сборки, которые указали в spec-файле.

# apt-get update

# apt-get install python3-module-qtpy python3-module-PyQt5 python3-module-poetry rpm-build-python3

Когда мы клонируем исходный код, нам нужно видеть отличия upstream от своих изменений, поэтому вести такой репозиторий принято в двух ветках: одна для неизменённого исходного кода, другая — для своих изменений.

Добавим ветку и перейдём на неё.

$ git checkout -b sisyphus

Так как в файле проекта .gitignore содержится запрет на отслеживание spec-файла, добавим этот файл с ключом -f. При последующих изменениях добавлять этот файл можно без ключа.

$ git add -f .gear/brightness.spec

Проверим сборку с помощью временного коммита

Запустим сборку с ключом --commit, чтобы не записывать изменения. Ключ --verbose используется для подробного вывода процесса сборки в терминале.

$ gear-rpm -ba --verbose --commit

Пакет rpm успешно записан.

Установим зависимость. Установим пакет rpm. Возьмём обозначение для запуска приложения из строки spec-файла %_bindir/brightness-controller и откроем программу из консоли.

# apt-get install python3-module-cx-freeze

# rpm -i ~/RPM/RPMS/noarch/brightness-controller-2.4-alt1.noarch.rpm

$ brightness-controller

Программа успешно запустилась.

Запишем изменения в проект

Проверим spec-файл с помощью утилиты cleanup_spec: она почистит файл от ненужных пробелов и прочее.

Проверим статус изменений в проекте и запишем изменения. Воспользуемся для этого git или gear. Когда spec-файл существенно меняется, следует повысить версию и релиз, дополнить Changelog новой записью и собрать пакет новой версии. В данном случае коммит связан с назначением версии для репозитория Сизиф, поэтому утилита gear-commit будет предпочтительнее. Утилита обращается к Changelog-у в spec-файле и записывает коммит определённым форматом: первой строкой версию-релиз, далее записывает все указанные в Changelog изменения.

$ gear-commit

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

$ git log
commit 498ecbe5ecaf37a41313159448f00211c0b61add (HEAD -> master, tag: 2.4-alt1,>
Author: Maria Fokanova
Date: Thu Oct 31 17:28:59 2024 +0400
2.4-alt1
- Initial build for ALT.

Запустим сборку с новым коммитом

$ gear-rpm -ba

Пакет rpm успешно записан.

Итого

Инструмент GEAR через скрипты обращается к Git для работы с исходными данными, взаимодействует со структурой каталогов RPM и обращается к RPM для запуска процесса сборки. gear — обвязка вокруг rpmbuild. Собранные пакеты будут расположены в базовой структуре RPM. В зависимости от процессорной архитектуры, rpm-пакет можно найти в каталогах noarch, x86_64 и других.

Благодарю за помощь в создании материала @Soviet_Anton

© Habrahabr.ru