[devel] girar-builder

Alexey Tourbin =?iso-8859-1?q?at_=CE=C1_altlinux=2Eru?=
Ср Дек 10 02:40:45 MSK 2008


Я подготовил предварительный вариант системы сборки из girar.
Пока продумана и реализована только часть идей из protva-2008.pdf
(тестовая пересборка пакетов не реализована).  С другой стороны,
уже на уровне текущей функциональности система может работать в основном
не хуже, а лучше, чем incoming.

ftp://ftp.altlinux.org/pub/people/at/protva-2008.pdf
http://git.altlinux.org/people/at/packages/girar.git
http://git.altlinux.org/people/at/packages/girar-builder.git

Я предлагаю уже в ближайшее время запустить girar-builder в тестовом
режиме, параллельно с incoming.  Это значит, что incoming будет, как
и раньше, принимать на сборку src.rpm пакеты, а girar-builder будет
принимать на сборку gear-репозитарии.  При таком раскладе потребуется
более аккуратно разграничивать конкурентный доступ между incoming и
girar-builder к общему репозитарию пакетов, но, в целом, это не должно
создать серьезных проблем.

К преимуществам girar-builder я отношу автоматические проверки,
направленные на поддержку целостности репозитария пакетов.

К недостаткам системы можно отнести следующее:

- Нет поддержки дополнительных архитектур; работа с двумя основными
  архитектурами (i586 и x86_64) реализована в hardcoded виде (с другой
  стороны, мы все-таки автоматически получаем жесткую синхронизацию
  пакетов между основными архитектурами).

- Слабое распараллеливание; серьезный подход к распараллеливанию
  пока не продуман.  С другой стороны, реально распараллеливание
  больше всего нужно для тестовой пересборки пакетов.  Еженедельная
  тестовая пересборка пакетов (beehive) пока будет работать как обычно.

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

Далее следуют некоторые детали и пояснения.
Краткое резюме: будет работать команда

$ ssh git.alt build [-b <sisyphus-branch>] pkg1.git 1.0-alt1 [pkg2.git 2.0-alt2]...

* * *

Пользователь взаимодействует со сборочной системой в терминах заданий
(task).  Каждое задание имеет уникальный целочисленный идентификатор
(идентификаторы заданий инкрементно увеличиваются).  Каждое задание
ассоциировано с пользователем, который создал задание (владелец задания,
task owner).  Задание по умолчанию, или же "подразумеваемое" задание,
означает задание с наибольшим идентификатором среди заданий, созданных
данным пользователем (владельцем задания).

Задание должно включать в себя один или несколько gear-репозитариев,
которые нужно собрать.  Примитивы работы с заданиями следующие (они
будут доступны как 'ssh git.alt <команда>...'):

- task new [<binary-repo>]
  Создает задание и возвращает его идентификатор; <binary-repo> означает
  "sisyphus", "4.0" или "4.1"; по умолчанию "sisyphus" (и на первое время
  будет работать только "sisyphus").  Таким образом, задание изначально
  ассоциировано с репозитарием пакетов, для которого придётся собирать
  пакеты.

- task add [<id>] <gear-repo> <gear-tag>
  Добавляет gear-репозитарий в задание на сборку.  Если идентификатор
  задания <id> опущен, подразумевается текущее задание.  <gear-repo>
  означает gear-репозитарий в каталоге /people/$GIRAR_USER/packages/,
  например, perl.git (суффикс .git писать не обязательно, но нужно
  помнить, что речь идёт о соответствующем каталоге).

  Таг <gear-tag> должен быть подписан gpg ключом из alt-gpgkeys,
  поле 'tagger' должно содержать GIRAR_USER на altlinux (то есть значение
  тага должно соответствовать текущему пользователю, который работает
  с girar).  Другими словами, "чужие" таги на сборку не принимаются.

- task run [<id>]
  Когда задание укомплектовано, его надо запустить на сборку.

Задание может находится в одном из четырех состояний:
0) none -- на ранних стадиях формирования задания; это состояние
не представляет принципиального интереса;
1) scheduled for run -- задание готово к сборке;
2) running -- выполняется сборка задания;
3) ret -- сборка задания выполнена (либо успешно, либо с ошибками).

Состояние задания сейчас реализовано как инкрементная последовательность
sequence number с остатком по модулю 3 (для состояний 1-3).

Команда 'task run' должна переводить задание в состояние 1 -- scheduled
for run.  Это возможно, только если задание находится в состоянии 0 (none)
или 3 (ret).

Когда задание завершилось с ошибкой, можно добавить в него
дополнительные gear-репозитарии для сборки (которые предположительно
исправляют ошибки) и повторно запустить на сборку.

	Сейчас состояние 3 (ret) не интерпретируется: грубо говоря,
	пока нельзя узнать, завершилось ли задание успешно или с
	ошибкой (не считая отчета, который отправляется по почте).
	Это довольно неудобно, и это надо будет исправить в первую
	очередь, но это не настолько глупо, как может показаться с
	первого взгляда.

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

Будет работать комбинированная команда

- build [-b <binary-repo>] <gear-repo-1> <gear-tag-1> [<gear-repo-2> <gear-tag-2>]...

Она эквивалентна последовательности команд
  id = task new [<binary-repo>]
  task add $id <gear-repo-1> <gear-tag-1>
 [task add $id <gear-repo-2> <gear-tag-2>]
  ...
  task run $id

- task rm [<id>]
  Задание можно удалить, если только оно не находится в состоянии
  running.

- task share [<id>]
  По умолчанию только владелец задания может комплектовать задание
  gear-репозитариями на сборку.  "Расшаривание" задания означает,
  что владелец задания разрешает другим пользователям добавлять
  в свое задание их gear-репозитарии.  Требование добавлять только
  свои таги всё ещё должно выполняться (расшаривание позволяет
  добавлять свои таги в чужие задания).

* * *

Выполнение задание сводится к последовательному выполнению "стадий"
в режиме "sh -e" (если очередная стадия завершается с ошибкой, то
последующие стадии не выполняются).  Последняя стадия -- копирование
собранных пакетов в репозитарий.

- gb-task-pkgtar
  Для каждого gear-репозитария в задании собирает pkg.tar (промежуточное
  между .gear и src.rpm представление исходного пакета).

["gb" означает "girar-builder".]

- gb-task-build
  Собирает rpm пакеты из pkg.tar.
  
  Сборка выполняется строго в той последовательности, в которой
  gear-репозитарии были добавлены в задание.  Если сборка очередного
  gear-репозитария завершается с ошибкой, то сборка всех последующих
  gear-репозитариев отменяется (и задание завершается с ошибкой).
  
  Сборка выполняется в режиме 'hsh --with-stuff', то есть ранее
  собранные в пределах задания пакеты доступны в hasher-репозитарии (и,
  как правило, они "перекрывают" соответствующие пакеты в Сизифе).

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

  Сборка всех пакетов должна успешно завершиться на всех архитектурах
  (i586 и x86_64).  Специальная обработка ExclusiveArch пока не реализована.

- gb-task-check-build
  Проверка собранных rpm пакетов.
  Должны выполняться ряд ограничений для набора пакетов в целом:

  + При сборке gear-репозитария на разных архитектурах должен получиться
    один и тот же src.rpm пакет (обнаруживает атаки на "имя проекта").

  + Если при сборке gear-репозитария получились noarch.rpm пакеты, то
    набор noarch.rpm пакетов должен быть одинаковым для всех архитектур;
    и сами noarch.rpm пакеты, собранные на разных архитектурах, должны быть
    идентичны: список файлов и всех зависимостей у noarch.rpm пакетов
    при сборке на i586 и x86_64 должен совпадать.

  + В результате сборки должен получиться уникальный список src.rpm
    пакетов (с точностью до имени -- то есть внутри задания нельзя
    собирать один и тот же исходный пакет разных версий).

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

  + Должно существовать однозначное соответствие между собранными
    src.rpm пакетами и бинарными пакетами.  Точнее, лучше говорить
    о "кортеже" (src,bin+).  (Терминология однозначного соответствия,
    как и терминология кортежей, оказывается слишком неточной:
    соответствие src->bin не однозначное, а "значением" в кортеже
    является не элемент, а множество.)

- gb-task-repo-plan
  Нужно составить план обновления репозитария пакетов: исходя из того,
  что все собранные пакеты, как src.rpm, так и бинарные, должны попасть
  в репозитарий, нужно вычислить, каким образом новые пакеты замещают
  старые пакеты в репозитарии.  Замещение происходит как по имени
  исходного пакета, так и по имени бинарных пакетов, и дополняется
  по однозначному соответствию между исходными и бинарными пакетами.

- gb-task-repo-vercheck
  Нужно убедиться, что составленный план обновления репозитария
  корректен по части изменения версий пакетов: при обновлении пакетов
  версии должны увеличиваться ("обновление" означает совпадение по
  имени; увеличение версии проверяется как для исходных, так и для
  бинарных пакетов).  Кроме того, не допускается, чтобы имя файла
  rpm пакета оставалось прежним (такое возможно в случае, если добавился
  Serial, а Version-Release остались прежними).

- gb-task-repo-unmets
  Проверка на неудовлетворенные зависимости.
  
  Создается временный репозитарий, к которому применяется план
  обновления репозитария (то есть добавляются новые пакеты и удаляются
  старые пакеты).  Не должно возникнуть новых удовлетворенных
  зависимостей.  Понятие "новой" удовлетворенной зависимости трактуется
  строго (как в cybertalk unmets): если обновленный пакет сохраняет
  неудовлетворенную зависимость, то она считается "новой".  Короче,
  нельзя отправлять на сборку пакеты с анметами, даже если эти анметы
  ранее существовали.

- gb-task-check-acl
  Проверка на ACL (право заливать определенные пакеты) выполняется последней.
  С одной стороны, это связано с тем, что имена пакетов заранее неизвестны
  (проверка доступа идет по имени src.rpm пакета, а соответствия между
  gear-репозитариями и src.rpm пакетами изначально не предполагается).
  С другой стороны, должен быть механизм NMU, то есть контролируемого
  нарушения ACL, но только при условии, что все остальные проверки были
  выполнены успешно.  Увы, механизм разрешения NMU пока не реализован.

  Проверка ACL реализована корректно для случая переименования пакетов
  (с учетом того, что задание может быть "расшарено", нужно специально
  вычислять ответственность за переименование пакетов).

- gb-task-repo-commit
  Подписывает собранные пакеты и копирует их в репозитарий.
  Метаданные репозитария перегенерируются (genbasedir и т.д.).
  После этого собранные пакеты сразу же доступны для последующих заданий.

* * *

Пропускная способность такой системы -- несколько заданий в час,
при условии, что сама сборка пакетов не занимает слишком много.
То есть чистый оверхед выполнения задания, включая две перегенерации
репозитария (для repo-unmets и repo-commit) -- несколько минут.
----------- следующая часть -----------
Было удалено вложение не в текстовом формате...
Имя     : =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Тип     : application/pgp-signature
Размер  : 197 байтов
Описание: =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Url     : <http://lists.altlinux.org/pipermail/devel/attachments/20081210/a1f4dfe8/attachment-0001.bin>


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