Pull to refresh

Стать мэинтейнером — часть пятая

Reading time 6 min
Views 7.3K
Настало, наконец, время вернуться к теме пакетирования в Debian и Ubuntu.
Начну я с оправданий. Причиной долгой паузы, между четвертой и этой частью была не моя лень, не диплом, который я никак не допишу, и даже не положение звёзд, а уже упомянутый мною в предыдущих статьях (раз, два, три, четыре) досадный баг в одном из пакетов Debian. Как я, наконец, понял, скорого исправления этого бага ждать не стоит, поэтому я предлагаю тем, кто уже освоил сборку пакетов, изучить интересное средство, облегчающее как тестирование вашего пакета, так и сборку его под разные архитектуры — pbuilder.

pbuilder — это интересное средство, позволяющее нам создать архив, хранящий в себе образ свежеустановленной Debian или Ubuntu в минимальной комплектации — то есть, только с самыми необходимыми пакетами.

Зачем это нужно?


Представьте себе, ваш src-пакет скачал безвестный системный администратор Василий Дудочкин и хочет собрать из него пакет под свою mipsel-архитектуру. Потирая в предвкушении руки, он набирает заветную команду dpkg-buildpackage и… получает ошибку сборки. Дудочкин негодует, клянет кривых авторов программы, пишет содержательные багрепорты («Нисабирается, памагите!!!!!!») в трак апстрима. А всё из-за того, что вы забыли в графе Build-Depends вашего пакета указать gnutls-dev, которого у Дудочкина конечно же не стоит.
Именно в таких случаях нас спасает pbuilder — он скачает и установит все указанные в Build-Depends пакеты, попробует собрать ваш пакет исходников и, что тоже важно, в конечном итоге сохранит свой образ в неизменном виде для ваших дальнейших экспериментов.

Какие у этого подхода есть минусы?


Минуса два, но довольно больших.
Первый заключается в том, что для работы пакета требуется sudo или рутовый пароль. Пока вы работаете на своей домашней машине — всё замечательно, у вас есть все права, но если вы собираете на каком-то чужом сервере, то с этим могут возникнуть проблемы. Скажу честно, я пытался заставить pbuilder работать без рута, но мне не хватило терпения до конца доэкспериментировать с fakeroot.
Второй минус — это не самая высокая скорость работы. Дело в том, что образ системы хранится в .tgz файле. Соответственно типичный алгоритм сборки пакета выглядит как: распаковать образ — выкачать недостающие в кэше пакеты для сборки — установить пакеты для сборки — собрать пакет — вернуть всё на круги своя. Из-за этого сборка занимает довольно много времени, из которого большую часть составляет распаковка tgz-образа.

Как создать свой образ для pbuilder'а


Для начала ставим пакет pbuilder и открываем любимым редактором файл ~/.pbuilderrc:
  1. # кодовые названия дистрибутивов Debian
  2. UNSTABLE_CODENAME="unstable"
  3. TESTING_CODENAME="testing"
  4. STABLE_CODENAME="stable"
  5. DEBIAN_SUITES=($UNSTABLE_CODENAME $TESTING_CODENAME $STABLE_CODENAME
  6.     "sid" "squeeze" "lenny")
  7. # названия дистрибутивов Ubuntu
  8. UBUNTU_SUITES=("jaunty" "intrepid" "hardy" "gutsy")
  9.  
  10. # адреса зеркал с пакетами
  11. DEBIAN_MIRROR="ftp.us.debian.org"
  12. UBUNTU_MIRROR="mirrors.kernel.org"
  13.  
  14. # выбираем дистрибутив для использования
  15. : ${DIST:="$(lsb_release --short --codename)"}
  16. # а также архитектуру
  17. : ${ARCH:="$(dpkg --print-architecture)"}
  18.  
  19. # компоненты дистрибутива по умолчанию
  20. COMPONENTS="main contrib non-free"
  21.  
  22. # ну и давайте определим имя, которым мы будем обозначать отдельный образ
  23. NAME="$DIST"
  24. if [ -n "${ARCH}" ]; then
  25.     NAME="$NAME-$ARCH"
  26.     # следующая строчка нужна для того чтобы собирать под разные архитектуры
  27.     DEBOOTSTRAPOPTS=("--arch" "$ARCH" "${DEBOOTSTRAPOPTS[@]}")
  28. fi
  29.  
  30. # где мы будем создавать, а потом искать файл образа
  31. BASETGZ="/home/torkvemada/pbuilder/$NAME-base.tgz"
  32. DISTRIBUTION="$DIST"
  33. # и куда мы будем класть собранные пакеты
  34. BUILDRESULT="/home/torkvemada/pbuilder/$DIST/result/"
  35. # тут у нас будет лежать кэш слитых из сети пакетов
  36. APTCACHE="/home/torkvemada/pbuilder/$NAME/aptcache/"
  37. # а в это место будет распаковываться образ для сборки
  38. BUILDPLACE="/home/torkvemada/pbuilder/build/"
  39.  
  40. # если мы собираем под дебиан, то качать пакеты тута
  41. if $(echo ${DEBIAN_SUITES[@]} | grep -q $DIST); then
  42.     MIRRORSITE="http://$DEBIAN_MIRROR/debian/"
  43.     COMPONENTS="main contrib non-free"
  44. # а если под убунту, то качать тама
  45. elif $(echo ${UBUNTU_SUITES[@]} | grep -q $DIST); then
  46.     MIRRORSITE="http://$UBUNTU_MIRROR/ubuntu/"
  47.     COMPONENTS="main restricted universe multiverse"
  48. # а если вообще непонятно под что - то просто идти нафиг
  49. else
  50.     echo "Неизвестный дистрибутив: $DIST"
  51.     exit 1
  52. fi
  53.  
  54. # еще можно раскомментировать следующие два параметра по необходимости:
  55. # примонтировать каталог вашей системы в такой же каталог образа
  56. #BINDMOUNTS="/var/cache/archive"
  57. # подключить дополнительное зеркало помимо стандартного
  58. #OTHERMIRROR="deb file:///var/cache/archive unstable main"


Итак, полдела сделано. Главное, не забыть заменить в приведенном мною конфиге мой домашний каталог на свой или вообще на что-нибудь другое.
Теперь нам надо создать образ какой-нибудь системы. Например, так:
$ sudo ARCH=i386 DIST=hardy pbuilder --create

Именно здесь всплывает упомянутый мною баг. На Debian-системах cdebootstrap кривоватенько работает с созданием образов Ubuntu, в частности intrepid он у меня собрать отказывался категорически, а все дистрибутивы Debian у меня уже имелись в наличии. Поэтому данная статья пишется только сейчас, когда я настроил pbuilder на убунту для сборки убунтовых пакетов.

Таким образом мы можем создать себе пачку разных систем, которые дальше использовать в своё удовольствие. Например, данная система у меня лежит по адресу /home/torkvemada/pbuilder/hardy-i386-base.tgz.

Что теперь можно сделать с этим образом


С ним можно сделать несколько интересных вещей. Первая, для которой собственно всё и затевалось — это сборка пакетов. Заходим в произвольный каталог, в котором лежит наш исходный пакет и пробуем собрать:
$ cd mypackage-1.0.19/
$ sudo DIST=hardy ARCH=i386 pdebuild

Ждём, пока образ распакуется, выкачает все необходимые для сборки пакеты (пока кэш пустой, это займёт некоторое время, потом эти пакеты будут ставиться из кэша), установит их, и только затем приступит к сборке. Когда всё закончится, то если наш пакет собрался успешно мы можем его найти:
$ ls ~/pbuilder/hardy/result/*.deb
/home/torkvemada/pbuilder/hardy/result/mypackage_1.0.19-1_i386.deb

Что бы сделать еще? Еще можно посмотреть, а что же творится внутри нашего образа? Набираем:
$ sudo pbuilder --login --basetgz ~/pbuilder/hardy-i386-base.tgz

Вуаля! Мы внутри нашего образа, можем творить всё, что душе угодно, правда учитывайте, что в вашем распоряжении нет даже любимого многими Midnight Commander'а, а из текстовых редакторов — только sed. А что, не поверите, но я им вполне успешно пользовался для правки конфигов.
Как я уже говорил, все наши эксперименты не испортят систему — как только вы наберете «exit», чтобы выйти, образ вернется в своё начальное состояние, даже историю команд не сохранит. Но иногда возникает ситуация, когда необходимо изменить содержимое образа. Например, для одного моего пакета требуется наличие полных исходников PHP5. Как обойти эту проблему, я пока не знаю, а посему пакет просто ищет при сборке данные исходники по вполне определенному пути. Как же сохранить каталог исходников в pbuilder'е? Набираем:
$ sudo pbuilder --login --save-after-login --basetgz ~/pbuilder/hardy-i386-base.tgz

Теперь, всё что мы изменим, после выхода сохранится, можете быть уверены. Именно поэтому данную возможность надо использовать крайне осторожно.

Также часто возникает необходимость обновить версии пакетов в образе системы, Особенно, если мы являемся счастливыми обладателями образа Debian unstable. Всего лишь одна команда удовлетворит эту потребность:
$ sudo pbuilder --update --basetgz ~/pbuilder/hardy-i386-base.tgz


Ещё бывает необходимо использовать внешний репозиторий, например, наш домашний reprepro, упомянутый мною в четвертой статье. Для этого нам надо перед созданием образа раскомментировать в ~/.pbuilderrc строчку c OTHERMIRROR. Дополнительных зеркал может быть несколько, тогда разделять их надо вертикальной чертой. Если зеркало лежит не в сети, а на том же самом компьютере, то тогда надо раскомментировать и строчку BINDMOUNTS, указав в ней путь до монтируемого репозитория.
Если к моменту осознания вами необходимости стороннего репозитория вы уже создали образ без подключения оного — это печально, но у нас все равно есть два выхода. Первый — это просто поправить конфиг и создать образ заново. cdebootstrap опять будет долго выкачивать пакеты из интернета, но что поделать.
Второй способ проще. Набираем:
$ sudo pbuilder update --override-config --basetgz ~/pbuilder/hardy-i386-base.tgz --othermirror "deb myhost.ru/ubuntu hardy main"


P.s. Вот собственно и всё. По большому счёту, тема статьи себя исчерпала и о чём ещё написать, я пока даже не знаю. Поэтому если хотите более подробного освещения какой-нибудь темы — оставляйте заявки :)
Tags:
Hubs:
+31
Comments 19
Comments Comments 19

Articles