Перевод статьи Людвика Курте от 29.03.2019, [[https://www.gnu.org/software/guix/blog/2019/connecting-repro.../ опубликованной]] в блоге Guix.В статье рассказано как в дистрибутиве GNU Guix связать повторяемые сборки, позволяющие убедиться в тождественности бинарных файлов эталонным исходным текстам, с загрузкой исходных текстов из архива кода [[https://www.softwareheritage.org/ Software Heritage]]. Software Heritage ставит перед собой задачу создания полного архива всех доступных в Сети исходных текстов. Код загружается из разных источников (GitHub, репозитории Debian, коллекции GNU и т.п.) с автоматическим переносом информации об изменениях, формируя таким образом историю развития кода разных проектов (можно посмотреть каким код был в разное время). В Guix можно использовать Software Heritage для получения кода, если репозиторий из которого собран пакет перестал существовать. В контексте повторяемых сборок пользователь может загрузить из Software Heritage состояние кода проекта, соответствующее имеющемуся бинарному пакету, и проверить, что бинарные файлы собраны именно из этого кода без добавления скрытых изменений.
GNU Guix может использоваться как пакетный менеджер, чтобы устанавливать и обновлять пакеты ПО. Также Guix может выступать менеджером окружения, создавать контейнеры или виртуальные машины, управлять операционной системой на компьютере.
Ключевым отличием GNU Guix, выделяющим его среди других подобных инструментов, является воспроизводимость. Для пользователя это означает следующее. Пользователь задаёт в конфигурационном файле программное окружение и запускает его установку. Пользователи могут делиться конфигурацией окружения с другими, чтобы воспроизвести или адаптировать его для своих нужд. Эта особенность играет ключевую роль для разработки программного обеспечения, так как чтобы получить результат внедрения программы в программное окружение, вначале нужно воспроизвести программное окружение. Этой темой мы занимаемся в рамках проекта
[[https://guix-hpc.bordeaux.inria.fr/ Guix-HPC]]. На программном уровне это означает, что Guix, как и другие проекты сообщества [[https://reproducible-builds.org/ Reproducible Builds]], производит сверку результатов [[https://reproducible-builds.org/docs/definition/ воспроизводимой]] сборки, бит за битом.
В вопросе воспроизводимости Guix ушёл вперёд. Пользователю Guix, можно сказать, доступна машина времени, позволяющая запустить окружение с предыдущими версиями пакетов. Но оставался один нюанс, который не позволял использовать эту технологию на практике - стабильный архив исходного кода. Тогда и появился
[[https://www.softwareheritage.org/ Software Heritage]] (SWH).
++ Когда исходный код исчезает
Guix содержит тысячи описаний пакетов. Каждое описание пакета задаёт URL исходного кода пакета и хеш, зависимости и процедуру сборки. В большинстве случаев исходный код пакета - это архив, извлекаемый с сайта, но всё чаще исходный код ссылается на конкретную ревизию, размещённую в системе управления версиями.
Что происходит, если ссылка на исходный код становится нерабочей? Все усилия, обеспечивающие воспроизводимость, не работают, когда исчезает исходный код. Исходный код, действительно, исчезает, более того, он может быть изменён в источнике. В GNU мы предоставляем стабильный хостинг, где размещаются релизы почти навсегда, без изменений (с незначительными редкими изменениями). Но большое количество свободного программного обеспечения в Интернете размещается на личных сайтах, которые имеют непродолжительное время жизни, или на коммерческих хостингах, которые работают и закрываются.
По умолчанию Guix ищет исходный код по хешу в кэше наших серверов сборки. Бесплатно
[[https://www.gnu.org/software/guix/manual/en/html_node/Substi... механизм]] подстановок расширяет функционал сборки, включая скачивание. Однако ограничения не позволяют нашим серверам сборки хранить весь исходный код всех пакетов долгое время. Так что вполне вероятно, что пользователь не сможет пересобрать пакет через месяцы или годы, просто потому что исходный код переместился или исчез.
++ Работа с архивом
Совершенно ясно, что для обеспечения воспроизводимых сборок должен быть постоянный доступ к исходному коду. Архив Software Heritage позволит нам воспроизводить программное окружение через годы вопреки непостоянству хостингов. Миссия Software Heritage - сохранить весь когда либо опубликованный исходный код, включая историю версий. Этот архив уже периодически поглощает релизы ПО с серверов GNU, репозитории с GitHub, пакеты PyPI и многое другое.
Мы предусмотрели политику, по которой Guix будет обращаться к архиву Software Heritage при невозможности скачать исходный код из источника. Описания пакетов при этом не нуждаются в изменениях: они всё ещё указывают на первоначальный URL, но механизм скачки прозрачно работает с Software Heritage, когда необходимо.
В Guix есть два типа скачивания исходных кодов: скачивание архива и осуществление контроля изменений версий. В первом случае взаимодействие с Software Heritage очень простое: Guix выполняет поиск по хешу SHA256, который ему известен, используя [[https://archive.softwareheritage.org/api/1/content/raw/ интерфейс архива]].
Выборка истории изменения версий более сложная. В этом случае вначале необходимо определить идентификатор коммита, чтобы обратиться к нужной
[[https://archive.softwareheritage.org/api/1/revision/ ревизии]] на Software Heritage. Код ревизии затем будет доступен через [[https://docs.softwareheritage.org/devel/swh-vault/api.html API]] хранилища.
Хранилище (Vault API) позволяет получить архив, соответствующий определённой ревизии пакета. Однако ясно, что не все ревизии доступны в качестве архивов, так что хранилище имеет интерфейс, через который можно запросить подготовку нужной ревизии. Подготовка асинхронная и может занимать некоторое время. В настоящее время, если ревизия недоступна, механизм скачивания Guix запрашивает и ждёт его готовности. Процесс может занять некоторое время, но в итоге завершается успешно.
Вот так! С этого момента мы собрали цепочку. Благодаря Software Heritage, который предоставляет стабильный архив, воспроизводимая сборка Guix работает. Этот код был [[https://issues.guix.info/issue/33432 внедрён]] в ноябре 2018, создав первый свободный дистрибутив, основанный на стабильном архиве.
++ Новые вызовы
Мы достигли цели и сделали её осязаемой, но нам известно о недостатках. Во-первых, даже если программное обеспечение, которое описано в наших пакетах, доступно в виде архивов, Software Heritage содержит относительно немногие из них. Software Heritage поглощает архивы, особенно те, которые найдены на серверах GNU, но он нацелен в первую очередь на сохранение репозиториев систем управления версиями, а не архивов релизов.
Нам всё ещё неясно, что делать с обычными старыми архивами. С одной стороны, они есть и не могут быть проигнорированы. Более того, многие содержат артефакты, которых нет в системе управления версими, например, скрипты configure, и довольно часто они сопровождаются криптографическими подписями разработчиков, которые позволяют получателям подтвердить код - важная информация, которая часто отсутствует в системе управления версиями. С другой стороны, теги систем управления версиями всё чаще становятся механизмом распространения релизов программ. Вполне вероятно, что теги станут главным механизмом распространения ПО в ближайшем будущем.
Теги систем управления версиями тоже не идеальны, так как они изменчивы и привязаны к репозиторию. С другой стороны, идентификаторы коммита Git совершенно точно указывают на нужную версию пакета, так как они относятся к пакету и не зависят от репозитория. Но наши описания пакетов часто ссылаются на теги, а не коммиты, так как это даёт понять, что пакет ссылается на актуальный релиз, а не обычную ревизию (такой вот [[https://en.wikipedia.org/wiki/Zooko''s_triangle треугольник Zooko]]).
Есть и другая проблема, которая происходит из того, что Guix вычисляет хеш версии пакета иначе, чем Software Heritage. Оба вычисляют хеш по файлам директории, но они упорядочивают файлы в разных последовательностях (SWH сериализует директории как дерево Git, а Guix использует "нормализованный архив", или Nars, формат, который использует демон сборки, наследованный от Nix). Это не позволяет Guix искать ревизии по хешу содержимого. Решением вероятно будет добавление в Guix поддержки такого метода, как в Software Heritage, ну, или Software Heritage добавит метод Guix.
Ожидание завершения подготовки архива также может вызывать проблемы. Команда Software Heritage внедряет возможность
[[https://forge.softwareheritage.org/T1350 автоматического]] добавления тегов в систему управления версиями. Таким образом, нужные ревизии почти всегда будут доступны в хранилище.
Также мы не гарантируем, что программы, поставляемые Guix, доступны в качестве архива. Мы [[https://forge.softwareheritage.org/T1352 запросили Software Heritage]] периодически скачивать исходный код программного обеспечения, поставляемого Guix.
++ Движемся далее
Работая над поддержкой Software Heritage, мы включили в Guix [[https://issues.guix.info/issue/33432 модуль Guile]], реализующий HTTP-интерфейс Software Heritage. Вот некоторые вещи, которые он умеет:
(use-modules (guix swh))
;; Check whether SWH has ever crawled our repository.
(define o (lookup-origin "https://git.savannah.gnu.org/git/guix.git"))
=> #{{origin> id: 86312956 ...>
;; It did! When was its last visit?
(define last-visit
(first (origin-visits o)))
(date->string (visit-date last-visit))
=> "Fri Mar 29 10:07:45Z 2019"
;; Does it have our "v0.15.0" Git tag?
(lookup-origin-revision "https://git.savannah.gnu.org/git/guix.git" "v0.15.0")
=> #{{revision> id: "359fdda40f754bbf1b5dc261e7427b75463b59be" ...>
Guix также является библиотекой Guile, так что используя guix и swh, мы получаем интересные вещи:
(use-modules (guix) (guix swh)
(gnu packages base)
(gnu packages golang))
;; This is our GNU Coreutils package.
coreutils
=> #{package coreutils@8.30 gnu/packages/base.scm:342 1c67b40>
;; Does SWH have its tarball?
(lookup-content (origin-sha256 (package-source coreutils))
"sha256")
=> #{{content> checksums: (("sha1" ...)) data-url: ...>
;; Our package for HashiCorp's Configuration Language (HCL) is
;; built from a Git commit.
(define commit
(git-reference-commit
(origin-uri (package-source go-github-com-hashicorp-hcl))))
;; Is this particular commit available in the archive?
(lookup-revision commit)
=> #{{revision> id: "23c074d0eceb2b8a5bfdbb271ab780cde70f05a8" ...>
В настоящее время мы используем этот инструментарий, но конечно, это не всё, что мы можем. Например, можно выяснить, какие пакеты Guix добавлены. Также можно запросить архив исходного кода каждого пакета с помощью интерфейса
[[https://archive.softwareheritage.org/api/1/origin/save/ 'save code']], но однако есть [[https://archive.softwareheritage.org/api/#rate-limiting ограничения]] по скорости.
++ Подведём итоги
Поддержка Software Heritage в Guix даёт для воспроизводимого развёртывания стабильный архив исходного кода и полное резервирование ранних версий. Впервые мы получили пакетный менеджер, который может пересобирать предыдущие версии программ. Это имеет практическую выгоду в области воспроизводимости: мы можем создавать воспроизводимое программное окружение - основу воспроизводимых экспериментов в области разработки ПО.
Собственно, мы можем предоставить инструменты загрузки программного обеспечения с доступом к ранним версиям. Да и сам Guix резервируется, так что мы выходим на метауровень, когда мы можем ссылаться на ревизии Guix, ссылаясь на ревизии пакетов, предоставляемые им. Есть барьеры, которые необходимо преодолеть, но результат уже обозрим.
URL: https://www.gnu.org/software/guix/blog/2019/connecting-repro.../
Обсуждается: http://www.opennet.me/tips/info/3100.shtml