Hasher/Руководство: различия между версиями

Материал из ALT Linux Wiki
(откатить вандализм от 2022 г. ~/.hasher — это каталог с настройками в виде исполнимого кода для шелла.)
 
(не показана 91 промежуточная версия 26 участников)
Строка 1: Строка 1:
[[Категория:Справочники]]
[[Категория:Devel]]
[[Категория:Sisyphus]]
{{stub}}
== Принцип действия ==
== Принцип действия ==


<tt>hasher</tt> — инструмент для сборки пакетов в «чистой» и контролируемой среде. Это достигается с помощью создания в chroot минимальной сборочной среды, установки туда указанных в source-пакете сборочных зависимостей и сборке пакета в свежесозданной среде. Для сборки нового пакета сборочная среда создаётся заново (за исключением кэширования образа базовой системы, которое не влияет на корректность и воспроизводимость результата).
<tt>hasher</tt> инструмент для сборки пакетов в «чистой» и контролируемой среде. Это достигается с помощью создания в chroot минимальной сборочной среды, установки туда указанных в source-пакете сборочных зависимостей и сборке пакета в свежесозданной среде. Для сборки каждого пакета сборочная среда создаётся заново<ref>за исключением кэширования образа базовой системы, что не влияет на корректность и воспроизводимость результата</ref>.


Такой принцип сборки вызывает несколько последствий:
Такой принцип сборки имеет несколько следствий:
* Все необходимые для сборки зависимости должны быть указаны в пакете. Для облегчения поддержания сборочных зависимостей в актуальном состоянии в Sisyphus придуман инструмент под названием [[buildreq]],
* Все необходимые для сборки зависимости должны быть указаны в пакете. Для облегчения поддержания сборочных зависимостей в актуальном состоянии в Sisyphus придуман инструмент под названием [[buildreq]],
* Сборка не зависит от конфигурации компьютера пользователя, собирающего пакет, и может быть повторена на другом компьютере,
* Сборка не зависит от конфигурации компьютера пользователя, собирающего пакет, и может быть повторена на другом компьютере,
* Изолированность среды сборки позволяет собирать на одном компьютере пакеты для разных дистрибутивов и веток репозитория — для этого достаточно лишь направить <tt>hasher</tt> на различные репозитории для каждого сборочного окружния.
* Изолированность среды сборки позволяет с лёгкостью собирать на одном компьютере пакеты для разных дистрибутивов и веток репозитория — для этого достаточно лишь направить <tt>hasher</tt> на различные репозитории для каждого сборочного окружения.


Дополнительно к сборке пакетов <tt>hasher</tt>
Дополнительно к сборке пакетов <tt>hasher</tt>
* проверяет их с помощью утилиты [[sisyphus_check]],
* проверяет их с помощью утилиты [[sisyphus_check]],
* создаёт локальный APT-репозиторий с результатами сборки, позволяя последовательно собирать пакеты опираясь на уже собранные.
* создаёт локальный APT-репозиторий с результатами сборки, позволяя последовательно собирать пакеты, опираясь на уже собранные<br>'''внимание:''' в {{pkg|hasher-1.3.17-alt1}} произведена оптимизация, вследствие которой по умолчанию хэши не генерируются (используется rpm-dir); при необходимости в них предлагается воспользоваться {{cmd|$workdir/aptbox/regenbasedir}}.


== Установка ==
== Установка ==


<tt>hasher</tt> в Sisyphus и дистрибутивах ALT Linux располагается в пакетах <tt>hasher</tt> и <tt>hasher-priv</tt> и легко устанавливается:
<tt>hasher</tt> в Sisyphus и дистрибутивах ALT Linux располагается в пакетах <tt>hasher</tt>, <tt>hasher-priv</tt> и легко устанавливается:
  # apt-get install hasher
  # apt-get install hasher
С версии 2.0 пакета hasher-priv нужно запустить сервис hasher-privd:
# systemctl enable --now hasher-privd.service


== Добавление пользователя ==
== Добавление пользователя ==


<tt>hasher</tt> использует специальных вспомогательных пользователей и группу <tt>hashman</tt> для своей работы. Каждого пользователя перед началом работы нужно зарегистрировать в <tt>hasher</tt>:
<tt>hasher</tt> использует специальных вспомогательных пользователей и группу <tt>hashman</tt> для своей работы, поэтому каждого пользователя, желающего использовать <tt>hasher</tt>, перед началом работы нужно зарегистрировать:
  # hasher-useradd USER
  # hasher-useradd USER
Эта команда создаёт вспомогательных пользователей USER_a и USER_b и добавляет пользователя USER в группы <tt>hashman</tt>, <tt>USER_a</tt> и <tt>USER_b</tt>.
Эта команда создаёт вспомогательных пользователей USER_a и USER_b и добавляет пользователя USER в группы <tt>hashman</tt>, <tt>USER_a</tt> и <tt>USER_b</tt>.


Поскольку <tt>hasher-useradd</tt> добавляет пользователя в группы, пользователю необходимо перелогиниться (открытие нового терминала в X не поможет) перед началом работы с <tt>hasher</tt>.
Поскольку {{prg|hasher-useradd}} добавляет пользователя в группы, пользователю необходимо перелогиниться перед началом работы с <tt>hasher</tt>.
<small>Если лень перелогиниваться, достаточно дать в терминале команду {{cmd|su - $USER}} и далее работать с hasher в этом окружении. Открыть новое окно с терминалом в X/Wayland недостаточно.</small>


== Настройка сборочной среды ==
== Настройка сборочной среды ==
Строка 35: Строка 34:
Рабочий каталог (в данном случае <tt>~/hasher</tt>) должен быть доступен на запись пользователю, запускающему сборку.
Рабочий каталог (в данном случае <tt>~/hasher</tt>) должен быть доступен на запись пользователю, запускающему сборку.


Кроме того, его нельзя располагать на файловой системе, которая смонтирована с опциями <tt>noexec</tt> или <tt>nodev</tt> — в таких услоиях <tt>hasher</tt> не сможет создать корректное сборочное окружение.
Кроме того, его нельзя располагать на файловой системе, которая смонтирована с опциями <tt>noexec</tt> или <tt>nodev</tt> — в таких условиях <tt>hasher</tt> не сможет создать корректное сборочное окружение.


Сборочное окружение можно создать явно:
Сборочное окружение можно создать явно:
  $ hsh --init ~/hasher<ref>Директория ~/hasher используется по умолчанию во всех операциях команды <tt>hsh</tt> и её можно опустить: <tt>hsh --init</tt></ref>
  $ hsh --initroot-only ~/hasher<ref>Директория ~/hasher используется по умолчанию во всех командах <tt>hsh-*</tt> и её можно не указывать: <tt>hsh --initroot-only</tt>, <tt>hsh somepkg.src.rpm</tt> и т. д.</ref>
Явное создание необязательно - при необходимости оно будет произведено при первой сборке пакета.
Явное создание необязательно — при необходимости оно будет произведено при первой сборке пакета.


<tt>hasher</tt> берёт пакеты для установки из APT-источников. По умолчанию в сборочную среду копируется список источников, указанный в конфигурации APT хост-системы, но это можно изменить с помощью альтернативного файла конфигурации APT:
<tt>hasher</tt> берёт пакеты для установки из APT-источников. По умолчанию в сборочную среду копируется список источников, указанный в конфигурации [[APT]] '''хост-системы'''; также можно явно задать дополнительные репозитории, указав альтернативный файл конфигурации APT:
  $ hsh --apt-config=~/branch4.1-apt.conf --init ~/hasher
  $ hsh --apt-config=branch4.1-apt.conf --initroot-only ~/hasher
В таком файле конфигурации необходимо укзать расположение файла с APT-источниками:
В таком файле конфигурации необходимо указать расположение файла с APT-источниками:
  Dir::Etc::SourceList "/home/USER/sources.list.branch4.1";
  Dir::Etc::SourceList "/home/USER/sources.list.branch4.1";
После создания сборочной среды (неявного, при сборке пакета, или явного, с помощью <tt>--init</tt>) параметр <tt>--apt-config</tt> больше не нужен.
После создания сборочной среды (неявного, при сборке пакета, или явного, с помощью <tt>--initroot-only</tt>) параметр <tt>--apt-config</tt> больше не нужен.
 
Однако если необходимо создать сборочную среду, независимую по источникам от основной операционной системы (например, основная система настроена на sisyphus, а необходимо собрать пакет для p5), в вышеуказанный файл помимо строки с источником следует добавить следующую строку во избежание включения {{path|/etc/apt/sources.list.d/*.list}}:
Dir::Etc::SourceParts "/var/empty";
 
'''Внимание!''' Замечено, что если <tt>apt</tt> подключен к репозиторию через прокси-сервер, то сборка пакета может завершаться с ошибкой «Connection reset by peer». Вероятно, это исправлено в [http://git.altlinux.org/gears/a/apt.git?p=apt.git;a=commit;h=3903d911f4a9a0d1f6c0549b06316d655692af6c apt-0.5.15lorg2-alt58]. См. также [[APT_в_ALT_Linux/NginxAsCache#Известные проблемы]].


== Сборка программ в hasher ==
== Сборка программ в hasher ==
Строка 54: Строка 58:
При удачной сборке полученные пакеты будут лежать в <tt>~/hasher/repo/<платформа>/RPMS.hasher/</tt>, в противном случае на stdout будет выведена информация об ошибках сборки.
При удачной сборке полученные пакеты будут лежать в <tt>~/hasher/repo/<платформа>/RPMS.hasher/</tt>, в противном случае на stdout будет выведена информация об ошибках сборки.


Создаваемый <tt>hasher</tt> репозиторий является обычным APT-репозиторием и может быть использован в <tt>sources.list</tt>. Дополнительно, этот репозиторий будет использован при дальнейшей сборке пакетов (это поведение можно регулировать ключом <tt>--without-stuff</tt>).
Создаваемый <tt>hasher</tt> репозиторий является обычным APT-репозиторием и может быть использован в <tt>sources.list</tt><ref>с типом rpm-dir либо после создания хэшей: {{cmd|mkdir ~/hasher/repo/i686/base; genbasedir --topdir ~/hasher/repo/i686/}}</ref>. Также он будет использован при дальнейшей сборке пакетов (это поведение можно регулировать ключом <tt>--without-stuff</tt>).
 
Если вы держите сборочную среду в tmpfs (см. ниже), каталог <tt>~/hasher/repo</tt>, вероятно, не переживёт перезагрузку системы. Репозиторий можно переместить в постоянное место, указав в настроечном файле hasher <tt>hasher/config</tt> параметр <tt>def_repo=постоянное_хранилище</tt> (или вызвав hasher с ключом <tt>--repo</tt>).


== Сборочные зависимости ==
== Сборочные зависимости ==
Строка 64: Строка 70:
Поскольку <tt>hasher</tt> собирает пакеты из <tt>src.rpm</tt> (не считая поддержки [[gear]]), то для сборки необходимо иметь в хост-системе установленные сборочные зависимости первого типа. Большинство таких зависимостей (но пока не все) содержатся в пакетах с названием <tt>rpm-build-*</tt>.
Поскольку <tt>hasher</tt> собирает пакеты из <tt>src.rpm</tt> (не считая поддержки [[gear]]), то для сборки необходимо иметь в хост-системе установленные сборочные зависимости первого типа. Большинство таких зависимостей (но пока не все) содержатся в пакетах с названием <tt>rpm-build-*</tt>.


Поскольку сборка <tt>src.rpm</tt> либо завершается неудачно (при отсутствии сборочной зависимости первого типа), либо корректно, то собирать <tt>src.rpm</tt>-пакеты в хост системе можно с помощью <tt>--nodeps</tt:
Поскольку сборка <tt>src.rpm</tt> либо завершается неудачно (при отсутствии сборочной зависимости первого типа), либо корректно, то собирать <tt>src.rpm</tt>-пакеты в хост системе можно с помощью <tt>--nodeps</tt>:
  rpm -bs --nodeps foo.spec
  rpm -bs --nodeps foo.spec


Сам <tt>hasher</tt>, в отличие от [[gear]], не предъявляет никаких требований к разделению сборочных зависимостей на первый и второй тип. Однако для совместимости с [[gear]] и для улучшения документируемости spec-файла рекомендуется распределять их так:
Сам <tt>hasher</tt>, в отличие от [[gear]], не предъявляет никаких требований к разделению сборочных зависимостей на первый и второй тип. Однако для совместимости с [[gear]] и для улучшения документируемости spec-файла рекомендуется распределять их так:
* В поле <tt>BuildRequires(pre)</tt> помещать сборочные завимости, требуемые для сборки <tt>src.rpm</tt>,
* В поле <tt>BuildRequires(pre)</tt> помещать сборочные завимости, требуемые для сборки <tt>src.rpm</tt>,
* В поле <tt>BuildRequires</tt> — все остальные.
* В поле <tt>BuildRequires</tt> все остальные.
 
'''Обратите внимание''': в поле <tt>BuildRequires(pre)</tt> нельзя использовать макросы.
 
== Архитектура пакетов ==
 
В связи с <s>идиотизмом</s>особенностями версии RPM, используемой в Sisyphus, [[rpmbuild]] (и, как следствие, <tt>hasher</tt>) на x86-системах могут собирать RPM-пакеты для совершенно разных архитектур: pentium3, pentium4, athlon и т.д.
 
Для отключения эвристик RPM по определению целевой архитектуры можно воспользоваться ключом <tt>--target</tt> или опцией конфигурации <tt>def_target</tt>.
$ hsh --target=i586 mypkg-0.0-alt0.src.rpm
или, в <tt>~/.hasher/config</tt>:
def_target=i586
 
или, более "интеллектуальный вариант":
if [ ! `uname -m` = x86_64 ]; then def_target=i586; fi


== Монтирование файловых систем внутри <tt>hasher</tt> ==
== Монтирование файловых систем внутри <tt>hasher</tt> ==
Строка 75: Строка 95:
Некоторым приложениям для сборки требуется смонтированная файловая система (например, <tt>/proc</tt>). <tt>hasher</tt> поддерживает монтирование дополнительных файловых систем в сборочную среду.
Некоторым приложениям для сборки требуется смонтированная файловая система (например, <tt>/proc</tt>). <tt>hasher</tt> поддерживает монтирование дополнительных файловых систем в сборочную среду.


Монтирование происходит при одновременном выполнении следующих трёх условий:
Монтирование происходит при одновременном выполнении следующих четырех условий:
* Необходимая файловая система указана в файле <tt>/etc/hasher-priv/fstab</tt>, либо является одной из <tt>/proc</tt>, <tt>/dev/pts</tt>, <tt>/sys</tt>.
* файловая система описана в файле {{path|/etc/hasher-priv/fstab}}, либо является одной из предопределённых: <tt>/proc</tt>, <tt>/dev/pts</tt>, <tt>/sys</tt>;
* Необходимая файловая система указана в опции <tt>--mountpoints</tt> при запуске <tt>hasher</tt>, либо, что то же самое, в ключе <tt>known_mountpoints</tt> конфигурационного файла <tt>hasher</tt> (<tt>~/.hasher/config</tt>).
* в конфигурации {{pkg|hasher-priv}} ({{path|/etc/hasher-priv/system}}) ФС указана  в опции <tt>allowed_mountpoints</tt>;
* Необходимая файловая система укзана сборочной зависимостью (например, <tt>BuildReq: /proc</tt>) собираемого пакета, прямой или косвенной (через другие сборочные зависимости пакета).
* файловая система указана в опции <tt>--mountpoints</tt> при запуске <tt>hasher</tt>, либо, что то же самое, в ключе <tt>known_mountpoints</tt> конфигурационного файла <tt>hasher</tt> ({{path|~/.hasher/config}});
* файловая система указана сборочной зависимостью (например, <tt>BuildReq: /proc</tt>) собираемого пакета, прямой или косвенной (через зависимости сборочных зависимостей пакета).


=== Монтирование /proc ===
=== Монтирование /proc ===


* <tt>known_mountpoints=/proc</tt> в конфиге <tt>hasher</tt>,
* <tt>allowed_mountpoints=/proc</tt> в {{path|/etc/hasher-priv/system}};
* <tt>BuildRequires: /proc</tt> в пакете.
* <tt>known_mountpoints=/proc</tt> в {{path|~/.hasher/config}} либо опция <tt>--mountpoints=/proc</tt> при сборке пакета;
* <tt>BuildRequires: /proc</tt> в спеке пакета.
 
Обязательно для использования java и иногда ghc<ref>Иначе характерное <tt>error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory</tt>; одно из объяснений с <code>$ORIGIN</code> см. в [[hasher/FAQ#В рабочей системе некая библиотека находится, а в хэшере -- нет, хотя она лежит в одном и том же месте]]</ref>.
 
Для сборки в [[girar]] на [[git.alt]] достаточно сборочной зависимости на <tt>/proc</tt>.
 
Если вы используете hasher для интерактивной разработки/отладки, например, запускаете в нём <tt>gdb</tt>, вам может потребоваться смонтировать </tt>/proc</tt> на '''RW''' (а не на RO, как это [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=05c06f318fd9a112529dfc313e6512b399a645e4 сейчас] по умолчанию). Для этого в {{path|/etc/hasher-priv/fstab}} нужно добавить примерно такую строку:
proc    /proc          proc    rw,nosuid,nodev,noexec,gid=proc,hidepid=2 0 0
 
== Использование нескольких сборочных окружений ==
 
<tt>hasher</tt> не ограничивает пользователей одним сборочным окружением. Первый параметр, передаваемый <tt>hsh</tt>, указывает на конкретную сборочницу, в которой необходимо производить работу:
$ hsh --apt-conf=/etc/apt/apt.conf.M40 ~/hasher-4.0 mypkg-0.0-alt0.M40.1.src.rpm
...
$ hsh --apt-conf=/etc/apt/apt.conf.M41 ~/hasher-4.1 mypkg-0.0-alt0.M41.1.src.rpm
...
По умолчанию используется директория <tt>~/hasher</tt>.
 
== Параллельная сборка ==
 
По умолчанию <tt>hasher</tt> позволяет одному пользователю производить не больше одной сборки на данной системе в любой момент времени. Для преодоления этого ограничения используются ''subconfigs'' и дополнительные вспомогательные пользователи.


При сборке пакетов в [[Incoming]] при наличии <tt>/proc</tt> в сборочных зависимостях пакета эта файловая система будет смонтирована.
Детали применения такой конфигурации описаны на man-странице <tt>hsh(1)</tt> в описании ключа <tt>--number</tt>.


== Сборка пакетов на <tt>tmpfs</tt> ==
== Сборка пакетов на <tt>tmpfs</tt> ==
При наличии достаточного количества памяти на сборочной машине сборку пакетов рекомендуется производить на [[tmpfs]] — такая конфигурация заметно [[Скоростные характеристики hasher|ускоряет]] сборку и бережёт жёсткие диски.
Можно взять уже смонтированный /tmp:
$ mkdir -p /tmp/.private/$USER/hasher
$ hsh --repo=$HOME/hasher-repo /tmp/.private/$USER/hasher somepkg-0.0-alt0.src.rpm
Создавать директорию <tt>/tmp/.private/$USER/hasher</tt> придётся после каждой перезагрузки (это можно сделать в файле <tt>~/.hasher/config</tt>, воспользовавшись тем, что это shell-скрипт). Указывать <tt>--repo</tt> придётся для каждой сборки (либо указать в <tt>.hasher/config</tt> параметр <tt>def_repo=постоянное_хранилище</tt>).
Начиная с 4.0, <tt>hasher-priv</tt> «из коробки» знает о директориях {{path|/tmp/.private/$USER}}, создаваемых [[pam_mktemp]] и поэтому дополнительной настройки не требует.
В {{altbug|16706}} идёт обсуждение создания более удобного средства для сборки на <tt>tmpfs</tt> и имеется предварительная реализация.
== Отключение проверок sisyphus_check ==
По умолчанию <tt>hasher</tt> запускает утилиту [[sisyphus_check|<tt>sisyphus_check</tt>]] с полным набором тестов. <tt>sisyphus_check</tt> проверяет не только технические требования репозитория Sisyphus, но и организационные: сборочный хост, подпись PGP-ключом члена ALT Linux Team и т.д., так что в случае сборки пакета не для репозитория Sisyphus возникает необходимость отключить часть проверок.
Для отключения части или всех проверок используется ключ <tt>--no-sisyphus-check[=LIST]</tt> или, что эквивалентно, опция конфига <tt>no_sisyphus_check</tt>.
Без аргумента этот ключ отключает запуск <tt>sisyphus_check</tt> вообще:
$ hsh --no-sisyphus-check mybroken-but-cool-package-I-need-to-run-today-0.0-alt0.src.rpm
С аргументом - списком отключаемых тестов - отключает только эти тесты:
$ hsh --no-sisyphus-check=packager,gpg my-package-for-different-repository-0.0-0.src.rpm
Со списком тестов можно ознакомиться в подсказке самого <tt>sisyphus_check</tt>:
$ sisyphus_check --help
...
Valid options are:
...
  --[no-]check-buildhost
  --[no-]check-buildtime
  --[no-]check-changelog
...
$
Более тонко запуск тестов можно настроить с помощью опций <tt>--no-sisyphus-check-in</tt> и <tt>--no-sisyphus-check-out</tt>, с описанием которых можно ознакомиться в man-странице <tt>hsh(1)</tt>.
== Ограничение ресурсов ==
<tt>hasher</tt> позволяет ограничить ресурсы, выделяемые на сборку: CPU, память, общее время исполнения и другие. Ограничения указываются в конфигурационном файле <tt>hasher-priv</tt>.
Полный список ограничиваемых ресурсов можно найти в man-странице <tt>hasher-priv.conf(5)</tt>.
== Отладка в сборочном <tt>chroot</tt> ==
Для отладки сборки иногда полезно запустить shell в сборочном <tt>chroot</tt>. Для этого используется утилита <tt>hsh-shell(1)</tt>:
$ hsh-shell
Можно запустить программу и с правами псевдо-root:
$ hsh-shell --rooter
Для контроля за содержимым сборочного <tt>chroot</tt>'а используются опции <tt>hsh</tt>: <tt>--cleanup-only</tt>, <tt>--eager-cleanup</tt>, <tt>--lazy-cleanup</tt> и соответствующие настройки вроде <tt>lazy_cleanup=1</tt> в {{path|~/.hasher/config}}.
Для запуска произвольных программ в сборочном чруте существует более низкоуровневая утилита <tt>hsh-run(1)</tt>.
== Использование <tt>buildreq</tt> в hasher ==
Начинаем и обламываем сборку пакета в hasher:
$ hsh --rebuild-prog=/bin/false somepackage.src.rpm
Далее применяем [[buildreq]]:
$ hsh-install ~/hasher rpm-utils
$ hsh-shell ~/hasher
$ buildreq ~/RPM/SPECS/*.spec
После этого в спеке появляется новая строка <code>BuildRequires</code>, сопровождаемая комментарием вида <code># Automatically added by buildreq ...</code> (если такая строка с комментарием уже была, она заменяется).
Из хост-системы получившийся спек доступен тут: <code>~/hasher/chroot/usr/src/RPM/SPECS/*.spec</code>
''Примечание.''
Если сборка делалась автономно, buildreq будет сообщать об ошибках отсутствия файлов, и понадобится скопировать в chroot hasher'a файлы: спек в ~/hasher/chroot/usr/src/RPM/SPECS/ и файлы-источники в ~/hasher/chroot/usr/src/RPM/SOURCES/.
== Пересборка пакета без пересоздания всего chroot ==
Даже в <code>tmpfs</code> развёртывание всей сборочной среды и зависимостей идёт небыстро.


При наличии достаточного количества памяти на сборочной машине сборку пакетов можно производить на [[enwp:Tmpfs#Linux|<tt>tmpfs</tt>]] - такая конфигурация заметно [[Hasher/Speed|ускоряет]] сборку.
Для того, чтобы собирать один и тот же пакет до тех пор, пока он не соберётся, нужно попросить hasher не разворачивать заново всю сборочницу, либо работать в самой сборочнице.


В качестве <tt>tmpfs</tt> можно взять уже смонтированный /tmp:
=== Многократная сборка пакета в одном hasher ===
  $ mkdir /tmp/.private/$USER/hasher
Пакет не собрался. Воспользуемся <code>hsh-shell</code>, предварительно установив любимый текстовый редактор, шелл, конфиги для них и прочие инструменты разработчика. Не забудем, что в дереве каталогов hasher есть каталог <code>~/hasher/chroot/.in</code>, в которой может писать сам пользователь (а не его двойники, пользователь_a и пользователь_b).
  $ hsh --repo=$HOME/hasher-repo /tmp/.private/$USER/hasher somepkg-0.0-alt0.src.rpm
$ hsh-install vim-console less rpm-utils patchutils zsh
Создавать директорию <tt>/tmp/.private/$USER/hasher</tt> придётся после каждой перезагрузки. Указывать <tt>--repo</tt> придётся для каждой сборки.
  $ mkdir -p ~/hasher/chroot/.in/src
$ cp -a .vim* .zprofile .zsh_aliases .zshenv .zsh_bind .zshrc .dircolors ~/hasher/chroot/.in/src
  $ hsh-run -- cp -r /.in/src /usr
$ hsh-shell --shell=/bin/zsh
zsh ругается на то, что системные файлы не принадлежат root, если вас это смущает, отключите проверку так:
$ hsh-run --rooter -- sed -i 's/compinit$/compinit -i/' /etc/zshrc
Отсутствующие сборочные зависимости можно доставлять с помощью <code>hsh-install</code> (выйдя из чрута).
 
'''ВАЖНО:''' по окончании работы (<code>rpm -ba</code> выполнился успешно) не забудьте выполнить <code>buildreq</code>, <code>rpm -bs</code> и забрать .src.rpm из <code>~/hasher/chroot/usr/src/RPM/SRPMS</code> (или спек из <code>~/hasher/chroot/usr/src/RPM/SPECS</code>).


Возможно, что для сборки чего-нибудь тяжёлого придётся в увеличить размер <tt>tmpfs</tt>, смонтированной в <tt>/tmp</tt>. Эта операция производится в файле <tt>/etc/fstab</tt>:
=== Многократная сборка пакета при работе с gear ===
tmpfs /tmp tmpfs nosuid,'''size=1g''' 0 0
Если вы используете [[gear]] и предпочитаете вести разработку (редактировать спек, править код и т. п.) в базовой системе, вместо <code>hsh</code> можно использовать <code>hsh-rebuild</code> -- программу, работающую с уже сформированным сборочным окружением.
Разумеется, изменения в <tt>/etc/fstab</tt> применяются только после перемонтирования файловой системы.


В [[altbug:16706|баге 16706]] идёт обсуждение создания более удобного средства для сборки на <tt>tmpfs</tt> и имеется предварительная реализация.
Первоначальная сборка (даже если прошла успешно, окружение не удаляется):
$ gear --hasher -- hsh --lazy-cleanup
Повторная сборка:
$ gear --hasher -- hsh-rebuild
'''ВАЖНО:''' по окончании работы не забудьте выполнить <code>buildreq</code> и забрать спек:
$ hsh-install rpm-utils
$ echo buildreq '/usr/src/RPM/SPECS/*.spec' | hsh-shell
$ cp ~/hasher/chroot/usr/src/RPM/SPECS/*.spec .


== Примечания ==
== Примечания ==


<references/>
<references/>
{{Category navigation|title=hasher|category=hasher|sortkey={{SUBPAGENAME}}}}
[[Категория:Руководства]]

Текущая версия от 17:50, 18 апреля 2024

Принцип действия

hasher — инструмент для сборки пакетов в «чистой» и контролируемой среде. Это достигается с помощью создания в chroot минимальной сборочной среды, установки туда указанных в source-пакете сборочных зависимостей и сборке пакета в свежесозданной среде. Для сборки каждого пакета сборочная среда создаётся заново[1].

Такой принцип сборки имеет несколько следствий:

  • Все необходимые для сборки зависимости должны быть указаны в пакете. Для облегчения поддержания сборочных зависимостей в актуальном состоянии в Sisyphus придуман инструмент под названием buildreq,
  • Сборка не зависит от конфигурации компьютера пользователя, собирающего пакет, и может быть повторена на другом компьютере,
  • Изолированность среды сборки позволяет с лёгкостью собирать на одном компьютере пакеты для разных дистрибутивов и веток репозитория — для этого достаточно лишь направить hasher на различные репозитории для каждого сборочного окружения.

Дополнительно к сборке пакетов hasher

  • проверяет их с помощью утилиты sisyphus_check,
  • создаёт локальный APT-репозиторий с результатами сборки, позволяя последовательно собирать пакеты, опираясь на уже собранные
    внимание: в hasher-1.3.17-alt1 произведена оптимизация, вследствие которой по умолчанию хэши не генерируются (используется rpm-dir); при необходимости в них предлагается воспользоваться $workdir/aptbox/regenbasedir.

Установка

hasher в Sisyphus и дистрибутивах ALT Linux располагается в пакетах hasher, hasher-priv и легко устанавливается:

# apt-get install hasher

С версии 2.0 пакета hasher-priv нужно запустить сервис hasher-privd:

# systemctl enable --now hasher-privd.service

Добавление пользователя

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

# hasher-useradd USER

Эта команда создаёт вспомогательных пользователей USER_a и USER_b и добавляет пользователя USER в группы hashman, USER_a и USER_b.

Поскольку hasher-useradd добавляет пользователя в группы, пользователю необходимо перелогиниться перед началом работы с hasher. Если лень перелогиниваться, достаточно дать в терминале команду su - $USER и далее работать с hasher в этом окружении. Открыть новое окно с терминалом в X/Wayland недостаточно.

Настройка сборочной среды

Для работы hasher требуется создать директорию, в которой будет строиться сборочная среда:

$ mkdir ~/hasher

Рабочий каталог (в данном случае ~/hasher) должен быть доступен на запись пользователю, запускающему сборку.

Кроме того, его нельзя располагать на файловой системе, которая смонтирована с опциями noexec или nodev — в таких условиях hasher не сможет создать корректное сборочное окружение.

Сборочное окружение можно создать явно:

$ hsh --initroot-only ~/hasher[2]

Явное создание необязательно — при необходимости оно будет произведено при первой сборке пакета.

hasher берёт пакеты для установки из APT-источников. По умолчанию в сборочную среду копируется список источников, указанный в конфигурации APT хост-системы; также можно явно задать дополнительные репозитории, указав альтернативный файл конфигурации APT:

$ hsh --apt-config=branch4.1-apt.conf --initroot-only ~/hasher

В таком файле конфигурации необходимо указать расположение файла с APT-источниками:

Dir::Etc::SourceList "/home/USER/sources.list.branch4.1";

После создания сборочной среды (неявного, при сборке пакета, или явного, с помощью --initroot-only) параметр --apt-config больше не нужен.

Однако если необходимо создать сборочную среду, независимую по источникам от основной операционной системы (например, основная система настроена на sisyphus, а необходимо собрать пакет для p5), в вышеуказанный файл помимо строки с источником следует добавить следующую строку во избежание включения /etc/apt/sources.list.d/*.list:

Dir::Etc::SourceParts "/var/empty";

Внимание! Замечено, что если apt подключен к репозиторию через прокси-сервер, то сборка пакета может завершаться с ошибкой «Connection reset by peer». Вероятно, это исправлено в apt-0.5.15lorg2-alt58. См. также APT_в_ALT_Linux/NginxAsCache#Известные проблемы.

Сборка программ в hasher

Сборка происходит от обычного пользователя, добавленного с помощью hasher-useradd:

$ hsh ~/hasher freetype-2.1.9-alt2.src.rpm

При удачной сборке полученные пакеты будут лежать в ~/hasher/repo/<платформа>/RPMS.hasher/, в противном случае на stdout будет выведена информация об ошибках сборки.

Создаваемый hasher репозиторий является обычным APT-репозиторием и может быть использован в sources.list[3]. Также он будет использован при дальнейшей сборке пакетов (это поведение можно регулировать ключом --without-stuff).

Если вы держите сборочную среду в tmpfs (см. ниже), каталог ~/hasher/repo, вероятно, не переживёт перезагрузку системы. Репозиторий можно переместить в постоянное место, указав в настроечном файле hasher hasher/config параметр def_repo=постоянное_хранилище (или вызвав hasher с ключом --repo).

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

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

  • необходимые для корректного создания src.rpm из spec-файла (содержащие определения RPM-макросов, используемых в spec-файле),
  • все остальные (необходимые для непосредственной сборки).

Поскольку hasher собирает пакеты из src.rpm (не считая поддержки gear), то для сборки необходимо иметь в хост-системе установленные сборочные зависимости первого типа. Большинство таких зависимостей (но пока не все) содержатся в пакетах с названием rpm-build-*.

Поскольку сборка src.rpm либо завершается неудачно (при отсутствии сборочной зависимости первого типа), либо корректно, то собирать src.rpm-пакеты в хост системе можно с помощью --nodeps:

rpm -bs --nodeps foo.spec

Сам hasher, в отличие от gear, не предъявляет никаких требований к разделению сборочных зависимостей на первый и второй тип. Однако для совместимости с gear и для улучшения документируемости spec-файла рекомендуется распределять их так:

  • В поле BuildRequires(pre) помещать сборочные завимости, требуемые для сборки src.rpm,
  • В поле BuildRequires — все остальные.

Обратите внимание: в поле BuildRequires(pre) нельзя использовать макросы.

Архитектура пакетов

В связи с идиотизмомособенностями версии RPM, используемой в Sisyphus, rpmbuild (и, как следствие, hasher) на x86-системах могут собирать RPM-пакеты для совершенно разных архитектур: pentium3, pentium4, athlon и т.д.

Для отключения эвристик RPM по определению целевой архитектуры можно воспользоваться ключом --target или опцией конфигурации def_target.

$ hsh --target=i586 mypkg-0.0-alt0.src.rpm

или, в ~/.hasher/config:

def_target=i586

или, более "интеллектуальный вариант":

if [ ! `uname -m` = x86_64 ]; then def_target=i586; fi

Монтирование файловых систем внутри hasher

Некоторым приложениям для сборки требуется смонтированная файловая система (например, /proc). hasher поддерживает монтирование дополнительных файловых систем в сборочную среду.

Монтирование происходит при одновременном выполнении следующих четырех условий:

  • файловая система описана в файле /etc/hasher-priv/fstab, либо является одной из предопределённых: /proc, /dev/pts, /sys;
  • в конфигурации hasher-priv (/etc/hasher-priv/system) ФС указана в опции allowed_mountpoints;
  • файловая система указана в опции --mountpoints при запуске hasher, либо, что то же самое, в ключе known_mountpoints конфигурационного файла hasher (~/.hasher/config);
  • файловая система указана сборочной зависимостью (например, BuildReq: /proc) собираемого пакета, прямой или косвенной (через зависимости сборочных зависимостей пакета).

Монтирование /proc

  • allowed_mountpoints=/proc в /etc/hasher-priv/system;
  • known_mountpoints=/proc в ~/.hasher/config либо опция --mountpoints=/proc при сборке пакета;
  • BuildRequires: /proc в спеке пакета.

Обязательно для использования java и иногда ghc[4].

Для сборки в girar на git.alt достаточно сборочной зависимости на /proc.

Если вы используете hasher для интерактивной разработки/отладки, например, запускаете в нём gdb, вам может потребоваться смонтировать /proc на RW (а не на RO, как это сейчас по умолчанию). Для этого в /etc/hasher-priv/fstab нужно добавить примерно такую строку:

proc    /proc           proc    rw,nosuid,nodev,noexec,gid=proc,hidepid=2 0 0

Использование нескольких сборочных окружений

hasher не ограничивает пользователей одним сборочным окружением. Первый параметр, передаваемый hsh, указывает на конкретную сборочницу, в которой необходимо производить работу:

$ hsh --apt-conf=/etc/apt/apt.conf.M40 ~/hasher-4.0 mypkg-0.0-alt0.M40.1.src.rpm
...
$ hsh --apt-conf=/etc/apt/apt.conf.M41 ~/hasher-4.1 mypkg-0.0-alt0.M41.1.src.rpm
...

По умолчанию используется директория ~/hasher.

Параллельная сборка

По умолчанию hasher позволяет одному пользователю производить не больше одной сборки на данной системе в любой момент времени. Для преодоления этого ограничения используются subconfigs и дополнительные вспомогательные пользователи.

Детали применения такой конфигурации описаны на man-странице hsh(1) в описании ключа --number.

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

При наличии достаточного количества памяти на сборочной машине сборку пакетов рекомендуется производить на tmpfs — такая конфигурация заметно ускоряет сборку и бережёт жёсткие диски.

Можно взять уже смонтированный /tmp:

$ mkdir -p /tmp/.private/$USER/hasher
$ hsh --repo=$HOME/hasher-repo /tmp/.private/$USER/hasher somepkg-0.0-alt0.src.rpm

Создавать директорию /tmp/.private/$USER/hasher придётся после каждой перезагрузки (это можно сделать в файле ~/.hasher/config, воспользовавшись тем, что это shell-скрипт). Указывать --repo придётся для каждой сборки (либо указать в .hasher/config параметр def_repo=постоянное_хранилище).

Начиная с 4.0, hasher-priv «из коробки» знает о директориях /tmp/.private/$USER, создаваемых pam_mktemp и поэтому дополнительной настройки не требует.

В altbug #16706 идёт обсуждение создания более удобного средства для сборки на tmpfs и имеется предварительная реализация.

Отключение проверок sisyphus_check

По умолчанию hasher запускает утилиту sisyphus_check с полным набором тестов. sisyphus_check проверяет не только технические требования репозитория Sisyphus, но и организационные: сборочный хост, подпись PGP-ключом члена ALT Linux Team и т.д., так что в случае сборки пакета не для репозитория Sisyphus возникает необходимость отключить часть проверок.

Для отключения части или всех проверок используется ключ --no-sisyphus-check[=LIST] или, что эквивалентно, опция конфига no_sisyphus_check.

Без аргумента этот ключ отключает запуск sisyphus_check вообще:

$ hsh --no-sisyphus-check mybroken-but-cool-package-I-need-to-run-today-0.0-alt0.src.rpm

С аргументом - списком отключаемых тестов - отключает только эти тесты:

$ hsh --no-sisyphus-check=packager,gpg my-package-for-different-repository-0.0-0.src.rpm

Со списком тестов можно ознакомиться в подсказке самого sisyphus_check:

$ sisyphus_check --help
...
Valid options are:
...
  --[no-]check-buildhost
  --[no-]check-buildtime
  --[no-]check-changelog
...
$

Более тонко запуск тестов можно настроить с помощью опций --no-sisyphus-check-in и --no-sisyphus-check-out, с описанием которых можно ознакомиться в man-странице hsh(1).

Ограничение ресурсов

hasher позволяет ограничить ресурсы, выделяемые на сборку: CPU, память, общее время исполнения и другие. Ограничения указываются в конфигурационном файле hasher-priv.

Полный список ограничиваемых ресурсов можно найти в man-странице hasher-priv.conf(5).

Отладка в сборочном chroot

Для отладки сборки иногда полезно запустить shell в сборочном chroot. Для этого используется утилита hsh-shell(1):

$ hsh-shell

Можно запустить программу и с правами псевдо-root:

$ hsh-shell --rooter

Для контроля за содержимым сборочного chroot'а используются опции hsh: --cleanup-only, --eager-cleanup, --lazy-cleanup и соответствующие настройки вроде lazy_cleanup=1 в ~/.hasher/config.

Для запуска произвольных программ в сборочном чруте существует более низкоуровневая утилита hsh-run(1).

Использование buildreq в hasher

Начинаем и обламываем сборку пакета в hasher:

$ hsh --rebuild-prog=/bin/false somepackage.src.rpm

Далее применяем buildreq:

$ hsh-install ~/hasher rpm-utils
$ hsh-shell ~/hasher
$ buildreq ~/RPM/SPECS/*.spec

После этого в спеке появляется новая строка BuildRequires, сопровождаемая комментарием вида # Automatically added by buildreq ... (если такая строка с комментарием уже была, она заменяется).

Из хост-системы получившийся спек доступен тут: ~/hasher/chroot/usr/src/RPM/SPECS/*.spec

Примечание. Если сборка делалась автономно, buildreq будет сообщать об ошибках отсутствия файлов, и понадобится скопировать в chroot hasher'a файлы: спек в ~/hasher/chroot/usr/src/RPM/SPECS/ и файлы-источники в ~/hasher/chroot/usr/src/RPM/SOURCES/.

Пересборка пакета без пересоздания всего chroot

Даже в tmpfs развёртывание всей сборочной среды и зависимостей идёт небыстро.

Для того, чтобы собирать один и тот же пакет до тех пор, пока он не соберётся, нужно попросить hasher не разворачивать заново всю сборочницу, либо работать в самой сборочнице.

Многократная сборка пакета в одном hasher

Пакет не собрался. Воспользуемся hsh-shell, предварительно установив любимый текстовый редактор, шелл, конфиги для них и прочие инструменты разработчика. Не забудем, что в дереве каталогов hasher есть каталог ~/hasher/chroot/.in, в которой может писать сам пользователь (а не его двойники, пользователь_a и пользователь_b).

$ hsh-install vim-console less rpm-utils patchutils zsh
$ mkdir -p ~/hasher/chroot/.in/src
$ cp -a .vim* .zprofile .zsh_aliases .zshenv .zsh_bind .zshrc .dircolors ~/hasher/chroot/.in/src
$ hsh-run -- cp -r /.in/src /usr
$ hsh-shell --shell=/bin/zsh

zsh ругается на то, что системные файлы не принадлежат root, если вас это смущает, отключите проверку так:

$ hsh-run --rooter -- sed -i 's/compinit$/compinit -i/' /etc/zshrc

Отсутствующие сборочные зависимости можно доставлять с помощью hsh-install (выйдя из чрута).

ВАЖНО: по окончании работы (rpm -ba выполнился успешно) не забудьте выполнить buildreq, rpm -bs и забрать .src.rpm из ~/hasher/chroot/usr/src/RPM/SRPMS (или спек из ~/hasher/chroot/usr/src/RPM/SPECS).

Многократная сборка пакета при работе с gear

Если вы используете gear и предпочитаете вести разработку (редактировать спек, править код и т. п.) в базовой системе, вместо hsh можно использовать hsh-rebuild -- программу, работающую с уже сформированным сборочным окружением.

Первоначальная сборка (даже если прошла успешно, окружение не удаляется):

$ gear --hasher -- hsh --lazy-cleanup

Повторная сборка:

$ gear --hasher -- hsh-rebuild

ВАЖНО: по окончании работы не забудьте выполнить buildreq и забрать спек:

$ hsh-install rpm-utils
$ echo buildreq '/usr/src/RPM/SPECS/*.spec' | hsh-shell
$ cp ~/hasher/chroot/usr/src/RPM/SPECS/*.spec .

Примечания

  1. за исключением кэширования образа базовой системы, что не влияет на корректность и воспроизводимость результата
  2. Директория ~/hasher используется по умолчанию во всех командах hsh-* и её можно не указывать: hsh --initroot-only, hsh somepkg.src.rpm и т. д.
  3. с типом rpm-dir либо после создания хэшей: mkdir ~/hasher/repo/i686/base; genbasedir --topdir ~/hasher/repo/i686/
  4. Иначе характерное error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory; одно из объяснений с $ORIGIN см. в hasher/FAQ#В рабочей системе некая библиотека находится, а в хэшере -- нет, хотя она лежит в одном и том же месте