On Fri, Mar 29, 2019 at 01:43:48PM +0300, Alexey Tourbin wrote: > Мужчины, оказывается у вас теперь можно пересобирать пакеты без > увеличения релиса. Файлы %{Name}-%{Version}-%{Release}.%{Arch}.rpm > в репозитории переписываются поверх старых, а apt будет обновлять > их по изменившемуся %{BuildTime}. В связи с этим несколько технических > замечаний. > > == Перезапись .src.rpm == > > При пересборке из /gears будет замещен .src.rpm пакет > https://bugzilla.altlinux.org/show_bug.cgi?id=27840#c16 > тогда как почти всегда этого можно не делать. > В частности, если у .src.rpm пакета не изменились запакованные файлы > и зависимости, то этого точно можно не делать (это похоже на критерий > "extensional equality", который советует делать noarch пакеты). Пересобирая пакет без изменения исходного кода, мы вправе ожидать, что получившийся новый .src.rpm не изменится существенным образом. Если у .src.rpm, собранного из /gears, не изменились запакованные файлы и зависимости, то действительно можно сэкономить и оставить прежний .src.rpm. > Репозиторий src.rpm пакетов не бесполезен, на нем можно проверять > сборочные зависимости (почти так же, как apt-cache unmet проверят > установочные зависимости). Строгая проверка, которая не дает ложных > срабатываний, возможна только для той архитектуры, для которой .src.rpm > файлы отбираются в files/SRPMS; по-моему сейчас это i586. Вероятно, > есть смысл отбирать пакеты в files/SRPMS из x86_64, поскольку именно она > давно уже стала основной архитектурой. Да, раньше это была архитектура i586, но с некоторых пор в прошлом году мы стали брать пакеты в noarch и SRPMS из результатов сборки для x86_64. > == Перезапись .noarch.rpm == > > Пересборка без увеличения релиса удобна в случае пересборки клиентов > с новыми версиями библиотек; при этом noarch-подпакеты, такие как foo-doc, > должны остаться без изменений; их тоже можно было бы не замещать. > Но теперь они получат зависимости с disttag+task, и поэтому критерий > extensional equality к ним не применим (пересобранные пакеты всегда > будут отличаться из-за таска). Возможно, стоило бы ослабить межпакетные > зависимости при пересечении границы arch/noarch: вместо EVR:disttag+task > требовать только EVR:disttag. Это дало бы возможность не переписывать > noarch-пакеты. > > Но ведь noarch-пакетами все не ограничивается. Так, при пересборке > библиотеки по идее должен измениться только подпакет libfoo, а libfoo-devel > должен остаться прежним. Хорошо бы не переписывать и libfoo-devel. > Сделать это, к сожалению, сложно. Я продумывал схему, как передать в > rpmbuild информацию об уже имеющихся собранных подпакетах. Тогда > в конце сборки rpmbuild сможет решить, какие подпакеты экзистенционально > равны, и скорректировать зависимости у некоторых подпакетов, чтобы > исключить переписывание/обновление. Но это не работает как следует, > потому что у зависимостей есть направление: пакет libfoo-devel требует > libfoo. Если в libfoo-devel зашита строгая зависимость на libfoo, то не > обновлять его нельзя. > > Почему не удается придумать хорошей схемы с частичным переписыванием > подпакетов? Может, это очевидно, но до меня почему-то не сразу дошло. > Строгие зависимости с EVR:disttag+task направлены на то, чтобы запретить > совмещение пакетов из разных сборок. А частичное переписывание как раз > направлено на совмещение пакетов из разных сборок. Это не просто > разные, а противоположные цели. Мы исходили из того, что если раньше зависимости между подпакетами были жёсткими, то введение ещё одной степени свободы в дополнение к EVR не должно сделать их менее жёсткими. Автоматически выяснять, нужна ли такая жёсткость в зависимостях между подпакетами, мы в общем случае не умеем, поэтому пусть они остаются жесткими. > == Пропатчивание индексов == > > Переписывание *.rpm пакетов поверх старых усложняет генерацию нового > pkglist.classic файла на основе старого pkglist.classic файла (это еще > как следует не реализовано). Если исходить из того, что сборочная > система не переписывает *.rpm пакеты, то перекомпоновка записей в > pkglist.classic реализуется легко: пусть имеется предыдущее состояние > pkglist.classic и новое состояние RPMS.classic/. Тогда все записи из > pkglist.classic, для которых в RPMS.classic/ есть пакет, кочуют в новый > pkglist.classic (совпадения по имени .rpm файла достаточно). > > Теперь же совпадения по имени .rpm файла становится недостаточно. > Причем чтобы схема перекомпоновки работала быстро, нужно ограничиваться > только stat-информацией (читать каждый .rpm пакет - гиблое дело). > На практике для идентификации пакетов st_size+st_mtime работают достаточно > хорошо. Тогда для сравнения записей и пакетов нужно хранить в записи > дополнительный таг, CRPMTAG_FILEMTIME (а CRPMTAG_FILESIZE уже хранится). > Поскольку там уже хранится и RPMTAG_BUILDTIME, то можно попытаться > отождествить FILEMTIME и BUILDTIME. Для этого придется выставлять > st_mtime в BUILDTIME. Но может это и не очень хорошо, поскольку > st_mtime может меняться по уважительной причине (из-за подписывания > пакета). У меня была идея определять, какие записи следует удалить из pkglist, а какие добавить, на основе плана обновления, поскольку в файлах add-bin и rm-bin уже достаточно информации. Может быть, это даже немного проще, чем добавлять новый CRPMTAG в pkglist. > Вообще, чтобы перекомпоновка работала как следует, нужно держать две > версии записей: более полную версию в pkglist.classic+bloat и обычную > версию для пользователя pkglist.classic. В pkglist.classic+bloat > у каждой записи будет полный список файлов, а в pkglist.classic - > урезанный, направленный на удовлетворение файловых зависимостей. > Поэтому обычный pkglist.classic использовать для перекомпоновки нельзя. > Потому что список требуемых файлов у каждой записи зависит от других > записей. Так что новый genpkglist должен концептуально работать в два > прохода: сначала перекомпоновать pkglist.classic+bloat, а потом отжать > из него pkglist.classic. При такой схеме хранить таг CRPMTAG_FILEMTIME > можно только в pkglist.classic+bloat. > > Индекс pkglist.classic+bloat и псевдорепозиторий classic+bloat не > бесполезны, у них просматривается несколько применений: > > - сборочная система в любом случае генерирует bloat-репозиторий, > когда пакетов в таске больше одного; > - аналогично при сборке нескольких пакетов в хешере иногда возникают > неудовлетворенные файловые зависимости; для обхода этой проблемы можно > вручную скопировать пакет из репозитория в RPMS.hasher, но это тяжело > автоматизировать; вместо этого можно будет настроить хешер на > classic+bloat; > - генерация contents_index; > - отслеживание файловых конфликтов (об этом - в другой раз). Да, пожалуй что так. -- ldv