Новая версия DNF - 0.5.5

Вышел DNF 0.5.5. В этой версии изменений в самом DNF немного. Можно выделить лишь улучшение работы через proxy-серверы, в т.ч. и добавление нового функционал в API. Но особенно интересное изменение внесли не в DNF, а в низкоуровневые библиотеки.

Igor Gnatenko заметил странную разницу в том, как работает Yum и DNF c пакетами, которые разбили на несколько других, и разбирательство привело в итоге к серьезным изменениям не только в Fedora.

Сначала опишем суть проблемы. Предположим, что есть пакет, который по зависимостям тянет нечто, не нужное всем подряд. Например, у приложения есть плугин, слинкованный с некоей библиотекой, предоставляющий редко используемую функциональность (типичная ситуация с медиаплейерами, у которых есть плугины для многих форматов, в т.ч. и давно забытых). Если этот модуль не требуется для функционирования приложения, то порой имеет смысл выделить этот кусок в отдельный пакет. Это сокращает количество обязательных зависимостей.

Иногда бывает так, что эта функциональность была неотделимой, а спустя некоторое время стало возможным ее выделение в отдельный модуль. Например, недавно мы вам рассказывали, что в NetworkManager часть функциональности, не требующейся в виртуалках, выделили в отдельные модули. Таким образом появилась возможность разбить исходный пакет на несколько частей. Но как это правильно сделать?

Мы требуем, чтобы изменения не нарушали работу текущих инсталляций. Т.е. пользователь, у которого NetworkManager использовал функционал, выделенный в отдельную часть, не должен заметить нарушений работы. В его случае, после разбиения, при обновлении должны установиться и новые пакеты. Иначе используемый им функционал будет недоступен. Мы это делаем так - в случае разбиения, во все пакеты, полученные из старого "монолитного", мы добавляем Obsoletes: %{name} <= 1.2.3-1. Получается так - был пакет shiny, а получилось два новых - shiny и shiny-test (выделили часть из shiny сюда). Благодаря тому, что оба пакета теперь содержат Obsoletes, yum использует их оба для обновления со старого. Т.е. по команде sudo yum update shiny если yum увидит, что старый пакет чем-то Obsoletes, то он найдет все новые пакеты с такой директивой и поставит их все вместо старого. Если же старого пакета не было (установка с нуля), то Obsoletes нечего, и он будет ставить лишь главный пакет. Таким образом на старых инсталляциях функциональность будет доступна как и раньше, а на новых будет установлена только нужная часть.

DNF поступает не так. По команде sudo dnf update shiny он сначала вычислит дерево обновлений, чему удовлетворит лишь новый пакет shiny. И не будет нужды ставить sniny-test. Поэтому у пользователей пропадет функциональность, выделенная в пакет shiny-test. Т.е. Yum сначала вычисляет Obsoletes, затем обновляет, а DNF наоборот - сначала обновляет, затем вычисляет Obsoletes.

Нельзя сказать, что правильнее с т.з. теории, но использование стратегии из Yum точно лучше с т.з. практики. Иначе обновления (и переименования qt→qt3 и qt4→qt) потребуют большого количества ручных операций и двойных изменений в SPEC-файлах. После обсуждения с разработчиками openSUSE, поведение Yum было реализовано в libsolv и уже доступно в Fedora 21 и выше. К сожалению, Fedora 20 пока использует более старый GIt-снапшот, так что поведение DNF в ней не совпадает с Yum - мы вас предупредили!