Windows. Вирусы. Ноутбуки. Интернет. Office. Утилиты. Драйверы

deb-файл представляет собой архив в формате ar , содержащий установочные файлы программы, информацию о программе, а также скрипты (командные файлы), выполняемые до и после установки и удаления программы (наличие скриптов не является обязательным - они могут и не входить в состав пакета).

Формат файла deb описывается в man-справке (man pages) deb(5) - эта справка выводится, если в терминале набрать команду man deb. Также в Интернете есть немало страниц, содержащих эту информацию - достаточно набрать в строке поиска deb(5), чтобы найти их. Здесь это руководство не приводится, так как в официальном руководстве для разработчиков Debian, в справке по формату пакетов (которое на момент написания этого руководства находилось по адресу http://www.debian.org/doc/manuals/debian-faq/ch-pkg_basics.en.html) написано, что формат пакетов может изменяться, а потому для работы с ними рекомендуестя использовать утилиту dpkg-deb. Справку по работе с утилитой dpkg-deb можно получить, набрав в терминале команду man dpkg-deb.

Работа программы GUI-deb как раз и заключается в создании директории, содержащей необходимые данные, и запуске программы dpkg-deb с указанием ей этой директории и других нужных параметров.

Правильная директория, нужная для создания установочного пакета программой dpkg-deb, должна, прежде всего, содержать вложенную директорию "DEBIAN". В этой директории должны находиться все данные, не копируемые в систему, а используемые непосредственно программами для работы с пакетами - информация о пакете, выполняемые до и после установки скрпиты и т.п. Никакие файлы, содержащиеся в директории DEBIAN, при установке пакета не попадут в файловую систему компьютера, на который устанавливается пакет.

Вне директории "DEBIAN" содержатся те файлы, которые будут скопированы в файловую систему компьютера, на который будет устанавливаться пакет. Файлы должны располагаться в тех директориях, в которые они будут помещаться при установке пакета. То есть, внутри директории, создаваемой для dpkg-deb, должна создаваться копия нужных нам частей файловой системы - так, как если бы эта директория являлась для неё корнем ("/"). То есть, допустим, если имя директории, на основе которой будет создаваться пакет - "~/TMP_DEBS/MyProgram", и нужно, чтобы при установке в файловой системе в директорию "/usr/share/pixmaps" записывался файл "MyProgram.png" - надо в директории "~/TMP_DEBS/MyProgram" создать директорию "usr", в ней - директорию "share", внутри "share" - директорию "pixmaps", и уже в директорию "pixmaps" поместить файл "MyProgram.png". В итоге, полный путь к файлу будет "~/TMP_DEBS/MyProgram/usr/share/pixmaps/MyProgram.png". При создании пакета часть директории "~/TMP_DEBS/MyProgram" будет обрезана, и при установке файл "MyProgram.png" как раз и попадёт по нужному адресу "/usr/share/pixmaps". Таким образом, нужные директории надо создать для каждого файла.

После создания директории остаётся только запустить dpkg-deb, передав нужные параметры. Самые необходимые для сборки пакетов параметры dpkg-deb описываются в разделе "Параметры командной строки для утилиты dpkg-deb" . В случае отсутствия ошибок в файле control, установочный пакет будет создан.

Я описывал сборку программы из исходного кода, а также создание простенького deb-пакета. В этот раз я хочу подробнее остановиться на их создании. Это руководство не претендует на звание инструкции для разработчики или сопровождающего, потому в конце я дам ссылки на подробные руководства от разработчиков Debian .

Способов создания deb-пакета довольно много. Я не буду здесь описывать крупные системы сборки, которые используются на сборочных серверах, ибо большинству это не нужно. Я опишу два наиболее простых способа создания своего пакета. Первым делом, нам нужно установить кое-какие инструменты для работы:

sudo apt-get install build-essential git automake devscripts make libtool fakeroot automake autotools-dev

Далее нужно создать цифровой ключ. Этот шаг не обязателен, но если вы планируете распространять свои пакеты, будет крайне мудрым решением подписать их своим ключом. Это позволит пользователю, скачавшему ваш пакет, удостовериться что именно вы его создали. Для создания ключа можно воспользовать графическими утилитами (Seahorse , Kgpg ) либо в терминале:

DEBEMAIL="ваш E-Mail который вы указали при создании ключа"
DEBFULLNAME="Ваше имя (или псевдоним)"
export DEBEMAIL DEBFULLNAME

Это позволит автоматически добавлять вашу цифровую подпись при подписании пакетов. Далее нам необходим архив с исходным кодом. Пример я буду проводить простой, так как в зависимости от сложности программы, необходима дополнительная настройка (создание постинсталяционных скриптов, правил сборки и т.д.). Предположим у нас есть архив с исходным кодом программы "Myprogramm" - myprogramm_1.0.tar.gz . Распакуем его в домашнюю директорию (или любую где вам удобнее). Обратите внимание: каталог после распаковки должен иметь имя myprogramm-1.0 . Название и через дефис - номер версии. Теперь откроем терминал и выполним:

cd ~/myprogramm-1.0
dh_make --createorig

Мы перешли в каталог с исходным кодом и создали архив с ним и базовую дебианизацию. После второй команды выведится сообщение, где нужно выбрать тип пакета: s (single, одиночный), m (multiple, несколько пакетов), l (library, библиотека), k (kernel module, модуль ядра). В нашем случае это s. Теперь нам нужно немного всё настроить. Перейдите в каталог /myprogramm-1.0/debian и откройте файл control в любом текстовом редакторе. Это главный файл для сборки пакета. В нём указывается вся основная информация. Он имеет примерно такой вид:

Source: myprogramm
Section: admin
Priority: optional
Maintainer: Aleksey Samoilov
Build-Depends: debhelper (>= 5)
Standards-Version: 3.9.6
Homepage: http://www.example.com

Package: myprogramm
Architecture: all
Depends: ${shlib:Depends}, ${misc:Depends}
Section: admin
Priority: optional
Description: My new programm
My programm is a simple example to build your own deb-package

Пошли по порядку. В первой секции указывается имя пакета с исходным кодом. Далее секция ПО (в данном случае admin). Затем приоритет (опционально), имя сопровождающего и его E-Mail (то есть ваше), сборочные зависимости (пакеты необходимые для сборки), версия стандарта (на данный момент 3.9.7), далее идёт имя пакета после сборки, архитектура для которой он собирается (all означает все поддерживаемые архитектуры), секция ПО, приоритет, краткое описание и полное описание. Так как пример у нас простой, для начала этого хватит. Вы также можете открыть файл copyright и указать там своё имя и E-Mail. В файле Changelog находится список изменений каждой версии данного ПО. Так как это первая сборка, то нужно указать что это First Release, а также закрыть некий баг (отсутствие данного пакета в репозитории). Номер бага можно написать от балды. Если вы пересобираете пакет, то сперва измените его версию командой dch -i Файлы в каталоге debian с расширениями .ex - это примеры. При сборке более сложных пакетов, будут нужны и эти дополнительные файлы. Это к примеру послеустановочные скрипты (postinst ), файл, проверяющий наличие новой версии тарболла с исходным кодом (watch ) и так далее. Файл rules - это мейкфайл, правила для сборки пакета. Для простых программ его можно не менять, в остальных случаях - необходима его правка, для указания параметров сборки, или установки иконок. Много чего.

Теперь, когда вы заполнили файл control, можно приступать к сборке. Для этого находясь в каталоге с исходным кодом, выполните команду debuild . Система проведёт конфигурацию, скомпилирует программу, запакует в пакет, выполнит проверку на распространённые ошибки при дэбианизации и попросит дважды ввести пароль для вашего ключа (если вы его не создавали, то ничего не будет). Теперь в каталоге уровнем выше (в нашем случае в домашней директории), вы увидите несколько файлов, среди которых искомый deb-пакет. Теперь его можно установить командой sudo dpkg -i myprogramm-1.0-1.deb или в графическом менеджере Gdebi.

Вот таким образом можно собрать простой пакет. Но что делать, если вы не хотите засорять систему кучей сборочных зависимостей? Более того, при сборке некоторых пакетов, могут быть использованы некоторые изменённые файлы. К примеру более новые версии библиотек, если вы обновили систему из бэкпортов, или различные изменения в конфигах. На подобные случаи можно воспользоваться виртуальной машиной, контейнером или использовать специальный инструмент под названием pbulder. Pbuilder - это инструмент для создания чистого окружения, в котором находится только то, что необходимо для сборки. Система при этом не засоряется ненужными файлами, а сборка программы происходит в лабораторных условиях. Устанавливаем:

sudo apt install pbuilder

Я приведу пример своего конфига, с помощью которого можно будет собирать пакеты не только под разные релизы Debian, но и Ubuntu.

sudo nano /etc/pbuilderrc

Вставляем следующее содержимое:

STABLE_CODENAME="stable"
OLDSTABLE_CODENAME="oldstable"
DEBIAN_SUITES=($UNSTABLE_CODENAME, $TESTING_CODENAME, $STABLE_CODENAME $STABLE_BACKPORTS_SUITE $OLDSTABLE_CODENAME
"sid" "stretch" "jessie" "wheezy")
UBUNTU_SUITES=("precise" "trusty" "xenial")
UBUNTU_MIRROR="mirror.yandex.ru"
DEBIAN_MIRROR="mirror.yandex.ru"
: ${DIST:="$(lsb_release --short --codename)"}
: ${ARCH:="$(dpkg --print-architecture)"}

NAME="$DIST"
if [ -n "${ARCH}" ]; then
NAME="$NAME-$ARCH"
# следующая строчка нужна для того чтобы собирать под разные архитектуры
DEBOOTSTRAPOPTS=("--arch" "$ARCH" "${DEBOOTSTRAPOPTS[@]}")
fi

BASETGZ="/home/sunderland93/pbuilder/$NAME-base.tgz"
DISTRIBUTION="$DIST"
BUILDRESULT="/home/sunderland93/pbuilder/$DIST/result/"
APTCACHE="/home/sunderland93/pbuilder/$NAME/aptcache/"
BUILDPLACE="/home/sunderland93/pbuilder/build/"
if $(echo ${DEBIAN_SUITES[@]} | grep -q $DIST); then
MIRRORSITE="http://$DEBIAN_MIRROR/debian/"
COMPONENTS="main contrib non-free"
elif $(echo ${UBUNTU_SUITES[@]} | grep -q $DIST); then
MIRRORSITE="http://$UBUNTU_MIRROR/ubuntu/"
COMPONENTS="main restricted universe multiverse"
else
echo "Неизвестный дистрибутив: @DIST"
exit 1
fi

export DPKG_GENSYMBOLS_CHECK_LEVEL=4
USE_PDEBUILD_INTERNAL=yes

Замените sunderland93 на своё имя в системе. Таким образом, мы сможем собирать пакеты для Debian 7, 8, testing и unstable, а также под Ubuntu 12.04, 14.04 и 16.04. Скачанные для сборки зависимости будут лежать в pbuilder/имя дистрибутива/aptcache . Это кстати очень полезно - у нас будет базовый архив, который не будет засорён левыми зависимостями и весить несколько гигабайт. И окружение будет готовиться индивидуально для каждой программы. Можно и вшить эти зависимости в базовый архив, но я не рекомендую это делать. Теперь давайте создадим базовый архив, содержащий чистое окружение для сборки. Для примера возьмём Debian 8 64-bit:

sudo DIST=jessie ARCH=amd64 pbuilder --create

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

sudo DIST=jessie ARCH=amd64 pdebuild

И ждём. Скачанные пакеты будут закешированны, и в следующий раз уже не буду качаться. После сборки, готовый deb-пакет появится в каталоге pbuilder/jessie/result . Вот и всё.

Сегодня я расскажу на абстрактном примере как правильно создать *.deb пакет для Ubuntu/Debian. Пакет мы будем делать бинарный. Пакеты, компилирующие бинарники из исходников здесь не рассматриваются: осилив изложенные ниже знания, в дальнейшем по готовым примерам можно понять суть и действовать по аналогии:)

В статье не будет никакой лишней возни «вручную»: формат пакета эволюционировал в достаточно простую, а главное - логичную структуру, и всё делается буквально на коленке, с применением пары специализированных утилит.

В качестве бонуса в конце статьи будет пример быстрого создания собственного локального репозитория: установка пакетов из репозитория позволяет автоматически отслеживать зависимости, и конечно же! - устанавливать всё одной консольной командой на нескольких машинах:)

Для тех, кто не хочет вдаваться в мощную систему установки софта в Linux, рекомендую посетить сайт проги CheckInstall : она автоматически создаёт deb-пакет из команды «make install» ;) А мы вместе с любопытными -

Источники

Информация надёргана из многих мест, но вот два основных:
  • Debian.org: Debian Policy Manual - официальная
  • Ubuntu Wiki: PackagingGuide/Basic
В статье подробно изложены основы создания пакетов, достаточные для получения достаточно мощного управления установкой приложений. Более продвинутые фичи опущены, но предложены прямые ссылки на документацию для интересующихся.
Статья не является копией или переводом какой-либо документации: это - коллекция знаний, валявшихся в виде заметок, а теперь оформленная в виде статьи. Для ясности везде есть примеры, разъяснения на пальцах, найденные мной удобные фичи и некоторые типичные ошибки, которые можно совершить по незнанию.

Подготовка

Зачем это всё?
Да, CheckInstall умеет создавать рабочий пакет, но он не поддерживает все вкусности, на которые способны deb пакеты:) А именно:
  • Скрипты, выполняющиеся до, после и вместо установки пакета:)
  • Автоматическое управление конфигурационными файлами: пакет не позволит затереть старые конфиги новыми без спроса
  • Работа с шаблонами: возможность задавать пользователю вопросы при установке (!!!)
  • Изменение файлов других пакетов
Что потребуется
Конечно, для создания полноценного пакета хватит архиваторов tar, gz, ar, но можно исключить лишнюю возню, и воспользоваться инструментами, созданными для облегчения жизни:)
Ставим:
$ sudo apt-get install dpkg debconf debhelper lintian
Что мы будем делать
Для примера будет рассмотрен некий скрипт /usr/bin/super.sh. Не важно что внутри, главное - как он появится на правильном месте:)
Подготовка папки
В домашнем каталоге (или где удобно) создаём папку, в которой будут лежать все файлы будущего пакета: mkdir ~/supersh . Далее будем называть её корень пакета .
В корне пакета создаём папку «DEBIAN» (заглавными буквами, это важно!). Эта папка содержит управляющую генерацией пакета информацию, и не копируется на диск при установке пакета.
Также корневая папка пакета содержит будущий «корень диска»: при установке пакета все файлы (кроме папки «debian») распаковываются в корень /. поэтому наш скрипт должен лежать по такому пути, относительно корня пакета: «usr/bin/super.sh»
Белым по чёрному:
mkdir -p ~/supersh/DEBIAN # управляющая папка
mkdir -p ~/supersh/usr/bin # путь к скрипту
cp super.sh ~/supersh/usr/bin/ # копируем наш скрипт в нужное место
В итоге имеем:
supersh/DEBIAN/
supersh/usr/
supersh/usr/bin/
supersh/usr/bin/super.sh

Создание пакета: DEBIAN/*

Как я уже сказал, папка DEBIAN содержит файлы, используемые при установке. Здесь я опишу (с примерами) каждый файл.
Для создания полноценного пакета достаточно контрольного файла «control», все остальные используются либо для прикрепления текстовой информации (changelog, лицензия), либо для управления расширенными возможностями установки приложений.
Из описанных ниже файлов в папке DEBIAN/* выбираем необходимые, и заполняем согласно инструкции:)
В наше примере реально используется только обязательный DEBIAN/control .
DEBIAN/control: Основная информация
control - центральный файл пакета, описывающего все основные свойства. Файл - текстовый, состоящий из пар «Атрибут: значение». Можно использовать комментарии: символ "#" в начале строки (возможность была добавлена в версии dpkg >= 1.10.11, надеяться на комментарии не стоит:).
В таблице приведены все поля, определённые для контрольного файла. Обязательные поля выделены жирным : без них пакет не будет считаться составленным верно.
Атрибут Описание Примеры
- основные -
Package: Имя пакета: - только латиница, цифры, и дефис. Имя используется при установке: apt-get install Package: supersh
Version: Версия пакета (и проги внутри). Используется для определения «обновлять ли».
Формат принят такой: <версия_программы>-<версия_пакета> .
Рекомендую всегда указывать версию пакета: при изменении структуры пакета цифра увеличивается на единичку.
Допустимые символы достаточно вольные: можно использовать дату и буквы. Примеры смотрите сегодня в своём репозитории:)
Version: 1.0-1
Version: 2009.12.12-1
Provides Имя приложения (возможно, виртуальное), регистрируемое в системе в результате установки этого пакета.
Используется редко: в основном, если нужно изменить имя пакета, или если более одного пакета предлагают одинаковый функционал. Например, пакеты Apache и nginx предоставляют возможность демона httpd: Provides: httpd
Вы наверняка сталкивались с ошибкой при попытке установки: «is a virtual package». Это оно и есть:)
Provides: supersh
Maintainer Имя и почта мэйнтейнера пакета: человека, который «дебианизировал» приложение.
Формат произвольный, но принято имя
Maintainer: o_O Tync
Architecture Архитектура процессора, для которой предназначен пакет.
Допустимые значения: i386, amd64, all, source
all используется для скриптов: они же портативные, верно? :)
source используется для компилируемых пакетов с исходниками
Architecture: all
Section Определяет задачу, для которой приложение обычно используется (группа приложений).
Возможные значения: admin, base, comm, contrib, devel, doc, editors, electronics, embedded, games, gnome, graphics, hamradio, interpreters, kde, libs, libdevel, mail, math, misc, net, news, non-free, oldlibs, otherosfs, perl, python, science, shells, sound, tex, text, utils, web, x11
Section: misc
Description Описание пакета.
Описание состоит из двух частей: короткое описание (70 символов) на той же строке, и длинное описание на последующих строках, начинающихся с пробела .
В расширенном описании все переводы строки игнорируются. Для вставки \n используется одиночная точка.
Description: Short.
␣Long
␣goes here.
␣.
␣New line.
- связи и зависимости -
Depends Список пакетов через запятую, которые требуются для установки этого пакета.
После имени пакета можно в круглых скобках указать ограничение на версию, используя операторы: <<, =, >>, <=, >=. Если оператор не указан - используется >=
Depends: dpkg, libz (>= 1.2.3), jpeg (= 6b), png (< 2.0)
Pre-Depends Список пакетов, которые требуются в процессе установки этого пакета.
Эти зависимости могут потребоваться для скриптов установки пакета: например, пакет flash-installer требует wget
Можно использовать ограничения на версию (см. Depends).
Pre-Depends: wget (>= 1.0)
Conflicts Список пакетов, которые не могут быть установлены одновременно с этим.
Установка не удастся, если хоть один из перечисленных пакетов уже будет установлен.
Conflicts: crapscript
Replaces Список пакетов, файлы которых модифицируются этим пакетом.
Требуется в случае создания «пакета-патча», изменяющего что-либо: в противном случае при замене файлов чужого пакета возникнет ошибка при установке. У меня, например, такой пакет патчит UT2004 и убирает звук наводящейся ракетницы:)
Replaces: ut2004
Recommends Список пакетов, рекомендуемых к установке
Эти пакеты не обязательны, но обычно используются вместе с текущим
Recommends: superplatform
Suggests Список пакетов, предлагаемых к установке.
Эти пакеты не обязательны, но с ними прога работает ещё лучше:) По идее, менеджер пакетов должен предлагать установить их.
Suggests: supersh-modules
Build-Depends (Только для Architecture: source)
Список пакетов, требуемых для компиляции исходников.
То же, что и Depends, но логически отделено.
Build-Depends: cmake
- экстра -
Installed-Size Размер файлов пакета в килобайтах.
Просто цифра, округлённая до ближайшего целого. Используется менеджером пакетов для определения суммарного требуемого объёма на диске.
Installed-Size: 3
Priority Приоритет пакета: насколько он важен в системе
Возможные значения: extra, optional, standard, important, required (такие пакеты не удаляются вообще!).
Priority: optional
Esssential Если установить этот атрибут в значение «yes», пакет нельзя будет удалить. Esssential: yes
Origin Строка: откуда получены программы в пакете. Обычно используется URL сайта автора, почта или имя. Origin: brain
X-Source Полная ссылка на *.tar.gz архив с исходниками X-Source: ...*.tgz

Да, вот такие солидные возможности у контрольного файла:)
А в нашем примере он выглядит так:
Package: supersh
Version: 1.0-1
Section: misc
Architecture: all
Depends: bash, sed (>= 3.02-8)
Maintainer: o_O Tync
Description: Super Shell Script
␣A super example script.
␣.
␣It does nothing:)
DEBIAN/copyright: / лицензия
Текст лицензии. Файл не обязателен, но лучше подчеркнуть своё авторство;)
DEBIAN/changelog: история изменений
Changelog в специальном формате: используется dpkg для получения номера версии, ревизии, дистрибутива и важности пакета. Лучше посмотреть в ;) а я лишь приведу пример:
supersh (1.0-1) stable; urgency=medium

O_O Tync Sun, 13 Dec 2009 00:11:46 +0300

DEBIAN/conffiles: список файлов конфигурации
Обычно пакеты содержат болванки конфигурационных файлов, например, размещаемых в /etc. Очевидно, что если конфиг в пакете обновляется, пользователь потеряет свой отредактированный конфиг. Эта проблема легко решается использованием папок типа «config.d», содержимое которых включается в основной конфиг, заменяя собой повторяющиеся опции.
Файл «DEBIAN/conffiles» позволяет решить проблему иначе: он содержит список файлов конфигурации (по одному на строке). Если в текущей версии пакета один из этих файлов обновляется, то пользователь получает предупреждение о конфликте версий конфигов, и может выбрать: удалить, заменить, или сделать merge.
С этой ситуацией наверняка сталкивался каждый линуксоид, копавшийся в конфигах:) А ноги растут отсюда.
На каждой строке должен быть полный абсолютный путь до каждого конфига. Например:
/etc/supersh/init.conf
/etc/supersh/actions.conf
DEBIAN/dirs: список папок для создания
«Список абсолютных путей к папкам, которые требуются программе, но по каким-либо причинам не создаются.» - гласит официальная документация. На практике – здесь перечисляются все папки, так или иначе используемые программой: и где лежат бинарники, и которые используются программой.
По одной на строке. Например:
/var/log/supersh
/var/lib/supersh
Удобно использовать для создания нескольких пустых папок.
DEBIAN/menu: создание пунктов меню
Хитрый файл для создания пунктов меню. У меня он так и не заработал:) Складывается ощущение, что его содержимое используется либо в необычных оконных менеджерах, либо в каком-то консольном меню… или же использовалось ранее и было забыто:)
Пример:
?package(supersh):needs="text" section="Applications/Programming" title="Super Shell Script" command="/usr/bin/super.sh"
TODO: узнать зачем нужно. Об этом написано в man5 menufile , честно говоря я не вникал:)
UPD: Правильный способ добавления пункта меню
Файл /DEBIAN/menu создаёт неизвестно что и непонятно где: элементы графического меню всё равно не создаются. Поэтому будем делать правильно:)
В /usr/share/applications видим кучку *.desktop файлов: это и есть пункты меню. Они представляют собой текстовые файлы с синтаксисом наподобие ini-файла. Открываем, учимся, делаем так же и кладём получившийся *.desktop файл в usr/share/applications/ . Иконка для него должна лежать в usr/share/pixmaps .
После этого в postinst скрипт нужно добавить выполнение команды обновления меню update-menus:
if [ "$1" = "configure" ] && [ -x "`which update-menus 2>/dev/null`" ] ; then
update-menus
fi

Работа со скриптами установки пакета будет рассмотрена далее.
Спасибо Condorious за наводку:)

DEBIAN/md5sums: контрольные суммы файлов
Используется для проверки целостности пакета. Важный файл.
Заполняется так (cwd=корень пакета):
$ md5deep -r usr > DEBIAN/md5sums
DEBIAN/watch: мониторинг сайта, откуда была скачана прога
Функция полезна, если Вы мэйнтейните от нескольких десятков пакетов, и уследить за всеми обновлениями сложно.
Файл содержит инструкции для программ uscan и uupdate. Используя эту возможность, можно следить за сайтом, откуда были получены исходники пакета, и обеспечивать контроль качества дистрибутива в целом.
Пример:
# Site Directory Pattern Version Script
ftp.obsession.se /gentoo gentoo-(.*)\.tar\.gz debian uupdate
DEBIAN/(preinst|postinst|prerm|postrm): скрипты установки
Всего можно создать до четырёх скриптов в одном пакете:

Обратите внимание, что ошибки, возникающие в этих скриптах никак не логируются : ничего интереснее кода возврата скрипта нигде не сохраняется, и логирование необходимо делать вручную! Пользователи одного моего пакета терпели неудачу при установке на Linux Mint, и не было даже возможности попросить у них лог ошибок (которого нету) чтобы выдебагать причину:)
Рекомендую использовать в начале каждого скрипта следующую болванку: она будет сохранять в syslog все возникающие ошибки.
#!/bin/bash
set -e # fail on any error
set -u # treat unset variables as errors

# ======[ Trap Errors ]======#
set -E # let shell functions inherit ERR trap

# Trap non-normal exit signals:
# 1/HUP, 2/INT, 3/QUIT, 15/TERM, ERR
trap err_handler 1 2 3 15 ERR
function err_handler {
local exit_status=${1:-$?}
logger -s -p "syslog.err" -t "ootync.deb" "supersh.deb script "$0" error code $exit_status (line $BASH_LINENO: "$BASH_COMMAND")"
exit $exit_status
}

Ваш код установочного скрипта...

WARNING: болванка пока не тестировалась широко, проверьте лишний раз! На невозможность отладки наткнулся совсем недавно:)

DEBIAN/templates: шаблоны для диалогов
Как уже было сказано, в скрипте DEBIAN/config можно задавать пользователю вопросы: ввести строку, выбрать один из вариантов, поставить галочку,… Этим занимается «библиотека» bash функций debhelper пакета debconf, умеющая кроме этого ещё массу полезных вещей. Здесь их не рассматриваю:)
Файл DEBIAN/templates содержит данные, используемые при выводе диалоговых окон (GUI или ncurses). Файл содержит блоки, разделённые пустой строкой. Каждый блок определяет ресурсы, используемые в одном конкретном диалоговом окне.
Шапка для всех типов диалогов стандартная:
Template: supersh/template-name
Type: string
Default: Default-value
Description: Dialog-title
␣Dialog-text

Template - уникальный (в пределах одного пакета) идентификатор шаблона. Если в скрипте нужно вызвать определённый диалог - используется именно это имя.
Type - тип шаблона. Определены такие типы: string, password, boolean, select, multiselect, text, note, error.
Default-value - значение по умолчанию: пользователь может просто согласиться с ним.
Description - как и в контрольном файле, состоит из двух полей: короткое описание, и длинный текст. Первое - это заголовок «окна», второе - более развёрнутое описание того, что требуется от пользователя. Рекомендуется не использовать слов вроде «введите», а сразу суть: «Приветствие скрипта», «Точка монтирования»,…

Тип Описание шаблона
string Приглашение на ввод текстовой строки
password Приглашение на ввод пароля.
Для этого типа шаблона нет значения Default по понятным причинам:)
boolean Галочка:) Имеет строковое значение «true» или «false»
select Возможность выбора одного из нескольких вариантов.

Choices: yes, no, maybe
multiselect Возможность выбора нескольких вариантов галочками.
Варианты предлагаются в дополнительном атрибуте шаблона:
Choices: sex, drugs, rock-n-roll
text Выводит на экран текст: некоторая не очень важная информация
note Выводит на экран текст: важная информация
error Выводит на экран текст: очень важная информация, критическая.

Для шаблонов text, note, error также нет значения Default, так как они лишь отображают информацию:)
Поиграемся с следующим шаблоном:
Template: supersh/greeting
Type: string
Description: Welcome message
␣The message you wish the script to welcome you with.
Default: Greetings, my master!
Основы использования debconf и debhelper
Это лишь работоспособные наброски. В оригинале почитать о шаблонах и работе с ними можно здесь: man 7 debconf-devel:)
Чтобы использовать шаблоны в своём скрипте настройки DEBIAN/config, необходимо сначала подключить функции debhelper:
. /usr/share/debconf/confmodule . Также этот файл нужно подключить в скрипте postinst: иначе скрипт DEBIAN/config вообще не выполнится!
Эти функции доступны в пакете debconf, не забудьте включить его в зависимости!
Примитивный пример использования. Файл DEBIAN/config
#!/bin/bash -e

# Подключение команд debconf

Case "$1" in
configure|reconfigure)
# Запрос


# Обработка ответа

greeting="$RET"
echo "$greeting" > /etc/supersh/greeting.txt
;;
*)
echo "config called with unknown argument \`$1"" >&2
exit 1
;;
esac
# Запрос
db_input medium "supersh/greeting" || true # инициализация
db_go || true # вывод запроса на экран

# Обработка ответа
db_get "supersh/greeting" # Получение значения в переменную $RET
greeting="$RET"
echo "$greeting" > /etc/supersh/greeting.txt

Здесь уже кроется неприятная засада: обратите внимание, что функции db_input передаётся приоритет диалога medium. Для debconf можно установить минимальный приоритет: диалоги с приоритетом ниже которого не отображаются, а берётся значение по умолчанию (Default шаблона)! Чтобы этого ТОЧНО не случилось - используем приоритет critical:) Кроме того, при установке из GUI порог вывода вопросов выше, и многие из них не отображаются вообще.
Возможные приоритеты: low - всегда используется default, medium - дефаулт обычно вполне подходит, high - дефаулт нежелателен, critical - внимание пользователя жизненно важно.
|| true используется чтобы скрипт не помер из-за ключика "-e" переданного bash.
В этом скрипте тоже рекомендуется использовать ту болванку для отлова ошибок, иначе с распространяемым пакетом могут возникнуть проблемы при отладке:)
Все тонкости использования debconf (функции, способы, параметры, коды ошибок) описаны в достаточно многословном мане: man debconf-devel .

И последнее: при удалении пакета командой purge - debconf должен также вычистить из своей базы сведения о пакете. Например, он сохраняет выбор пользователя при запросах db_input.
Чтобы вычистить эти данные, нужно в postinst-скрипт добавить следующее:
if [ "$1" == "purge" ] && [ -e /usr/share/debconf/confmodule ] ; then
. /usr/share/debconf/confmodule
db_purge
fi

Собираем пакет! :)

Ура! Все нужные файлы созданы, лежат по нужным папочкам. Теперь пора собирать пакет:)
Первое, что нужно сделать - это рекурсивно выставить всем файлам в корне пакета пользователя и группу root:root (или другие, если потребуется). Это нужно затем, что файлы пакета упаковываются в tar.gz архив который сохраняет и права доступа к файлам, и владельца. Потому нужно выполнить:
$ sudo chown -R root:root .
Однако делать это не обязательно. Есть отличная команда fakeroot которая при создании архива подменит владельца файлос root-ом.
В нашем примере, скрипт должен иметь бит выполнимости.
Потом выходим на папку назад, чтоб было видно корневую папку пакета, и пакет создаётся лёгким пинком сам:
$ fakeroot dpkg-deb --build supersh
Созданный пакет необходимо переименовать, чтобы он соответствовал порядку именования *.deb пакетов: <имя пакета>_<версия>_<архитектура>.deb
$ mv supersh.deb supersh_1.0-1_all.deb
Всё, пакет готов!
Автоматическая проверка пакета
Существует утилита lintian, позволяющая проверить пакет и выявить типичные ошибки в его структуре. Делается это так:
$ lintian supersh_1.0-1_all.deb
Установка пакета
$ sudo dpkg -i supersh_1.0-1_all.deb

Создаём собственный репозиторий пакетов

Теперь у нас есть собственный пакет. Когда их будет несколько, и тем более - с зависимостями, окажется, что намного удобнее быстренько поднять собственный локальный микро-репозиторий, и включить его в список источников менеджера пакетов:) Здесь я опишу быстрый HowTo «как создать свой репозиторий». Идею будет легко развить, почитывая соответствующую документацию:)
Сперва установим помощника:
$ sudo apt-get install reprepro
Описание будущего репозитория
Центр репозитория - его описание. Главное в нём - список компонент репозитория. Мы создадим компоненты «soft» и «games».
Выберите папку для будущего репозитория. Все действия производятся из её корня.
Создаём файл conf/distributions следующего содержания:
Description: my local repository
Origin: Ubuntu
Suite: testing
AlsoAcceptFor: unstable experimental
Codename: karmic
Version: 5.0
Architectures: i386 amd64 source
Components: soft games
UDebComponents: soft games

В нашем деле создания простого репозитория все поля не играют принципиальной роли, и используются лишь для визуального определения «что есть что»:)

Создание репозитория
Репозиторий описан! Теперь сгенерируем болванку на основе описания. Команды выполняются в корне репозитория:
$ reprepro export
$ reprepro createsymlinks
И добавим готовый репозиторий в /etc/apt/sources.list:
deb file:///path/to/repo/ karmic soft games
Этот репозиторий можно также расшарить при помощи веб-сервера.
Управление пакетами в репозитории
В корень репозитория кладём *.deb файлы для добавления, и добавляем их в компоненту soft дистрибутива karmic:
reprepro -C soft includedeb karmic *.deb
теперь пакеты доступны из менеджера пакетов:)
Удаление пакетов:
reprepro -C soft remove karmic supersh

Финиш

В статье рассмотрены материалы по созданию deb пакетов. Акцент сделан на моментах, для которых в сети нет достаточно наглядного описания. Надеюсь, что моя попытка изложить просто и понятно не провалилась:)
Домашнее задание:)) - вполне неплохо документированные вещи, которые легко найти в man"ах и статьях:
  • Создание source пакетов, компилирующих исходники: на примере Zabbix об этом отлично рассказал хабраюзер mahoro в своей статье
  • Debconf, debhelper в конфигурационных скриптах: читаем маны по debconf-devel и debhelper. Они также позволяют создать скелет пакета командой dh_make.
  • Продвинутые способы создания документации в пакетах: файлы DEBIAN/docs, DEBIAN/manpage.*
  • Создание init скриптов
  • Управление заданиями cron
  • Подписывание репозитория ключём gpg

Постараюсь как можно доступнее изложить процесс создания deb пакетов на примере ruby-zookeper. Предупреждаю сразу, что описанный мной метод пакетирования ruby gems неправильный, лучше использовать gem2deb для этого, но т.к. из исходников с помощью gem2deb собрать ruby-zookeper последней версии у меня не получилось, то вот самый простой метод сборки.

Если вы будете собирать ruby пакеты, как рекомендуется, через gem2deb, то лучше добавьте строку

Export DH_RUBY_IGNORE_TESTS=all/export DH_RUBY_IGNORE_TESTS=all

в debian/rules.

Т.к. мы будем собирать ruby код, то нам понадобится ruby и набор инструментов для сборки deb пакетов.

Sudo apt-get install ruby dpkg-dev

Если у вас старая версия ruby, то в ней нет команды gem, придется устанавливать еще и пакет rubygems или обновлять ruby.

Теперь установим гем fpm , который соберет за нас deb пакет.

Sudo gem install fpm fpm -s gem -t deb zookeeper

В текущей директории у нас появился пакет rubygem-zookeeper_1.4.11_amd64.deb, казалось бы, что дело уже в шляпе, но т.к. нам нужен source пакет, для того, чтобы можно было собрать из него deb, например в OBS , то мы будем продолжать.

Создадим сборочную директорию

Cp rubygem-zookeeper_1.4.11_amd64.deb ~/ cd mkdir -p ruby-zookeeper/fakeroot cd ruby-zookeeper/fakeroot

Извлечем в нее содержание только что собранного пакета

Dpkg-deb -R ~/rubygem-zookeeper_1.4.11_amd64.deb ruby-zookeeper_1.4.11-1

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

Mkdir debian cp rubygem-zookeeper_1.4.11-1/DEBIAN/control debian/control

Отредактируем его до следующего состояния. Не забудьте поменять Maintainer

Source: ruby-zookeeper Maintainer: Section: ruby Build-Depends: debhelper (>= 7.0.50~) Priority: extra Homepage: https://github.com/slyphon/zookeeper Package: ruby-zookeeper Architecture: amd64 Depends: ${shlibs:Depends}, ${misc:Depends}, ruby Description: A low-level multi-Ruby wrapper around the ZooKeeper API bindings. For a friendlier interface, see http://github.com/slyphon/zk. Currently supported: MRI: {1.8.7, 1.9.2, 1.9.3}, JRuby: ~> 1.6.7, Rubinius: 2.0.testing, REE 1.8.7. . This library uses version 3.4.5 of zookeeper bindings.

Нам еще нужен debian/rules. Создадим его. override_dh_shlibdeps нужен, чтоб не проверять линковку библиотек zookeeper, т.к. она не проходит.

#!/usr/bin/make -f # -*- makefile -*- %: dh $@ override_dh_shlibdeps: true

Табуляции в debian/rules обязательны, заменить их на пробелы нельзя. Сделаем его исполняемым.

Chmod +x debian/rules

Usr/* var/*

Теперь создадим debian/changelog и запишем туда:

Ruby-zookeeper (1.4.11-1) UNRELEASED; urgency=medium * Initial release -- root Wed, 25 Nov 2015 20:01:55 +0300

Также нам еще нужен debian/compat

Echo 7 > debian/compat

Скопируем файлы, которые будут установлены, в локальную директорию и удалим папку с распакованным пакетом, она нам больше не пригодится.

Mv ruby-zookeeper_1.4.11-1/{usr,var} . rm -r ruby-zookeeper_1.4.11-1

Соберем новый пакет, а также source пакет.

Dpkg-buildpackage -rfakeroot -uc -F

В директории выше у нас появятся все необходимые файлы.

Ll .. total 5528 drwxr-xr-x 3 root root 4096 Dec 20 13:32 ./ drwx------ 12 root root 4096 Dec 20 13:31 ../ drwxr-xr-x 5 root root 4096 Dec 20 13:28 fakeroot/ -rw-r--r-- 1 root root 1261 Dec 20 13:32 ruby-zookeeper_1.4.11-1_amd64.changes -rw-r--r-- 1 root root 2375044 Dec 20 13:32 ruby-zookeeper_1.4.11-1_amd64.deb -rw-r--r-- 1 root root 565 Dec 20 13:32 ruby-zookeeper_1.4.11-1.dsc -rw-r--r-- 1 root root 3263381 Dec 20 13:32 ruby-zookeeper_1.4.11-1.tar.gz

Можно проверить содержимое получившегося deb пакета

Создаём список пакетов:

$ dpkg-scanpackages . /dev/null | gzip -9c > ./Packages.gz
Может быть, нам будет выведено сообщение типа:

Dpkg-scanpackages: warning: Packages in archive but missing from override file: dpkg-scanpackages: warning: fossil linux-headers-3.8.0-avl9-pae linux-image-3.8.0-avl9-pae pdfsam sublimetext virtualbox-4.2 xserver-xorg-input-wacom zotero dpkg-scanpackages: info: Wrote 8 entries to output Packages file.
Теперь в нашем репозитории 8 пакетов. Отлично, добавляем наш репозиторий в файл:

строчкой типа:

Deb file:///home/имя_пользователя/zips/virensdebianrepository ./
Теперь нужно обновить список пакетов, чтобы они стали доступны для установки:

Всё, теперь можно установить, к примеру, свежесобранный текстовый редактор Sublime Text 2 (отличная инструкция там) как всегда: Теперь, для того, чтобы установить SublimeText достаточно сделать:
# apt-get install sublimetext

Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: sublimetext 0 upgraded, 1 newly installed, 0 to remove and 245 not upgraded. Need to get 0 B/11.4 MB of archives. After this operation, 17.4 MB of additional disk space will be used. WARNING: The following packages cannot be authenticated! sublimetext Install these packages without verification ? Y Selecting previously deselected package sublimetext. (Reading database ... 247813 files and directories currently installed.) Unpacking sublimetext (from ..././sublimetext_2.0.2_i386.deb) ... Setting up sublimetext (2.0.2) ... Всё, пакет будет распакован и установлен, а то, что он из местного репозитория, видно вот тут: (from ..././sublimetext_2.0.2_i386.deb)

Заключение

Описанные в этом посте рецепты - блюда на скорую руку, а не фуагра с трюфелями. Для больших репозиториев или сложных пакетов придётся-таки ознакомиться с документацией и руководствами . Ещё можно воспользоваться программой , которая умеет не только создавать репозитории, но и записывать их на CD/DVD диски.

Отдельное спасибо тов. brainstream , который указал на баг в посте с отрисовкой окружения PRE. Такое бывает, когда доверяешь хаскельным поделкам вроде pandoc:-)

Да, если есть что добавить - пишите в комментариях, но учтите, что пост - именно на скорую руку, без нужды перечитывать фолианты Debian Packaging Guidelines и прочую квантовую физику.

Анонимный комментирует...

Ошибка у вас в тексте:
"Теперь, для того, чтобы установить Skype достаточно сделать:

# apt-get install sublimetext "

Анонимный комментирует...

Распаковывать пакеты можно через dpkg-deb:
$ dpkg-deb -x что.deb куда/

Анонимный комментирует...

Всегда использовал dpkg -e и dpkg -x для полной распаковки пакета и быстрой правки файлов или зависимостей в контрольных файлах. А так же использовал checkinstall вместо make install для создания пакета при компиляции чего либо. Мне кажется эти утилиты стоит упомянуть.

virens комментирует...

Сборка пакетов из исходников в Debian - это от лукавого! Я сейчас припомню свой опыт:

1. В deb-пакете должны быть прописаны майнтейнер и прочая чепуха, без которой (сюрприз-сюрприз!) пакет не соберется.

2. Вы собрали, установили и думаете, что на этом всё? Не тут-то было, добрый aptitude может снести пакет ко всем чертям при установке чего-то другого. Вам знакомо такое чувство: как? где? что? я же уже ставил этот пакет!!! Ну вот такой он aptitude - весь из себя православный, а значит, патриархальный и вольнодумства не позволяющий.

3. Поэтому срочно необходим маневр: aptitude hold package. "Что, хорошо держится? А теперь будьте любезны - отлепите!" (с) Поскольку с этого момента aptitude будет ругаться, что он не в состоянии разрулить зависимости, не снеся вашего пакета.

4. На этом нервы мои сдали... И я открыл для себя Gentoo, а мои волосы снова стали мягкими и шелковистыми!

virens комментирует...

@iv_vl комментирует...
И я открыл для себя Gentoo, а мои волосы...
Наглый пиар Генты?! В моём бложике??? Нет пути! ;-)

1. В deb-пакете должны быть прописаны майнтейнер и прочая чепуха
Стандартное policy - надо же знать, кому дать в морду за сломанный пакет:-) И потом, это всяко лучше того бедлама, который творится в RPM-ных федорах и зюзях.

2. Вы собрали, установили и думаете, что на этом всё? Не тут-то было, добрый aptitude может снести пакет ко всем чертям при установке чего-то другого.
Только если ты ставишь пакет старой версии - например, у меня стоит hold на IceWM, который я поставил из Lenny (придурок-майнтейнер запихнул в Squeeze айс с отломанным треем). Аптитуда тебя предупредит перед подобными манёврами, если что.

3. Поэтому срочно необходим маневр: aptitude hold package.... aptitude будет ругаться, что он не в состоянии разрулить зависимости
Это ложь и провокация: только если ты не влепил hold на что-нибудь типа gcc или glibc, нормально оно разруливать зависимости будет. В отличие от RPM-ов, которые любят сдаваться сразу в стиле "Ну не шмогла я, не шмогла" :-)

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

4. На этом нервы мои сдали...
Как-то ты быстро сдулся. Кстати, а как дела с зависимостями в генте? Как вы там живёте-то с конпелянием на каждый чих?
Я это...не троллинга ради.... народ интересуется.

iv_vl

Если заметили ошибку, выделите фрагмент текста и нажмите Ctrl+Enter
ПОДЕЛИТЬСЯ: