- комментарий 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]:
>Сборочное окружение устроено так, что весь трафик идёт через [...]
Ага, спасибо за удовлетворение любопытства!
СУБД тут уже удобна будет, согласен.