Внутреннее устройство

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

Посмотреть содержимое deb-пакета можно утилитой ar (предшественник tar):

ar -t bat-musl_0.23.0_amd64.deb
 
# Deb-пакеты
# control.tar.xz
# data.tar.xz

Видно, что по сути deb-пакет состоит из двух архивов и файла debian-binary, в котором указывается версия формата пакета и убедиться в этом можно так:

# Просмотр содержимого файла в архиве
ar -p bat-musl_0.23.0_amd64.deb debian-binary  # 2.0
 
# Просмотреть можно и содержимое архивов control.tar.xz и data.tar.xz, но
# из-за того, что архив - это бинарник, придется передать вывод в tar
ar -p bat-musl_0.23.0_amd64.deb data.tar.xz | tar -tvJ

debian-binary - файл, в котором указывается версия формата пакета
data.tar.xz - архив, где хранятся все данные программы (конфиги, библиотеки, исполняемые файлы и т.п.)
control.tar.xz - архив, где хранятся метаданные и некоторые maintainer-ские скрипты

Метаданные выглядят примерно так:

Package: bat-musl
Version: 0.23.0
Section: utils
Priority: optional
Maintainer: David Peter <mail@david-peter.de>
Homepage: https://github.com/sharkdp/bat
Architecture: amd64
Provides: bat
Conflicts: bat
Description: cat(1) clone with wings.
  A cat(1) clone with syntax highlighting and Git integration.

Там могут указываться:

  • Package (Имя пакета)
  • Version (Версия)
  • Architecture (Архитектура процессора)
    для которого предназначено ПО
  • Maintainer
    тот, кто поддерживает пакет
  • Installed-Size (Размер)
  • Depends (Зависимости пакета)
    В зависимостях указывают список программ с версиями или без, нужные для корректной работы ПО. Зависимости перечисляются либо через запятые, что означает логическое “И”, либо через вертикальные линии (|), что означает логическое “ИЛИ”. То есть, например, нужно поставить один из этих пакетов: “gpgv | gpgv2 | gpgv1”, а у тех, которые перечислены через запятую нет альтернатив.
    При установке ПО подтягиваются автоматически и зависимости.
  • Recommends (Рекомендуемые пакеты)
    Хоть и необязательные пакеты, но их лучше установить, ибо часто перечисленные в этом пункте пакеты довольно полезны.
  • Suggests (Предлагаемые пакеты)
    Необязательные пакеты, которые могут помочь как-то данному ПО, но и без них оно будет работать.
  • Conflicts (Конфликтуемые с ПО пакеты)
    ПО не может быть установлено рядом с перечисленными пакетами.
  • Breaks (Несовместимости)
    Говорит о том, что установка данного ПО повредит перечисленным пакетам.
  • Replaces (Заменяет)
    Перечисляются пакеты, которые будут заменены данным ПО
  • Provides (Предоставляет)
    Перечисляются пакеты, которые могут быть установлены вместо данного ПО

В архиве control.tar.xz могут также хранится некоторые скрипты:

  • postinst
    Выполняется после установки пакета
  • postrm
    Выполняется после удаления пакета
  • preinst
    Выполняется до установки пакета
  • prerm
    Выполняется до удаления пакета

Схема выполнения этих скриптов (установки и удаления пакетов) выглядит примерно так:


Обновление пакетов

При обновлении пакетов тоже задействуются “pre” и “post” скрипты. Там схема побольше, но суть там в том, что обновление пакета - это его удаление и установка новой версии.

В том же месте могут находиться файлы:

  • debconf
    Используется для хранения настроек, связанных с установкой и настройкой пакета
  • md5sums
    В нем содержатся хэш-суммы для всех файлов пакета
  • conffiles
    В нем перечисляются файлы пакета, которые должны обрабатываться как файлы конфигурации (конфиги). Их можно изменять и тогда dpkg попытается сохранить их во время установки.

Сборка deb-пакетов

Попробую обернуть shell скрипт в deb-пакет. Буду пробовать сделать deb-пакет для vliquid (скрипт, который искажает видео эффектом liquid-scale). Для этого понадобится две программы:

sudo apt install dh-make devscripts

Создаем папку, где будем работать и копируем туда скрипт vliquid:

mkdir vliquid-1.0; cd $_; cp ~/sh/vliquid .

Версии пакета

Версии программы принято писать в таком виде “<major>.<minor>.<patch>”, то есть “версия 1.2.1”, например.

Major версия меняется, если изменения не совместимы с предыдущей версией
Minor версия меняется, если изменения обратно совместимы
Patch версия меняется, если были сделаны обратно совместимые и, обычно, мелкие исправления ошибок, например.

dh-make-у нужны будут имя и email maintainer-а пакета - можно просто прописать следующие строки в .zshrc, чтобы упростить ему работу:

export DEBEMAIL="test@mail.ru"
export DEBFULLNAME="test"
 
# и подтянем изменения
source ~/.zshrc
# и можно проверить переменные
echo $DEBEMAIL $DEBFULLNAME

И создадим шаблон из папки vliquid-1.0/:

dh_make --indep --createorig
# --indep указывает, что пакет будет доступен на всех архитектурах процессоров
# --createorig создаст необходимый для пакета архив

dh_make создал директорию debian/ с неким содержимым.

В этой папке находятся (перечислено не всё):

  • шаблоны README
  • файлы .ex
    Примеры, например preinst.ex, который если переименовать в preinst - попадет в deb-пакет
  • файл rules
    набор инструкций для сборки deb-пакетов, похожий на Makefile
  • control
    с метаданными

В моем случае *.ex файлы и README.* не понадобятся, поэтому можно:

cd debian; rm *.ex README.*

Нужен еще файл install, с помощью которого передастся инфа утилите debuild, собирающей пакет, какие файлы должны быть в него включены. Пишем туда название скрипта и путь, куда хочешь его положить:

vliquid usr/bin

Можно также отредактировать файл changelog, если нужно добавить инфу об изменениях, версиях. Там лежит такой шаблон:

vliquid (1.0-1) unstable; urgency=medium

  * Initial release (Closes: #nnnn)  <nnnn is the bug number of your ITP>

 -- test <test@mail.ru>  Sat, 20 May 2023 23:02:21 +0300

Я просто уберу лишнее:

vliquid (1.0-1) unstable; urgency=medium

  * Initial release.

 -- test <test@mail.ru>  Sat, 20 May 2023 23:02:21 +0300

Также изменять файл changelog можно утилитой dch - просто нужно ввести эту команду и откроется шаблон с новой версией.

Запускаем debuild

debuild -us -uc
# -us -uc указывают, что не хочешь подписывать пакет, потому что на локалке это не нужно, нет нужды пока что грузить пакет в сеть, в какой-нибудь репозиторий
# подпись пакетов происходит так: приватным ключом оставляем уникальную подпись, а публичным ключом потом можно будет подтвердить подпись, чтобы удостоверится, что изменения, например, производил именно ты, мэйнтейнер

Вне папки vliquid-1.0/ появились пакет и другие файлы.

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

sudo dpkg -i vliquid_1.0-1_all.deb
# пакет после установки закинет скрипт в /usr/bin - можно убедиться:
ls /usr/bin/vliquid

Удаление пакета:

sudo dpkg -r vliquid

Подпись пакета

Если пары gpg ключей нет - надо сгенерировать:

gpg --gen-key

Меняю версию:

dch -i
 
# Там же поменяю строки из шаблона
vliquid (1.1) unstable; urgency=medium
 
  * Signed changes.
 
 -- test <test@mail.ru>  Sun, 21 May 2023 16:56:44 +0300
 
vliquid (1.0-1) unstable; urgency=medium
 
  * Initial release.
 
 -- test <test@mail.ru>  Sun, 21 May 2023 16:32:27 +0300

И rebuild-им пакет, но уже подписывая изменения:

debuild -b

О подписи gpg-ключами

Name и email в паре gpg ключей должны совпадать с $DEBEMAIL $DEBFULLNAME, которые мы прописывали в ~/.zshrc
Иначе подпись не произойдет.


Полезный короткий гайд: Простейший способ собрать свой deb-пакет с данными