#bass 

Код с GitHub как distfile

https://github.blog/changelog/2023-01-30-git-archive-checksums-may-change/
https://www.cambus.net/on-the-importance-of-distfiles/
https://marc.info/?l=openbsd-ports&m=151973450514279&w=2
не годится, так как они не дают никаких гарантий что не изменится
алгоритм формирования автогенерируемых tarball-ов. В итоге все
контрольные суммы поедут. Грамотный способ делать релизы на GitHub:
заливать самостоятельно сделанные tarball-ы. Насколько вижу по BASS,
большинство так и делает.

    [оставить комментарий]
    комментарий 0:
    From: kmeaw
    Date: 2026-03-12 17:15:11Z
    
    Я писал утилиту для зеркалирования distfiles, и специально для snapshot с
    vcs-систем добавил туда костыль. Если URL распознаётся правилом "это snapshot
    с vcs", то преобразуем (если этого ещё не сделано) branch в commitid, а
    потом используем его в качестве cache key.
    
    Например, если на вход подали ссылку
    https://www.cpan.org/src/5.0/perl-5.36.0.tar.gz, то всё хорошо, это не vcs
    snapshot, поэтому ничего специально не делаем. Cache key будет hash($uri).
    
    А если
    https://github.com/NetworkConfiguration/dhcpcd/archive/refs/tags/v10.2.2.tar.gz,
    то резолвим tags/v10.2.2, и cache key теперь f6983c18dbf….
    
    Если на следующем цикле зеркалирования tags/v10.2.2 вдруг поменяется, то
    только в этом случае попытаемся его перекачать. Не поменяется - значит
    можно вообще не дёргать snapshot и сэкономить ресурсы апстрима.
    
    Для всех файлов в базе хранятся Last-Modified, Content-Length и ETag. Если
    апстрим не поддерживает ETag, то делаем HEAD и сверяем Last-Modified и
    Content-Length. Если Last-Modified не отдаётся или слишком часто меняется,
    а апстрим часто отвечает 4xx или 5xx, то проверяем только Content-Length.
    
    Если интересно, то вот схема:
    
    CREATE TABLE errors (
        uri character varying(4096) NOT NULL,
        fetched_at timestamp with time zone DEFAULT now() NOT NULL,
        status_code integer DEFAULT 500 NOT NULL,
        body character varying(8192)
    );
    
    CREATE TABLE distfiles (
        sha256 character varying(64) NOT NULL,
        fetched_at timestamp with time zone DEFAULT now() NOT NULL,
        size integer DEFAULT 0 NOT NULL,
        uri character varying(4096) NOT NULL,
        etag character varying(8192),
        last_modified timestamp with time zone,
        head boolean DEFAULT false
    );
    
    комментарий 1:
    From: Sergey Matveev
    Date: 2026-03-12 18:43:18Z
    
    *** kmeaw@kmeaw.com [2026-03-12 17:15]:
    >Я писал утилиту для зеркалирования distfiles, и специально для snapshot с
    >vcs-систем добавил туда костыль. Если URL распознаётся правилом "это snapshot
    >с vcs", то преобразуем (если этого ещё не сделано) branch в commitid, а
    >потом используем его в качестве cache key.
    
    Ну у меня redo цели используются. Если есть foo.do, то будет выполнятся
    он, и только в противном случае default.do, который будет пытаться
    качать обычные файлы. Можно бы было сделать default.vcs.do какую-нибудь
    цель, чтобы для VCS-got tarball-ов не писать отдельный .do каждый раз.
    Но их у меня не много, пока не напрягает. Плюс у некоторых не просто
    надо стянуть, но ещё и submodule-и достать, сформировать архив со всем
    этим добром вместе. Но идея VCS-specific URLs импонирует.
    
        % cat distfiles/dl/opustags-1.10.1.tar.zst.do
        redo-ifchange ../utils/git-to-tarball
        ../utils/git-to-tarball opustags \
            https://github.com/fmang/opustags.git \
            d9b051210ba756d28086c9b75e983e84ae11e730 \
            ${1%.tar.zst}
    
    >Если на следующем цикле зеркалирования tags/v10.2.2 вдруг поменяется, то
    >только в этом случае попытаемся его перекачать. Не поменяется - значит
    >можно вообще не дёргать snapshot и сэкономить ресурсы апстрима.
    
    Я бы вообще не ориентировался на тех, кто может поменять значение tag.
    Не хорошо так делать (только если быстро, пока никто не заметит :-)).
    Ну и использовать GitHub API для скачивания tarball-ов я тоже перестал.
    Так как они сами заявляют что нет гарантий что алгоритм не поменяется и
    все хэши разойдутся. Я теперь VCS-ы клонирую и уже сам формирую tar-ы.
    Что ещё и правильнее тем, что хоть какие-то хэши у нас (коммиты) появляются.
    
    >Для всех файлов в базе хранятся Last-Modified, Content-Length и ETag. Если
    >апстрим не поддерживает ETag, то делаем HEAD и сверяем Last-Modified и
    >Content-Length. Если Last-Modified не отдаётся или слишком часто меняется,
    >а апстрим часто отвечает 4xx или 5xx, то проверяем только Content-Length.
    
    Для локальной установки вроде как-то избыточно. Я отталкиваюсь от того,
    что tar-ы будут immutable. Если скачали один раз и хэши напротив
    закоммиченного эталона сошлись, то больше к upstream и не надо обращаться.
    Любые обновления делаются вручную человеком, который забьёт коммиты/хэши,
    напротив которых всё будет проверяться. Не очень понимаю use-case для БД
    с хранением ETag/времени. Это же не Atom/RSS которые периодически надо
    опрашивать и проверять не обновилось ли чего.
    
    Или это для проверки вообще кто жив из зеркал, к кому можно обращаться?
    
    комментарий 2:
    From: Sergey Matveev
    Date: 2026-03-12 18:51:37Z
    
    *** kmeaw@kmeaw.com [2026-03-12 17:15]:
    >Если интересно, то вот схема: [...]
    
    Для своего RSS/Atom feeder я всё на ФС храню:
    
        feeder/state % l feeds/antirez.com_rss/
        cur/ download.hash etag feed hdr new/ out parse.hash title tmp/ url
    
    Тоже учитывается ETag и time condition. Плюс хэши чтобы проверять точно
    ли поменялось что скачалось.
    
    комментарий 3:
    From: kmeaw
    Date: 2026-03-13 10:55:36Z
    
    > Не очень понимаю use-case для БД с хранением ETag/времени.
    
    Для себя я бы тоже хранил просто в ФС, но тут причина в организационной
    структуре. Это сервис зеркалирования, который торчит наружу по http и
    находится близко к сборочной ферме, где собирается ОС.
    
    Сборочное окружение устроено так, что весь трафик идёт через
    перехватывающий (и перешифровывающий) прокси, который пишет логи. Прокси
    может читать мои таблицы, а я могу читать логи прокси. Когда я вижу, что
    в логах появился новый URI, то ставлю его в очередь на скачивание и
    добавляю запись в files. Когда в files появляется новая запись, прокси
    перестаёт ходить в апстрим, и начинает ходить ко мне. Запустить
    downloader и proxy на одной машине сложно, ими занимаются разные люди, и
    их зоны ответственности и релизные циклы не совпадают.
    
    Меня бы тоже VCS не особо напрягали, но downloader напрягает админов
    Gitlab - у них от частого хождения в ручку, отдающую tarball,
    заканчиваются ресурсы, и они меня банят по IP. Поэтому пришлось написать
    код, специфичный для Gitlab, GitHub, cgit и ещё нескольких систем, чтобы
    они не делали для меня export тогда, когда этого не нужно.
    
    Проблема с воспроизводимостью тут решается за счёт того, что я однажды
    скачав файл буду отдавать одно и то же содержимое до тех пор, пока ref
    не начнёт указывать в другое место. Сборочное окружение следит за
    целостностью build inputs и создаёт тикеты на владельцев пакетов, если
    что-то изменилось, например прокси отдал другой файл. Тут база данных
    тоже оказывается полезной - в таблицу легко пустить человека, чтобы
    он разобрался, почему произошли изменения.
    
    комментарий 4:
    From: Sergey Matveev
    Date: 2026-03-13 14:36:39Z
    
    *** kmeaw@kmeaw.com [2026-03-13 10:55]:
    >Сборочное окружение устроено так, что весь трафик идёт через [...]
    
    Ага, спасибо за удовлетворение любопытства!
    СУБД тут уже удобна будет, согласен.