Воспроизводимая сборка
Введение
В рамках проекта 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]:
- http://www.altlinux.org/Sisyphus_archive
- http://ftp.altlinux.org/pub/distributions/archive/sisyphus/index/src/
- http://ftp.altlinux.org/pub/distributions/archive/sisyphus/index/src/l/
- 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/:
- http://ftp.altlinux.org/pub/distributions/archive/sisyphus/task/archive/_129/132244/
- http://ftp.altlinux.org/pub/distributions/archive/sisyphus/task/archive/_129/132244/files/
- 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»:
- http://ftp.altlinux.org/pub/distributions/archive/sisyphus/index/src/l/lxqt-about/
- http://git.altlinux.org/tasks/archive/done/_129/132244/#s1000
- http://git.altlinux.org/tasks/archive/done/_129/132244/gears/1000/git
Делаем копию этого репозитория на tmpfs (для скорости сборки):
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 $TM/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, по крайней мере по умолчанию.