Выпуск 7. Сентябрь 2013

Статический анализ кода | Содержание | Обзор CPAN за август 2013 г.

Сборка deb-пакетов модулей Perl для Debian и Ubuntu

Несколько докладов прошедшего YAPC::Europe 2013 были посвящены теме сборки пакетов (rpm, pkgsrc) модулей Perl для упрощения процесса установки Perl-программ с использованием штатного менеджера пакетов системы. Чтобы дополнить спектр охваченных пакетных менеджеров, в данной статье будет рассказано о сборке deb-пакетов, которые применяются во множестве популярных Linux-дистрибутивов, таких как Debian и Ubuntu.

Зачем паковать Perl-модули в пакеты?

Большинство Perl-программистов знакомы с привычными утилитами для установки Perl модулей: cpan или cpanm. Эти утилиты очень удобны для разработчиков и позволяют им достаточно легко установить нужные модули в системный или домашний каталоги. К сожалению, подобный метод установки плохо пригоден для развёртывания уже готового проекта, поскольку набор устанавливаемых модулей мог обновиться на CPAN, и обновлённые модули могли оказаться неработоспособными или могли сломать работу зависимых модулей. Даже развёртывание собственного CPAN с использованием таких систем как Pinto для фиксации версий может быть непригодно, если администратор не хочет, чтобы на сервер, на котором будет работать продукт, нужно было устанавливать компиляторы, заголовочные файлы всех сторонних библиотек, которые потребуются для сборки XS-модулей, и следить за тем, чтобы после обновления системных библиотек не возникло бинарной несовместимости с собранными XS-модулями. К тому же ожидание процесса завершения компиляции и тестов на каждом сервере может занимать неприлично долгое время.

Упаковка модуля в пакет того типа, который применяется в текущей системе, даёт следующие преимущества:

  • фиксируется версия модуля,
  • уменьшается время установки за счёт того, что компиляция и тесты происходят только во время сборки пакета,
  • фиксируются все зависимости на другие пакеты, включая зависимости на сторонние библиотеки,
  • отслеживаются файловые конфликты,
  • отслеживаются бинарные конфликты (нельзя обновить библиотеку с новым soname без удаления всех пакетов, зависящих от старой версии),
  • отслеживается целостность (md5sum, gpg),
  • возможность простого обновления до новой версии и отката на старую версию.

Единственный недостаток упаковки — это жёсткая привязка к той платформе, на которой работает данный менеджер пакетов. Но если в эксплуатации отсутствует зоопарк дистрибутивов, то этот недостаток незаметен.

dh-make-perl

В составе дистрибутива Debian присутствует утилита dh-make-perl, которая значительно упрощает процесс создания deb-пакета для Perl-модулей. В большинстве случаев практически не требуется вникать в суть того, как организованы deb-пакеты, как происходит их сборка, что очень удобно для начинающих.

Для её установки достаточно вызывать команду:

$ sudo apt-get install dh-make-perl

Эта команда, как и все последующие в данной статье примеры команд, выполняются на системе Ubuntu Server 12.04.3 LTS. К сожалению, идущий в составе этого дистрибутива dh-make-perl 0.75 сломан и мало пригоден к работе, поэтому первым делом его требуется обновить до версии 0.79-1, которая есть в репозитории Ubuntu Saucy. Достаточно вручную загрузить пакет с launchpad.net и установить вручную с помощью dpkg:

$ sudo dpkg -i dh-make-perl_0.79-1_all.deb

Также будет полезным утилиты для сборки пакетов devscripts и модуль local::lib:

$ sudo apt-get install devscripts liblocal-lib-perl

Первое, о чём нужно упомянуть, — это способность dh-make-perl искать имя пакета в репозитории по имени модуля. Например, чтобы узнать в каком пакете находится модуль File::ShareDir надо выполнить команду:

$ dh-make-perl locate File::ShareDir
...
File::ShareDir is in libfile-sharedir-perl package

Таким образом, модуль File::ShareDir содержится в пакете libfile-sharedir-perl. По принятой традиции в Debian имена пакетов для Perl-дистрибутивов всегда пишутся с маленькой буквы, и полученное имя оборачивается в формат lib%s-perl. Т.о. по имени модуля можно догадаться о названии его пакета, но угадать получается не всегда, например:

$ dh-make-perl locate Test::Git
...
Test::Git is in libgit-repository-perl package

Для поиска по именам модулей dh-make-perl использует утилиту apt-file. Поэтому перед выполнением поиска необходимо установить apt-file и обновить локальную копию базы данных файлов в подключённых репозиториях:

$ sudo apt-file update

dh-make-perl может самостоятельно искать и загружать пакеты со CPAN, для этого он использует классическую утилиту cpan из одноимённого модуля. Поэтому при первом использовании dh-make-perl скорее всего придётся ответить на вопросы конфигурации модуля CPAN о поиске зеркала и т.д.

Сборка Path::Tiny

Для примера попробуем собрать модуль Path::Tiny. Нацелим dh-make-perl на CPAN и попробуем загрузить модуль:

$ dh-make-perl --cpan Path::Tiny
...
Needs the following debian packages during building: libcapture-tiny-perl,
libtest-failwarnings-perl, libfile-pushd-perl, perl (>= 5.13.4),
libtest-fatal-perl, libdevel-hide-perl, libtest-deep-perl
Needs the following modules for which there are no debian packages available:
 - Test::FailWarnings

Утилита загрузила последнюю версию модуля со CPAN, проанализировала его зависимости и выдала очень полезную информацию о том, что нам потребуется для сборки модуля. Прежде всего указан список зависимостей пакетов, которые уже доступны в репозиториях Ubuntu, и их можно установить простым apt-get install. Также указан и модуль Test::FailWarnings, которого нет в репозиториях. Таким образом, перед тем как продолжить, необходимо собрать модуль Test::FailWarnings.

$ dh-make-perl --cpan Test::FailWarnings
...
Needs the following debian packages during building: libcapture-tiny-perl
(>= 0.12), perl (>= 5.13.4)

Данный модуль может быть собран, для него требуется установить лишь libcapture-tiny-perl:

$ sudo apt-get install libcapture-tiny-perl

Теперь попробуем собрать пакет:

$ dh-make-perl --build --cpan Test::FailWarnings

Если всё прошло благополучно, то в текущем каталоге вы получите файл libtest-failwarnings-perl_0.006-1_all.deb, который можно сразу установить в систему:

$ sudo dpkg -i libtest-failwarnings-perl_0.006-1_all.deb

Установим и другие зависимости Path::Tiny из репозитория:

$ sudo apt-get install libfile-pushd-perl libtest-fatal-perl \
    libdevel-hide-perl libtest-deep-perl

Попробуем собрать Path::Tiny:

$ dh-make-perl --build --cpan Path::Tiny
...
Warning: prerequisite File::Spec 3.40 not found. We have 3.33.
Warning: prerequisite autodie::exception 2.14 not found. We have 2.1001.

Сборка завершится ошибкой, поскольку два необходимых нам модуля File::Spec и autodie::exception устаревшие, и их требуется обновить.

Оба этих модуля входят в состав базового Perl, поэтому dh-make-perl не даст их собрать:

$ dh-make-perl --build --cpan autodie::exception
 autodie::exception is a standard module. Will not build without --core-ok.

Но он сразу подскажет, что надо сделать, чтобы сборка прошла успешно: указать опцию –core-ok:

$ dh-make-perl --core-ok --build --cpan autodie::exception
$ dh-make-perl --core-ok --build --cpan File::Spec

Установим получившиеся пакеты:

$ sudo dpkg -i libautodie-perl_2.20-1_all.deb \
    libpathtools-perl_3.40-1_amd64.deb

После чего сборка Path::Tiny завершится успешно, и можно будет установить полученный пакет с помощью dpkg.

Репозиторий пакетов

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

Для этих целей в Debian существует утилита reprepro, позволяющая организовать собственный репозиторий пакетов, пригодный для использования наряду с официальными репозиториями дистрибутива. Устанавливается утилита командой:

$ sudo apt-get install reprepro

Затем создаётся каталог, в котором будет располагаться репозиторий, например:

$ mkdir ~/repo

После чего внутри него создаётся каталог conf, в котором создаётся файл distributions, например, так:

$ cat <<EOF >  ~/repo/conf/distributions

Origin: cpan
Label: cpan
Codename: precise
Architectures: i386 amd64 source
Components: main
Contents: .gz
Description: fresh cpan packages

EOF

В данном файле задаётся список дистрибутивов, для которых будет создан наш репозиторий, указывается, для каких архитектур будут доступны собранные пакеты. Кроме того, есть возможность разбить пакеты на группы (компоненты), в данном примере создаётся только один компонент — main.

Инициализируем репозиторий:

$ reprepro -Vb ~/repo export

После этого добавим в репозиторий один из собранных пакетов:

$ reprepro -b ~/repo -C main includedeb precise \
    ~/libautodie-perl_2.20-1_all.deb

Утилита скопирует пакет в наш репозиторий и обновит все необходимые индексные файлы. Пакет будет отнесён к дистрибутиву precise в составе компонента main.

Для того, чтобы репозиторий стал доступен для установки пакетов в систему, необходимо добавить запись о нём в /etc/apt/sources.list:

deb file:///path/to/repo precise main

Как видно, указывается путь к репозиторию, кодовое имя дистрибутива и список нужных компонентов.

Чтобы обновить индексы apt, необходимо выполнить команду:

$ sudo apt-get update

После чего пакеты, которые были добавлены в репозиторий, станут доступны для установки с помощью команды apt-get install. Аналогичным образом после выполнения:

$ sudo apt-file update

начнёт работать поиск по файлам в пакетах нового репозитория.

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

server {
    listen 80;
    server_name mycpan.example.org;

    location / {
        root /path/to/repo;
    }
}

В таком случае в /etc/apt/sources.list указывается строка:

deb http://mycpan.example.org/ precise main

Заключение

dh-make-perl позволяет значительно сэкономить усилия по созданию deb-пакетов, но, к сожалению, не во всех случаях удаётся легко выполнить преобразование. Процесс дальнейшей поддержки пакета, в том числе и периодическое обновление, потребует знаний о сборочных инструментах среды Debian/Ubuntu. Во всех этих случаях рекомендую ознакомиться с «Руководством начинающего разработчика Debian», которое поможет решить многие возникающие вопросы.

Владимир Леттиев


Статический анализ кода | Содержание | Обзор CPAN за август 2013 г.
Нас уже 1393. Больше подписчиков — лучше выпуски!

Комментарии к статье