Гид по технологиям

Как собрать RPM‑пакеты в chroot‑окружении с помощью mach

• 9 min read • DevOps • Обновлено 26 Nov 2025
Сборка RPM в chroot с mach
Сборка RPM в chroot с mach

Коротко о назначении статьи

Эта статья описывает методику сборки бинарных RPM‑пакетов в изолированном chroot‑окружении с помощью инструмента mach. Она переведена и дополнена практическими советами, чек‑листами, планом действий при сбоях и кратким SOP, чтобы вы могли безопасно и повторяемо собирать пакеты для разных целевых дистрибуций на одной машине‑сборщике.

Важно: материал тестировался на CentOS 5.1, но подход применим к другим RPM‑основанным дистрибутивам (Fedora, SUSE и т. п.).

Проблема, которую решает mach

Если вы собираете RPM вручную с помощью rpmbuild, вы можете столкнуться с несколькими повторяющимися проблемами:

  • rpmbuild не скачивает исходники и патчи — их нужно положить в директорию SOURCES самостоятельно.
  • rpmbuild аварийно завершится, если отсутствуют build‑time зависимости, и вы будете вынуждены прерывать процесс, собирать и устанавливать эти зависимости, а затем запускать сборку снова.
  • Во время конфигурации пакет может «автоопределить» библиотеки, которые есть в вашей системе сборки, но отсутствуют в целевой. В результате бинарник будет линкуется к лишним библиотекам, а RPM не объявит такие зависимости, и пакет упадёт на целевой системе.
  • Вы можете собирать пакеты только для той же «семьи» дистрибутива, что и система сборки (например, CentOS 4 на CentOS 4).

Эта совокупность проблем приводит к «адским» цепочкам зависимостей — когда сохранённая спецификация требует сборки десятков дополнительных пакетов в строгом порядке (пример: perl‑SOAP‑Lite). mach автоматизирует и изолирует процесс, чтобы избежать таких ситуаций.

Как работает mach — базовая идея

Mach (от «make a chroot») создаёт минимальное подмножество целевой системы в каталоге /var/lib/mach/roots// и использует chroot для выполнения сборки внутри этой «песочницы». Процесс:

  1. mach превращает .spec в .src.rpm, автоматически скачивая исходники (или принимает уже готовый .src.rpm).
  2. mach chroot’ится в чистую среду и запускает сборку. Все BuildRequires подтягиваются через yum внутри chroot.
  3. Результат — бинарные RPM — кладётся в локальный yum‑репозиторий внутри окружения и доступен для последующих сборок.
  4. По завершении mach восстанавливает chroot до «исходного» состояния, удаляя лишние пакеты и артефакты.

Преимущества:

  • Сборка идёт в среде, близкой к целевой, исключая «проклятие autoconf».
  • BuildRequires вынуждают явно указывать зависимости в .spec.
  • Можно поддерживать несколько chroot‑ов для разных целей (CentOS 4, 5 и т. п.) на одном хосте.

Установка mach (пример для CentOS 5.1)

Я покажу установку из исходников — это одноразовая операция. После установки все будущие сборки будут происходить в mach.

$ wget http://thomas.apestaart.org/download/mach/mach-0.9.3.tar.bz2
$ sudo rpmbuild -tb mach-0.9.3.tar.bz2
$ sudo yum install createrepo
$ sudo rpm -Uvh /usr/src/redhat/RPMS/i386/mach-0.9.3-1.i386.rpm

Подсказка: если не хотите запускать rpmbuild от root, добавьте в ~/.rpmmacros:

%_topdir                %(echo "$HOME")/redhat

и создайте поддиректории:

mkdir ~/redhat ~/redhat/{BUILD,RPMS,SOURCES,SPECS,SRPMS}

Однако установку .rpm всё равно выполняет root.

После установки убедитесь, что документация доступна в /usr/share/doc/mach-0.9.3/README и что в /etc/group появилась группа mach.

Опционально: указываем локальный yum‑зеркало

Для детерминированных результатов удобнее фиксировать зеркало в /etc/mach/location. Например, для Великобритании можно заменить строку:

centos      = 'http://mirror.centos.org/centos'

на:

centos      = 'http://www.mirrorservice.org/sites/mirror.centos.org'

Это полезно, когда вы хотите контролировать источник пакетов и минимизировать несогласованность зеркал.

Настройка пользователей и прав

Каждый, кто будет использовать mach, должен быть в дополнительной группе mach. Добавьте пользователя в /etc/group:

mach:x:102:user1,user2,user3...

Затем выйдите и войдите снова, чтобы изменения вступили в силу.

Важно: mach полагается на общие групповые права, поэтому значение umask должно быть 0002 (разрешая групповую запись).

Проверка и установка umask:

$ umask
0002             # это правильно
$ umask
0022             # это неправильно
$ umask 0002
$ umask
0002             # теперь правильно

Если umask сбрасывается при входе в систему, добавьте umask 0002 в вашу ~/.profile или другой стартовый скрипт сессии.

Каждому пользователю нужен ~/.machrc со специфическими настройками; пример:

config['installer'] = 'yum'
config['files'] = {
  '/etc/hosts': '''
127.0.0.1 builder.example.com builder localhost
''',
  '/etc/resolv.conf': '''
nameserver 1.1.1.1
nameserver 2.2.2.2
search example.com
'''
}
config['defaultroot'] = 'centos-4-i386-extras'
config['macros'] = {
    'vendor':   'My Company Name',
}

(Альтернатива: задать эти параметры глобально в /etc/mach.conf.)

Комментарии к конфигурации:

  • /etc/hosts: первый хост в строке — это желаемое имя билд‑хоста, второе — реальное имя вашей машины (если отличаются).
  • defaultroot — указывает, какой chroot использовать по умолчанию; посмотрите присутствующие конфигурации в /etc/mach/dist.d/.

Подготовка окружения сборки

Убедитесь, что под /var достаточно свободного места (рекомендуется не меньше 2 ГБ, лучше больше — в зависимости от количества и размера пакетов).

Перед началом проверьте umask:

$ umask

0002                  # Подтвердите, что это 0002 !!

Запустите инициализацию окружения сборки:

$ mach setup build

Пример вывода (сокращённо):

Preparing root
Installing package set 'minimal' .........................
Installing package set 'base' ............................
... snip lots ...
Retrying installing package set 'base' .............
Installing package set 'build' ...........................
Making snapshot ...

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

Если потребуется полностью пересоздать корень:

$ mach clean
$ mach setup build

Ваш новый корень будет находиться в /var/lib/mach/roots//, и вы можете войти в него:

$ mach chroot

Пример: вход в /var/lib/mach/roots/centos-4-i386-extras, команда exit покидает окружение.

Иногда при входе вы увидите предупреждение вроде:

ERROR: ld.so: object '/usr/lib/libselinux-mach.so' from
LD_PRELOAD cannot be preloaded: ignored.

Это не критично — mach использует примочки для SELinux, но продолжает работу.

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

Проще простого: передайте один или несколько .spec или .src.rpm файлов команде mach build или mach rebuild:

$ mach build foo.spec bar.spec ...

или

$ mach rebuild foo.src.rpm bar.src.rpm ...

mach сам создаст .src.rpm (если дадите .spec), скачает исходники и зависимости, соберёт пакеты в chroot и положит результат в /var/tmp/mach//.

Пример на практике: perl‑SOAP‑Lite

Проверим «сложный» кейс, упомянутый ранее.

$ umask
0002        # просто проверяем!
$ wget http://svn.rpmforge.net/svn/trunk/rpms/perl-SOAP-Lite/perl-SOAP-Lite.spec
$ mach build perl-SOAP-Lite.spec

Типичный вывод (сокращённо):

Building .src.rpm from perl-SOAP-Lite.spec
... snip ...
Build of perl-SOAP-Lite-0.710.05-1 succeeded, results in
/var/tmp/mach/centos-4-i386-extras/perl-SOAP-Lite-0.710.05-1
Results: /var/tmp/mach/centos-4-i386-extras/perl-SOAP-Lite-0.710.05-1
Build done.

Содержимое директории с результатами:

$ ls -l /var/tmp/mach/centos-4-i386-extras/perl-SOAP-Lite-0.710.05-1
total 764
-rw-rw-r-- 1 candlerb mach 440039 May 15 16:43 perl-SOAP-Lite-0.710.05-1.noarch.rpm
-rw-rw-r-- 1 candlerb mach 270301 May 15 16:43 perl-SOAP-Lite-0.710.05-1.src.rpm
-rw-rw-r-- 1 candlerb mach 2734 May 15 16:43 perl-SOAP-Lite.spec
-rw-rw-r-- 1 candlerb mach 50507 May 15 16:43 rpm.log

Если сборка прошла успешно — можно радоваться.

Устранение неполадок

Отсутствующие зависимости

Если пакет не собирается из‑за отсутствия пакета в репозитории (например, perl‑Compress‑Zlib), найдите .spec для этой зависимости и соберите её вместе с требуемым пакетом:

$ wget http://svn.rpmforge.net/svn/trunk/rpms/perl-Compress-Zlib/perl-Compress-Zlib.spec
$ mach build perl-SOAP-Lite.spec perl-Compress-Zlib.spec

Порядок .spec в командной строке не важен — mach сам выстроит граф зависимостей.

Прочие проблемы

  • Для подробного вывода используйте флаг -d:
$ mach -d build foo.spec bar.spec
  • Если репозиторий блокирован (locked) и вы уверены, что никакой другой процесс не работает, разблокируйте его:
$ mach unlock
  • Если зависимость BuildRequires ссылается на бинарный RPM, которого нет в репозитории и который нельзя собрать из исходников (например, oracle‑instantclient‑devel), скопируйте этот RPM вручную в:
/var/lib/mach/roots//usr/src/rpm/RPMS.mach-local/

Mach учтёт эти файлы при сборке.

Несколько chroot‑ов

Вы можете держать на одной машине несколько целевых chroot‑ов. Используйте флаг -r для выбора нужного корня при запуске mach:

$ mach -r centos-4-i386-extras build foo.spec

Или измените defaultroot в ~/.machrc для постоянного переключения. Это даёт возможность собирать пакеты для разных версий дистрибутивов на одной машине.

Дополнительные советы и лучшие практики

Ментальные модели

  • «Чистая комната» (cleanroom build): всё, что влияет на сборку, должно быть доступно внутри chroot. Внешние файлы и библиотеки из хоста не должны влиять на результат.
  • «Локальный репозиторий» (local cache): собранные пакеты сохраняются в локальном репозитории, что ускоряет повторные сборки зависимых пакетов.
  • «Повторяемая сборка»: фиксируйте зеркала и конфигурации, чтобы сборки были детерминированы.

Альтернативные подходы

Если по каким‑то причинам mach не подходит, рассмотрите:

  • mock — популярный инструмент для сборки RPM в изолированных средах (поддерживается в Fedora/CentOS). Mock использует chroot/qemu/образ и имеет собственную конфигурацию.
  • Koji — система для масштабируемой сборки и CI‑потока в больших проектах (используется Fedora).
  • Локальная виртуальная машина (VM) — вместо chroot можно использовать полностью виртуализованную среду, когда требуется полная изоляция.

Каждый подход имеет свои преимущества: mock и Koji больше ориентированы на автоматизацию на CI, VM даёт изоляцию уровня ОС.

Когда метод не сработает

  • Если требуемая зависимость доступна только как проприетарный бинарник без возможности установки внутри chroot (и вы не можете вручную положить RPM в RPMS.mach-local).
  • Если сборка требует аппаратного доступа или особой конфигурации ядра, недоступной в chroot.

Критерии приёмки

  • Собирается .src.rpm и результат — нужные бинарные RPM — присутствует в /var/tmp/mach//.
  • Пакет устанавливается в чистой виртуальной системе того же дистроя без ошибок зависимостей.
  • В спецификации явно указаны BuildRequires и Requires, соответствующие тому, что используется при сборке.

SOP: стандартная процедура сборки пакета с mach

  1. Подготовка рабочего каталога и прав
    • Добавьте пользователя в группу mach.
    • Установите umask 0002.
    • Настройте ~/.machrc (или /etc/mach.conf) с нужным defaultroot.
  2. Инициализация окружения (один раз или при пересоздании)
    • mach setup build
  3. Скачайте .spec или .src.rpm
    • wget
  4. Запустите сборку
    • mach build foo.spec
    • или mach rebuild foo.src.rpm
  5. Проверка результатов
    • Посмотрите /var/tmp/mach//... на наличие *.rpm и rpm.log
    • Установите пакет в чистой VM/chroot для теста
  6. Если зависимость отсутствует — найдите её .spec и запустите сборку вместе с целевым пакетом
  7. Если необходимо — скопируйте проприетарные RPM в RPMS.mach-local
  8. При проблемах — mach -d build ... и mach unlock при блокировке

Инцидентный план: что делать если сборка упала

  1. Прочитать rpm.log в директории с результатами.
  2. Повторить сборку с -d для подробностей: mach -d build foo.spec.
  3. Если ошибка — Missing BuildRequires, найти .spec и добавить в команду сборки.
  4. Если репозиторий заблокирован: mach unlock.
  5. Если chroot «повреждён» и вы хотите начать заново: mach clean && mach setup build.
  6. Если нужна помощь — сохраните лог и окружение и проконсультируйтесь с коллегами/вендором.

Чек‑лист по ролям

  • Разработчик пакета:

    • Проверил, что .spec собирает .src.rpm и бинарник в mach.
    • Проверил, что BuildRequires перечислены явно.
    • Запустил установку в чистой VM.
  • Оператор сборки:

    • Настроил ~/.machrc и defaultroot.
    • Проверил umask и членство в группе mach.
    • [ ] Инициализировал chroot (mach setup build).
  • Системный администратор:

    • Обеспечил достаточно дискового места под /var.
    • Настроил локальное зеркало yum при необходимости.
    • Обеспечил доступ к проприетарным RPM через RPMS.mach-local.

Шаблон: быстрый контрольный сценарий перед отправкой в релиз

  • Собрать пакет через mach build.
  • Установить RPM в чистой VM одного из target root и запустить smoke‑тесты.
  • Проверить зависимости rpm -qpR package.rpm и сравнить с ожиданием.
  • Обновить changelog и версионирование, если нужно.

Совместимость и миграция

  • Для сборки пакетов для CentOS 4 на хосте CentOS 5 используйте соответствующий chroot (например, centos-4-i386-extras), чтобы избежать «заимствования» библиотек с хоста.
  • При миграции на более новые версии mach и дистрибутивов проверьте конфигурации в /etc/mach/dist.d/ и обновите /etc/mach/location для зеркал.

Полезные ссылки по теме

  1. “The Fight”
  2. Maximum RPM
  3. rpmforge spec file repository
  4. yum and yum repository metadata
  5. apt RPM repository
  6. cpan2spec and cpan2rpm
  7. gem2rpm

Примеры часто встречающих вопросов

Как заставить mach учитывать локальный проприетарный RPM?

Скопируйте RPM в /var/lib/mach/roots//usr/src/rpm/RPMS.mach-local/ — mach учтёт этот файл как локальную зависимость.

Что делать, если chroot заблокирован?

Убедитесь, что действительно нет активных процессов в репозитории, затем выполните mach unlock.

Почему umask должен быть 0002?

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

Резюме

Mach — удобный инструмент для воспроизводимых и изолированных сборок RPM. Он автоматизирует скачивание исходников, разрешение build‑зависимостей и сборку в chroot, что делает процесс надёжнее и проще для поддержки нескольких целевых дистрибутивов. Следуйте описанному SOP, используйте чек‑листы и runbook при инцидентах — это значительно снизит вероятность человеческой ошибки и сократит время на отладку.


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

mach setup build        # подготовить chroot
mach chroot             # войти в chroot
mach build foo.spec     # собрать пакет из .spec
mach rebuild foo.src.rpm # собрать пакет из .src.rpm
mach clean              # удалить и пересоздать chroot при необходимости
mach unlock             # разблокировать репозиторий

Конец статьи.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро