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

  • Автор
В Windows для установки софта как правило следует запустить файл инсталятора и следовать его инструкциям в оконном режиме, задав папку для установки и т.д
В Linux концепция установки ПО полностью отличается. Хотя Windows-подобные инсталяторы встречаются и для Linux софта, наиболее распространёнными вариантами являются:

  1. Установка ПО из исходных кодов

  2. Установка ПО из бинарных пакетов



Второй вариант является самым простым и распространённым. В этой статье мы рассмотрим структуру таких пакетов, методику их создания, а также менеджер пакетов apt-get и создание репозитория, из которого apt-get может устанавливать ПО.

В мире Linux наиболее распространёнными форматами пакетов являются rpm ( используются в дистрибутивах Red Hat, Fedora), и deb (используются в дистрибутивах Debian, Ubuntu).
В Raspbian соответственно используются deb пакеты

Установка/удаление пакета производится утилитой dpkg
установка: dpkg -i файл_пакета.deb
частичное удаление пакета: dpkg -r файл_пакета.deb Остаются настройки пакета, пользовательские данные и т.д
полное удаление пакета: dpkg -P файл_пакета.deb

дополнительные возможности dpkg:
dpkg -L название_пакета - список файлов, установленных пакетом в файловую систему.
dpkg -S имя_файла - покажет, какой пакет установил данный файл
dpkg -s название_пакета - вывод информации об установленном пакете.
dpkg -l - список установленных пакетов
dpkg -c файл_пакета.deb - список файлов, упакованных в deb пакет
dpkg -I файл_пакета.deb - информация о пакете

Deb пакет не установится, если в системе отсутствуют важные пакеты, от которых зависит работоспособность ПО, упакованного в deb пакет. Зависимости задаются разработчиком, при упаковке файлов в deb пакет.

Автоматически установить требуемые зависимости dpkg не может, поэтому для упрощения установки ПО в Linux были придуманы менеджеры пакетов.
В Raspbian используется менеджер пакетов apt-get.
Установка пакета осуществляется командой sudo apt-get install название_пакета
Во время выполнения данной команды apt-get произведёт поиск пакета в репозиториях, указанных в конфиге /etc/apt/sources.list, а также поиск всех зависимостей данного пакета, после чего будет произведена установка.
Обратите внимание, что apt-get ведёт поиск пакетов по локально сохранённому "индексу" пакетов. Поэтому периодически необходимо обновлять этот индекс командой sudo apt-get update
Удаление пакета осуществляется командой sudo apt-get remove название_пакета, если к команде добавить ключ -purge, то будут удалены и конфигурационные файлы пакета

Чтобы обновить все пакеты, установленные через apt-get до самой свежей версии используется команда sudo apt-get upgrade. Я этой функцией не пользуюсь без крайней необходимости - как показывает опыт, если что-то нормально работает, то это лучше не трогать

Создание собственных deb пакетов


Создание deb пакета довольно обширная тема, в рамках этой статьи мы рассмотрим только основы.
Допустим вы разработчик ПО для raspberry pi, создали и скомпилировали программный комплекc, состоящий из бинарника my_raspi_soft и конфига к нему my_raspi_soft.conf
Для упрощения дистрибуции вашей программы упакуем её в deb-пакет и добавим его в собственный репозиторий, чтобы
ваши пользователи могли легко установить вашу программу командой apt-get my_raspi_soft install

Итак, создадим в удобном месте (например в домашней директории) папку (в дальнейшем я буду называть её директорией пакета), в которой будем создавать структуру пакета
mkdir  ~/my_raspi_soft
и установим инструменты необходимые для создания deb пакета:
sudo apt-get install dpkg lintian

В директории пакета создаём папку DEBIAN (в ней будут храниться служебные файлы пакета, необходимые для его правильной упаковки):
mkdir ~/my_raspi_soft/DEBIAN

и файловую структуру установки пакета - она указывает, куда копировать файлы пакета во время его установки. Допустим мы предполагаем, что во время установки пакета файл my_raspi_soft должен быть скопирован в /usr/bin, а его конфиг my_raspi_soft.conf в /etc/. Тогда файловая структура должна иметь вид:
mkdir -p ~/my_raspi_soft/usr/bin //после создания диретории помещаем в неё наш бинарник my_raspi_soft
mkdir ~/my_raspi_soft/etc //после создания диретории помещаем в неё наш конфиг my_raspi_soft.conf


Теперь приступим к наполнению папки DEBIAN служебными файлами.
Главным служебным файлом является файл control, в него заносятся свойства пакета в формате свойство: значение свойства.
Свойства, которые добавляются в control файл (обязательные свойства я выделил жирным шрифтом):
Package - имя пакета. Именно оно используется при установке через apt-get install. Допустимо использовать латинские буквы, цифры и дефис (Package: my-raspi-soft)
Version - версия программы и пакета в формате версия_программы-версия_пакета. (пример: 0.9-1)
Maintainer - "мэйнтейнер", создатель пакета, ответственный за его обновление и т.д Формат вида имя email (Vasya )
Architecture - архитектура процессора, для которого предназначен пакет. В случае с Raspberry Pi это будет armhf
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
Description - описание пакета
Depends - список зависимостей - пакетов, без которых не возможна работа нашей my_raspi_soft. Также можно указать требуюмую версию таких пакетов при помощи операторов <<, =, >>, <=, >=. Допустим в нашем проекте используется библиотека wiringPi. Тогда в config добавим строку - Depends:libwiringpi
Conflicts - список пакетов, с которыми конфликтует наша программа. Пока эти пакеты установлены в системе, установка пакета с нашей программой будет невозможна.

В итоге наш файл control будет выглядеть как-то так:

Package: my-raspi-soft
Version: 0.1-1
Section: misc
Architecture: armhf
Depends: libwiringpi
Maintainer: Vasya Description: My RasPi software


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

Какие ещё служебные файлы можно разместить в папке DEBIAN?
copyright - текст лицензии и декларация авторских прав
changelog - история изменений в специальном формате
conffiles - список файлов конфигурации (полный путь). Это нужно для того, чтобы при обновлении пакета можно было оставить старые настройки. Можно добавить сюда наш /etc/my_raspi_soft.conf
md5sums - контрольные суммы файлов пакета. можно заполнить так:
md5deep -r директория_пакета > директория_пакета/DEBIAN/md5sums


Кроме служебных файлов в папке DEBIAN можно разместить скрипты, которые будут выполняться до/после установки/удаления пакета.
preinst - скрипт с таким именем выполняется до установки пакета
postinst - скрипт, выполняющийся после установки пакета
prerm - скрипт, выполняющийся перед удалением пакета
postrm - скрипт, выполняющийся после удаление пакета

Минимальная структура пакета создана, теперь можно приступать к его упаковке в deb файл!
Переходим на 1 папку выше директории пакета и выполняем команду
fakeroot dpkg-deb --build my_raspi_soft

Всё, пакет готов. Осталось лишь переименовать его согласно стандарту имяпакета_версия_архитектура.deb
mv my_raspi_soft.deb my-raspi-soft_0.9-1_armhf.deb

В завершении протестируем пакет на ошибки при помощи lintian:
lintian my-raspi-soft_0.9-1_armhf.deb

Если ошибок нет, то можно закачивать пакет в репозиторий для последующего распространения

Создание репозитория deb пакетов


Нам потребуется сервер с установленным веб-сервером Apache (или любым другим).
Создаём в конфиге апача новый виртуальный хост для домена (например repo.yourserver.com), на котором будет висеть наш репозиторий. В настройках виртуального хоста обязательно разрешаем просмотр папок в DOCUMENT_ROOT (Options All Indexes)
В этом примере в качестве DOCUMENT_ROOT будет выступать директория - /home/repo/www

Создаём структуру репозитория:
# mkdir -p /home/repo/www/apt/pool/main
# mkdir -p /home/repo/www/apt/dists/stable/main/binary-armhf


Загружаем наш deb пакет my-raspi-soft_0.9-1_armhf.deb в /home/repo/www/apt/pool/main/

Создание GPG ключей

Публичный GPG ключ должен быть создан и затем скачан пользователями вашего репозитория. Если этого не сделать, то каждый раз при установке пакетов из вашего репозитория apt-get будет выводить предупреждение.

Создаём ключ командой:
gpg --gen-key

Проверяем ключ:
gpg --list-keys

Вывод этой команды будет примерно таким:
pub   2048R/CE123456 2012-09-02 [expires: 2022-08-31]
uid My repo


Далее:
# gpg --export -a CE123456 > ~/repo.key
# gpg --no-default-keyring --keyring /home/repo/www/apt/myrepo.gpg --import ~/repo.key
# rm ~/repo.key


Индексация и подпись пакетов


Чтобы клиентские менеджеры пакетов apt-get могли устанавливать пакеты из нашего репозитория, необходимо произвести индексацию пакетов, которые мы загрузили в /home/repo/www/apt/pool/main/
Для этого можно использовать вот такой несложный скрипт. Он произведёт индексацию всех пакетов в /home/repo/www/apt/pool/main, создаст файл /home/repo/www/apt/pool/main/Release, который содержит MD5 и SHA хэши всех файлов пакета и подпишет файл Release ключом Release.gpg.
Запускать этот файл нужно каждый раз после загрузки нового deb пакета в наш репозиторий (GPG_NAME заменить на параметр, который соответствует вашему ключу, созданному в предыдущем шаге)
#!/bin/bash

GPG_NAME=CE123456
REPONAME=stable
VERSION=6.0

for bindir in `find dists/${REPONAME} -type d -name "binary*"`; do
arch=`echo $bindir|cut -d"-" -f 2`
echo "Processing ${bindir} with arch ${arch}"

overrides_file=/tmp/overrides
package_file=$bindir/Packages
release_file=$bindir/Release

# Create simple overrides file to stop warnings
cat /dev/null > $overrides_file
for pkg in `ls pool/main/ | grep -E "(all|${arch})\.deb"`; do
pkg_name=`/usr/bin/dpkg-deb -f pool/main/${pkg} Package`
echo "${pkg_name} Priority extra" >> $overrides_file
done

# Index of packages is written to Packages which is also zipped
dpkg-scanpackages -a ${arch} pool/main $overrides_file > $package_file
# The line above is also commonly written as:
# dpkg-scanpackages -a ${arch} pool/main /dev/null > $package_file
gzip -9c $package_file > ${package_file}.gz
bzip2 -c $package_file > ${package_file}.bz2

# Cleanup
rm $overrides_file
done

# Release info goes into Release & Release.gpg which includes an md5 & sha1 hash of Packages.*
# Generate & sign release file
cd dists/${REPONAME}
cat > Release < Suite: ${REPONAME}
Version: ${VERSION}
Component: main
Origin: My Company
Label: My Repo
Architecture: armhf
Date: `date`
ENDRELEASE

# Generate hashes
echo "MD5Sum:" >> Release
for hashme in `find main -type f`; do
md5=`openssl dgst -md5 ${hashme}|cut -d" " -f 2`
size=`stat -c %s ${hashme}`
echo " ${md5} ${size} ${hashme}" >> Release
done
echo "SHA1:" >> Release
for hashme in `find main -type f`; do
sha1=`openssl dgst -sha1 ${hashme}|cut -d" " -f 2`
size=`stat -c %s ${hashme}`
echo " ${sha1} ${size} ${hashme}" >> Release
done

# Sign!
gpg --yes -u $GPG_NAME --sign -bao Release.gpg Release
cd


Сохраните код скрипта в /home/repo/www/apt/reindex.sh и запустите его:
chmod +x /home/repo/www/apt/reindex.sh
/home/repo/www/apt/reindex.sh

В результате выполнения скрипта, структура файлов в нашем репозитории примет вид:
/home/repo/www/apt/
/home/repo/www/apt/dists
/home/repo/www/apt/dists/stable
/home/repo/www/apt/dists/stable/Release
/home/repo/www/apt/dists/stable/Release.gpg
/home/repo/www/apt/dists/stable/main
/home/repo/www/apt/dists/stable/main/binary-armhf
/home/repo/www/apt/dists/stable/main/binary-armhf/Packages.gz
/home/repo/www/apt/dists/stable/main/binary-armhf/Packages.bz2
/home/repo/www/apt/dists/stable/main/binary-armhf/Packages
/home/repo/www/apt/pool
/home/repo/www/apt/pool/main
/home/repo/www/apt/pool/main/my-raspi-soft_0.9-1_armhf.deb
/home/repo/www/apt/reindex_stable.sh
/home/repo/www/apt/myrepo.gpg

Клиентские настройки для apt-get

Чтобы пользователи могли устанавливать ПО из вашего репозитория при помощи менеджера пакетов apt-get, они должны
1.добавить ваш репозиторий в /etc/apt/sources.list
deb http://repo.yourserver.com/ stable main


2.скачать ключ:
# cd /etc/apt/trusted.gpg.d/
# wget http://repo.yourserver.com/myrepo.gpg


3.Обновить локальный индекс пакетов apt-get
sudo apt-get update


После выполнения этих шагов ваша программа может быть установлена командой:
sudo apt-get install my-raspi-soft

Комментарии:

Для написания комментариев необходимо зарегистрироваться