Лекция 7. Управляемая сборочница

Сегодня у нас логичное продолжение того, о чём говорили в прошлый раз. А именно о том, как устроена управляемая сборочница на примере того, как это устроено у нас в ALT Linux'e, то есть в Сизифе.

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

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

Как эти ситуации могут возникнуть? Во-первых, когда вам нужно профилировать эти сборки. Например, выжимать из бинарной сборки максимальную продуктивность. Наивысшего пилотажа в этом деле, как я понимаю, достигла Дженту. Там есть большое число различных «ручек», которые можно дёргать при сборке пакета. Примерно так же устроена и FreeBSD. Там есть так называемые порты, которые представляют собой makefile + набор патчей + что-то ещё. Таким образом, системы пакетирования, нацеленные на локальную сборку, дожили до наших дней и имеют определённые преимущества.

С целью того, чтобы хранилище всегда было консистентным, в настоящее время идёт ужесточение правил приёма и выхода годного из сборочницы. Проводится жёсткий контроль за тем, не только кто собирает пакет, но и из каких исходников он его собирает. Если раньше можно было ограничиться просто changelog'ом, то сегодня можно чисто по случайности собрать пакет не из того места, забыть включить какие-то изменения и тем самым поломать историю разработки пакета.

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

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

Видимо надо это всё превратить в список:

DVCS

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

На это ещё накладывается специфика распределённых систем контроля версий, связанная с тем, что понятие коммит — это помещение изменения в локальный репозиторий. Соответственно, есть отдельные команды для помещения и изъятия изменений из удалённого репозитория: push и pop. (В отличие от централизованных систем контроля версий, в которых push и commit — одно и то же.)

Git-хостинг для исходников пакетов

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

Когда вы заходите на git.alt, первое, что вам встречается, это программа girar. У неё куча возможностей: завести, склонировать, переименовать, удалить. Посмотреть список файлов со своими пакетами.

Ещё есть отдельная забавная фича, которая называется find package. Она показывает вам, у каких членов team'а есть каталог с заданным именем. Есть программы, которые активно пошли по рукам, и которые уже собирает 10 человек. Вопрос в том, у кого самая свежая версия.

Если вы хотите последнюю актуальную, собранную в сизиф версию, такая штука тоже есть. Существует специальный репозиторий, куда делается push при каждой удачной сборке.

В этом репозитории лежат:

Одним из вариантов работы является хранить upstream в отдельном каталоге. При этом для удобства пользовательского обновления существует следующая договорённость: upstr-vers.tar.gz распаковывается всегда в каталог upstr/...

Два инструмента, которые предназначены именно для такого формата хранения исходников в git-репозитории:

  1. gear-srpminport
  2. gear-update
    • Это инструмент, который позволяет вам обновлять исходник внутри upstr. Вы говорите gear-update <tarball> <каталог>. Это скрипт, который распаковывает тарбол и переименовывает его в название каталога. В результате вы будете видеть чистый, беспримесный diff между старым тарболом и новым, что очень удобно.

При всём удобстве этой схемы мы не пользуемся одной возможностью гита. У нас патчи хранятся как файлы. Возникает желание затолкать эти патчи в git-дерево, чтобы эти патчи выглядели как диффы.

У этой схемы есть один явный и один неявный недостаток.

Предлагается следующая схема:

upstream
.gear/rules
      spec
      другие файлы

<здесь лектор рисовал на доске несколько схем, которые здесь не описаны>

В чём скрытый недостаток этого метода? Представим себе, что приезжает новый upstr. Эти патчи не накладываются. Вам приходится эти патчи мёрджить. Что вы видите в вашем недомёрдженном варианте? Какие-то патчи применились, какие-то пропали.

Проблема этой ситуации состоит в том, что вместо того, чтобы накладывать новый апстрим на пропатченный старый, вам нужно пропатчисть старый апстрим и снова наложить патчи поверх (то есть делать rebase). Но в таком случае теряется наследование и ломается история.

Есть два способа избежать этой ситуации. Первый — просто держать каждый патч в отдельной ветке. Помимо того, что мы просто будем получать в src.rpm разрозненный набор патчей, у нас будет видна атомарность применения патчей.

Есть ещё одна модификация того, о чём я говорил. Это если у апстрима код не в тарболе, а в гите или SVN'е. Тогда хочется украсть себе ещё и историю разработки апстрима.

И ещё один способ, который изобрёл ваш покорный слуга, который называется «совместить неприятное с бесполезным»: а именно, хранить патчи, как в самом первом варианте, но генерировать их гитом. В гите есть прекрасная функция format-patch. Если соблюдать некоторую дисциплину оформления этих патчей, то можно замутить следующую схему: у вас есть репозиторий первого типа. Старая добрая схема с патчами + возможность работать с исходниками в гите.

Управление сборочницей

Как дать сборочнице команду собери пакет? Да очень просто. Поставить тег специального вида, затем зайти по ssh и сказать «собери по такому-то тегу». Это командочка build. В более сложных случаях, когда вам нужно сделать груповое задание, вы заходите на сборочницу и говорите: заведи мне задание и добавь туда сборку того-то и того-то. Я позже приведу на сайте пример с соответствующими заданиями. Если хотя бы один из пакетов не собрался или не прошёл тест, создаётся временный репозиторий, где вы можете посмотреть, что произошло.

ACL. Есть разные группы пользователей. Есть пользователь everybody, который означает, что кто угодно может пересобирать ваш пакет. Всё тем же ssh, gitalt вы управляете ACL. Понятие мейнтейнер сохраняется, именно он редактирует этот список допущенных.

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

LecturesCMC/PackageMaintaining2013/Conspects/08 (последним исправлял пользователь FrBrGeorge 2013-05-06 13:19:03)