Как собрать 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/
- mach превращает .spec в .src.rpm, автоматически скачивая исходники (или принимает уже готовый .src.rpm).
- mach chroot’ится в чистую среду и запускает сборку. Все BuildRequires подтягиваются через yum внутри chroot.
- Результат — бинарные RPM — кладётся в локальный yum‑репозиторий внутри окружения и доступен для последующих сборок.
- По завершении 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
Проверим «сложный» кейс, упомянутый ранее.
$ umask0002 # просто проверяем!$ 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-1total 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
- Подготовка рабочего каталога и прав
- Добавьте пользователя в группу mach.
- Установите umask 0002.
- Настройте ~/.machrc (или /etc/mach.conf) с нужным defaultroot.
- Инициализация окружения (один раз или при пересоздании)
mach setup build
- Скачайте .spec или .src.rpm
wget
- Запустите сборку
mach build foo.spec- или
mach rebuild foo.src.rpm
- Проверка результатов
- Посмотрите
/var/tmp/mach/на наличие *.rpm и rpm.log/... - Установите пакет в чистой VM/chroot для теста
- Посмотрите
- Если зависимость отсутствует — найдите её .spec и запустите сборку вместе с целевым пакетом
- Если необходимо — скопируйте проприетарные RPM в RPMS.mach-local
- При проблемах —
mach -d build ...иmach unlockпри блокировке
Инцидентный план: что делать если сборка упала
- Прочитать rpm.log в директории с результатами.
- Повторить сборку с -d для подробностей:
mach -d build foo.spec. - Если ошибка — Missing BuildRequires, найти .spec и добавить в команду сборки.
- Если репозиторий заблокирован:
mach unlock. - Если chroot «повреждён» и вы хотите начать заново:
mach clean && mach setup build. - Если нужна помощь — сохраните лог и окружение и проконсультируйтесь с коллегами/вендором.
Чек‑лист по ролям
Разработчик пакета:
- Проверил, что .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 для зеркал.
Полезные ссылки по теме
- “The Fight”
- Maximum RPM
- rpmforge spec file repository
- yum and yum repository metadata
- apt RPM repository
- cpan2spec and cpan2rpm
- gem2rpm
Примеры часто встречающих вопросов
Как заставить mach учитывать локальный проприетарный RPM?
Скопируйте RPM в /var/lib/mach/roots/
Что делать, если 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 # разблокировать репозиторийКонец статьи.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента