[devel] Announce: автоматизация замещающих пересборок.

Igor Vlasenko vlasenko на imath.kiev.ua
Вс Ноя 28 15:19:28 UTC 2010


Уважаемые коллеги!

Все вы, наверное, помните, скольких усилий в свое время потребовало
обновление python, да и недавнее обновление perl. Это был настоящий 
запоминающийся подвиг, и низкий поклон Евгению, Алексею и Владимиру.

Но плохо, что для регулярных неизбежных обновлений требуется
подвижничество. Что будет, если в нужный момент герой не найдется?
Сизиф протухнет, крупные устаревшие компоненты будут тянуть его на
дно.

Вот почему я посчитал важным и нужным написать набор утилит girar-nmu,
с помощью которого такая пересборка может быть выполнена за вечер.
Но, чтобы ими можно было пользоваться, надо понимать, как они работают.

В настоящий момент я пишу в devel@ и параллельно оформляю 
manual на [ http://altlinux.org/Git.alt/girar-nmu ].
Уже описал, как генерировать пакеты для NMU и как их заливать. 
Осталась самая сложная тема -- как вычислять порядок пакетов для
замещающей пересборки. 

Что я называю замещающей пересборкой? Это пересборка, которая вызвана
обновлением, нарушающим Shared libs Policy, т.е. когда старая версия
библиотеки замещается новой, бинарно не совместимой со старой.
При этом надо пересобрать все зависимые пакеты, чтобы убрать unmets.

Разные причины могут быть для такой пересборки.
Иногда майнтайнеру просто удобнее пересобрать зависящие пакеты.
А иногда по другому просто нельзя -- это как раз всем знакомые пересборки
python, perl, ghc и т. д.

Для замещающей пересборки очень важен порядок пакетов. Например,
собрали новый perl. Теперь ни одним из старых arch perl-* пакетов 
воспользоваться не получится -- их даже не получится установить в hasher.
Их надо будет собрать заново в порядке их зависимостей.

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

Для решения всех этих проблем в состав girar-nmu utils входит скрипт
girar-nmu-sort-transaction.
Им можно пользоваться, и не понимая, как он работает,
но если скрипт нашел в транзакции проблемы, то уже без понимания не
обойтись.

попытаюсь рассказать ее работу как можно проще. 
В качестве примера возьму пересборку perl.

Разберем запуск этой утилиты.

girar-nmu-sort-transaction --mark '^libperl\.so\.5\.' \
 /Sisyphus/files/SRPMS /Sisyphus/files/noarch/RPMS /Sisyphus/files/i586/RPMS | \
 grep -v '^perl$' > names.txt

grep -v '^perl$ здесь --- технический. Поскольку список мы скармливаем 
другим утилитам girar-nmu utils, а с собственно пакетом perl мы
готовим его новую версию руками и руками же начнем с него транзакцию,
то в списке он не нужен.

Важные моменты.
1) на вход эта утилита получает весь Сизиф.

Казалось бы, если я хочу отсортировать пакеты, зависящие от
libperl\.so, зачем мне Сизиф? Может быть, это для удобства,
поскольку опция --mark-regexp '^libperl\.so\.5\.'
сама найдет и пометит эти пакеты? 
Нет, скормить весь Сизиф -- это принципиально.
Вы можете явно указать "важные", т.е. зависящие от libperl.so.5.9
опцией --rpm-names-transaction (или --rpm-files-transaction),
а сортируемые src.rpm пакеты - опцией -srpm-names-transaction
(--srpm-files-transaction). 

Утилите нужно скормить весь Сизиф, чтобы избежать проблем.
Проблема в том, что зависимости могут собираться в длинные цепочки.
Допустим, вы сортируете пакеты perl-*.
Но может оказаться, что perl-A зависит от foo, foo зависит от bar, bar
зависит от perl-B. perl-A от perl-B прямо не зависит, но если вы
попытаетесь собрать их в порядке perl-A perl-B,
то perl-A вытянет foo, foo вытянет bar, bar вытянет perl-B,
а perl-B hasher установить не сможет и пересборка аварийно завершится.
Поэтому, если даже сортируются только perl-* пакеты, для корректного
вычисления зависимостей нужно брать весь Сизиф.

2) утилита находит в транзакции блокирующие циклы.
Что это такое? Это ситуация, когда при попытке собрать пакет A
в сборочное окружение будет втянут пакет, старая версия которого
не установится, а новый можно собрать, только если уже собран пакет A.

Пример блокирующего цикла.
perl-Math-BigInt-FastCalc-0.19-alt1.src ->
(Buildrequires:) -> perl-Math-BigInt-1.89-alt1.noarch ->
(Requires:) -> perl-Math-BigInt-FastCalc-0.19-alt1.x86_64 ->
(BuiltFrom:) -> perl-Math-BigInt-FastCalc-0.19-alt1.src

Наличие блокирующих циклов означает, что транзакция "в лоб"
не пройдет гарантированно, и сначала надо убрать зависимость,
создающую цикл.

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

На этом введение в girar-nmu-sort-transaction заканчиваю,
надеюсь, со временем напишу и подробный разбор алгоритма сортировки.

При возникновении вопросов спрашивайте.

-- 

Dr. Igor Vlasenko
--------------------
Topology Department
Institute of Math
Kiev, Ukraine



Подробная информация о списке рассылки Devel