Как использовать FPM для простого создания пакетов в нескольких форматах

Вступление

Форматы упаковки, используемые в различных дистрибутивах Linux, могут быть проблемой для разработчиков программного обеспечения, желающих выпустить свои проекты в удобном для использования виде. Debian и Ubuntu используют пакеты + .deb +, в то время как Fedora и RedHat оба используют системы упаковки в стиле + .rpm +. Они несовместимы, и инструменты, необходимые для их создания, могут быть довольно трудными для тех, кто не знаком с эксцентричностью каждого из них.

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

Чтобы свести к минимуму сложности этого процесса, был создан инструмент под названием + fpm +. Используя + fpm, вы можете легко создавать файлы` + .deb` и + .rpm без необходимости знать какие-либо команды инструментов упаковки, которые он использует. В этом руководстве мы обсудим, как использовать + fpm + для создания пакетов разных форматов с использованием сервера Ubuntu 14.04.

Установка FPM

Основной метод распространения самого инструмента + fpm + - это Ruby gem. Мы можем подготовить нашу систему к установке + fpm +, установив как пакеты разработки Ruby, так и инструменты сборки программного обеспечения, необходимые для компиляции дополнительного программного обеспечения.

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

sudo apt-get update
sudo apt-get install ruby-dev build-essential

После установки вышеуказанных пакетов вы можете получить сам пакет + fpm +, набрав:

sudo gem install fpm

Это установит + fpm + на системном уровне и сделает его доступным для любого пользователя в системе. Традиционная мудрость упаковки рекомендует создавать пакеты как обычный пользователь без полномочий root. Это безопаснее в случае ошибки упаковки, которая может повлиять на вашу систему.

Теперь вы должны иметь исполняемый файл + fpm +, доступный в вашей системе. Вы можете убедиться в этом, проверив обширную справочную информацию инструмента:

fpm --help
Intro:

 This is fpm version 1.2.0

 If you think something is wrong, it's probably a bug! :)
 Please file these here: https://github.com/jordansissel/fpm/issues

 You can find support on irc (#fpm on freenode irc) or via email with
 [email protected]

Usage:
   fpm [OPTIONS] [ARGS] ...
. . .

Теперь вы можете начать сборку пакетов.

Знакомство с основными функциями FPM

Инструмент + fpm + довольно хорошо говорит вам, что ему нужно для завершения сборки пакета. Чтобы получить представление о самых основных требованиях, вы можете вызвать команду без аргументов:

fpm
Missing required -s flag. What package source did you want? {:level=>:warn}
Missing required -t flag. What package output did you want? {:level=>:warn}
No parameters given. You need to pass additional command arguments so that I know what you want to build packages from. For example, for '-s dir' you would pass a list of files and directories. For '-s gem' you would pass a one or more gems to package from. As a full example, this will make an rpm of the 'json' rubygem: `fpm -s gem -t rpm json` {:level=>:warn}
Fix the above problems, and you'll be rolling packages in no time! {:level=>:fatal}

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

fpm -s  -t

Источник может быть любого из нескольких типов. Тип источника также определяет способ передачи имени или местоположения источника команде. Мы обсудим возможные форматы ввода и вывода в следующем разделе.

В некоторых форматах для конвертации потребуются дополнительные вспомогательные утилиты, связанные с отдельным типом пакета. Поскольку мы уже установили основы Ruby, чтобы заставить работать + fpm +, и поскольку мы используем систему Ubuntu, преобразование файла gem Ruby в пакет + .deb + должно быть возможным.

Давайте выберем часто используемый гем, например + bundler +. Мы можем создать пакет + .deb + из пакета + bundler +, расположенного на rubygems.org, набрав:

fpm -s gem -t deb bundler
Created package {:path=>"rubygem-bundler_1.6.5_all.deb"}

Файл с именем + rubygem-bundler_1.6.5_all.deb + был создан в локальном каталоге (номер вашей версии может отличаться). Теперь мы можем установить это так же, как любой другой пакет + .deb +:

sudo dpkg -i rubygem-bundler_1.6.5_all.deb

Когда вы проверите список установленных драгоценных камней, вы увидите, что теперь у нас есть пакет:

gem list
*** LOCAL GEMS ***

arr-pm (0.0.9)
backports (3.6.0)

cabin (0.6.1)
childprocess (0.5.3)
clamp (0.6.3)
ffi (1.9.3)
fpm (1.2.0)
json (1.8.1)

Мы могли бы так же легко использовать другой исходный или выходной формат, но для их преобразования в нашей системе требуются дополнительные инструменты. Мы обсудим это позже.

Форматы источника и цели

Инструмент + fpm + может работать с несколькими различными исходными и целевыми форматами. У каждого из них свои требования и особенности.

В случае наличия относительно стандартного индекса пакета в сети для формата (такого как rubygems.org для Ruby gem-файлов), + fpm + может автоматически выполнять поиск в индексе и загружать необходимые файлы. Сначала будет выполнен поиск совпадения в текущем каталоге, а затем поиск по индексу, если локальное совпадение не найдено.

В настоящее время поддерживаются следующие типы источников:

Source Type Source Description How to Pass Source Name or Location Additional Packages Needed

dir

Directory or files

Pass the absolute or relative path(s) of the project files on the local filesystem.

(none)

tar

A tarball source package

Pass the path to the location of the tarball (compressed or uncompressed) on the local filesystem.

(none)

gem

A Ruby gem

Pass the name of a Ruby gem that can be find on www.rubygems.org. It will be auto-downloaded to create the package.

ruby, rubygems-integration

python

A Python package

Pass the name of a Python package as you would pass it to easy_install. Names are searched for in the Python Package Index and auto-downloaded to create the package.

python-setuptools

pear

A PHP extension

Pass the name of a PHP extension or application found on pear.php.net. The appropriate files will be auto-downloaded when creating the package.

php-pear

cpan

A Perl module

Pass the name of a Perl module as found at cpan.org. The files will be auto-downloaded and used to build the package.

cpanminus

zip

A zipped directory structure

Pass the location on the local filesystem of a zip file containing the package.

zip

npm

A Node.js module

Pass the name of a Node module as specified on npmjs.org. The package will be auto-downloaded and used to make the output package.

npm

osxpkg

An OS X package

Pass the location on the local filesystem of an OS X package (this will only work on OS X systems with pkgbuild in their path).

pkgbuild (only available for OS X systems)

empty

(no source)

Used to create a package without any actual packages. This is used most often for meta-packages that only contain dependencies.

(none)

deb

A .deb package

Pass the location of a .deb file on the local filesystem.

(none on Debian-based systems)

rpm

An .rpm package

Pass the location of an .rpm file on the local filesystem.

rpm

Есть также довольно много вариантов для целевых форматов упаковки, которые вы хотите создать. В таблице ниже описаны некоторые из различных вариантов:

Output Type Output Description Additional Packages Needed

deb

A Debian-style package that can be installed on Debian or Ubuntu systems.

(none on Debian-based systems)

rpm

A RedHat-style package that can be installed on CentOS, Fedora, or RedHat systems.

rpm

zip

A zip file containing the directory and file structure of the input package.

zip

tar

A tarball (compressed or uncompressed) of the directory structure of the input package.

(none)

dir

A directory in which to extract the inputted package.

(none)

sh

A self-extracting .sh file. This is a shell script with a bzipped tar file that will be extracted when run.

(none)

osxpkg

A package file for OS X. You must be working on an OS X installation with pkgbuild installed to create these packages.

pkgbuild (only available for OS X systems)

solaris

A package suitable for installing on a Solaris system. You must have pkgproto and pkgmk installed, which are only available on Solaris machines.

pkgproto, pkgmk (only available on Solaris systems)

pkgin

A package suitable for installing on BSD systems. You must have the pkg_create package installed, which is only available on BSD systems.

pkg_create (only available on BSD systems)

puppet

A puppet module that can be used to install on various systems. ().

(cannot test in non-working state)

Как видите, некоторые форматы для исходных и целевых спецификаций требуют, чтобы вы работали в конкретной операционной системе. Поскольку мы демонстрируем этот инструмент в Ubuntu 14.04, исходный формат + osxpkg + и выходные форматы + osxpkg +, + solaris + и + pkgin + будут недоступны.

Изменение поведения FPM с помощью опций

Используя информацию из таблиц в вышеприведенном разделе, вы сможете создавать некоторые базовые пакеты, используя настройки по умолчанию + fpm +. Тем не менее, в большинстве случаев вы захотите предоставить некоторую дополнительную информацию для формирования результирующего пакета.

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

Для + fpm + доступно множество различных параметров. Мы рассмотрим только некоторые из наиболее распространенных ниже. Для получения полного списка проверьте команду + fpm --help +.

Некоторые общие параметры, которые вы можете использовать:

  • * -C *: укажите каталог для изменения перед поиском файлов.

  • * –Prefix *: путь к каталогу, который указывает, куда будут устанавливаться файлы в результирующем пакете.

  • * -p *: имя пакета и путь к нему. Это может переопределить имя файла результирующего файла пакета.

  • * -n *: имя, которое вы хотите использовать для пакета. Это имя отображается в инструментах упаковки для вашей платформы.

  • * -v *: номер версии, которую вы хотите использовать для своего пакета.

  • * –Iteration *: Информация о выпуске для пакета. Название дистрибутива для этого номера различается, но обычно это способ отследить версию пакета, а не версию приложения.

  • * –License *: лицензионное имя для пакета. Это будет включать тип лицензии в метаданные для пакета, но не будет включать связанный файл лицензии в самом пакете.

  • * –Category *: категория, к которой относится данный пакет. Это может быть использовано для организации пакета в репозиториях.

  • * -d *: Это можно использовать несколько раз, чтобы указать зависимости пакета.

  • * –Provides *: Это можно использовать для указания функциональности системы, предоставляемой этим пакетом. Это обычно используется, когда существует более одного варианта выполнения требования.

  • * –Conflicts *: используется для указания пакетов, которые не должны быть установлены.

  • * –Replaces *: Используется для указания пакетов, которые должны быть удалены при установке этого пакета.

  • * –Config-files *: используется для пометки файлов в пакете как файлов конфигурации. Обычно менеджеры пакетов оставляют их нетронутыми при удалении пакета.

  • * –Directories *: пометить каталог как принадлежащий пакету.

  • * -a *: указать архитектуру для пакета.

  • * -m *: переопределить поле сопровождающего пакета. По умолчанию для этого поля будет использоваться + username @ host +.

  • * -e *: вручную просмотреть и отредактировать файл спецификации перед сборкой пакета. Это может быть использовано для настройки любых значений по умолчанию, которые использовались для спецификации пакета.

  • * –Description *: установить описание для пакета.

  • * –After-install *, * –before-install *, * –after-remove *, * –before-remove *: файлы сценариев, которые должны быть запущены в соответствующее время.

Есть также довольно много опций, специфичных для выбранных вами форматов упаковки. Для полного списка, проверьте справку.

Настройка пакетов

Если вы хотите настроить больше деталей и не хотите прямого перевода одного формата в выходной формат, вам может потребоваться принять другой рабочий процесс.

Этот процесс будет более точно отражать традиционную упаковку, но также обеспечит возможность быстрого создания нескольких выходных форматов. Ниже мы можем продемонстрировать общий рабочий процесс, предполагая, что рассматриваемое приложение использует стандартный процесс компиляции и установки +. / Configure +, + make +, + make install +.

Для начала установите все зависимости, которые вам нужны для пакета. Затем получите исходный пакет для проекта со своего веб-сайта и поместите его в рабочий каталог:

mkdir ~/build
cd ~/build
wget

Теперь вы можете извлечь файл и перейти в получившийся каталог:

tar xzvf .tar.gz
cd

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

Обычный способ указать опции во время процесса сборки - использовать включенный скрипт +. / Configure +. Ознакомьтесь с документацией проекта, чтобы узнать, какие варианты компиляции доступны. Вы можете указать их, вызвав скрипт + configure + с вашими параметрами:

./configure --= --= -- ...

Это создаст или изменит файлы, которые читаются командой + make + при сборке пакета. Теперь мы можем создать фактические установочные файлы, набрав:

make

Вместо того, чтобы устанавливать эти файлы, которые мы настроили в нашей системе, мы установим их в пустую, фиктивную директорию, из которой мы можем создать реальный пакет. Создайте каталог для установки пакета:

mkdir -p /tmp/

Мы можем пометить этот новый каталог как корневой каталог установки, передав опцию + DESTDIR + в + make install +:

make DESTDIR=/tmp/ install

Наш пакет теперь правильно установлен в пустой каталог скелета. Он создал всю необходимую структуру каталогов, но с этим пакетом ничего не связано.

Это ваша вторая возможность изменить настройки. Если вы хотите включить дополнительные файлы в иерархию для установки, вы можете добавить их в соответствующее место в этой структуре.

Когда вы будете готовы, вы можете использовать + fpm + для создания соответствующего файла пакета. Например, мы можем передать некоторую информацию о версиях и описание пакета в нашей команде + fpm +. Мы также можем перечислить информацию о зависимостях или предоставить дополнительную информацию, которая повлияет на создание метафайлов упаковки.

Мы можем использовать структуру каталогов для создания нескольких форматов упаковки. Например, мы могли бы затем создать пакет + .deb +, набрав:

fpm -s dir -t deb -C /tmp/ --name  --version  --iteration  --depends  --description "A sample package" .

Это создаст пакет с именем + project-name_1.0.0-1_amd64.deb + в текущем каталоге.

Затем вы можете изменить некоторые параметры для создания пакета + .rpm + (при условии, что вы установили пакет + rpm + из репозиториев):

fpm -s dir -t  -C /tmp/project --name project_name --version 1.0.0 --iteration 1 --depends  --description "A sample package" .

Это создаст пакет с именем + project_name-1.0.0-1.x86_64.rpm + в вашем текущем каталоге.

Как видите, создавать настраиваемые пакеты с помощью + fpm + довольно просто. Большинство сложных задач по-прежнему решаются с помощью инструмента.

Заключение

Использование + fpm + может упростить вашу жизнь при попытке создания пакетов для использования в вашей инфраструктуре или при распространении общедоступных пакетов вашего проекта. Хотя это может быть не идеальным решением для упаковки для репозиториев реального дистрибутива из-за политических проблем, его преимущества привлекательны во многих сценариях.

Related