Пакет для Arch Linux
Пакет для Arch Linux

В последнее время вырос интерес сообщества к дистрибутиву Arch Linux: он лёг в основу SteamOS, его стал использовать PewDiePie, создатель Ruby on Rails сделал свою сборку. Хакеры тоже активизировались и начали распространять вредоносные пакеты в Arch User Repository. Часто при обсуждении дистрибутива упоминается его пакетный менеджер — pacman. Информацию о его использовании можно легко найти в Сети. Но что происходит на самом деле, когда мы выполняем sudo pacman -S firefox или sudo pacman -Syu?

В этой статье детально изучим работу с пакетами в Arch Linux: что они из себя представляют, как создаются и распространяются, чем мета-пакет отличается от группы пакетов и какую информацию о них хранит pacman. Писал с расчётом на тех, кто не боится командной строки. При этом если вам интересно, но нет установленного Arch под рукой — не беда: все команды можно выполнить в Docker контейнере, инструкция прилагается.

Вам пакет нужен?

Для установки программ в Linux принято использовать специальную программу — пакетный менеджер. Например вместо скачивания Firefox с официального сайта, можно написать в терминале sudo pacman -S firefox и браузер будет установлен в вашу систему. Pacman — название менеджера пакетов Arch Linux, сокращение от Package Manager.

Использование пакетного менеджера открывает дополнительные возможности по управлению программами:

  • Массовая установка, обновление и удаление программ.

  • Поиск программы по описанию.

  • Получение списка файлов, которые программа установливает в систему.

Давайте разберёмся, что из себя представляют пакеты, на примере программы lazygit.

Если вы не используете Arch Linux

Если у вас нет установленного Arch Linux, то легче всего выполнять команды в контейнере:

  1. Запускаем в фоне контейнер с официальным образом Arch:
    docker run --name arch -d archlinux sleep inf

  2. Открываем консоль пользователя root:
    docker exec -it arch bash

  3. Создаём себе пользователя user с правами суперпользователя и выходим из контейнера.

    pacman -Syu sudo
    useradd -m user
    echo 'user ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/00_user
    exit
  4. Открываем консоль от имени нашего пользователя
    docker exec -w /home/user -u user -it arch bash
    Все дальнейшие команды выполняем в ней.

Скачаем пакет lazygit без его установки:
sudo pacman -Sw lazygit

Посмотрим, какие файлы скачал pacman:

cd /var/cache/pacman/pkg
ls | grep lazygit

В выводе будет два файла (версия на момент прочтения статьи может быть новее):

  • lazygit-0.54.0-1-x86_64.pkg.tar.zst — пакет в виде архива, сжатого zstd.

  • lazygit-0.54.0-1-x86_64.pkg.tar.zst.sig — файл с подписью. Позволяет пакетному менеджеру проверить, можно ли доверять пакету.

Посмотрим содержимое архива:
tar tf lazygit-*-x86_64.pkg.tar.zst

Вывод
.BUILDINFO
.MTREE
.PKGINFO
usr/
usr/bin/
usr/bin/lazygit
usr/share/
usr/share/doc/
usr/share/doc/lazygit/
usr/share/doc/lazygit/Config.md
usr/share/doc/lazygit/Custom_Command_Keybindings.md
usr/share/doc/lazygit/Custom_Pagers.md
usr/share/doc/lazygit/Fixup_Commits.md
usr/share/doc/lazygit/README.md
usr/share/doc/lazygit/Range_Select.md
usr/share/doc/lazygit/Searching.md
usr/share/doc/lazygit/Stacked_Branches.md
usr/share/doc/lazygit/Undoing.md
usr/share/doc/lazygit/dev/
usr/share/doc/lazygit/dev/Busy.md
usr/share/doc/lazygit/dev/Codebase_Guide.md
usr/share/doc/lazygit/dev/Demo_Recordings.md
usr/share/doc/lazygit/dev/Find_Base_Commit_For_Fixup_Design.md
usr/share/doc/lazygit/dev/Integration_Tests.md
usr/share/doc/lazygit/dev/Profiling.md
usr/share/doc/lazygit/dev/README.md
usr/share/doc/lazygit/keybindings/
usr/share/doc/lazygit/keybindings/Custom_Keybindings.md
usr/share/doc/lazygit/keybindings/Keybindings_en.md
usr/share/doc/lazygit/keybindings/Keybindings_ja.md
usr/share/doc/lazygit/keybindings/Keybindings_ko.md
usr/share/doc/lazygit/keybindings/Keybindings_nl.md
usr/share/doc/lazygit/keybindings/Keybindings_pl.md
usr/share/doc/lazygit/keybindings/Keybindings_pt.md
usr/share/doc/lazygit/keybindings/Keybindings_ru.md
usr/share/doc/lazygit/keybindings/Keybindings_zh-CN.md
usr/share/doc/lazygit/keybindings/Keybindings_zh-TW.md
usr/share/licenses/
usr/share/licenses/lazygit/
usr/share/licenses/lazygit/LICENSE

Для начала обратим внимание, что структура архива повторяет структуру файловой системы. Например в архиве есть файл usr/bin/lazygit - исполняемый файл программы. При установке он будет распакован в /usr/bin/lazygit .

Кроме того в архиве есть 3 особых файла, из которых pacman извлекает информацию о пакете:

.PKGINFO — содержит основную информацию о пакете.

.PKGINFO
# Generated by makepkg 7.0.0
# using fakeroot version 1.37.1.2
pkgname = lazygit
pkgbase = lazygit
xdata = pkgtype=pkg
pkgver = 0.54.0-1
pkgdesc = Simple terminal UI for git commands
url = https://github.com/jesseduffield/lazygit
builddate = 1754152891
packager = Caleb Maclennan <alerque@archlinux.org>
size = 22296659
arch = x86_64
license = MIT
depend = git
depend = glibc
makedepend = go
  • pkgname — название пакета

  • pkgver — версия пакета

  • depend — названия других пакетов, которые требуются для корректной работы программы

  • makedepend — названия пакетов, которые нужны были при сборке, но не нужны для выполнения. Здесь это компилятор Go т.к. программа написана на этом языке.

  • size — размер распакованных файлов пакета в байтах.

.BUILDINFO — содержит описание окружения, в котором собирался пакет. Используется для воспроизводимых сборок.

.BUILDINFO
format = 2
pkgname = lazygit
pkgbase = lazygit
pkgver = 0.54.0-1
pkgarch = x86_64
pkgbuild_sha256sum = b70731ff6f079e8247eaaf4f1c8e087ff8b2880dcdf889b8f3c97388fb854686
packager = Caleb Maclennan <alerque@archlinux.org>
builddate = 1754152891
builddir = /build
startdir = /startdir
buildtool = devtools
buildtoolver = 1:1.3.2-1-any
buildenv = !distcc
buildenv = color
buildenv = !ccache
buildenv = check
buildenv = !sign
options = strip
options = docs
options = !libtool
options = !staticlibs
options = emptydirs
options = zipman
options = purge
options = debug
options = lto
installed = acl-2.3.2-1-x86_64
installed = archlinux-keyring-20250716-1-any
installed = attr-2.5.2-1-x86_64
installed = audit-4.0.5-1-x86_64
installed = autoconf-2.72-1-any
installed = automake-1.18.1-1-any
installed = base-devel-1-2-any
installed = bash-5.3.3-2-x86_64
installed = binutils-2.45+r8+g09be88bfb653-1-x86_64
installed = bison-3.8.2-8-x86_64
installed = brotli-1.1.0-3-x86_64
installed = bzip2-1.0.8-6-x86_64
installed = ca-certificates-20240618-1-any
installed = ca-certificates-mozilla-3.114-1-x86_64
installed = ca-certificates-utils-20240618-1-any
installed = coreutils-9.7-1-x86_64
installed = cryptsetup-2.8.0-1-x86_64
installed = curl-8.15.0-1-x86_64
installed = db5.3-5.3.28-5-x86_64
installed = dbus-1.16.2-1-x86_64
installed = dbus-broker-37-2-x86_64
installed = dbus-broker-units-37-2-x86_64
installed = dbus-units-37-2-x86_64
installed = debugedit-5.2-1-x86_64
installed = device-mapper-2.03.34-1-x86_64
installed = diffutils-3.12-2-x86_64
installed = e2fsprogs-1.47.3-1-x86_64
installed = expat-2.7.1-1-x86_64
installed = fakeroot-1.37.1.2-1-x86_64
installed = file-5.46-4-x86_64
installed = filesystem-2025.05.03-1-any
installed = findutils-4.10.0-3-x86_64
installed = flex-2.6.4-5-x86_64
installed = gawk-5.3.2-1-x86_64
installed = gc-8.2.8-2-x86_64
installed = gcc-15.1.1+r500+gb1b8d8ce3eea-1-x86_64
installed = gcc-libs-15.1.1+r500+gb1b8d8ce3eea-1-x86_64
installed = gdbm-1.25-1-x86_64
installed = gettext-0.26-1-x86_64
installed = git-2.50.1-3-x86_64
installed = glib2-2.84.3-1-x86_64
installed = glibc-2.42+r3+gbc13db739377-1-x86_64
installed = gmp-6.3.0-2-x86_64
installed = gnulib-l10n-20241231-1-any
installed = gnupg-2.4.8-1-x86_64
installed = gnutls-3.8.10-1-x86_64
installed = go-2:1.24.5-1-x86_64
installed = gpgme-2.0.0-1-x86_64
installed = grep-3.12-2-x86_64
installed = groff-1.23.0-7-x86_64
installed = guile-3.0.10-1-x86_64
installed = gzip-1.14-2-x86_64
installed = hwdata-0.397-1-any
installed = iana-etc-20250612-1-any
installed = icu-76.1-1-x86_64
installed = jansson-2.14.1-1-x86_64
installed = json-c-0.18-2-x86_64
installed = kbd-2.8.0-1-x86_64
installed = keyutils-1.6.3-3-x86_64
installed = kmod-34.2-1-x86_64
installed = krb5-1.21.3-2-x86_64
installed = leancrypto-1.5.1-1-x86_64
installed = libarchive-3.8.1-1-x86_64
installed = libassuan-3.0.0-1-x86_64
installed = libcap-2.76-1-x86_64
installed = libcap-ng-0.8.5-3-x86_64
installed = libelf-0.193-3-x86_64
installed = libevent-2.1.12-4-x86_64
installed = libffi-3.5.1-1-x86_64
installed = libgcrypt-1.11.1-1-x86_64
installed = libgpg-error-1.55-1-x86_64
installed = libidn2-2.3.7-1-x86_64
installed = libisl-0.27-1-x86_64
installed = libksba-1.6.7-2-x86_64
installed = libldap-2.6.10-2-x86_64
installed = libmpc-1.3.1-2-x86_64
installed = libnghttp2-1.66.0-1-x86_64
installed = libnghttp3-1.11.0-1-x86_64
installed = libnsl-2.0.1-1-x86_64
installed = libp11-kit-0.25.5-1-x86_64
installed = libpsl-0.21.5-2-x86_64
installed = libsasl-2.1.28-5-x86_64
installed = libseccomp-2.5.6-1-x86_64
installed = libsecret-0.21.7-1-x86_64
installed = libssh2-1.11.1-1-x86_64
installed = libsysprof-capture-48.0-6-x86_64
installed = libtasn1-4.20.0-1-x86_64
installed = libtirpc-1.3.6-2-x86_64
installed = libtool-2.5.4+r23+g5b582aed-2-x86_64
installed = libunistring-1.3-1-x86_64
installed = libusb-1.0.29-1-x86_64
installed = libverto-0.3.2-5-x86_64
installed = libxcrypt-4.4.38-1-x86_64
installed = libxml2-2.14.5-1-x86_64
installed = linux-api-headers-6.16-1-x86_64
installed = lmdb-0.9.33-1-x86_64
installed = lz4-1:1.10.0-2-x86_64
installed = m4-1.4.20-1-x86_64
installed = make-4.4.1-2-x86_64
installed = mpfr-4.2.2-1-x86_64
installed = ncurses-6.5-4-x86_64
installed = nettle-3.10.2-1-x86_64
installed = npth-1.8-1-x86_64
installed = openssl-3.5.1-1-x86_64
installed = p11-kit-0.25.5-1-x86_64
installed = pacman-7.0.0.r6.gc685ae6-6-x86_64
installed = pacman-mirrorlist-20250702-2-any
installed = pam-1.7.1-1-x86_64
installed = pambase-20250719-1-any
installed = patch-2.8-1-x86_64
installed = pcre2-10.45-1-x86_64
installed = perl-5.42.0-1-x86_64
installed = perl-error-0.17030-2-any
installed = perl-mailtools-2.22-2-any
installed = perl-timedate-2.33-8-any
installed = pinentry-1.3.1-5-x86_64
installed = pkgconf-2.5.1-1-x86_64
installed = popt-1.19-2-x86_64
installed = readline-8.3.001-1-x86_64
installed = sed-4.9-3-x86_64
installed = shadow-4.18.0-1-x86_64
installed = sqlite-3.50.3-1-x86_64
installed = sudo-1.9.17.p1-1-x86_64
installed = systemd-257.7-2-x86_64
installed = systemd-libs-257.7-2-x86_64
installed = tar-1.35-2-x86_64
installed = texinfo-7.2-1-x86_64
installed = tpm2-tss-4.1.3-1-x86_64
installed = tzdata-2025b-1-x86_64
installed = util-linux-2.41.1-1-x86_64
installed = util-linux-libs-2.41.1-1-x86_64
installed = which-2.23-1-x86_64
installed = xxhash-0.8.3-1-x86_64
installed = xz-5.8.1-1-x86_64
installed = zlib-1:1.3.1-2-x86_64
installed = zlib-ng-2.2.4-1-x86_64
installed = zstd-1.5.7-2-x86_64

.MTREE — содержит информацию о файловой структуре пакета. Используется для проверки целостности. Бинарный, поэтому не привожу его.

При установке/обновлении/удалении некоторых пакетов требуется выполнить тот или иной скрипт. В таком случае в пакете будет присутствовать файл .INSTALL с соответствующими командами.

Со структурой пакетов познакомились, теперь разберёмся как pacman управляет ими на наших устройствах.

Где живёт граф Пакетов

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

Наивным подходом к разрешению зависимостей было бы:

  1. Скачать пакет

  2. Распаковать

  3. Считать зависимости из .PKGINFO

  4. Выполнить пункт 1. для каждой зависимости, которая ещё не установлена

Этот подход формально решает проблему, но намного лучше знать граф зависимостей заранее, без скачивания пакетов. Вот лишь пара примеров, где это позволяет существенно улучшить пользовательский опыт:

  • Зная граф зависимостей заранее, можно по максимуму скачивать пакеты параллельно, лучше утилизируя сеть. Pacman использует параллельное скачивание, настраивается параметром ParallelDownloads в /etc/pacman.conf

  • Некоторые пакеты могут конфликтовать с другими пакетами. Если знать граф зависимостей заранее, то можно обнаружить конфликт, не скачивая пакетов.

Поэтому pacman скачивает сжатую базу пакетов с сервера. Правильнее даже сказать базы т.к. их может быть несколько, но об этом чуть позже. Они располагаются в директории /var/lib/pacman/sync и имеют названия, оканчивающиеся на .db.

Давайте посмотрим содержимое базы extra.db (да, это просто архив):

tar tf /var/lib/pacman/sync/extra.db

Вывод будет вида

0ad-a27.1-1/
0ad-a27.1-1/desc
0ad-data-a27.1-1/
0ad-data-a27.1-1/desc

Т.е. для каждого пакета хранится один файл с описанием.

lazygit-0.54.0-1/desc
%FILENAME%
lazygit-0.54.0-1-x86_64.pkg.tar.zst

%NAME%
lazygit

%BASE%
lazygit

%VERSION%
0.54.0-1

%DESC%
Simple terminal UI for git commands

%CSIZE%
6384337

%ISIZE%
22296659

%SHA256SUM%
1997ad5f9705a4ece8ec260c7d9b55915acf4409a7baf92109e7fd429e64206a

%PGPSIG%
iQIzBAABCgAdFiEEsNZSlUdmBrcfDG+CqF6BHrTKLggFAmiOQHEACgkQqF6BHrTKLgjRtA/+MiG7hlx+1Pqlt6ZsxjHDsPhoCa2JRzvdX1frq4HbkfgMkSDhMoGEsCAF8J+G3NqQ0YdPdGbgQFlBOWzoE07YA+EBFFkKpt3aDCeBveaBX2Mi0iHPWfIGteVSXaVqAbEkFp44sIO4UPJm9eBm71YuKZEkzvaBryB9spKiZskCp9CyQkfstMwjSrP1tTJVzEQschKr98cHzk56br49kpc7qVbYDWwm/MGgrLA6syph+eP7uB09FZseF7oOOoy8f36/DXHPU8LLAlVeECDv1hhmoGkXLdEl7YLk4GrV6Ad01aBxKQ7kYeS6nioqe+PWPWTFVEmRN1kFyANg3xZ8cRXO6gvgglYeWTs+6xUZt4KZebfOs5lK8ii1EMyFV0syn7IaW/jaET/Z5arD+F5YanFShgOCa62uRJxfuab1LNZoYp1i9oOgWwzq+OrHMYqcTGCqy7i2TYYj4VTVxi3BjVBD6g4DjrHxLq86ndn60Zsn19AZ9PegJBplJ2SysJIWfYupi3char8UzZFaxnWSvvJHnmN/XhP4mI9h3PxqCNWOuXmEsniYZfjDS7dZXbUfG/9q0L8THx/TLGq9nXpPDqH2/bt1f7H7SKtf3FD+fD1779YhCSPYeynjLipbbwn0fXmQZzdMiM+c5i6IlZliNVjWQClFm50tWR6d+Umkh9aKVog=

%URL%
https://github.com/jesseduffield/lazygit

%LICENSE%
MIT

%ARCH%
x86_64

%BUILDDATE%
1754152891

%PACKAGER%
Caleb Maclennan <alerque@archlinux.org>

%DEPENDS%
git
glibc

%MAKEDEPENDS%
go

Если посмотреть его содержимое, то оно чем-то напомнит .PKGINFO , но имеет некоторые дополнительные поля о файле с архивом:

  • CSIZE — размер сжатого архива. Благодаря этой информации pacman может до установки пакета определить размер загрузки.

  • SHA256SUM — контрольная сумма для проверки целостности.

  • PGPSIG — цифровая подпись в base64 для проверки, стоит ли доверять этому пакету.

Следует обратить внимание, что в файлах desc хранится лишь общий размер файлов, но не хранится список файлов. Зачем он может понадобится?

Например мы увидели в Сети как кто-то использует команду nslookup, но пакета с таким названием нет. Как узнать, в каком пакете есть такая программа? Мы знаем, что программы устанавливаются в директорию /usr/bin/ . Поэтому выполняем команду
pacman -F /usr/bin/nslookup

Но что-то не так:

warning: database file for 'core' does not exist (use '-Fy' to download)
warning: database file for 'extra' does not exist (use '-Fy' to download)

Дело в том, что список файлов хранится в отдельной базе. Чтобы её скачать надо выполнить
sudo pacman -Fy

После этого
pacman -F /usr/bin/nslookup
вернёт нам название пакета, в котором содержится программа nslookup:
usr/bin/nslookup is owned by extra/bind 9.20.11-1

Теперь мы знаем, что она является частью пакета bind, проверим:

sudo pacman -S bind
nslookup habr.com

И действительно, получаем

Server:         192.168.1.1
Address:        192.168.1.1#53

Non-authoritative answer:
Name:   habr.com
Address: 178.248.237.68

Посмотрим, что изменилось в директории с базами:
ls /var/lib/pacman/sync

core.db  core.files  extra.db  extra.files

В файлах .files находятся списки файлов в пакетах. По умолчанию с сервера скачиваются только файлы .db, а чтобы скачать .files надо выполнить sudo pacman -Fy.

Теперь разберёмся, что за core и extra. В Arch Linux официальные пакеты разделены на репозитории с разными правилами включения и тестирования пакетов.

  • core содержит критические компоненты системы, такие как загрузчики и ядра. Пакеты тщательно тестируются прежде чем туда попасть.

  • В репозитории extra размещены менее критические компоненты.

  • Репозиторий multilib содержит 32-битные пакеты (например Steam). По умолчанию он не используется, но его можно включить в /etc/pacman.conf.

  • У каждого из трёх репозиториев есть -testing «близнец» для тестирования. Например перед тем, как попасть в репозиторий core, пакеты проходят через core-testing, в extra через extra-testing, в multilib через multilib-testing.

pacman не только синхронизирует репозитории с сервером, но и хранит базу установленных пакетов в директории /var/lib/pacman/local. Она содержит информацию об установленных версиях пакетов и причине их установки: явно или как зависимость.

Полезные команды, использующие локальную базу:

pacman -Qe # Список пакетов, установленных явно
pacman -Qd # Список пакетов, установленных как зависимость
pacman -Qdt # Список пакетов, установленных как зависимость, которые больше не требуются
pacman -Qm # Список пакетов, установленных не из репозиториев (которых нет в .db файлах)

Пакет с пакетами

При установке системы ставится мета-пакет base. Что значит «мета-пакет»? Давайте посмотрим список файлов, которые он устанавливает в систему:

pacman -Fl base

Вывод будет пустым т.е. файлов в систему он не устанавливает. Зачем тогда вообще нужен этот пакет? Посмотрим информацию о нём из локальной базы:

pacman -Qi base

Вывод
Name            : base
Version         : 3-2
Description     : Minimal package set to define a basic Arch Linux installation
Architecture    : any
URL             : https://www.archlinux.org
Licenses        : GPL
Groups          : None
Provides        : None
Depends On      : filesystem  gcc-libs  glibc  bash  coreutils  file
                  findutils  gawk  grep  procps-ng  sed  tar  gettext
                  pciutils  psmisc  shadow  util-linux  bzip2  gzip  xz
                  licenses  pacman  archlinux-keyring  systemd
                  systemd-sysvcompat  iputils  iproute2
Optional Deps   : linux: bare metal support
Required By     : None
Optional For    : None
Conflicts With  : None
Replaces        : None
Installed Size  : 0.00 B
Packager        : Jan Alexander Steffens (heftig) <heftig@archlinux.org>
Build Date      : Sun Oct 8 01:15:41 2023
Install Date    : Sun Jul 27 00:04:13 2025
Install Reason  : Explicitly installed
Install Script  : No
Validated By    : Signature

В его зависимостях указаны базовые компоненты, которые нужны для функционирования системы, в том числе менеджер пакетов pacman сам устанавливается через пакет. Примечательно, что здесь нет пакета linux с ядром. Это не упущение — так разработчики позволяют пользователю устанавливать наиболее подходящее ему ядро.

Если разработчики решат, что для работы системы нужен ещё один пакет, они просто добавят его в зависимости base и pacman скачает его при обновлении. Таким образом мета-пакет — просто пакет, определяющий набор зависимостей.

Есть связанная сущность — группа пакетов. Например если захотите установить окружение KDE Plasma, то можете установить группу пакетов plasma. При этом пакета с названием plasma не существует:
pacman -Si plasma
выводит
error: package 'plasma' was not found

Дело в том, что plasma — не пакет, а группа пакетов. Само окружение содержится в пакете plasma-desktop, но вряд ли вам понадобится только оно. Скорее всего вы захотите установить ещё приложение с настройками, системный монитор, а это всё отдельные пакеты.

Рассмотрим отличия мета-пакета от группы пакетов:

Мета-пакет

Группа пакетов

Установка

Как обычный пакет

При установке pacman спрашивает какие пакеты группы установить

Зависимости

Устанавливаются все

Устанавливаются выбранные

Новые зависимости

Устанавливаются при обновлении

Не устанавливаются при обновлении

Удаление зависимостей

Нельзя удалить без удаления метапакета

Можно удалить без удаления остальных пакетов группы

Таким образом мета-пакет является обычным пакетом, в то время как установка группы пакетов — то же самое, что установка её пакетов по отдельности. Мета-пакет даёт больше контроля разработчикам, а группа пакетов — пользователям.

Королевство кривых зеркал

Пришла пора понять, откуда скачиваются базы пакетов и сами пакеты.

Смотрим конфиг pacman:
cat /etc/pacman.conf

# ...
[core]
Include = /etc/pacman.d/mirrorlist
# ...
[extra]
Include = /etc/pacman.d/mirrorlist
# ...

Т.е. список серверов хранится в файле /etc/pacman.d/mirrorlist. Эти сервера называются зеркалами т.к. отражают состояние официальных репозиториев. Основные характеристики зеркала  — его географическое расположение и своевременность обновления пакетов. Некоторые зеркала обновляются быстрее других. Для создания списка зеркал по местоположению есть генератор. Также можно посмотреть на своевременность обновлений на специальной странице.

Чтобы лучше понять, что хранится на серверах, можно взять адрес какого-нибудь зеркала и открыть его в браузере. Например есть зеркало repository.su. Если зайти в директорию /core/os/x86_64/ то увидим что на каждый пакет есть по два файла, которые скачиваются при установке: .pkg.tar.zst и .sig. Также там есть файлы core.db и core.files, с которыми мы тоже знакомы. Т.е. ничего сложного в зеркале нет — это обычный веб-сервер, раздающий файлы по HTTPS. Управление зависимостями и прочая логика реализована в pacman.

В Arch используется двухуровневая система зеркал. Tier 2 зеркала берут пакеты с tier 1 зеркал, а те напрямую с archlinux.org. К tier 1 зеркалам выше требования, кроме того они должны побыть tier 2 некоторое время и хорошо себя зарекомендовать. Например в списке tier 1 зеркал в России указано только одно — repository.su. Так что если вдруг захотите поднять своё, то можете синхронизировать пакеты с него.

Важно обратить внимание, что на зеркалах хранятся только последние версии пакетов. Т.е. если в локальной базе .db указана старая версия пакета, а на сервере уже новая, то при попытке установить этот пакет получите ошибку 404. Логичным решением кажется сначала обновить базу pacman -Sy, а затем установить пакет. Крайне не рекомендуется так делать. Дело в том, что зависимости этого пакета тоже могут обновиться, а у вас в системе другие пакеты могут всё ещё зависеть от их старых версий. Поэтому рекомендуется обновить все пакеты в системе через pacman -Syu и лишь затем устанавливать пакет.

Может возникнуть вопрос: а что мешает создать вредоносное зеркало и заливать туда пакеты с вирусами? Для предотвращения таких ситуаций и используются файлы .sig. Перед установкой пакета, pacman проверяет, что подпись сделана ключом, входящим в сеть доверия пользователя. Ключи разработчиков Arch Linux устанавливаются вместе с пакетом archlinux-keyring при установке системы. Можно на свой страх и риск добавлять в сеть доверия другие ключи.

Из-за этого с системой на Arch Linux могут возникнуть трудности если её долго не обновлять:

  1. Первый уровень сложности возникает когда сменился ключ, которыми подписываются пакеты и pacman отказывается устанавливать пакеты, подписанные новым ключом. В таком случае можно отдельно обновить ключи sudo pacman -Sy archlinux-keyring и лишь затем обновлять систему. Это не нарушает сеть доверия т.к. новый пакет archlinux-keyring подписан доверенным ключом.

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

Рецепты от шефа

Прежде чем пакет попадает в репозитории, а затем на зеркала, его должен кто-то приготовить. В качестве рецепта выступает файл PKGBUILD — это bash скрипт с информацией, требуемой для создания пакета. В качестве ингридиентов — исходный код программы или бинарные файлы. В официальных репозиториях Arch Linux, пакеты с открытым исходным кодом собираются из исходников на инфраструктуре разработчиков — в целях безопасности.

Файлы PKGBUILD, из которых собираются официальные пакеты, находятся на официальном gitlab проекта. Посмотрим например на PKGBUILD для пакета lazygit.

PKGBUILD
# Maintainer: Levente Polyak <anthraxx[at]archlinux[dot]org>
# Maintainer: Caleb Maclennan <caleb@alerque.com>
# Contributor: Fredy García <frealgagu at gmail dot com>
# Contributor: fuero <fuerob@gmail.com>

pkgname=lazygit
pkgver=0.54.0
pkgrel=1
pkgdesc='Simple terminal UI for git commands'
url='https://github.com/jesseduffield/lazygit'
arch=('x86_64')
license=('MIT')
depends=('git' 'glibc')
makedepends=('go')
source=("${url}/archive/v${pkgver}/${pkgname}-${pkgver}.tar.gz")
sha256sums=('3df7680f0d5bf58fc9912ca57362fc544ffec05d40b54d4163031bc005abdb8e')
b2sums=('03ba95a4074db88a2ede507e646812a4f8c9caa721199aab90c62790248cf5a6f8da824cdf1c91e22641749ce8a13649b0a3d2081da9ba5ac5bf928a2fa6e979')

build() {
  cd ${pkgname}-${pkgver}

  export CGO_CPPFLAGS="${CPPFLAGS}"
  export CGO_CFLAGS="${CFLAGS}"
  export CGO_CXXFLAGS="${CXXFLAGS}"
  export GOFLAGS="-buildmode=pie -trimpath -mod=readonly -modcacherw -x -v"

  go build \
    -ldflags "\
      -linkmode external \
      -extldflags '${LDFLAGS}' \
      -X main.date=$(date --date=@${SOURCE_DATE_EPOCH} -u +%Y-%m-%dT%H:%M:%SZ) \
      -X main.buildSource=binaryRelease \
      -X main.version=${pkgver} \
      -X main.commit=v${pkgver} \
    "
}

package() {
  cd ${pkgname}-${pkgver}
  install -Dm 755 lazygit -t "${pkgdir}/usr/bin"
  install -Dm 644 README*.md -t "${pkgdir}/usr/share/doc/${pkgname}"
  cp -r docs/* -t "${pkgdir}/usr/share/doc/${pkgname}"
  install -Dm 644 LICENSE -t "${pkgdir}/usr/share/licenses/${pkgname}"
}

# vim: ts=2 sw=2 et:

Здесь многие поля уже знакомы нам по .PKGINFO, а вот на что стоит обратить внимание:

  • source — содержит список исходных файлов для сборки пакета.

  • sha256sums — контрольные суммы файлов из source для воспроизводимости сборки. Если контрольная сумма какого-то файла поменяется — сборка завершится с ошибкой.

  • makedepends — зависимости, которые нужны только для сборки пакета. Они попадают в .PKGINFO, но не ставятся при установке пакета. В данном случае это компилятор Go.

  • Функции build и package описывают компиляцию и размещение скомпилированных файлов по директориям. Если к программе надо применить патчи, то будет присутствовать ещё и шаг prepare, который выполняется перед build.

Соберём локально этот пакет:

sudo pacman -S git base-devel # Нужно для сборки
cd # Переходим в домашнюю директорию
git clone https://gitlab.archlinux.org/archlinux/packaging/packages/lazygit
cd lazygit
makepkg -s # Сборка пакета без установки
ls # Смотрим, что получилось

У нас появилось два пакета:

  • lazygit-0.54.0-1-x86_64.pkg.tar.zst — пакет с программой.

  • lazygit-debug-0.54.0-1-x86_64.pkg.tar.zst — пакет с отладочными символами.

Установить пакет можно вызовом
sudo pacman -U lazygit-*-x86_64.pkg.tar.zst

Теперь если напечатаем lazygit, то у нас откроется эта программа. Чтобы выйти из неё, нажмите Ctrl+C.

PKGBUILD мы взяли из официальных репозиториев в учебных целях — программы из них устанавливаются куда проще с помощью pacman -S. Но что если мы хотим установить программу, которой нет в официальных репозиториях? Вот тут нам понимание PKGBUILD и пригодится.

Рецепты народной кухни

Кроме официальных репозиториев, есть ещё народный Arch User Repository. С помощью него распространяются не готовые пакеты, а PKBUILD'ы, которые туда может залить любой желающий. Такая народная книга рецептов. Конечно же бывают и вирусы, но их оттуда вычищают.

Для каждого рецепта в AUR заведён свой git репозиторий, аналогично официальному gitlab. Давайте установим оттуда пакет yay-bin, а потом я расскажу зачем он нужен. Не вирус, но лучше почитайте его PKGBUILD и убедитесь сами.

cd # Переходим в домашнюю директорию
git clone https://aur.archlinux.org/yay-bin.git
cd yay-bin
makepkg -si # makepkg -s + pacman -U

Как видите, ничем не отличается от обычной сборки пакета из PKGBUILD — это она есть. Напоминаю, что AUR — это репозиторий рецептов, а не пакетов и у него нет файла .db. Поэтому командой pacman -Qm можно посмотреть список пакетов, установленных с AUR.

Единственное неудобство использования AUR — надо самому отслеживать обновления и пересобирать пакеты. Но сообщество давно придумало решение — обёртки над pacman, отслеживающие пакеты из AUR. Их несколько и одна из них называется yay и содержится в пакете, который мы установили ранее.

Чтобы установить другой пакет из AUR, скажем paru-bin (другая обёртка над pacman) теперь можно просто написать
yay -S paru-bin

Кстати, что за -bin такое в названии рецептов? Дело в том, что собирать пакеты из исходников дольше и ресурсозатратнее, поэтому у многих рецептов есть версия -git для сборки из исходников и -bin, использующая готовые бинарники. Но это лишь соглашение, надо читать PKGBUILD чтобы узнать как на самом деле собирается пакет.

Команда yay -Syu или просто yay не только обновляет пакеты из официальных репозиториев, но и пересобирает обновлённые пакеты из AUR. Здесь важно понимать, что автором рецептов в AUR может быть кто угодно и в PKGBUILD вполне может оказаться вирус, поэтому стоит их читать.

Заключение

Надеюсь эта статья помогла вам лучше разобраться в системе пакетов Arch Linux, а именно:

  • Что из себя представляют пакеты, какие файлы содержатся внутри

  • Зачем pacman нужна база пакетов и как она устроена

  • Чем отличиается мета-пакет от группы пакетов

  • Что такое репозитории и какие они бывают

  • Как с помощью зеркал распространяется пакеты

  • Как выглядит рецепт создания пакета

  • Что такое AUR и какие у него подводные камни

Желаю всем свежих и безопасных пакетов!

Использованные статьи из Arch Wiki

Комментарии (0)