Вопросы, связанные с разработкой и сборкой пакетов

Я хочу создать пакет для Fedora. Что мне следует знать?

См. здесь и здесь.

Как собрать RPM пакет в mock?

См. здесь.

Как добавить свой пакет в репозиторий Fedora и стать мейнтейнером?

См. здесь.

Что такое Koji?

Fedora Koji - это автоматизированная среда для сборки пакетов для Fedora.

Хочу внести свои правки в пакет и пересобрать его для личных нужд. Как проще это сделать?

Установим утилиты fedpkg и mock:

sudo dnf install fedpkg mock

Скачаем исходники необходимого пакета foo-bar:

fedpkg clone -a foo-bar

Перейдём в каталог с загруженными исходниками и переключимся на ветку для конкретной версии Fedora (если нужна версия из Rawhide - следует использовать master):

cd foo-bar
fedpkg switch-branch f29

Внесём свои правки, сделаем коммит в репозиторий:

git add -A
git commit -m "Description of our changes."

Запустим автоматическую сборку в mock:

fedpkg mockbuild

Как создать tarball с исходниками из Git репозитория?

Если проект по какой-либо причине не поставляет готовые тарболы и отсутствует возможность их скачать напрямую с хостинга VCS, можно создать их из Git.

Клонируем репозиторий источника:

git clone https://example.org/foo-bar.git

Создадим архив с исходниками:

git archive --format=tar --prefix=foo-bar-1.0.0/ HEAD | gzip > ~/rpmbuild/SOURCES/foo-bar-1.0.0.tar.gz

Здесь HEAD - указатель на актуальный коммит (вместо этого можно использовать SHA1 хеш любого коммита, а также имя тега или ветки), foo-bar - название проекта, а 1.0.0 - его версия.

Как переопределить пакет в Koji репозитория RPM Fusion?

Создание build override для репозитория f29-free:

koji-rpmfusion tag f29-free-override foo-bar-1.0-1.fc29

Удаление build override для репозитория f29-free:

koji-rpmfusion untag f29-free-override foo-bar-1.0-1.fc29

Как настроить Git для работы с почтовым сервисом Gmail?

Для того, чтобы использовать функцию git send-mail с почтовым сервисом Gmail, необходимо:

  1. включить двухфакторную аутентификацию в настройках Google аккаунта;
  2. в настройках безопасности почтового ящика Gmail разрешить использование «небезопасных приложений» (под небезопасными Google понимает любые, не поддерживающие OAuth2);
  3. там же включить доступ к почте посредством POP3 или IMAP (это активирует также и необходимый для нас протокол SMTP);
  4. в настройках безопасности сгенерировать новый пароль для приложения;
  5. указать в файле ~/.gitconfig параметры почтового сервиса;
  6. когда будет запрошен пароль, ввести созданный ранее пароль приложения.

Пример файла ~/.gitconfig для работы с почтовым сервисом Gmail:

[sendemail]
    smtpEncryption = tls
    smtpServer = smtp.gmail.com
    smtpUser = yourname@gmail.com
    smtpServerPort = 587

Правильно ли использовать dlopen для загрузки динамических библиотек в приложении?

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

  1. в каждом дистрибутиве GNU/Linux именование библиотек, особенно если у них нет чётко установленной апстримом SOVERSION константы, ложится на плечи мейнтейнеров. К примеру есть популярная libcurl. Во всех дистрибутивах она линкуется с openssl и называется libcurl.so, а в Debian и Ubuntu была переименована в libcurl-gnutls.so из-за линковки с gnutls;
  2. нет никакой гарантии, что загрузится именно необходимая версия библиотеки, имеющая необходимую функцию, а отсутствии оной приложение будет аварийно завершено с ошибкой сегментирования;
  3. если существует несколько версий библиотеки с разными SOVERSION, необходимо самостоятельно их искать на диске и подгружать с рядом хаков ибо имя libfoo.so без указанной SOVERSION в большинстве дистрибутивов представляет собой символическую ссылку и доступен лишь после установки соответствующего development пакета. Соответственно на машинах обычных пользователей он отсутствует;
  4. о библиотеках, подгружаемых динамически, не в курсе LD, а следовательно он не сможет при загрузке образа приложения подгрузить их в память;
  5. в случае корректной линковки LD перед запуском приложения осуществит автоматический поиск необходимых экспортируемых функций во всех указанных библиотеках. При их отсутствии приложение не будет запущено;
  6. при сборке пакета динамически подгружаемые через dlopen библиотеки не будут определены и прописаны в качестве зависимостей пакета, что может вызвать проблемы у пользователей и падение приложения;

Как получить полный список установленных переменных окружения в текущем терминале?

Получить список установленных переменных окружения можно посредством выполнения утилиты env:

env

Как получить полный список установленных переменных для запущенного процесса?

Получение списка установленных переменных окружения для запущенных процессов:

cat /proc/$PID/environ

Здесь $PID - PID процесса, информацию о котором необходимо получить.

Как задать переменную окружения?

Вариант 1. Запуск процесса с заданной переменной окружения:

FOO=BAR /usr/bin/foo-bar

Вариант 2. Экспорт переменной окружения в запущенном терминале и дальнейший запуск приложения:

export FOO=BAR
/usr/bin/foo-bar

Вариант 3. Модификация директивы Exec= в ярлыке запуска приложения:

env FOO=BAR /usr/bin/foo-bar

Как правильно настроить Git для работы?

Сначала укажем своё имя и адрес электронной почты:

git config --global user.name "Your Name"
git config --global user.email email@example.org

Установим предпочитаемый текстовый редактор для работы с коммитами:

git config --global core.editor vim

Я хочу внести правки в проект. Как правильно отправить их в апстрим?

Если проект хостится на одном из популярных сервисов (GitHub, BitBucket или GitLab), сначала войдём в свой аккаунт (при осутствии создадим) и сделаем форк репозитория.

Осуществим базовую настройку Git клиента если это ещё не было сделано ранее.

Клонируем наш форк:

git clone git@github.com:YOURNAME/foo-bar.git

Создадим ветку new_feature для наших изменений (для каждого крупного изменения следует создавать отдельную ветку и ни в коем случае не коммитить в master):

git checkout -b new_feature

Внесём свои правки в проект, затем осуществим их фиксацию:

git add -A
git commit -s

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

Signed-off-by: Your Name <email@example.org>

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

git remote add upstream https://github.com/foo/foo-bar.git

Скачаем актуальные изменения и выполним rebase основной ветки нашего форка с апстримом:

git fetch upstream
git checkout master
git merge upstream/master

Осуществим rebase ветки с нашими изменениями с основной:

git checkout new_feature
git rebase master

Отправим наши изменения на сервер:

git push -u origin new_feature

Создадим новый Pull Request.

Как скомпилировать простую программу на языке C++ из консоли?

Установим компилятор GCC-C++ (G++) и ряд вспомогательных компонентов:

sudo dnf install gcc-c++ rpm-build

Создадим простейший пример helloworld.cpp:

#include <iostream>

int main(int argc, char *argv[], char *env[])
{
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

Скомпилируем и слинкуем его:

g++ $(rpm -E %{optflags}) -fPIC helloworld.cpp -o helloworld $(rpm -E %{build_ldflags}) -lstdc++

Здесь g++ - запускающий файл файл компилятора, helloworld.cpp - файл с исходным кодом (если их несколько, то разделяются пробелом), helloworld - имя результирующего бинарника, -lstdc++ - указание компоновщику на необходимость линковки со стандартной библиотекой C++.

Корректные флаги компиляции и компоновки вставляются автоматически из соответствующих макросов RPM.

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

./helloworld

Если всё сделано верно, то увидим сообщение Hello, World! в консоли.

Приложение падает. Как мне его отладить?

Для начала рекомендуется (хотя и не обязательно) установить отладочную информацию для данного пакета:

sudo dnf debuginfo-install foo-bar

После завершения процесса отладки символы можно снова удалить.

Чтобы получить бэктрейс падения, нужно выполнить в терминале:

gdb /usr/bin/foo-bar 2>&1 | tee ~/backtrace.log

Далее в интерактивной консоли отладчика ввести: handle SIGPIPE nostop noprint и затем run, дождаться сегфолта и выполнить bt full для получения бэктрейса. Теперь можно прописать quit для выхода из режима отладки.

Далее получившийся файл ~/backtrace.log следует загрузить на любой сервис размещения текстовых файлов.

Также рекомендуется ещё сделать трассировку приложения до момента падения:

strace -o ~/trace.log /usr/bin/foo-bar

Полученный файл ~/trace.log также следует загрузить на сервис.

Безопасно ли использовать LD_PRELOAD для загрузки сторонних библиотек?

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

Создадим и скомпилируем простой пример example.c:

#include <stdio.h>

static __attribute__((constructor (200))) void bar()
{
    printf("%s", "Method bar() was called.\n");
}

static __attribute__((constructor (150))) void foo()
{
    printf("%s", "Method foo() was called.\n");
}

Данный метод содержит сразу два суперглобальных конструктора с указанием приоритетов. Чем ниже приоритет, тем скорее данный метод будет исполнен.

Скомпилируем и слинкуем наш пример:

gcc -shared $(rpm -E %{optflags}) -fPIC example.c -o example.so $(rpm -E %{build_ldflags}) -lc

Внедрим нашу библиотеку в известный доверенный процесс, например whoami:

LD_PRELOAD=./example.so whoami

Оба суперглобальных метода будут немедленно исполнены с правами запускаемого приложения и изменят его вывод:

Method foo() was called.
Method bar() was called.
user1

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

Как можно активировать LTO оптимизации при сборке пакета?

Для активации LTO оптимизаций необходимо и достаточно передать параметр -flto как для компилятора (CFLAGS и/или CXXFLAGS), так и для компоновщика.

Самый простой способ сделать это - переопределение значений стандартных макросов внутри SPEC файла:

%global optflags %{optflags} -flto
%global build_ldflags %{build_ldflags} -flto

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

export AR=%{_bindir}/gcc-ar
export RANLIB=%{_bindir}/gcc-ranlib
export NM=%{_bindir}/gcc-nm

Если используется система сборки cmake, то помимо этого придётся патчить манифест CMakeLists.txt, т.к. он в настоящее время не поддерживает загрузку переопределённых значений:

set(CMAKE_AR "/usr/bin/gcc-ar")
set(CMAKE_RANLIB "/usr/bin/gcc-ranlib")
set(CMAKE_NM "/usr/bin/gcc-nm")

В противном случае появится ошибка plugin needed to handle lto object.

Как вывести список установленных пакетов, от которых никто не зависит?

В настоящее время данная функциональность отсутствует в dnf «из коробки», поэтому напишем и скомпилируем небольшую программу на языке C, реализующую это средствами библиотеки libsolv.

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

sudo dnf install gcc libsolv-devel

Создадим файл rpm-unneeded.c с исходным текстом программы:

#include <solv/pool.h>
#include <solv/poolarch.h>
#include <solv/repo_rpmdb.h>
#include <solv/solver.h>

int main(void)
{
    Pool *pool;
    Repo *rpmdb;
    Solver *solver;
    Queue q;

    pool = pool_create();
    pool_setarch(pool, NULL);
    pool_set_flag(pool, POOL_FLAG_IMPLICITOBSOLETEUSESCOLORS, 1);

    rpmdb = repo_create(pool, "@system");
    repo_add_rpmdb(rpmdb, NULL, 0);
    pool->installed = rpmdb;

    solver = solver_create(pool);
    solver_set_flag(solver, SOLVER_FLAG_KEEP_EXPLICIT_OBSOLETES, 1);
    solver_set_flag(solver, SOLVER_FLAG_BEST_OBEY_POLICY, 1);
    solver_set_flag(solver, SOLVER_FLAG_YUM_OBSOLETES, 1);

    queue_init(&q);
    solver_solve(solver, &q);
    solver_get_unneeded(solver, &q, 1);

    for (int i = 0; i < q.count; i++)
    {
        printf("%s\n", pool_solvid2str(pool, q.elements[i]));
    }

    queue_free(&q);
    pool_free(pool);

    return 0;
}

Скомпилируем и слинкуем приложение:

gcc $(rpm -E %{optflags}) -fPIC rpm-unneeded.c -o rpm-unneeded $(rpm -E %{build_ldflags}) -lsolv -lsolvext

Запустим приложение ./rpm-unneeded и получим список установленных пакетов, от которых никто не зависит.

Можно ли использовать cpack для сборки пакетов для GNU/Linux?

Нет, использовать cpack категорически не рекомендуется по следующим причинам:

  • создаёт RPM и DEB пакеты в виде архивов;
  • не добавляет метаданные в создаваемые пакеты;
  • не прописывает зависимости от библиотек и других пакетов;
  • не экспортирует provides;
  • не обрабатывает mime-типы;
  • не добавляет обязательные скриптлеты;
  • не соблюдает гайдлайны дистрибутивов.

Вместо cpack следует собирать нативные пакеты.

Приложение собрано со старой версией библиотеки. Как заставить его работать?

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

  1. LD_PRELOAD - небезопасный - библиотека (или библиотеки) напрямую инъектируется в процесс средствами интерпретатора динамических библиотек LD до его непосредственного запуска;
  2. LD_LIBRARY_PATH - более безопасный - список каталогов, в которых интерпретатор динамических библиотек LD ищет соответствующие so, расширяется на указанные пользователем значения.

Рассмотрим второй способ с переопределением переменной окружения LD_LIBRARY_PATH.

Скачаем RPM пакет foo-bar необходимой версии из любого источника (лучшим вариантом будет конечно же репозитории старых версий Fedora), распакуем его например в ~/lib/foo-bar и извлечём необходимые динамические библиотеки (.so файлы).

Создадим shell-скрипт run-foo.sh для запуска бинарника:

#!/usr/bin/sh
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/lib/foo-bar
/path/to/binary/foo

Здесь foo - имя бинарника, который требуется запустить, а /path/to/binary - каталог, в котором он находится. В качестве разделителя путей LD_LIBRARY_PATH применяется двоеточие. Закрывающий слэш не ставится.

Установим скрипту разрешение не запуск и запустим его:

chmod +x run-foo.sh
./run-foo.sh

Если всё сделано верно, приложение успешно стартует.

Проекты под какими лицензиями допускается распространять в репозиториях?

См. здесь.

В каком порядке запускаются процессы через канал (пайп)?

Если запускается несколько процессов с передачей данных через канал (пайп; pipe), то все они стартуют одновременно, затем начинает выполняться первый, а остальные уходят в состояние ожидания ввода.

Можно ли использовать собственные флаги компиляции при сборке пакета?

Для любых официальных сборок следует использовать исключительно стандартные для дистрибутива флаги, предоставляемые макросами %{optflags} (флаги компилятора) и %{build_ldflags} (флаги компоновки).

Какую IDE использовать для разработки на C++ в Fedora?

Мы рекомендуем Qt Creator, которая одинаково хорошо подходит как для разработки на C++ (с Qt и без него), так и чистого C.

Установим данную IDE, а также компилятор C++ и ряд необходимых библиотек и средств для сборки проектов:

sudo dnf install gcc gcc-c++ qt-creator qt5-qtbase-devel cmake

При необходимости установим также документацию Qt и готовые примеры стандартных приложений:

sudo dnf install qt5-qtbase-doc qt5-qtbase-examples qt-creator-doc

В Qt Creator отсутствует документация. Как исправить?

Если Qt Creator при попытке загрузить документацию выдаёт ошибку Error loading: qthelp://org.qt-project.qtcreator.472/doc/index.html, выберем пункт меню Tools - Options - Help - Documentation - Add, затем вручную добавим следующие файлы:

/usr/share/doc/qt5/qmake.qch
/usr/share/doc/qt5/qtconcurrent.qch
/usr/share/doc/qt5/qtcore.qch
/usr/share/doc/qt5/qtdbus.qch
/usr/share/doc/qt5/qtgui.qch
/usr/share/doc/qt5/qtnetwork.qch
/usr/share/doc/qt5/qtnetworkauth.qch
/usr/share/doc/qt5/qtopengl.qch
/usr/share/doc/qt5/qtplatformheaders.qch
/usr/share/doc/qt5/qtprintsupport.qch
/usr/share/doc/qt5/qtsql.qch
/usr/share/doc/qt5/qttestlib.qch
/usr/share/doc/qt5/qtwidgets.qch
/usr/share/doc/qt5/qtxml.qch
/usr/share/doc/qt5/qtxmlpatterns.qch
/usr/share/doc/qtcreator/qtcreator.qch
/usr/share/doc/qtcreator/qtcreator-dev.qch

Изменения вступят в силу после перезапуска IDE.

В Qt Creator отсутствуют компиляторы. Как исправить?

Если Qt Creator не смог самостоятельно обнаружить установленный в системе фреймворк Qt, а также компилятор, то необходимо добавить их самостоятельно.

Для этого войдём в настройки IDE, затем сначала добавим компилятор GCC /usr/bin/gcc, а затем тулчейн Qt - /usr/bin/qmake-qt5. После этого на вкладке Kits создадим новый набор из данных компонентов.

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

Какую IDE использовать для разработки на Python в Fedora?

Мы рекомендуем PyCharm Community Edition.

Подключим COPR репозиторий:

sudo dnf copr enable phracek/PyCharm

Установим IDE:

sudo dnf install pycharm-community pycharm-community-jre

При необходимости установим также набор популярных плагинов:

sudo dnf install pycharm-community-plugins

Как получить информацию о содержимом образа бинарной прошивки?

Для работы с образами прошивок можно использовать утилиту binwalk. Установим её:

sudo dnf install binwalk

Произведём анализ файла и получим результат:

binwalk foo-bar.bin

Как автоматически скачать исходники, прописанные в SPEC-файле?

Установим необходимые утилиты:

sudo dnf install rpm-build rpmdevtools

Создадим базовую иерархию каталогов для rpmbuild:

rpmdev-setuptree

Скачаем исходники, прописанные в SPEC-файле foo-bar.spec:

spectool -g -R foo-bar.spec

Как автоматически инкрементировать релиз в SPEC-файле?

Установим необходимый для работы пакет:

sudo dnf install rpmdevtools

Инкрементируем релиз SPEC-файла (директива Release) с автоматическим созданием новой строки в %changelog:

rpmdev-bumpspec -c "Updated to latest snapshot."

Как загрузить изменения во всех вложенных репозиториях из данного каталога?

Если Git репозитории были клонированы в общий каталог ~/foo-bar, то загрузим изменения в каждом из вложенных проектов при помощи find и bash:

find ~/foo-bar -maxdepth 1 ! -path . -type d -exec bash -c "pushd '{}' ; git pull ; popd" \;

Как создать пустую ветку в Git без общей истории?

Создадим новую пустую ветку foo-bar от текущего HEAD:

git checkout --orphan foo-bar

Создадим удалим всё проиндексированное содержимое данной ветки:

git reset --hard

Можно ли перенести каталоги сборки и кэшей mock на другой диск?

Система автоматической сборки пакетов mock занимает огромное количество места в корневом разделе, поэтому многие мейнтейнеры хотели бы перенести её на другой диск. Штатно это сделать не представляется возможным ибо значения каталогов по умолчанию /var/cache/mock и /var/lib/mock жёстко прописаны внутри приложения и не подлежат изменению со стороны пользователя, поэтому воспользуемся символическими ссылками.

Создадим на другом накопителе (его файловая система должна поддерживать права доступа Unix) базовый каталог для mock:

cd /media/foo-bar
sudo mkdir mock
sudo chown root:mock mock
sudo chmod 42775 mock

Переместим содержимое текущих рабочих каталогов mock:

sudo mv /var/cache/mock /media/foo-bar/mock/cache
sudo mv /var/lib/mock /media/foo-bar/mock/lib

Создадим символические ссылки на старом месте:

sudo ln -s /media/foo-bar/mock/cache /var/cache/mock
sudo ln -s /media/foo-bar/mock/lib /var/lib/mock

Зададим контекст SELinux по умолчанию для нового хранилища:

sudo semanage fcontext -a -t mock_cache_t "/media/foo-bar/mock/cache(/.*)?"
sudo semanage fcontext -a -t mock_var_lib_t "/media/foo-bar/mock/lib(/.*)?"

Сбросим контекст SELinux для всех рабочих каталогов:

sudo restorecon -Rv /var/cache/mock
sudo restorecon -Rv /var/lib/mock
sudo restorecon -Rv /media/foo-bar/mock/cache
sudo restorecon -Rv /media/foo-bar/mock/lib

Здесь /media/foo-bar - точка монтирования нового накопителя, на котором будут располагаться кэши mock.

Как включить отображение текущей ветки Git в Bash?

Модуль интеграции с Bash входит в состав пакета Git. Добавим в приветствие Bash следующую строку:

export PS1='[\u@\h \W$(declare -F __git_ps1 &>/dev/null && __git_ps1 " (%s)")]\$ '

В качестве опциональных параметров поддерживаются GIT_PS1_SHOWDIRTYSTATE (показывать наличие незакреплённых изменений внутри каталога) и GIT_PS1_SHOWUNTRACKEDFILES (учитывать, либо нет не отслеживаемые системой контроля версий файлы):

export GIT_PS1_SHOWDIRTYSTATE=true
export GIT_PS1_SHOWUNTRACKEDFILES=true

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

Как создать унифицированный патч изменений между двумя файлами?

Для создания патча нам необходимо две версии файла: оригинальная и текущая.

Создадим унифицрованный патч с разностью между файлами foo-bar.txt.orig (оригинальный) и foo-bar.txt (текущий):

diff -Naur foo-bar.txt.orig foo-bar.txt > result.patch

Результат будет сохранён в файле result.patch.

Как создать унифицированный патч изменений между двумя каталогами?

Создадим унифицрованный патч с разностью между каталогами foo-bar_orig (оригинальный) и foo-bar (текущий):

diff -Naur foo-bar_orig foo-bar > result.patch

Результат будет сохранён в файле result.patch.

Как применить унифицированный патч?

Проверим возможность применения патча foo-bar.patch без внесения каких-либо изменений:

patch -p0 --dry-run -i foo-bar.patch

Применим патч:

patch -p0 -i foo-bar.patch

Параметром -p задаётся количество каталогов, которые будут отброшены при поиске файлов, указанных внутри унифицированного патча.

Как откатить наложенный унифицированный патч?

Проверим возможность отката патча foo-bar.patch без внесения каких-либо изменений:

patch -p0 -R --dry-run -i foo-bar.patch

Откатитим внесённые изменения:

patch -p0 -R -i foo-bar.patch

Параметром -p задаётся количество каталогов, которые будут отброшены при поиске файлов, указанных внутри унифицированного патча.

Как создать унифицированный патч между двумя коммитами?

Создадим патч между двумя коммитами AAA и BBB:

git diff AAA BBB > result.patch

Создадим патч коммитом CCC и текущим рабочей рабочей версией:

git diff CCC > result.patch

Здесь AAA, BBB и CCC - хеши коммитов в Git репозитории.

Как экспортировать Git коммит для отправки по электронной почте?

В Git имеется встроенное средство экспорта коммитов для их дальнейшей отправки по электронной почте.

Экспортируем один коммит:

git format-patch -1

Экспортируем сразу 3 коммита:

git format-patch -3

Как авторизоваться в инфраструктуре Fedora?

Для авторизации мы должны использовать вход в домен посредством Kerberos:

kinit foo-bar@FEDORAPROJECT.ORG

Здесь foo-bar - логин в FAS. Имя домена должно быть указано строго в верхнем регистре.

Также для некоторых операций необходимо загрузить публичный ключ SSH в FAS аккаунт.

Как запросить создание пакета в репозитории?

Сразу после завершения процедуры package review, мейнтейнер должен запросить создание пакета в репозиториях Fedora.

Установим утилиту fedpkg

sudo dnf install fedpkg

Получим новый токен в Pagure, который будет использоваться утилитой fedpkg для создания заявки. Для этого перейдём в раздел Settings - API Keys - Create new key, затем в списке доступных разрешений (ACLs) установим флажок только около опции Create a new ticket и нажмём кнопку Add.

Создадим файл конфигурации fedpkg:

mkdir -p ~/.config/rpkg
touch ~/.config/rpkg/fedpkg.conf

Загрузим созданный файл ~/.config/rpkg/fedpkg.conf в любом текстовом редакторе и добавим:

[fedpkg.pagure]
token = XXXXXXXXXX

Здесь XXXXXXXXXX - полученный от Pagure токен.

Запросим создание нового пакета в репозитории, а также веток для всех поддерживаемых релизов Fedora:

fedpkg request-repo --namespace rpms --monitor monitoring foo-bar YYYYYY
fedpkg request-branch --namespace rpms --repo foo-bar --all-releases

Здесь foo-bar - имя пакета, а YYYYYY - номер заявки в Red Hat BugZilla с успешно завершённым package review.

Как загрузить файлы с исходными кодами пакета в систему сборки?

После создания пакета осуществим вход в инфраструктуру Fedora, затем скачаем репозиторий пакета из Fedora SCM, содержащий SPEC файл и набор патчей (при необходимости), а также прочие службные файлы:

fedpkg clone foo-bar
cd foo-bar

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

fedpkg switch-branch master
fedpkg import /путь/к/foo-bar-1.0-1.fc30.src.rpm

Проверим внесённые изменения и если всё верно, жмём Q для выхода. Зафиксируем наши изменения:

git commit -m "Initial import."

При необходимости внесём изменения и в ветки поддерживаемых релизов Fedora:

fedpkg switch-branch f30
git merge master

Отправим изменения на сервер:

git push

Как осуществить сборку пакета для публикации в репозиториях?

После загрузки файлов с исходными кодами пакета, осуществим вход в инфраструктуру Fedora, а затем приступим к непосредственно сборке в Fedora Koji:

cd foo-bar
fedpkg switch-branch master
fedpkg build

При необходимости соберём и для других поддерживаемых релизов Fedora:

fedpkg switch-branch f30
fedpkg build

Как осуществить тестовую сборку пакета для определённой архитектуры?

Осуществим вход в инфраструктуру Fedora.

Выполним стандартную scratch-сборку для всех поддерживаемых данным выпуском архитектур:

cd foo-bar
fedpkg switch-branch master
fedpkg build --scratch

Выполним scratch-сборку только для указанных архитектур:

cd foo-bar
fedpkg switch-branch master
fedpkg scratch-build --arches x86_64 aarch64

Как выложить собранный пакет в репозитории?

По окончании сборки мы можем воспользоваться Fedora Bodhi и выложить обновление в репозитории.

Сначала все обновления попадают в тестовые репозитории Fedora (updates-testing) и лишь после получения положительной кармы от других участников сообщества (уровень задаётся мейнтейнером, но не может быть меньше 1), либо по истечении 7 дней, оно может попасть в стабильные (updates) и будет доставлено конечным пользователям.

Заполним стандартную, хорошо документированную форму, затем нажмём кнопку Submit.