Руководство по очистке SRPM от неиспользуемых файлов

Быстрый старт

Начальная конфигурация

После установки пакета srpm-cleanup скопируйте пример конфигурационного файла /usr/share/doc/srpm-cleanup/Makefile.example в новый файл с именем Makefile в рабочей директории и отредактируйте его.

Списки пакетов

Прежде всего нужно определить списки исходных пакетов — то есть составы дистрибутивов для определённого набора архитектур. Для определения набора пакетов для каждой из архитектур нужно, используя макрос def_srpm_list: указать название архитектуры и перечислить имена файлов со списками пакетов. Список таких определений обозначается именем SRPM_LISTS. Например:

SRPM_LISTS = $(call def_srpm_list,ppc64le,lists/alt-sp8-server-latest-ppc64le.iso.srpms)
SRPM_LISTS += $(call def_srpm_list,aarch64,lists/alt-sp8-server-latest-aarch64.iso.srpms lists/alt-sp8-workstation-latest-aarch64.iso.srpms)
SRPM_LISTS += $(call def_srpm_list,armh,lists/alt-sp8-workstation-01-mcom02-latest-armh.img.srpm-list)
SRPM_LISTS += $(call def_srpm_list,i586,lists/alt-sp8-server-latest-i586.iso.srpms lists/alt-sp8-workstation-latest-i586.iso.srpms)
SRPM_LISTS += $(call def_srpm_list,x86_64,lists/alt-sp8-server-latest-x86_64.iso.srpms lists/alt-sp8-workstation-latest-x86_64.iso.srpms)

Как можно видеть, в этом примере для архитектур ppc64le и armh определено по одному файлу со списком пакетов, а для остальных архитектур перечислено по два таких файла (серверный и настольный вариант).

Файл с списком пакетов — это простой текстовый файл, каждая строка которого определяет имя файла одного исходного пакета и имеет вид:

<name>-<version>-<release>.src.rpm

Рабочие машины

Далее нужно определить конфигурацию рабочих машин, которые условно подразделяются на сборщиков (builders) и чистильщиков (cleaners). Условно потому, что на практике это, обыкновенно, одни и те же машины, но используемые в разных режимах.

Для настройки каждого сборщика и чистильщика требуется указать достаточно много параметров, используя макросы def_builder и def_cleaner. Рассмотрим их на примере:

power_slots = 1-40
taishan_slots = 1-30
xeon_slots = 1-20
cleaning_slots = 1-50
hasherdir = /tmp/.private/builder/hashers
nfs_repo = /mnt/build/branch/c9f1
nfs_srpms = $(nfs_repo)/files/SRPMS
nprocs = nprofile

BUILDERS = $(call def_builder,builder@power,ppc64le,$(power_slots),$(hasherdir),$(nfs_repo),$(nprocs))
BUILDERS += $(call def_builder,builder@taishan,aarch64 armh,$(taishan_slots),$(hasherdir),$(nfs_repo),$(nprocs))
BUILDERS += $(call def_builder,builder@xeon,x86_64 i586,$(xeon_slots),$(hasherdir),$(nfs_repo),$(nprocs))

CLEANERS = $(call def_cleaner,builder@power,$(cleaning_slots),$(hasherdir),$(nfs_srpms))
CLEANERS += $(call def_cleaner,builder@taishan,$(cleaning_slots),$(hasherdir),$(nfs_srpms))
CLEANERS += $(call def_cleaner,builder@xeon,$(cleaning_slots),$(hasherdir),$(nfs_srpms))

В качестве первого аргумента макросам def_builder и def_cleaner передаётся параметр, известный как “sshlogin” — имя или адрес узла, опционально снабжаемый именем пользователя: [<user>@]<host>.

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

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

Количество слотов ограничивается количеством ресурсов (главным образом оперативной памяти) рабочих машин и должно соответствовать действительному количеству (и номерам) слотов, определённых с помощью утилиты hasher-useradd на каждой из машин. Обратите внимание, что при определении чистильщиков для всех машин указано одно и то же значение 1-50, то есть целых 50 слотов. Это связано с тем, что количество потребляемых ресурсов в этом режиме в среднем значительно ниже, чем в режиме сборки пакетов.

Далее оба макроса ожидают определение директории (на рабочей машине), в которой будут создаваться поддиректории для каждого слота для запуска hasher. В примере для всех машин используется директория с одним и тем же именем /tmp/.private/builder/hashers (переменная hasherdir).

Кроме слотовой директории рабочие машины должны получить доступ к репозиторию пакетов: в режиме сборки — к препозиторию бинарных пакетов, в режиме чистки — к репозиторию исходных. Для каждой рабочей машины (и режима) этот путь может быть своим, но в примере выше мы исходили из того, что все машины настроены одинаково и имеют доступ к репозиторию по протоколу NFS. Поэтому путей вариантов в примере всего два: путь до репозитория (переменная nfs_repo) и путь до директории с исходными пакетами в том же репозитории (переменная nfs_srpms).

Завершает настройку сборщиков параметр nprocs — количество потоков для каждой сборки. В качестве значения можно передать число, а можно имя файла с профилем вида:

<N>[:M]
<имя пакета>=<N>[:M]

Строка с числом N или парой чисел N:M без имени пакета задаёт количество потоков по умолчанию (число M задаёт количество потоков отдельно ля секции %check). Строки профиля с именем пакета ограничивают количество потоков лишь при сборке данного пакета. Важно: файл профиля не копируется на сборочные машины. Он должен быть помещён туда вручную и поэтому может различаться от машины к машине.

Прочие параметры

Все прочие параметры, указанные в файле Makefile.example должны подойти для типовой пересборки пакетов. При необходимости обращайтесь к странице руководства make-srpm-cleanup(7).

Этапы пересборки

Этап I

На первом этапе производится пересборка исходных пакетов из всех списков (без повторов) на всех архитектурах с обнаружением не используемых в процессе сборки исходных файлов. Информацию по текущему выполнению первого этапа можно получить по команде

make stage1-status

Например:

$ make stage1-status
Total packages:  1573
Not found SRPMs: 0

Arch    Done  Excl  BDep  Chk   NoSI  Other  LErr  NoAtt  Total
----    ----  ----  ----  ----  ----  ----   ----  ----   ----
armh    0     0     0     0     0     0      0     1573   1573
aarch64 0     0     0     0     0     0      0     1573   1573
ppc64le 0     0     0     0     0     0      0     1573   1573
x86_64  0     0     0     0     0     0      0     1573   1573
i586    0     0     0     0     0     0      0     1573   1573

Total unique SRPMs processed: 0
Lists for unused packages:    0

Для запуска пересборки всех не прошедших обработку пакетов (колонка NoAtt в таблице) используйте команду

make stage1

Если к консоли на данном компьютере вы подключаетесь удалённо, то перед запуском пересборки имеет смысл запустить надёжный сеанс, например, с помощью screen(1), потому что пересборка может занять десятки часов, за которые связь с удалённой консолью может неожиданно прерваться, а вместе с ней прервётся и выполнение этапа, если сеанс командной оболочки не будет дополнительно от этого защищён.

Цель первого этапа заключается в создании списков лишних файлов для максимального количества исходных пакетов. Но этому препятствует то, что не все пакеты удаётся пересобрать. И причин для этого может быть несколько. Рассмотрим для примера такой отчёт о состоянии этапа:

$ make stage1-status
Total packages:  1573
Not found SRPMs: 0

Arch    Done  Excl  BDep  Chk   NoSI  Other  LErr  NoAtt  Total
----    ----  ----  ----  ----  ----  ----   ----  ----   ----
armh    1444  5     23    16    53    32     0     0      1573
aarch64 1451  5     18    11    48    40     0     0      1573
ppc64le 1482  5     13    18    32    23     0     0      1573
x86_64  1500  0     0     7     52    14     0     0      1573
i586    1493  0     2     8     43    27     0     0      1573

Total unique SRPMs processed: 1573
Lists for unused packages:    0

Подобная ситуация может возникнуть уже после первого прогона: все исходные пакеты были обработаны, но не везде сборка прошла благополучно. Часть пакетов было отброшено по причине ограничения архитектуры (Excl), у других обнаружились проблемы со сборочными зависимостями (BDep) и выполнением встроенных тестов (Chk). В отдельную категорию NoSI выделяются ошибки, связанные с нехваткой на файловой системе (как правило tmpfs) свободного места или количества inodes. Все прочие ошибки попадают в колонку Other.

Сборку тех пакетов, которым не хватило место достаточно перезапустить, сократив количество одновременно запускаемых сборок. Например:

make stage1-retry-nospace power_slots=2 taishan_slots=2 xeon_slots=2

Количество inodes на tmpfs можно просто увеличить, и затем перезапустить сборку этой категории пакетов без дополнительных ограничений:

make stage1-retry-noinode

А вот с остальными проблемными пакетами придётся разбираться с каждым отдельно. И начать «разбор полётов» имеет смысл с просмотра журналов сборки. Список журналов сборки для каждой категории и архитектуры можно получить по командам вида make list-stage1-<категория>-<архитектура>-logs. Например:

make list-stage1-brkndep-armh-logs
make list-stage1-chkerr-aarch64-logs
make list-stage1-other-x86_64-logs

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

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

make stage1-retry-chkerr [OPTS=...]
make stage1-retry-brkndep-armh [OPTS=...]
make stage1-retry-pkgs PKGS=... [FOR_ARCHES=...] [OPTS=...]

Последний вариант позволяет выбрать не какую-то общую категорию, а перечислить конкретные пакеты для пересборки (в формате <name>-<version>-<release>). При необходимости можно ограничить архитектуры. Для разделения значений списков можно использовать как пробелы (не забывая экранировать их от оболочки), так и запятые.

Этапы II и III

Для перехода ко второму этапу не обязательно доводить процент пересобранных на первом этапе пакетов до 100%. Во-первых, это вряд ли удастся. А во-вторых, в то время, пока вы разбираетесь с тем, как починить пересборку конкретного пакета, дальнейшая обработка тех пакетов, которые успешно прошли первый этап, вполне может и должна продолжаться — незачем технике простаивать.

Этапы II и III — это собственно «чистка» SRPM-пакетов. На втором этапе «лишние» исходные файлы обрезаются и запаковываются в TAR-архивы, а на третьем из них формируются новые SRPM-пакеты. Важное отличие этих этапов от первого состоит в том, что обработка пакетов на них не зависит от архитектуры и к тому же потребляет значительно меньше ресурсов. Поэтому для этих этапов используется отдельная конфигурация рабочих машин-чистильщиков — CLEANERS, количество слотов на которых может отличаться (в большую сторону) от конфигурации машин-сборщиков.

Управление вторым и третьим этапом производится в общем-то так же, как и первым, только stage1 в названиях целей нужно заменить на stage2 и stage3 соответственно.

Этап IV

Четвёртый этап – это почти полное повторение первого, только на этот раз списки «лишних» файлов не составляются, а проверяются. Если всё идёт как надо, то никаких «лишних» файлов в уже почищенных пакетах обнаружено быть не должно. Однако на практике такое случается, потому что в самой процедуре чистки есть неоднозначности, и тогда такой пакет попадает в колонку VErr отчёта об этапе. Что делать с такими «недочищенными» пакетами решать вам. Если вы решите пропускать их, то установите TOOLERANCE в Makefile в значение, отличное от нуля.

Перед началом запуска пакетов на этап IV нужно настроить параметр REPO_DIR — путь до репозитория пакетов, доступный с текущей, управляющей машины. Располагаемый в репозитории файл bin.list используется для составления индекса dist-tags.

Кроме проверки списков на четвёртом этапе выявляются различные ошибки сборки, которые возникают в следствии чистки. Если причина поломки ясна, то потерявшиеся файлы можно восстановить, добавив из в exceptions.list и повторив этапы II и III. Для облегчения этой задачи определены цели:

reclean-pkgs PKGS=... [FOR_ARCHES=...] [OPTS=...]
reclean-and-rebuild-pkgs PKGS=... [FOR_ARCHES=...] [OPTS=...]

Первая из них включает в себя этапы II и III, а вторая ещё и этап IV.

Этап V, завершающий

Необходимость в пятом этапе возникла по причине пересборки под аудитом. Причём пересборка затрагивает как почищенные пакеты, проверенные на этапе IV, так и пакеты, по разным причинам не дошедшие до этапа V. По этой причине пятый этап делится на два подэтапа stage5v и stage5o (именно эти слова фигурируют в названиях целей этапа V). На этап 5v проходят только почищенные и проверенные пакеты, а на этапе 5o под аудитом пересобираются оригинальные SRPM из репозитория.

Перед запуском сборки под аудитом на каждой из рабочих машин-сборщиков нужно установить пакет srpm-cleanup-audit, содержащий стандартные скрипты для включения и отключения аудита: autit_on и audit_off (подробнее см. REBUILD_OPTS в Makefile).

Кроме того, /sbin/auditctl на рабочих машинах должен успешно добавлять и удалять правила аудита при запуске от имени пользователя, фигурирующего в параметре “sshlogin” в BUILDERS (или текущего пользователя). Добиться этого можно, например, разрешив suid-root для этой программы (при необходимости ограничив группу пользователей, которым вообще разрешён её запуск).

Проверить комплектацию пакетов перед запуском этапа V можно по команде

make check-rebuild-lists

Будет выведена информация об общем количестве пакетов с разделением на пакеты, прошедшие этап IV и оригинальные пакеты, а также кросс-платформенные пакеты и архитектурно-специфические. Пересечений между этими списками быть не должно (это проверяется). Также выводится информация о покрытии, то есть о готовности всех требуемых пакетов для каждой из архитектур.

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

make check-rebuild-results-armh
make check-rebuild-results-aarch64
make check-rebuild-results-x86_64

Итоговый отчёт аналогичен предыдущему, но включает в себя дополнительную строку Coverage with excl. Общий результат в этой строке считается с учётом пакетов, отмеченных как ExcludeArch или ExclusiveArch ещё на этапе I.

Результаты пересборки под аудитом записываются в директории rebuild.v и rebuild.o.

Обновление списков пакетов

«Чистка» SRPM занимает порядочное время и за это время комплектация тех дистрибутивов, для которых она выполняется может измениться. Для введения новых пакетов на первый и последующие этапы достаточно обновить указанные в SRPM_LISTS списки исходных пакетов. И сделать это можно двумя способами.

Первый способ — это просто предоставить новые списки. Заменить файлы или имена файлов в SRPM_LISTS.

Второй способ — отредактировать существующие списки. Сделать это можно с помощью скрипта update-versions.sed, приготовить (и обновить) который можно командой

make update-versions.sed

При этом используется файл bin.list (его расположение зависит от REPO_DIR). Использовать полученный скрипт можно, например, таким образом:

sed -i -f update-versions.sed <файлы списков пакетов...>

Естественно, что при обновлении списка пакетов вторым способом, комплектация дистрибутивов не изменится, новых пакетов в них не появится. Но версии всех пакетов будут заменены на те, что в данный момент находятся в репозитории.

После обновления списков пакетов тем или иным способом, на всех этапах, начиная с первого в категории NoAtt должно появиться ненулевое число. Это значит, что можно снова запускать эти этапы — будут обработаны только новые пакеты.

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

При прогоне новых версий пакетов через этапы старые результаты не удаляются. Обыкновенно это не мешает работе (поскольку <name>-<version>-<release> фигурирует в именах всех результирующих файлов). Однако для этапа V это не так: наличие в директориях rebuild.v и rebuild.o лишних пакетов может привести к ошибке при их дальнейшей обработке (например, при сборке дистрибутива). Поэтому старые результаты сборки под аудитом, которые уже не нужны, желательно просто удалить. Для этого определены команды:

make clean-stage5v-unused
make clean-stage5o-unused

Дополнительные проверки

Проверить соответствие версий и dist-tags пересобранных под аудитом пакетов версиям и dist-tags в репозитории можно с помощью команды:

make check-versions

Экспорт результатов

Экспортировать результаты пересборки под аудитом, то есть этапа V, можно командами:

make export-rpms DESTDIR=... [EXPORT_OPTS=...]
make export-repo DESTDIR=... [EXPORT_REPO_OPTS=...]

Обеим командам необходимо передать путь до директории для экспорта. Экспорт производится командой rsync(1). Поэтому повторный экспорт должен скопировать только новые или изменившиеся пакеты. Отсутствующие в rebuild.v и rebuild.o пакеты удаляются из целевой директории.

Цель export-repo включает в себя цель repo, которая готовит репозиторий пакетов в директории repo командой genbasedir(1). Для экономии места репозиторий строится на основе символических ссылок, однако, при экспорте происходит их разъименование (для чего в набор EXPORT_REPO_OPTS по умолчанию входит опция -L).