Убунтариум

индекс
253,47

deb-пакет на коленке

Задача: создать пакет для Debian для выливки демона/сайта на сервер.
Я никогда ранее не работал с deb-пакетами — так что решение может быть не оптимальным. Но оно работает и достаточно просто в использовании.

Подготовка

В первую очередь для переодических выливок на сервер нам понадобится версионность кода. Если оспользуется svn — то, скорее всего, можно использовать номер ревизии. Так как я использую git — написал простенький скрипт для ведения версии проекта: tag.sh
Для увеличения версии проекта вызываем ./tag.sh build, ./tag minor или ./tag major. Скрипт создаёт метки вида v<MAJOR>.<MINOR>.<BUILD> (к примеру v0.1.25)
Для получения версии вызываем git describe --match=v* HEAD и получаем в результате версию в виде v0.2.1 (либо v0.2.1-59-g919ab19 если после тага были коммиты).

В сети много мануалов по созданию пакетов, которые используют dh_make либо описывают все возможные варианты создания пакета с нуля. Но нам не требуется правильный пакет для внесения в репозиторий дебиана, а всего лишь пакет нашего проекта, который мы установим на сервере.

Из всех файлов конфигурации пакета важными показались лишь 2:
control — описание пакета
conffiles — описание конфигурационных файлов пакета (при установке новой версии apt спросит заменить ли файл или оставить старую версию).

control

Формат файла достаточно простой:
Package: ИМЯ_ПАКЕТА
Version: ВЕРСИЯ - получаная git describe
Architecture: АРХИТЕКТУРА - amd64 если есть бинарники или all - если только скрипты
Depends: ЗАВИСИМОСТИ - можно упустить
Maintainer: ВАШЕ_ИМЯ
Description: ОПИСАНИЕ

К примеру:
Package: ggseductionserver
Version: v0.2.1-59-g919ab19
Architecture: amd64
Depends: libc6 (>= 2.4), libgcc1 (>= 1:4.1.1), libstdc++6 (>= 4.1.1), libboost-system1.38.0 (>=1.38.0),
libboost-thread1.38.0 (>=1.38.0), libboost-regex1.38.0 (>=1.38.0), libboost-serialization1.38.0 (>=1.38.0), libboost-program-options1.38.0 (>=1.38.0),
tokyotyrant, tokyocabinet, mysql-client (>=5.0), libssl0.9.8 (>=0.9.8), libreadline5 (>= 5.2), libmysql++3 (>= 3.0),
libpcre3 (>= 7.6), libpcrecpp0 (>= 7.6), libgd2-xpm (>= 2.0)
Maintainer: Alexander Fedora <alexander.fedora at gmail.com>
Description: glagol games server
<ПРОБЕЛ>This is server

Зависимости можно получить используя ldd и apt-file
$ ldd ./build/server | grep libboost_thread
/usr/lib/libboost_thread-mt.so.1.38.0
$ apt-file search /usr/lib/libboost_thread-mt.so.1.38.0
libboost-thread1.38.0: /usr/lib/libboost_thread-mt.so.1.38.0
libboost1.38-dbg: /usr/lib/debug/usr/lib/libboost_thread-mt.so.1.38.0

conffiles

В этом файле находится список конфигурационных файлов пакета. Пример:
/etc/seduction/seductiond.conf
/etc/seduction/seductiond.log.properties


Создание пакета

Я решил использовать простой шелл скрипт для создания пакета. Действия по порядку:
  1. Создаём директорию deb
  2. Создаём директорию deb/DEBIAN
  3. Получаем текущую версию проекта version=`git describe --match=v* HEAD`
  4. Записываем в deb/DEBIAN/control описание пакета, а в качестве версии используем $version
  5. Записываем в файл deb/DEBIAN/conffiles список конфигурационных файлов
  6. В директорию deb/ записываем файлы прокета как будто deb/ — это рут диска (к примеру deb/usr/local/bin/exe_name, deb/etc/config_name и тд)
  7. Создаём пакет при помощи комманды dpkg -b deb/ ИМЯПАКЕТА_$version'.deb'

После имени пакета обязательно поставить подчеркивание (_) перед версией.
Пример рабочего скрипта можно посмотреть тут (это пример для с++ демона, для сайта на php пример тут)

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

Устанавливаем пакет dpkg-dev.
Создаем директорию /var/opt/repo/, а в ней 2 подддиректории binary и source.
Заливаем пакеты в binary и выполняем комманду для создания каталога архива:

dpkg-scanpackages -m binary /dev/null | gzip -9c > binary/Packages.gz

Записываем shell-скрипт для автоматизации апдейта сервера:

rsync -av -e ssh $HOME/projects/repo/*.deb server_name:/var/opt/repo/ || exit 1
ssh server_name 'cd /var/opt/repo; dpkg-scanpackages -m binary /dev/null | gzip -9c > binary/Packages.gz' || exit 1


Поднятие nginx для доступа к репозиторию

Устанавливаем nginx, добавляем новый сайт:
$ cat /etc/nginx/sites-available/repo
server {
listen 9977;
server_name localhost;
access_log /var/log/nginx/repo.access.log;
location / {
autoindex on;
allow 127.0.0.1;
allow 192.168.0.2;
root /var/opt/repo;
}
}


Поднимаем сайт и убеждаемся что он работает.
$ ln -s /etc/nginx/sites-available/repo /etc/nginx/sites-enabled/repo
$ sudo /etc/init.d/nginx restart
$ wget 192.168.0.1:9977/binary/Packages.gz


Установка пакетов из созданного репозитория

Добавляем в /etc/apt/sources.list наш сайт:
deb 192.168.0.1:9977/ binary/
И устанавливаем пакет:
$ sudo apt-get update
$ sudo apt-get install package_name


Заключение

При установке пакета apt-get будет вопить, что пакет не может быть аутентифицирован. В принципе можно добавить цифровую подпись к пакету, но мы то и так знаем что он устанавливается с нашего репозитория — поэтому можно добавить ключики -y --force-yes и устанавливать пакет в автоматическом режиме.

PS. сильно не пинайте — это мой первый пост.
_________
Текст подготовлен в ХабраРедакторе
+53
17 октября 2009, 03:30
104

комментарии (47)

НЛО прилетело и опубликовало эту надпись здесь
0
ghisguth #
В какой блог перенести? Может «Разработка» или «Убунтариум»?
0
skobkin #
Лучше в убунтариум.
0
ghisguth #
Ок, сейчас перенесу.
0
oe24 #
Может, стоит перенести в блог Убунтариум?..
0
ghisguth #
Это наиболее близкий блог по тематике? А не лучше будет в «Разработку» перенести?
0
unicast #
Когда в следующий раз появится статья про «установим PHP из исходников», буду на Вашу ссылаться, как на образец.
Спасибо!
0
develop7 #
Не знаю, как в RPM-based дистрибутивах, но сборка debов PHP — процесс, мягко говоря, сложный.
НЛО прилетело и опубликовало эту надпись здесь
0
ghisguth #
Можно попробовать использовать git svn, но я не использую там теги — поэтому не знаю получится ли залить их в svn.
В крайнем случае можно использовать номер ревизии с git-svn-id, а версию делать 1.0.НОМЕР_РЕВИЗИИ
0
NixGuy #
Можно попробовать checkinstall, который сделает почти всю грязную работу сам.
–1
ghisguth #
Смысл был не в том, что бы установить пакет на локальной машине, а что бы на локальной машине собрать пакет и установить его на серверах
0
NixGuy #
Одной из возможностей checkinstall как раз является сборка пакетов: вот и вот
0
Deepwalker #
Гораздо полезнее было бы подготовить директорию для сборки пакета со всякими control.
Потому что автоматически собранный пакет это совсем не то, что надо — надо подправить стартовые скрипты, настройки в /etc/default кинуть и тп.

Мне больше понравился вариант с tap2deb — эта утилита готовит для приложения на twisted все требуемое — остается обтесать и собирать.
0
nerezus #
Какие отличия будут для убунту?
Как пропписать действие(!) при установке обновлении, чтобы прописать в другие конфиги пару строк?
0
skobkin #
В убунту те же менеджеры пакетов. apt и aptitude.
–1
nerezus #
Ну я поэтому и спросил, какие отличия.

postinst файл — ответ на мой второй вопрос.
0
skobkin #
Да тупо добавляешь свою репу в sources.list и будет тебе счастье. Вот же беда…
0
nerezus #
Я задал вполне конкретный вопрос, если что. Можно не отвечать: отличий нет. Но вот прочитать вопрос перед ответом все же было желательно.
+1
skobkin #
>Как пропписать действие(!) при установке обновлении, чтобы прописать в другие конфиги пару строк?

Извиняюсь, но это все что я понял из заданного вопроса. Об такой вопрос можно мозг сломать.
+1
ghisguth #
У нас как раз пакет собирается на локальной машине с Ubuntu, а заливается на офисный сервер с Ubuntu Server и на площадку на Debian Lenny.
Для выливки с++ кода на Debian есть одна проблема — версии пакетов зависимостей могу не совпадать. Для её решения мы используем chroot дебиана на локальной машине с ubuntu в котором версии пакетов те же что и на бою. В chroot-е собирается пакет, а потом выливается на бой.
0
Honeyman #
pbuilder?
0
ghisguth #
Нет. Сделал как написано тут DebootstrapChroot. А pbuilder посмотрю, спасибо.
0
ghisguth #
Для задания действия при установке достаточно добавить shell скрипт с именем postinst (детальнее тут).
0
nerezus #
Ну я думаю, что не обязательно shell )
0
NixGuy #
Да, можно любой. Допустим, на любимом разарбочиками Ubuntu python'е.
0
Veshij #
не обязательно :) но он должен обрабатывать небольшой набор передаваемых параметров.
0
alisfen #
Кстати интересно было бы коммьюнити узнать о сборке рпм-пакетов?
0
Deepwalker #
Да! Если возможно, то было бы неплохо узнать про отличия от deb-пакетов.
+2
Deepwalker #
Кстати все таки советую не лениться, а сделать свой ключ и подписывать им репозитарий и внести его в доверенные на всех серверах. В интернетах были руководства и готовые скрипты для автоматизации.

Вот когда то давно писал — deepwalker.blogspot.com/2008/03/ubuntu.html
0
Strange #
Где Вы были два дня назад, когда я читал многостраничные мануалы)
Спасибо, в избранное.
+1
Veshij #
Это работающий, но не совсем правильный способ сборки deb-пакета.
Для облегчения этой задачи есть набор утилит debhelper, которые позволяют создавать «рыбы» пакетов, автоматически заполнять их и собирать, соблюдая все зависимости (debuild).
Если интересно — могу немного рассказать.
0
ghisguth #
Будет время попробую и правильный способ вместе с pbuilder-ом.
А какие преимущества он даст (ну окромя автоматической генерации зависимостей пакета)?
0
d1m #
Было бы весьма интересно.
0
qmax #
в составе утилит серии dh_make есть утилитка, котрая автоматически вычисляет зависимостии запихивает их в заголовок пакета
хотя для пакета-сайта, оно, конечно, не требуется.
0
nerezus #
Требуется как раз ;)
Пяток пакетов типа ZF, jQuery с модулями, Rich-редактора и прочих обновляемых либ все же придется тащить ;)
0
brainerazer #
Плюсанул. Но всё равно PKGBUILD`ы рулят %)
0
Vii #
А что вы подразумеваете под «выливки сайта на сервер»? Весь серверный код (php/python-скрипты), вёрстку, картинки?
Нельзя ли пару слов о преимуществах перед (например) какими-нибудь скриптами для SCM-системы, которая закачивает изменения на сервак (вроде для svn это можно делаеть через хуки, не уверен)? Для чего это, что даёт?
0
ghisguth #
Да именно — код на php, swf-ки, верстка, статические картинки. Ну а так же все демоны, обслуживающие сайт. Как раз из-за демонов и было прийнято решение перейти на пакеты.
Используя пакеты вместо VCS облегчается сама выливка. И её может проводить не программист, а админ (который умеет работать с пакетной системой и не хочет знать что такое код и как его выливать).
Для выливок сугубо скриптовой части, в принципе, подойдут и Capistrano, Vlad the Deployer и похожие утилиты (они могут забирать исходики с VCS, но это не отменяет того, что их можно использовать в комбинации с пакетами).
Раньше мы использовали такую схему: на офисном сервере делали чекаут конкретной версии исходников, rsync-ом заливали код на все сервера и билдили демоны на каждой машине. Тогда боевые сервера были на Gentoo и такой метод был приемлем, хотя и вызывал более длительные выливки чем нам хотелось. Сейчас мы перешли на Debian и использовать его пакетную систему было логично. К слову раньше минимальная выливка занимала около полу часа (пока зальются все изменения, пока соберется код). Теперь все пакеты загружены на сервер до выливки. Админ вызывает apt-get install, рестартует демоны и проводит небольшую проверку. Это занимает отсилы 5 минут.
А пулить код с боевого сервера не такая уж и хорошая идея. Недавняя история с уязвимостю с svn подтверждает это. Лучше пушить код на сервер, который ничего не знает о сервере, где код хранится. Но это сугубо моё личное мнение.
+1
Mezomish #
Сам некоторое время собирал свой проект именно так, сляпанным на коленке control-файлом и dpkg -b :)
Потом всё-таки собрался с духом и довёл до ума, чтобы собиралось с помощью dpkg-buildpackage, теперь горя не знаю: заливаю на OBS и он собирает мне под любые архитектуры и любые релизы Дебиана/Убунты.
Остался последний шаг, который я всё никак не соберусь сделать: надо добавить gpg-ключ.
0
Fragster #
есть программа checkinstall, которая из исходников делает и .rpm и .deb, а заодно и устанавливать в систему этот пакет может. версию и зависимости можно прописывать интерактивно.
0
ergil #
то как это делает чекинсталл… лучше бы и не делало.
ни зависимостей, ничего.
единственный толк от него это возможность потом штатно удалить, а не вычищать систему.

а уважаемый коллега все же писал статью как сделать пакет который будет ставится на другие сервера+к тому с зависимостями и версионностью.
0
Fragster #
при использовании checkinstall можно задавать зависимости. Автор же предлагает точно также указывать зависимости в файлике с незатейливым именем «control»
0
ergil #
этот «незатейливый» файлик — часть стандарта при создании пакета для дэбиан.
сорри, не знал, что чекинсталл хоть чему-то научился, использовал его году в 2002.
0
ergil #
на самом деле, чем руками создавать control и товарищи тебе тут правильно рекомендуют dh_make, который создает болванку директории со всеми файлами.
я тут просто свежий luarocks в пакетик заворачиваю, вот и столкнулся с вопросом тоже :)
0
alexeyshockov #
Было бы очень интересно почитать про приемущества такого способа (deb-пакеты) для обновления сайта перед остальными (svn, к примеру) в отдельной статье. А то методика есть, а цель её не совсем ясна. Да и в Сети таких статей (сравнений методов обновления сайта) я, к сожалению, не нашёл :(

Привести примеры задач, для которых это требуется и т.д.

P.S. Да, в комментариях выше это частично объясняется, но только частично. Хотелось бы более развёрнуто.
+1
ghisguth #
Ну тут дело не в преимуществе одного метода над другим, а выборе верного метода под конкретную задачу. К примеру:

1. git/svn/hg/… — для контроля версий
2. deb/rpm/… — для хранения бинарных данных, трекинга зависимостей, менеджмента версий средствами ОС
3. capistrano/vlad the deployer/… — для автоматизации работы на нескольких серверах, автоматизации выливки и отката изменений и тд.

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

Для сайта на одном-двух серверах, который состоит из нескольких модулей и сложными зависимостями на установленые приложения (либо включает в себя компоненты на с/c++, которые должны быть собраны в бинарники) — оптимальным будет использование пакетов, так как часть работы ложится на пакетный менеджер ОС.

Для развернутых на большом числе машин и сложной системой развартывания — лучше использовать специальные системы деплоя типа capistrano. Причем можно использовать в комбинации как с vcs, так и с теми же пакетами.

У меня мало опыта работы с системами автоматического деплоя, но есть планы по внедрению capistrano в недалеком будущем. После этого постараюсь оформить полученный опыт в статью, в которой сравнить все три указанных подхода.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.