Bug 46206 - расчистка устаревших зависимостей
Summary: расчистка устаревших зависимостей
Status: CLOSED WONTFIX
Alias: None
Product: Infrastructure
Classification: Infrastructure
Component: rdb.altlinux.org (show other bugs)
Version: unspecified
Hardware: all Linux
: P5 enhancement
Assignee: Danil Shein
QA Contact: Andrey Cherepanov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-05-22 15:27 MSK by Michael Shigorin
Modified: 2023-10-05 17:09 MSK (History)
2 users (show)

See Also:


Attachments
pkglist-query.cc им. glebfm@ (972 bytes, text/plain)
2023-09-05 18:00 MSK, Michael Shigorin
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Shigorin 2023-05-22 15:27:52 MSK
В альтовых репозиториях заведомо есть лишние зависимости (в основном видов Conflicts: да Obsoletes:, но могут быть и Provides:), которые увеличивают объём графа для разбора apt'ом.

Хорошо бы до них добраться и потихоньку начать собирать список на вычистку -- например, в branding-* такие зависимости генерируются десятками (в т.ч. на design-*, которые не используются со времён p6), но точно бывают не только там.

При этом к Provides: стоит относится внимательней -- в идеале бы простроить базу если не по архиву сизифа, то как минимум по всем (в т.ч. старым) стабильным веткам с тем, чтобы была возможность различить Provides:, появившийся при переименовании альтового пакета (или для другого альтового пакета, который мог дожить или не дожить до нынешних пор), и Provides:, вписанный для совместимости с чем-то вне альтовых репозиториев (таковы, например, пакеты *-preinstall).

Польза от расчистки зависимостей в плане сокращения времени работы apt ожидается весьма умеренная, но может оказаться даже измеримой (а сборка чрутов у нас задача очень частая на одной только сборочнице); `apt-cache pkgnames` сейчас по p10 насчитывает порядка 260 тыс. строк, из них более двухсот тысяч -- виртуальные Provides: (со скобками).

Количество Conflicts:/Obsoletes: сходу оценить не могу, но не удивлюсь, если окажется в районе тысяч/десятков тысяч (возможно, такие оценки делал msp@ в рамках работ по deepsolver).
Comment 1 Anton Zhukharev 2023-07-19 18:02:17 MSK
То есть хочется запрос, который для определенного репозитория выводит все зависимости (Requires/Provides/Conflicts/Obsoletes), которые не сопоставляются для заданного репозитория?

Например, A замещает (Obsoletes) B, но B при этом на текущий момент в репозитории никем не предоставляется (Provides) => такая B - зависимость для зачистки. Я правильно понимаю?

Насчёт Provides: я так понимаю, необходимо определить те зависимости (Provides), которые когда-то были кому-то нужны, но эти "кто-то" уже отсутствуют в заданном репозитории? А что если такие провайды используются где-нибудь при сборке образов (в таком случае можно случайно (или не совсем) сломать сборку образа)?
Comment 2 Michael Shigorin 2023-08-31 17:55:06 MSK
Прошу прощения, был в отпуске, сейчас вспомнил.

(Ответ для Anton Zhukharev на комментарий #1)
> То есть хочется запрос, который для определенного репозитория выводит
> все зависимости (Requires/Provides/Conflicts/Obsoletes), которые не
> сопоставляются для заданного репозитория?
Лучше бы не для данного, а со временнОй отсечкой (скажем, для сизифа это может быть пять лет или два бранча -- если что-то с конфликтом на него было в p8 и пропало в p9, к p11 можно считать такое нерелевантным, т.к. обновление с p8 должно проходить через _два_ бранча, где такого уже нет).

> Например, A замещает (Obsoletes) B, но B при этом на текущий момент
> в репозитории никем не предоставляется (Provides) => такая B - зависимость
> для зачистки. Я правильно понимаю?
По сути да -- с учётом того, что пакет B также предоставляет самого себя (B).

> Насчёт Provides: я так понимаю, необходимо определить те зависимости
> (Provides), которые когда-то были кому-то нужны, но эти "кто-то" уже
> отсутствуют в заданном репозитории? А что если такие провайды используются
> где-нибудь при сборке образов (в таком случае можно случайно (или не совсем)
> сломать сборку образа)?
По части Provides: всё в принципе сложней, поскольку они бывают и для внешних потребителей (например, совместимости с чем-нить для редхата или сузи), и для применения в дистрибутивных профилях.

Я бы тут начинал именно с Conflicts: и Obsoletes:, а к более нетехнически сложным Provides: переходил уже после решения задачи попроще (которая с учётом желательности именно временной отсечки сама по себе не особо тривиальна).  Полуавтоматизировать тут разве что кластеризацией результатов получится, поскольку нужные ручные обычно точечные, но не массовые (хотя и такое исключить нельзя).

Можно забрать условный http://ftp.altlinux.org/pub/distributions/archive/sisyphus/task/archive/_207/212240/daily/ той самой пятилетней давности и часть достоверных сведений вида "было, но пропало" получить из него (это не закроет ещё более древних "потеряшек", которых не было уже и тогда, но конфликты на которые стоят до сих пор -- например, design-graphics-education).

В принципе можно и все (или ежемесячные) daily/{x86_64,noarch}/base/pkglist.classic.xz позабирать да поразбирать, но мне кажется, что для такой задачки не в математическом, а в инженерном варианте решения это слишком.

И на самом деле может иметь смысл не городить итеративный огород, а предпринять единоразовый набег на конкретно взятый сизиф (в идеале до p11) и в дальнейшем подвязав к удалению пакета проверку на наличие Obsoletes:/Conflicts: на порождаемые из него бинарные подпакеты с уведомлением майнтейнеров тех пакетов, где эти O:/C: станут мусором (лишь бы эти уведомления не оказались спамом в плане частоты/многочисленности).
Comment 3 Danil Shein 2023-08-31 18:28:57 MSK
Не могу сказать, что мне полностью понятна цель и смысл расчистки "висячих/мёртвых" зависимостей пакетов в репозитории.

В БД мы храним метаинформацию извлекаемую из пакетов репозиториев, т.е. всё что есть в хэдереах .rpm.
У нас уже реализованы механизмы поиска и разрешения зависимостей пакетов для аналитических запросов и отображения этой информации на packages.altlinux.org.
При реализации этого функционала используется непосредственно часть функций из librpm (в части сравнения версий при разрешении зависимостей) и в определённых местах мы вынуждены были повторить поведение apt для получения результатов аналогичных таковым в работе с пакетами на реальной системе.

Тут главный момент, что apt при разрешении зависимостей помимо метаинформации из хэдеров rpm-пакетов использует ещё и свои индексные файлы, в частности для разрешения файловых зависимостей.

По моему скромному мнению, решать озвученную задачу (если я правильно понял, что собственно планируется сделать) нужно именно с использованием непосредственно функционала apt и rpm на каком то конкретном консистентном состоянии репозитория.

По поводу удаления Conflicts и Obsoletes - не случится ли так, что после "расчистки" это доставит массу радости пользователям, которые давно не обновлялись либо по какой-то причине сохраняют установленными в системе пакеты, которые уже удалены из текущего состояния репозитория?

Относительно удаления Provides, которые никто не хочет - а что будет, когда в репозиторий попадут новые пакеты или новые версии пакетов, которые зависят от "расчищенных" ранее зависимостей?

Ну и к цифрам: какое количество зависимостей из условны 250-300 тысяч таким образом удастся убрать? Есть какие то оценки результата, хотя бы примерные?
Comment 4 Michael Shigorin 2023-09-05 18:00:49 MSK
Created attachment 14340 [details]
pkglist-query.cc им. glebfm@

Спасибо за вопросы!  Постараюсь кратенько зафиксировать частичную выжимку сегодняшнего общения с практикантами по теме.

Из замеченных интересных особых случаев -- zoneminder: >3000 перловых Provides:, причём похоже на то, что нужны они только ему самому (похоже, надо AutoProv: no или как минимум noperl добавить).

(Ответ для Danil Shein на комментарий #3)
> Не могу сказать, что мне полностью понятна цель и смысл расчистки
> "висячих/мёртвых" зависимостей пакетов в репозитории.
Ускорение работы apt в первую очередь (в т.ч. для hasher => сборочницы, множитель -- _минимум_ сотни тысяч запусков; тут и секунда уже выгода).

> В БД мы храним метаинформацию извлекаемую из пакетов репозиториев,
> т.е. всё что есть в хэдереах .rpm.
Про pkglist.classic и pkglist-query в курсе, кстати? (прилагаю)
Или забираете инкрементально из заданий?
Это сводка заголовков пакетов из конкретного состояния репозитория.

> При реализации этого функционала используется непосредственно часть функций
> из librpm (в части сравнения версий при разрешении зависимостей) и в
> определённых местах мы вынуждены были повторить поведение apt для получения
> результатов аналогичных таковым в работе с пакетами на реальной системе.
Метаданные каждый раз поднимаете из файликов?  Посмотрите apt-pipe, когда-то Большаков писал, помнится -- его можно инициализировать при переходе на конкретное задание, дальше гонять команды по уже горячему состоянию.

> По моему скромному мнению, решать озвученную задачу (если я правильно понял,
> что собственно планируется сделать) нужно именно с использованием
> непосредственно функционала apt и rpm на каком то конкретном консистентном
> состоянии репозитория.
В целом да; об этом тоже сегодня поговорили с ребятами.

> По поводу удаления Conflicts и Obsoletes - не случится ли так, что после
> "расчистки" это доставит массу радости пользователям, которые давно не
> обновлялись либо по какой-то причине сохраняют установленными в системе
> пакеты, которые уже удалены из текущего состояния репозитория?
Вот потому и уточнил в comment 2 насчёт отсечки в пару бранчей; цитирую выработанную сегодня формулировку:

---
по тому, что точно было, но уже отсутствует:
возьмите http://ftp.altlinux.org/pub/distributions/ALTLinux/{4.0,4.1,p{5,6,7,8}}/branch/{noarch,x86_64}/base/pkglist.classic.xz и дёрните из них %name (возможно, и [%{providename}], но это уже по вкусу) — вычтя из этого сизифные [%{name}] и соотв. провайдесы, получите список того, что ГАРАНТИРОВАННО было И исчезло.

соответственно то, что C: или O: имя из такого списка — ГАРАНТИРОВАННО* "наш клиент"
---

То, чего _никогда_ не было -- скорее всего, или ошибка в спеке, или Provides: для внешнего пакета, которого в сизифе никогда не было и обычно никогда не будет (для _строгого_ ответа на этот вопрос надо разобрать метаданные всех заданий плюс все известные состояния репозиториев до транзакционной сборочницы, но математическая точность нам и не требуется покрмере на данном этапе).

Что до пользователей, которые давно не обновлялись (скажем, до сих пор на p7): так им сперва понадобится обновиться до промежуточных стабильных репозиториев, где эти C:/O: в наличии => вынос устаревших пакетов произойдёт на этой стадии, потому и предложен зазор в _два_ бранча (он останется неплохим даже после свежеответвлённого p11).

> Относительно удаления Provides, которые никто не хочет - а что будет, когда
> в репозиторий попадут новые пакеты или новые версии пакетов, которые зависят
> от "расчищенных" ранее зависимостей?
И как они попадут, если при этом будет попытка сгенерировать unmet?

Понятно, что количество "глупых" циклов "убрали-вернули" надо свести к минимуму, но у меня сходу даже иллюстрации рабочей к Вашему примеру подобрать не вышло.

> Ну и к цифрам: какое количество зависимостей из условны 250-300 тысяч таким
> образом удастся убрать? Есть какие то оценки результата, хотя бы примерные?
Порядка 1% даёт один zoneminder... помножьте на кол-во собираемых заданий (и ещё учтите, что в каждом из них сейчас минимум три запуска apt для хотя бы одного собираемого, а не удаляемого, пакета: hsh --query-repackage, собственно hsh и installcheck; может, и больше, но эти сходу вспомнил).

Думаю, несколько тысяч.  В плохом случае -- несколько десятков тысяч (это если майнтейнеры расслабились и генерят ненужные provides оптом, есть одна подозрительная на сей счёт подсистема).
Comment 5 Anton Farygin 2023-09-05 18:19:18 MSK
С zoneminder и его provides всё в порядке.
Возможно это надо вынести в отдельные перловые подпакеты, но это не вопрос этой задачи.
Comment 6 Anton Farygin 2023-09-05 18:23:20 MSK
и ответ Шигорину Мише на вопрос как кто и что грузит - там есть информация, про pkglist мы естественно в курсе:

https://git.altlinux.org/people/dshein/public/?p=altrepodb.git
Comment 7 Anton Farygin 2023-10-05 17:09:20 MSK
В целом задача выглядит странно я бы точно ей не советовал заниматься на этапе JOIN. 

Думаю что мы не будем делать такой функционал, т.к. всё это на усмотрение ментейнера и зависит от массы факторов, в том числе времени жизни такой "лишней" зависимости.