Бинарный кэш Nix — это три функции, а значит им может быть что угодно
Разбираясь с собственным проектом, Фарид Закария наткнулся на любопытное наблюдение: чтобы стать бинарным кэшем Nix, серверу не нужно ничего знать про Nix. Достаточно уметь отвечать на три запроса — отдать файл nix-cache-info со строкой StoreDir, выдать по хэшу .narinfo с метаданными архива и, наконец, вернуть сам сжатый архив по адресу из поля URL. Всё. Любой статический файловый сервер справляется с этой задачей.
Отсюда и провокационный тезис автора: если с ролью кэша справляется скромный раздатчик файлов, то кэшем можно сделать почти что угодно. Например, GitHub Pages, который автоматически проставляет разрешающий заголовок access-control-allow-origin: *, — достаточно закоммитить в репозиторий вывод nix copy --to file://, и бесплатный substituter готов.
Почему это безопасно
Секрет в том, что Nix не доверяет транспорту. Подпись в .narinfo покрывает только StorePath, NarHash, NarSize и References, но не URL, не размер файла и не способ сжатия. После загрузки архив распаковывается, и клиент сверяет NarHash. Именно поэтому пакет, подписанный cache.nixos.org, можно скачать откуда угодно, и подпись всё равно останется валидной. Поле URL вообще не обязано указывать на тот же хост или даже на тот же протокол.
Кэш из чего угодно
Автор собрал целую коллекцию курьёзных реализаций. gachix складывает архивы в объектную базу git, которая сама дедуплицирует и сжимает данные — выигрыш около 82% против обычного кэша. Есть proof-of-concept, раскладывающий .narinfo и четырёхкилобайтные куски архива по TXT-записям DNS. Кэшем может служить пастебин (истечение срока хранения работает как естественный сборщик мусора), OCI-реестр и даже YouTube — проект «infinite storage glitch» кодирует данные внутри видеоролика.
npm как substituter
Отдельно разобран npm. Поскольку nix copy --to file:// создаёт каталог, а npm умеет публиковать каталоги, автор пропатчил классический hello, чтобы тот печатал «Hello from the npm registry!», подписал замыкание собственным ключом и опубликовал пакет. После этого Nix спокойно тянет всё замыкание с unpkg.com и запускает бинарник. Бонусом идут «каналы» через npm dist-tags: тег latest изменяемый, а конкретные версии неизменяемы.
Главный недостаток — отсутствие инкрементальной публикации: пятьдесят замыканий с общим glibc загрузят glibc пятьдесят раз. Теоретически лечится публикацией каждого store-path отдельным пакетом с индексом, но автор честно признаётся, что строить такое не станет — по отношению к экосистеме npm это было бы не по-джентльменски.
Источник: Lobsters
Комментарии
Войдите, чтобы комментировать.