Debian.pro

Блог для пользователей и администраторов Debian


Создаём свой репозиторий с deb-пакетами.

Мы научились собирать пакеты и подписывать их. Теперь самое время сделать свой репозиторий с пакетами.

По сути, есть 3 способа (более или менее «легальных») способа собрать свой репозиторий: dpkg-scanpackages, mini-dinstall и reprepo. dpkg-scanpackages — достаточно простая тулза, но требует много ручной работы. Я хоть и напишу про неё, но использовать её в промышленных масштабах не стоит. С reprepo я особенно не разобрался — официальная документация старовата и далека от вменяемости. Так что в основном здесь написано про mini-dinstall.

dpkg-scanpackages — утилита, которая индексирует каталог и создаёт для него файл Packages. Эту тулзу можно использовать как временную локальную замену (чтобы, например, проверить, что пакеты будут ставиться через apt-get), но не нужно использовать её там, где важна проверка подписи пакетов — dpkg-scanpackages сам по себе этого просто не умеет (хотя и можно подписывать репозиторий лапками).

Сам dpkg-scanpackages живет в пакете dpkg-dev, так что:

root@server:~# apt-get install dpkg-dev

Представим, что наши пакеты в прошлых статьях мы собирали в /home/user/packages:

user@server:~$ ls /home/user/packages
example-package_0.3_amd64.build example-package_0.3_amd64.changes example-package_0.3_amd64.deb

Тогда мы генерируем Packages.gz следующим образом:

user@server:~$ dpkg-scanpackages -t deb /home/user/packages/ | gzip | cat > /home/user/packages/Packages.gz

А в sources.list.d добавляем строчку "deb file:/home/user/ packages/":

root@server:~# echo "deb file:/home/user/ packages/" > /etc/apt/sources.list.d/my-own-repo.list

Проверяем, что репозиторий работает:

root@server:~# apt-get update; apt-cache policy example-package
...
example-package:
  Installed: (none)
  Candidate: 0.3
  Version table:
    0.3 0
      500 file:/home/ inkvizitor68sl/ Packages

Так в простейшем виде работает и mini-dinstall — генерирует Packages.gz. Но он умеет проверять подписи пакетов, работать по крону/демоном и прочие плюшки.

Повеселились, хватит. Давайте ставить mini-dinstall и другой софт, который пригодится:

root@server:~# apt-get install mini-dinstall debian-keyring gnupg acl

Дальше всё я буду расписывать исходя из того, что заливать пакеты в репозиторий будет несколько пользователей. Конечно, можно использовать dput и всё делать под одним пользователем, но если у вас полтора разработчика — то такой вариант вас уже не устроит и захочется предоставить возможность заливать пакеты с подписями разных разработчиков. Поэтому мы создадим отдельного пользователя и отдельный gpg-ключ, которым будем подписывать репозиторий. А подписи пакетов будем проверять перед тем, как добавить их в репозиторий.
Mini-dinstall незачем работать под рутом (если запустить его под рутом — нам не придется вводить целую дополнительную команду по выставлению вменяемых прав на каталог incoming, гы). Создадим отдельного пользователя:

root@server:~# adduser repokeeper

Пойдем под этого пользователя:

root@server:~# su repokeeper

Создадим папочку, куда будем складывать наш репозиторий:

repokeeper@server:~$ mkdir /home/repokeeper/repo/

Напишем конфиг /home/repokeeper/.mini-dinstall.conf для нашей собиралки репозиториев:

[DEFAULT]
archivedir = /home/repokeeper/repo/
mail_to = root@vlad.pro
verify_sigs = true
architectures = all, amd64, i386
archive_style = flat
generate_release = true
mail_on_success = true
release_codename = SomeShit
release_description = My Own Repo
release_label = someshit
release_origin = someshit
release_suite = None
extra_keyrings = ~/.gnupg/pubring.gpg
release_signscript = ~/sign-release.sh
incoming_permissions = 0
chown_changes_files = false

Генерируем ключ уже знакомой нам командой:

repokeeper@server:~$ LANG=C gpg --gen-key

Что там отвечать уже написано, стоит только заметить, что нам нужен именно новый ключ, а не ключ с теми же ответами. Ну там ник и почту измените для приличия.

Создадим каталог keys, в который для начала положим публичный ключ нашего репозитория. Там же мы будем складировать публичные ключи наших разработчиков (себя для начала).

repokeeper@server:~$ mkdir /home/repokeeper/keys

Сначала экспортируем публичный ключ репозитория. Под пользователем repokeeper делаем такое:

repokeeper@server:~$ gpg --export --armor repo@vlad.pro > ~/keys/repo.key

Где repo@vlad.pro — почта, которую мы использовали при генерации ключа для пользователя repokeeper.

Так же экспортируем ключ, которым мы подписываем пакеты и «добавим его» в валидные ключи для repokeeper (разрешив тем самым заливать пакеты, подписанные тем ключом). Под пользователем, из-под которого мы собираем пакеты, выполняем команду:

user@server:~$ gpg --export --armor root@vlad.pro > ~/inkvizitor68sl.gpg

(напомню, что свою почту я использовал в прошлом примере)
Файл inkvizitor68sl.gpg нам нужно закинуть в каталог /home/repokeeper/keys на том сервере, где у вас будет работать mini-dinstall. О правах на файлы можно не сильно беспокоиться (в конце концов, это публичная подпись — обладая ей хуже вам не сделают).

Теперь под пользователем repokeeper импортируем ключ «разработчика»:

repokeeper@server:~$ gpg --no-default-keyring --ignore-time-conflict --keyring .gnupg/pubring.gpg --import ~/keys/inkvizitor68sl.gpg

Так же нам понадобится скрипт, который будет запускаться для подписывания собранного репозитория. Подходящий скрипт есть в документации к mini-dinstall, утащим его себе:

repokeeper@server:~$ cp /usr/share/doc/mini-dinstall/examples/sign-release.sh ~/sign-release.sh

Немного подправим для своих нужд:

repokeeper@server:~$ sed -i 's/export GNUPGHOME=.*/export GNUPGHOME=~\/.gnupg/' sign-release.sh

В файл ~/.gnupg/passphrase нужно написать пароль от GPG ключа, который мы сгенерировали для репозитория.

Так как мы запускаем mini-dinstall не от рута, нам нужны корректные права на его incoming-каталог. При помощи chmod/chown надежно добиться у нас этого не получится (разработчики обязательно будут заливать с такими правами, что у mini-dinstall не будет хватать прав на удаление залитых файлов — и он будет падать с ошибкой), посему сделаем это через chattr:

root@server:~# setfacl -R --modify user:repokeeper:rwx /home/repokeeper/repo/
root@server:~# setfacl -R --modify group:repokeeper:rwx /home/repokeeper/repo/
root@server:~# setfacl -R --modify default:user:repokeeper:rwx /home/repokeeper/
root@server:~# setfacl -R --modify default:group:repokeeper:rwx /home/repokeeper/

А так же создадим группу, присутствие в которой будет позволять системным пользователям заливать пакеты на сервер (от рута):

root@server:~# addgroup repouploaders

И выставим права этим пользователям на каталог incoming:

root@server:~# setfacl -R --modify group:repouploaders:rwx /home/repokeeper/repo/mini-dinstall/incoming/
root@server:~# setfacl -R --modify default:group:repouploaders:rwx /home/repokeeper/repo/mini-dinstall/incoming/

И добавим пользователя, от которого собираем пакеты в группу аплоадеров. Точнее, добавим пользователя, которому мы хотим дать права на заливание файлов в репозиторий. Это может быть и аккаунт разработчика, который будет заливать пакеты по sftp/scp через dupload.

root@server:~# usermod -a -G repouploaders user

Заодно по дороге запретим заливать файлы всем остальным:

root@server:~# chmod 0700 /home/repokeeper/repo/mini-dinstall/incoming/

«Зальём» наш собранный ранее пакетик в репозиторий. Сейчас мы это делаем при помощи простого cp, в будущем я напишу о том, как использовать dupload.

repokeeper@server:~$ cp /home/user/packages/example-package_0.3_amd64.deb /home/repokeeper/repo/mini-dinstall/incoming/
repokeeper@server:~$ cp /home/user/packages/example-package_0.3_amd64.changes /home/repokeeper/repo/mini-dinstall/incoming/

Наконец-то запускаем сборку нашего репозитория (обратите внимание, не от рута):

repokeeper@server:~$ mini-dinstall -b -v

Если ошибок не видно, то проверяем содержимое файла Packages:

repokeeper@server:~$ cat ~/repo/unstable/Packages | grep Package
Package: example-package

Как видим, у нас в репозитории появился наш example-package. Попробуем поставить его.
Для начала подключим репозиторий локально:

root@server:~# echo "deb file:/home/repokeeper/repo/ unstable/" > /etc/apt/sources.list.d/my-own-repo.list; apt-get update

Проверяем, что пакет появился в индексе apt’a:

root@server:~# apt-cache policy example-package
example-package:
  Installed: (none)
  Candidate: 0.3
  Version table:
    0.3 0
      500 file:/home/repokeeper/repo/ unstable/ Packages

Пробуем его поставить:

root@server:~# apt-get install example-package
...
Install these packages without verification [y/N]?

Фиг нам, как говорится. apt считает пакеты недоверенным. Что ж мы, зря мучались с подписями) ? Скормим публичный ключ нашего репозитория нашему локальному apt-у:

root@server:~# cat /home/repokeeper/keys/repo.key | apt-key add -
OK

Обновим индекс apt-а, как обычно:

root@server:~# apt-get update

Пробуем поставить пакет:

root@server:~# apt-get install example-package

Вуаля. Поставился молча и сделал нам пустой /root/.ssh/authorized_keys, ибо я ленивая жопа и собрал таки пакет с пустыми файлами)

Теперь мы можем закидывать файлы в repo/mini-dinstall/incoming когда нам нужно и перегенерировать репозиторий командой от рута

root@server:~# su -c "mini-dinstall -b -v" repokeeper

или просто от пользователя repokeeper

repokeeper@server:~$ mini-dinstall -b -v

Дальше нам предстоит научиться использовать upload, запускать mini-dinstall по крону и демоном. А ещё не забыть расшарить репозиторий по http и https. А потом уже перейдем ко всяким забавным полезностям в dpkg.


Комментарии (2):

  1. Saymon21 :

    Есть ещё aptly — http://www.aptly.info/ но с ним я не разбирался.

  2. Я описал самый простой и самый правильный способ создания репозиториев)
    Aptly пока некоторых вещей не умеет, но его достаточно плотно сейчас пилят. Так что и про него напишу через годик)

Написать комментарий