Если вы администрируете устройства с RHEL, Fedora или CentOS на борту то вы уже вводили команду dnf install огромное количество раз, и возможно никогда даже и не задумывались о том, что же там происходит после вызова этой команды. Нет, конечно понятное дело, что в итоге ставится нужный нам пакет, но вот как это происходит?

Установка пакета

Для примера мы хотим поставить пакет telnet. Для начала нужно понимать, что, когда мы говорим пакет telnet, мы как бы говорим о том, что нужно установить некий файл с расширением .rpm, если конкретнее что-то в стиле telnet-0.17-76.el8.x86_64.rpm.

Часто поэтому можно встретить словосочетание RPM пакет, что сразу говорит о том, что этот пакет предназначен для RHEL, Fedora или CentOS.

sudo dnf install telnet

Команда выше перед тем как поставить пакет должна еще его найти, обычно ищет в интернете. Также вы можете устанавливать пакеты используя команду rpm, но сделать это с использованием dnf или yum куда легче порой быстрее.

yum или dnf?

Я думаю уже ни для кого ни секрет что эти 2 команды по сути выполняют одно и тоже. Но этот абзац я включил в статью так как до этого момента никогда не задумывался как расшифровывается yum и dnf.

  • yum - Yellowdog Updater, Modified
  • dnf - Dandified yum

Yum появился раньше dnf, но на данный момент dnf является менеджером пакетов по умолчанию, но сам yum никто никуда еще не убирал.

Как находятся пакеты?

Как мы уже говорили вначале нужно найти необходимый нам пакет. Для этого dnf обращается в начале к файлу манифестов репозитория (repository manifest file), который должен находится в ОС. У самого dnf этот файл также хранится в кэше, что ускоряет установку пакета. Но если информацию о необходимом пакете в кэше найти не удалось, то поиски продолжатся в файлах с расширением .repo в директории /etc/yum.repos.d. В этих файлах dnf ищет url для того чтобы обратится к хранилищу пакетов (репозиторий) ассоциированных с файлом репозитория .repo.

Кэш

Для примера давайте сперва очистим весь наш кэш и попробуем снова установить пакет telnet. В итоге мы должны увидеть процесс обновления кэша.

  1. Для начала проверим что у нас в директории /var/cache/dnf есть файлы кэша для всех наших репозиториев.
sudo dnf repolist
appstream                                                       CentOS Stream 8 - AppStream
baseos                                                          CentOS Stream 8 - BaseOS
extras                                                          CentOS Stream 8 - Extras
sudo ls -la /var/cache/dnf | grep solv
-rw-r--r--.  1 root root 21152015 Oct 28 17:50 appstream-filenames.solvx
-rw-r--r--.  1 root root  6069505 Oct 28 17:50 appstream.solv
-rw-r--r--.  1 root root 12148821 Oct 28 17:50 baseos-filenames.solvx
-rw-r--r--.  1 root root  5945363 Oct 28 17:50 baseos.solv
-rw-r--r--.  1 root root     1787 Oct 28 17:50 extras-filenames.solvx
-rw-r--r--.  1 root root    27929 Oct 28 17:50 extras.solv
  1. Теперь очистим наш кэш и снова проверим наличие файлов.
sudo dnf clean dbcache
sudo ls -la /var/cache/dnf | grep solv
  1. И теперь попробуем установить пакет telnet.
sudo dnf install telnet

Согласитесь что теперь команда установки ищет наш пакет гораздо дольше чем ранее, всё это происходит из-за того что наш кэш пуст и нужно добавить туда информацию из репозиториев, указанных в /etc/yum.repos.d.

Кэш и новый репозиторий

Также каждый раз когда мы вызываем dnf install у нас проверяется наличие нового файла репозитория в директории /etc/yum.repos.d, точнее наличие метаданных для репозитория. Для примера поставим пакет epel-release, который добавит нам новый репозиторий.

sudo dnf install -y epel-release
ls -la /etc/yum.repos.d | grep epel
-rw-r--r--.  1 root root  1417 Jun  8  2021 epel.repo

Теперь снова попробуем поставить пакет telnet, информация про который уже есть у нас в кэше.

sudo dnf install telnet
Extra Packages for Enterprise Linux 8 - x86_64                                                                   4.8 MB/s |  13 MB     00:02
Extra Packages for Enterprise Linux Modular 8 - x86_64                                                           611 kB/s | 733 kB     00:01

Тут вы можете немного запутаться и посчитать что тут происходит обновление кэша и то что я говорил в начале что сперва проверяется кэш может показаться враньём. Но дело в том, что тут идёт загрузка метаданных. Но справедливости ради сразу обновится и кэш потому что сам кэш генерируется на основе этих метаданных. Вот такая вот ситуация оно вроде как бы да, а вроде и нет.

Метаданные описывают, какие пакеты можно найти в репозитории, различные атрибуты каждого пакета, списки файлов и каталогов, а также информацию журнала изменений.

sudo ls -la /var/cache/dnf | grep epel
drwxr-xr-x.  3 root root       42 Oct 28 16:49 epel-6519ee669354a484

Но мы могли избежать этого просто указав опцию -C, которая означает что искать информацию о пакете нужно только в уже существующем кэше.

Репозитории

По сути так или иначе вся информация о наличие того или иного пакета берётся с файлов репозитория, а точнее с URL указанного в файле репозитория. Просто чтобы каждый раз не скачивать информацию о всех пакетах с этих url и существует кэш.

Dnf также пробегается по каждому файлу .rpm и ищет там необходимый пакет до первого совпадения.

Для того чтобы посмотреть список всех наших репозиториев используется следующая команда:

sudo dnf repolist
appstream                                           CentOS Stream 8 - AppStream
baseos                                              CentOS Stream 8 - BaseOS
extras                                              CentOS Stream 8 - Extras

Собственно команда выше просто пробегает по файлам .repo в директории /etc/yum.repos.d/ и вытаскивает оттуда repo id и repo name, но только если репозиторий активен (enabled=1).

Т.е. если у нас не будет нужного репозитория в системе, то и поставить нужны пакет мы не сможем, если только не выкачаем файл .rpm вручную, но это уже совсем другая история. Также при установке пакета из вручную с использованием файла .rpm все зависимости также придётся выкачивать и ставить вручную.

В итоге

  1. При установке пакета сперва смотрится кэш
  2. Если нет в кэше нет информации о пакете (например, устаревший кэш) проверяются файлы репозитория и также обновляется кэш
  3. Пакет выкачивается с url ассоциированного с репозиторием
  4. Происходит установка