<?xml version="1.0" encoding="UTF-8" ?>

<bugzilla version="5.2"
          urlbase="https://bugzilla.altlinux.org/"
          
          maintainer="jenya@basealt.ru"
>

    <bug>
          <bug_id>46206</bug_id>
          
          <creation_ts>2023-05-22 15:27:52 +0300</creation_ts>
          <short_desc>расчистка устаревших зависимостей</short_desc>
          <delta_ts>2026-02-23 21:44:44 +0300</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>2</classification_id>
          <classification>Infrastructure</classification>
          <product>Infrastructure</product>
          <component>rdb.altlinux.org</component>
          <version>unspecified</version>
          <rep_platform>all</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>CLOSED</bug_status>
          <resolution>WONTFIX</resolution>
          
          <see_also>https://bugzilla.altlinux.org/show_bug.cgi?id=47849</see_also>
    
    <see_also>https://bugzilla.altlinux.org/show_bug.cgi?id=47852</see_also>
    
    <see_also>https://bugzilla.altlinux.org/show_bug.cgi?id=57977</see_also>
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P5</priority>
          <bug_severity>enhancement</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Michael Shigorin">mike</reporter>
          <assigned_to name="Danil Shein">dshein</assigned_to>
          <cc>ancieg</cc>
    
    <cc>rider</cc>
          
          <qa_contact name="Andrey Cherepanov">cas</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>226197</commentid>
    <comment_count>0</comment_count>
    <who name="Michael Shigorin">mike</who>
    <bug_when>2023-05-22 15:27:52 +0300</bug_when>
    <thetext>В альтовых репозиториях заведомо есть лишние зависимости (в основном видов Conflicts: да Obsoletes:, но могут быть и Provides:), которые увеличивают объём графа для разбора apt&apos;ом.

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

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

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

Количество Conflicts:/Obsoletes: сходу оценить не могу, но не удивлюсь, если окажется в районе тысяч/десятков тысяч (возможно, такие оценки делал msp@ в рамках работ по deepsolver).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>230027</commentid>
    <comment_count>1</comment_count>
    <who name="Anton Zhukharev">ancieg</who>
    <bug_when>2023-07-19 18:02:17 +0300</bug_when>
    <thetext>То есть хочется запрос, который для определенного репозитория выводит все зависимости (Requires/Provides/Conflicts/Obsoletes), которые не сопоставляются для заданного репозитория?

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

Насчёт Provides: я так понимаю, необходимо определить те зависимости (Provides), которые когда-то были кому-то нужны, но эти &quot;кто-то&quot; уже отсутствуют в заданном репозитории? А что если такие провайды используются где-нибудь при сборке образов (в таком случае можно случайно (или не совсем) сломать сборку образа)?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>232285</commentid>
    <comment_count>2</comment_count>
    <who name="Michael Shigorin">mike</who>
    <bug_when>2023-08-31 17:55:06 +0300</bug_when>
    <thetext>Прошу прощения, был в отпуске, сейчас вспомнил.

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

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

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

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

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

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

И на самом деле может иметь смысл не городить итеративный огород, а предпринять единоразовый набег на конкретно взятый сизиф (в идеале до p11) и в дальнейшем подвязав к удалению пакета проверку на наличие Obsoletes:/Conflicts: на порождаемые из него бинарные подпакеты с уведомлением майнтейнеров тех пакетов, где эти O:/C: станут мусором (лишь бы эти уведомления не оказались спамом в плане частоты/многочисленности).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>232287</commentid>
    <comment_count>3</comment_count>
    <who name="Danil Shein">dshein</who>
    <bug_when>2023-08-31 18:28:57 +0300</bug_when>
    <thetext>Не могу сказать, что мне полностью понятна цель и смысл расчистки &quot;висячих/мёртвых&quot; зависимостей пакетов в репозитории.

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

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

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

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

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

Ну и к цифрам: какое количество зависимостей из условны 250-300 тысяч таким образом удастся убрать? Есть какие то оценки результата, хотя бы примерные?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>232581</commentid>
    <comment_count>4</comment_count>
      <attachid>14340</attachid>
    <who name="Michael Shigorin">mike</who>
    <bug_when>2023-09-05 18:00:49 +0300</bug_when>
    <thetext>Created attachment 14340
pkglist-query.cc им. glebfm@

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

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

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

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

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

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

&gt; По поводу удаления Conflicts и Obsoletes - не случится ли так, что после
&gt; &quot;расчистки&quot; это доставит массу радости пользователям, которые давно не
&gt; обновлялись либо по какой-то причине сохраняют установленными в системе
&gt; пакеты, которые уже удалены из текущего состояния репозитория?
Вот потому и уточнил в 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: имя из такого списка — ГАРАНТИРОВАННО* &quot;наш клиент&quot;
---

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

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

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

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

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

Думаю, несколько тысяч.  В плохом случае -- несколько десятков тысяч (это если майнтейнеры расслабились и генерят ненужные provides оптом, есть одна подозрительная на сей счёт подсистема).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>232583</commentid>
    <comment_count>5</comment_count>
    <who name="Anton Farygin">rider</who>
    <bug_when>2023-09-05 18:19:18 +0300</bug_when>
    <thetext>С zoneminder и его provides всё в порядке.
Возможно это надо вынести в отдельные перловые подпакеты, но это не вопрос этой задачи.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>232584</commentid>
    <comment_count>6</comment_count>
    <who name="Anton Farygin">rider</who>
    <bug_when>2023-09-05 18:23:20 +0300</bug_when>
    <thetext>и ответ Шигорину Мише на вопрос как кто и что грузит - там есть информация, про pkglist мы естественно в курсе:

https://git.altlinux.org/people/dshein/public/?p=altrepodb.git</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>234416</commentid>
    <comment_count>7</comment_count>
    <who name="Anton Farygin">rider</who>
    <bug_when>2023-10-05 17:09:20 +0300</bug_when>
    <thetext>В целом задача выглядит странно я бы точно ей не советовал заниматься на этапе JOIN. 

Думаю что мы не будем делать такой функционал, т.к. всё это на усмотрение ментейнера и зависит от массы факторов, в том числе времени жизни такой &quot;лишней&quot; зависимости.</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>14340</attachid>
            <date>2023-09-05 18:00:49 +0300</date>
            <delta_ts>2023-09-05 18:00:49 +0300</delta_ts>
            <desc>pkglist-query.cc им. glebfm@</desc>
            <filename>pkglist-query.cc</filename>
            <type>text/plain</type>
            <size>972</size>
            <attacher name="Michael Shigorin">mike</attacher>
            
              <data encoding="base64">Ly8gZysrIHBrZ2xpc3QtcXVlcnkuY2MgLW8gcGtnbGlzdC1xdWVyeSAtbHJwbSAtbHJwbWlvCgoj
aW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHJwbS9oZWFkZXIuaD4KCmludCBtYWluKGludCBh
cmdjLCBjaGFyICphcmd2W10pCnsKICAgIGNvbnN0IGNoYXIgKnByb2duYW1lID0gYXJndlswXTsK
ICAgIGlmIChhcmdjIDwgMykgewoJZnByaW50ZihzdGRlcnIsICJVc2FnZTogJXMgPGZvcm1hdD4g
PHBrZ2xpc3Q+Li4uXG4iLCBwcm9nbmFtZSk7CglyZXR1cm4gMjsKICAgIH0KICAgIGNvbnN0IGNo
YXIgKmZvcm1hdCA9IGFyZ3ZbMV07CiAgICBpbnQgcmMgPSAwOwogICAgY29uc3QgY2hhciAqcGtn
bGlzdDsKICAgIGludCBpeCA9IDI7CiAgICB3aGlsZSAoKHBrZ2xpc3QgPSBhcmd2W2l4KytdKSAh
PSBOVUxMKSB7CglGRF90IEZkID0gRm9wZW4ocGtnbGlzdCwgInIudWZkaW8iKTsKCWlmIChGZXJy
b3IoRmQpKSB7CgkgICAgZnByaW50ZihzdGRlcnIsICIlczogJXM6ICVzXG4iLCBwcm9nbmFtZSwg
cGtnbGlzdCwgRnN0cmVycm9yKEZkKSk7CgkgICAgcmMgPSAxOwoJICAgIGNvbnRpbnVlOwoJfQoJ
SGVhZGVyIGg7Cgl3aGlsZSAoKGggPSBoZWFkZXJSZWFkKEZkLCBIRUFERVJfTUFHSUNfWUVTKSkg
IT0gTlVMTCkgewoJICAgIGNvbnN0IGNoYXIgKmVyciA9ICJ1bmtub3duIGVycm9yIjsKCSAgICBj
aGFyICpzdHIgPSBoZWFkZXJGb3JtYXQoaCwgZm9ybWF0LCAmZXJyKTsKCSAgICBpZiAoc3RyID09
IE5VTEwpIHsKCQlyYyA9IDE7CgkJZnByaW50ZihzdGRlcnIsICIlczogJXM6ICVzXG4iLCBwcm9n
bmFtZSwgcGtnbGlzdCwgZXJyKTsKCSAgICB9CgkgICAgZWxzZSB7CgkJZnB1dHMoc3RyLCBzdGRv
dXQpOwoJCWZyZWUoc3RyKTsKCSAgICB9CgkgICAgaGVhZGVyRnJlZShoKTsKCX0KCUZjbG9zZShG
ZCk7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0KCi8vIGV4OnNldCB0cz04IHN0cz00IHN3PTQgbm9l
dDoK
</data>

          </attachment>
      

    </bug>

</bugzilla>