Воспроизводимая сборка

Материал из ALT Linux Wiki
(перенаправлено с «Reproducible»)

Введение

В рамках проекта ALT Linux и его сборочной инфраструктуры Алексеем Турбиным (at@) и Дмитрием Левиным (ldv@) были приложены немалые усилия для обеспечения возможности воспрозведения сборки пакетов при помощи girar (управление сборкой и репозиториями), hasher (сборка в «чистом» изолированном окружении) и gear (воссоздание архива исходных текстов по тегу из git-репозитория специального вида).

Теоретические основы описаны в статье Алексея Турбина «Сборочная система git.alt» (PDF, стр. 47).

Пример

В качестве наглядного пособия выбрал один из пакетов, которые недавно обновлял — lxqt-about (так как со времени предыдущей сборки изменился как состав репозитория, так и сборочные зависимости переехавшего с Qt 4 на Qt 5 проекта). Попробуем воспроизвести сборку версии 0.8.0-alt1 несколько месяцев спустя.

Подготовка сборочного окружения

Хост-система

В качестве «чистой» хост-системы можно воспользоваться стартеркитом altlinux-p7-builder; был взят текущий altlinux-p7-builder-20141212-x86_64.iso и запущен в экземпляре VirtualBox с 4 Гб оперативной памяти и ethernet-интерфейсом с доступом к интернету.

Репозиторий

Сборочная инфраструктура git.alt фиксирует предыдущий по отношению к собираемому репозиторий, на базе которого он будет пересобран перед commit (т.е. перед тем, как станет текущим состоянием Sisyphus или бранча).

Возьмём архив Сизифа с предшествующим состоянием[1]:

  1. http://www.altlinux.org/Sisyphus_archive
  2. http://ftp.altlinux.org/pub/distributions/archive/sisyphus/index/src/
  3. http://ftp.altlinux.org/pub/distributions/archive/sisyphus/index/src/l/
  4. http://ftp.altlinux.org/pub/distributions/archive/sisyphus/index/src/l/lxqt-about/

Здесь видим:

Date Version Task Subtask
2014-05-14 17:21 0.7.0-alt1 119542 1000
2014-10-14 23:59 0.8.0-alt1 132244 1000
2015-02-09 21:04 0.9.0-alt1 140101 400

Проходим по ссылке с даты и далее в files/list/:

  1. http://ftp.altlinux.org/pub/distributions/archive/sisyphus/task/archive/_129/132244/
  2. http://ftp.altlinux.org/pub/distributions/archive/sisyphus/task/archive/_129/132244/files/
  3. http://ftp.altlinux.org/pub/distributions/archive/sisyphus/task/archive/_129/132244/files/list/

Здесь интересует содержимое task.info:

task 132244
prev 132240

Следовательно, задание 132244 было собрано на основе репозитория по заданию 132240; соответственно создаём sources.list[2]:

rpm [alt] http://ftp.altlinux.org/pub/distributions/archive/sisyphus/task/archive/_129/132240/daily x86_64 classic
rpm [alt] http://ftp.altlinux.org/pub/distributions/archive/sisyphus/task/archive/_129/132240/daily noarch classic

и apt.conf к нему:

Dir::Etc::main "/dev/null";
Dir::Etc::parts "/var/empty";
Dir::Etc::SourceParts "/var/empty";
Dir::Etc::sourcelist "/home/altlinux/sources.list";

Исходники

Для каждого собранного из git задания фиксируется тег и репозиторий, воспользуемся этим, перейдя к подзаданию 1000 задания 132244 и оттуда по ссылке «lxqt-about.git 0.8.0-alt1»:

  1. http://ftp.altlinux.org/pub/distributions/archive/sisyphus/index/src/l/lxqt-about/
  2. http://git.altlinux.org/tasks/archive/done/_129/132244/#s1000
  3. http://git.altlinux.org/tasks/archive/done/_129/132244/gears/1000/git

Делаем копию этого репозитория на tmpfs[3]:

cd $TMP
git clone git://git.altlinux.org/tasks/archive/done/_129/132244/gears/1000/git

Сверяем тег:

$ cd git
$ git describe
0.8.0-alt1

Сборка

Запускаем процесс извлечения исходников из git, упаковки и передачи на сборку hsh(1):

gear-hsh --apt-config=$HOME/apt.conf

С учётом получения пакетов из сети выполнение займёт некоторое время:

Wrote: /usr/src/RPM/SRPMS/lxqt-about-0.8.0-alt1.src.rpm
Wrote: /usr/src/RPM/RPMS/x86_64/lxqt-about-0.8.0-alt1.x86_64.rpm
Wrote: /usr/src/RPM/RPMS/x86_64/lxqt-about-debuginfo-0.8.0-alt1.x86_64.rpm
12.17user 11.36system 0:24.12elapsed 97%CPU (0avgtext+0avgdata 59380maxresident)k
0inputs+0outputs (0major+445974minor)pagefaults 0swaps

Сверка

Получим и распакуем архивный пакет:

mkdir $TMP/orig
cd $TMP/orig
wget -qO- http://git.altlinux.org/tasks/archive/done/_129/132244/build/1000/x86_64/rpms/lxqt-about-0.8.0-alt1.x86_64.rpm | rpm2cpio | cpio -id

Из бинарников в нём только usr/bin/lxqt-about.

В соседнем каталоге распакуем только что собранный:

mkdir $TMP/rebuilt
cd $TMP/rebuilt
rpm2cpio ~/hasher/repo/x86_64/RPMS.hasher/lxqt-about-0.8.0-alt1.x86_64.rpm | cpio -id

Смотрим:

-rwxr-xr-x 1 altlinux altlinux 10448 Feb 14 20:14 orig/usr/bin/lxqt-about
-rwxr-xr-x 1 altlinux altlinux 10448 Feb 14 20:15 rebuilt/usr/bin/lxqt-about

Сверяем контрольные суммы (например, SHA1):

3b5c596b4603ce8ba7403448dfe48a952ed65135  orig/usr/bin/lxqt-about
3b5c596b4603ce8ba7403448dfe48a952ed65135  rebuilt/usr/bin/lxqt-about

Приехали :)

Известные и потенциальные проблемы

Временные/псевдослучайные метки

При порождении кода или данных их фрагменты (например, отметки о времени сборки или идентификаторы параграфов) могут генерироваться невоспроизводимым образом; если это важно, следует доработать алгоритмы с целью достижения воспроизводимости.

Современные gcc/g++ уже не ставят timestamps, по крайней мере по умолчанию.

Примечания

  1. следует понимать, что вследствие практических ограничений по дисковому пространству архив для каждого сборочного задания через некоторое время «прореживается», превращаясь в ежесуточный.
  2. префиксы с подчёркиванием — результат целочисленного деления номера задания на 1024
  3. tmpfs используется для временного содержимого, повышения скорости сборки и большей воспроизводимости

Ссылки