Packaging Automation/Преобразование Пакетов: различия между версиями

Материал из ALT Linux Wiki
 
(не показано 17 промежуточных версий этого же участника)
Строка 6: Строка 6:
использующие библиотеку {{pkg|RPM::Source::Transform}} (сейчас в пакете {{pkg|perl-RPM-Source-Editor}}).
использующие библиотеку {{pkg|RPM::Source::Transform}} (сейчас в пакете {{pkg|perl-RPM-Source-Editor}}).


Эту библиотеку можно расширять различными плагинами, с помощью которых можно
=== Основные понятия. ===
 
* Объект src rpm пакета. По умолчанию его можно создать:
** из src.rpm файла (в таком случае библиотека распакует его в какой-то временный каталог)
** из спек файла (каталог для исходников будет найден по {{term|%_sourcedir}} или где укажет пользователь или создан, в зависимости от режима работы).
** Объект src rpm пакета предоставляет доступ к своим исходникам, объявленным как Source:,Patch:, и к спек файлу, и как файлу в целом, и распарсеным в список объектов секций (%package, %description, %prep, ...).
** С расширением BundleImport объект src rpm пакета можно создать просто из исходников, BundleImport по исходникам сгенерирует достаточно разумный спек (используется, к примеру, в импорте перловых модулей со CPAN; каталоги для исходников по умолчанию во временном каталоге)
 
* трансформации.
 
Библиотека только открывает (создает) и закрывает (сохраняет) объект src rpm пакета,
но не выполняет над ним никаких действий. Действия выполняют специальные плагины
к библиотеке - трансформации.
 
В библиотеке есть контейнер трансформаций, куда утилиты, ее использующие,
могут добавить разные трансформации, как в конструкторе Lego.
Загружая в библиотеку разные трансформации, получим разные утилиты.
Порядок выполнения трансформаций важен. К примеру, change_version и add_changelog
не то самое, что add_changelog и change_version.
 
* объект src rpm пакета, к которому применяются трансформации.
В коде переменная этого объекта носит название<source lang="perl">$spec</source>
 
* необязательный объект-предок src rpm пакета, к которому применяются трансформации.
В коде переменная этого объекта носит название<source lang="perl">$parent</source>
 
Например, пусть в p8 есть пакет {{pkg|poo-1.0-alt4.src.rpm}}, в Сизифе есть пакет
{{pkg|poo-2.0-alt1.src.rpm}}. Если мы будем бакпортировать пакет
{{pkg|poo-2.0-alt1.src.rpm}} из Сизифа в p8 с помощью утилиты srpmbackport, то
мы создадим {{term|$spec}} из пакета {{pkg|poo-2.0-alt1.src.rpm}} из Сизифа, сохраним {{term|$spec}} как
итоговый пакет {{pkg|poo-2.0-alt0.M80P.1.src.rpm}}, а в качестве {{term|$parent}} укаже этой утилите {{pkg|poo-1.0-alt4.src.rpm}} из p8.
 
=== Возможности ===
 
Библиотеку {{pkg|RPM::Source::Transform}} можно расширять различными плагинами, с помощью которых можно
решать следующие задачи:
решать следующие задачи:


Строка 13: Строка 47:
* [[Git.alt/girar-nmu|проведение массовых nmu]]
* [[Git.alt/girar-nmu|проведение массовых nmu]]


* автообновление пакета до следующей версии [[Gear/gear-uupdate]], [[Gear/gear-cronbuild]], [[cronbuild]], [[croncopy]], [[cronport]]
* автообновление пакета до следующей версии [[Gear/gear-uupdate]], [[Gear/cronbuild]], [[cronbuild]], [[croncopy]], [[cronport]]


* [[Packaging_Automation/BundleImport|создание пакета из архива с исходниками]]
* [[Packaging_Automation/BundleImport|создание пакета из архива с исходниками]]
Строка 30: Строка 64:


При запуске  
При запуске  
* библиотека осуществляет инициализацию объектов из контейнера ресурсов,  
* библиотека осуществляет инициализацию объектов из контейнера ресурсов, контейнера фабрик преобразований, текущих READER, PLAYER, WRITER.
контейнера фабрик преобразований, текущих READER, PLAYER, WRITER.
* для каждого входящего аргумента  
* для каждого входящего аргумента  
** READER возвращает объект преобразуемого пакета (класс {{pkg|RPM::Source::Editor}}).
** READER возвращает объект преобразуемого пакета (класс {{pkg|RPM::Source::Editor}}).
Строка 44: Строка 77:
В свою очередь, библиотека {{pkg|RPM::Source::Transform}} может выступать обработчиком событий для библиотеки
В свою очередь, библиотека {{pkg|RPM::Source::Transform}} может выступать обработчиком событий для библиотеки
[[Packaging_Automation/MassProcessing|масовой обработки]].
[[Packaging_Automation/MassProcessing|масовой обработки]].
==== Библиотека в разрезе принципов модульности ====
Принципы модульности:
*  Автономность — модули можно создавать, тестировать и эксплуатировать независимо от любого конкретного набора других модулей. Это сразу требует, чтобы все зависимости и вся реализованная функциональность модулей описывались явными контрактами на уровне кода.
*  Компонуемость — сборка приложения из набора модулей должна быть простой задачей, в идеале — решаемой автоматически.
*  Рекурсивность — из набора модулей должен легко собираться композитный модуль, неотличимый от обычных модулей снаружи.
*  Прозрачность — должна иметься возможность сгенерировать актуальную диаграмму компонентов для модулей в работающем приложении.
*  Ортогональность — инструмент для организации модульности должен быть библиотекой, а не фреймворком. Правки в коде для поддержки модульности должны быть минимально возможными.
=== Принципы отладки библиотеки ===
TODO
--SET RPM::Source::Transform::debug_container=1
Волшебная опция для создания digest.diff файла
--SET RPM::Source::TransformContainer::PLAYER=RPM::Source::Transformation::DiffWritePlayer \
и усиленный ее вариант, если нужно найти конкретный фильтр:
--SET RPM::Source::TransformContainer::PLAYER=RPM::Source::Transformation::DiffWritePlayer \
--SET RPM::Source::Transformation::Factory::DependencyFilter::group_filters_by_transformation=0


=== Базовый набор плагинов ===
=== Базовый набор плагинов ===
Строка 96: Строка 151:
               (saves space with native xz)
               (saves space with native xz)
  --uupdate  -- perform a version update using a source watch file
  --uupdate  -- perform a version update using a source watch file
Замечания: --macrodef<ref>используется для изменения значения макроса <name> внутри библиотеки (в таблице значений определенных в спеке макросов)</ref>
|-
|-
|DependencyFilter|| Фреймворк для фильтров зависимостей в тегах (Build) Requires, Conflicts, etc. || (без опций)
|DependencyFilter|| Фреймворк для фильтров зависимостей в тегах (Build) Requires, Conflicts, etc. || (без опций)
Строка 111: Строка 165:
   Multiple --hook options are allowed.
   Multiple --hook options are allowed.
  --no-default-hook do not look for the default hook '\%{name}.pl'
  --no-default-hook do not look for the default hook '\%{name}.pl'
Скриптов для выполнения можно указать сколько угодно. Есть 2 контейнера
{{term|@SPECHOOKS}} и {{term|@PREHOOKS}}.
В каждом контейнере скрипты выполняются в том порядке, как они загружены.
Из {{term|@SPECHOOKS}} скрипты выполняются после преобразований,
для коррекции ошибок.
Из {{term|@PREHOOKS}} скрипты выполняются до основных преобразований,
для обмана преобразований. По умолчанию надо загружать скрипты в
{{term|@SPECHOOKS}}.
Синтаксис hook-файлов см. [[Packaging_Automation/Embedded_Language|Embedded_Language]].
Синтаксис hook-файлов см. [[Packaging_Automation/Embedded_Language|Embedded_Language]].
|-
|-
|ParentI18NMerge|| merges summary(ru), description -l ru and so on from parent|| (без опций)
|ParentI18NMerge|| добавляет, если нет, summary(ru), description -l ru и т.д. из пакета 'parent'|| (без опций)
|-
|-
|RaiseRelease|| Увеличение релиза, смена версии, релиза, Epoch. ||
|RaiseRelease|| Увеличение релиза, смена версии, релиза, Epoch. ||
Строка 132: Строка 197:
  --refresh-timestamp update timestamp in existing changelog
  --refresh-timestamp update timestamp in existing changelog
|}
|}
Замечания:
* --macrodef используется для изменения значения макроса <name> внутри библиотеки (в таблице значений определенных в спеке макросов). Это нужно в случаях, когда внутренне вычесленные значения макросов некорректны.
Пример: пусть в спеке есть конструкция
<source lang="rpmspec">
%if %time_of_peace
%define PI 3.1415926
%else
%define PI 4
%endif
Source10: extra-%PI.tar
</source>
Пусть в сборочном окружении макрос %time_of_peace был определен, и в пакет был упакован файл extra-3.1415926.tar. Если библиотека обработает эту конструкцию некорректно, то во внутренней таблице значений макросов будет PI=4. Как следствие, например, библиотеке SourceAnalyzer не удастся найти файл extra-4.tar для анализа. --macrodef PI=3.1415926 это подправит.
См. также [[altbug:32597]].


=== Базовые утилиты ===
=== Базовые утилиты ===
Строка 156: Строка 237:


srpmnmu то же, что и srpmtool, но имеет действие по умолчанию --- инкрементирование релиза как при NMU
srpmnmu то же, что и srpmtool, но имеет действие по умолчанию --- инкрементирование релиза как при NMU
и добавление changelog (лучше указывать changelog явно опцией --ch (--changelog).
и добавление умолчального малосодержательного changelog (лучше всегда явно указывать changelog опцией --ch (--changelog).
 
==== buildroot2files ====


buildroot2files
Более подробно эти утилиты описаны на странице [[Packaging_Automation/Embedded_Language]].
 
TODO


[[Категория:Справочники]]
[[Категория:Справочники]]
{{Category navigation|title=Автоматизация работы с пакетами|category=Packaging Automation}}
{{Category navigation|title=Автоматизация работы с пакетами|category=Packaging Automation}}

Текущая версия от 15:12, 14 апреля 2018

Введение.

В системах автоматизации за преобразование пакетов отвечают утилиты, использующие библиотеку RPM::Source::Transform (сейчас в пакете perl-RPM-Source-Editor).

Основные понятия.

  • Объект src rpm пакета. По умолчанию его можно создать:
    • из src.rpm файла (в таком случае библиотека распакует его в какой-то временный каталог)
    • из спек файла (каталог для исходников будет найден по %_sourcedir или где укажет пользователь или создан, в зависимости от режима работы).
    • Объект src rpm пакета предоставляет доступ к своим исходникам, объявленным как Source:,Patch:, и к спек файлу, и как файлу в целом, и распарсеным в список объектов секций (%package, %description, %prep, ...).
    • С расширением BundleImport объект src rpm пакета можно создать просто из исходников, BundleImport по исходникам сгенерирует достаточно разумный спек (используется, к примеру, в импорте перловых модулей со CPAN; каталоги для исходников по умолчанию во временном каталоге)
  • трансформации.

Библиотека только открывает (создает) и закрывает (сохраняет) объект src rpm пакета, но не выполняет над ним никаких действий. Действия выполняют специальные плагины к библиотеке - трансформации.

В библиотеке есть контейнер трансформаций, куда утилиты, ее использующие, могут добавить разные трансформации, как в конструкторе Lego. Загружая в библиотеку разные трансформации, получим разные утилиты. Порядок выполнения трансформаций важен. К примеру, change_version и add_changelog не то самое, что add_changelog и change_version.

  • объект src rpm пакета, к которому применяются трансформации.

В коде переменная этого объекта носит название

$spec
  • необязательный объект-предок src rpm пакета, к которому применяются трансформации.

В коде переменная этого объекта носит название

$parent

Например, пусть в p8 есть пакет poo-1.0-alt4.src.rpm, в Сизифе есть пакет poo-2.0-alt1.src.rpm. Если мы будем бакпортировать пакет poo-2.0-alt1.src.rpm из Сизифа в p8 с помощью утилиты srpmbackport, то мы создадим $spec из пакета poo-2.0-alt1.src.rpm из Сизифа, сохраним $spec как итоговый пакет poo-2.0-alt0.M80P.1.src.rpm, а в качестве $parent укаже этой утилите poo-1.0-alt4.src.rpm из p8.

Возможности

Библиотеку RPM::Source::Transform можно расширять различными плагинами, с помощью которых можно решать следующие задачи:

  • различные операции по редактированию пакета, включая редактирование любых тегов, секций, переименование, добавление и удаление подпакетов, переименование пакета.
  • импорт пакета в формате другого диалекта rpm (fedora, mageia, suse, pld, ...)
  • импорт пакета в формате deb из Debian/Ubuntu (в планах).

Принципы работы библиотеки

В библиотеке имеется контейнер ресурсов, контейнер фабрик преобразований, и объекты, имеющие роли READER, PLAYER, WRITER.

Загружаемые плагины добавляют свои объекты в контейнер ресурсов и(ли) контейнер фабрик преобразований, и при необходимости переопределяют объекты для ролей READER, PLAYER, WRITER.

При запуске

  • библиотека осуществляет инициализацию объектов из контейнера ресурсов, контейнера фабрик преобразований, текущих READER, PLAYER, WRITER.
  • для каждого входящего аргумента
    • READER возвращает объект преобразуемого пакета (класс RPM::Source::Editor).
    • библиотека опрашивает объекты из контейнера фабрик преобразований, которые в ответ генерируют и возвращают объекты преобразований.
    • Библиотека создает объект шины обмена сообщений и передает объект преобразуемого пакета, контейнер ресурсов, шину обмена сообщений и набор объектов преобразований в текущий объект PLAYER.
    • PLAYER последовательно применяет к преобразуемому пакету каждый из объектов преобразований в порядке, отсортированными по приоритету, а с одинаковым приоритетом -- по порядку загрузки плагинов.
    • WRITER сохраняет изменения.

Каждый плагин может экспортировать независимо от других плагинов свой набор опций командной строки (при этом названия опций должны быть уникальными для каждого плагина) и свой фрагмент вывода --help.

В свою очередь, библиотека RPM::Source::Transform может выступать обработчиком событий для библиотеки масовой обработки.

Библиотека в разрезе принципов модульности

Принципы модульности:

  • Автономность — модули можно создавать, тестировать и эксплуатировать независимо от любого конкретного набора других модулей. Это сразу требует, чтобы все зависимости и вся реализованная функциональность модулей описывались явными контрактами на уровне кода.
  • Компонуемость — сборка приложения из набора модулей должна быть простой задачей, в идеале — решаемой автоматически.
  • Рекурсивность — из набора модулей должен легко собираться композитный модуль, неотличимый от обычных модулей снаружи.
  • Прозрачность — должна иметься возможность сгенерировать актуальную диаграмму компонентов для модулей в работающем приложении.
  • Ортогональность — инструмент для организации модульности должен быть библиотекой, а не фреймворком. Правки в коде для поддержки модульности должны быть минимально возможными.

Принципы отладки библиотеки

TODO

--SET RPM::Source::Transform::debug_container=1

Волшебная опция для создания digest.diff файла

--SET RPM::Source::TransformContainer::PLAYER=RPM::Source::Transformation::DiffWritePlayer \

и усиленный ее вариант, если нужно найти конкретный фильтр:

--SET RPM::Source::TransformContainer::PLAYER=RPM::Source::Transformation::DiffWritePlayer \
--SET RPM::Source::Transformation::Factory::DependencyFilter::group_filters_by_transformation=0

Базовый набор плагинов

Опишем здесь некоторые плагины, идущие в одном пакете с библиотекой RPM::Source::Transform, которые видны пользователю.

Плагины из контейнера ресурсов

Плагин Назначение Опции
Resource:: Datapath указывает список каталогов, в которых ищутся подгружаемые ресурсы
Filesystem resources options:
--datapath /path1:/path2:... colon separated list of directories
  to search for hooks/, patches/, etc...
Parent указывает пакет-родитель (пакет, от которого наследуется %changelog, Epoch:, и т.д.)
Parent package input options:
--parent[-rpm] /path/to/parent/src.rpm
--parent[-spec] /path/to/parent/spec
 Supplying parent spec/srpm is optional. If parent spec is supplied,
 parent changelog, Serial/Epoch and possibly Packager tag will be merged.
--parent-sourcedir /path/to/parent/SOURCEDIR (optional)
 parent-sourcedir option can be used together with --parent-spec
 to provide a location for parent source files, if required.

Плагины из контейнера фабрик трансформаций

Плагины имеют общий префикс RPM::Source::Transformation::Factory::*

Плагин Назначение Опции
CommandLine делает некоторые команды редактирования доступными в командной строке
Editing options:
--macrodef '<name> <value>' set the value of an rpm macro.
--macroundef <name> undefine rpm macro.
  It does not change spec but influence spec processing.
--add-source <file> (can be specified multiple times)
--copy_to_sources <file> (can be specified multiple times)
--copy-to-sources <file> - alias for --copy_to_sources
--rename 'new name of source rpm package'
--spec_apply_patch <patch file> -- apply <patch file> to spec
--repack   -- repack src.rpm archives to plain tar
              (saves space with native xz)
--uupdate  -- perform a version update using a source watch file
DependencyFilter Фреймворк для фильтров зависимостей в тегах (Build) Requires, Conflicts, etc. (без опций)
Flags загружает настройки пакетов из каталога flags экспериментальная фича
GroupTranslation замены в теге Group:, как указвнные вручную, так и из каталога groups
Group Editing options:
--group-translate 'group translation'
Hook загружает пользовательские скрипты редактирования (hooks)
Hook load options:
--hook /path/to/<hook code> - load a subroutine hook.
 Multiple --hook options are allowed.
--no-default-hook do not look for the default hook '\%{name}.pl'

Скриптов для выполнения можно указать сколько угодно. Есть 2 контейнера @SPECHOOKS и @PREHOOKS. В каждом контейнере скрипты выполняются в том порядке, как они загружены.

Из @SPECHOOKS скрипты выполняются после преобразований, для коррекции ошибок.

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

Синтаксис hook-файлов см. Embedded_Language.

ParentI18NMerge добавляет, если нет, summary(ru), description -l ru и т.д. из пакета 'parent' (без опций)
RaiseRelease Увеличение релиза, смена версии, релиза, Epoch.
Release options:
--tag-packager-replace 'new value' set Packager: tag to a new value.
 special values are: 
   auto - use rpm's \%{packager} value
   none - clear tag
   parent - use parent's value of Packager:
--tag-packager-default 'new value' - if the Packager: tag is not defined
 set it to the new value. This option allows comma separated list
 of multiple sources, for example, 'parent,A. R. <ar\@b.org>'
--changelog '- changelog entry'
--epoch 'new value'
--version 'version' - set new package version
--release 'release' - if we need to adjust the package release
--nextrel|--next-release-policy <policy>
--refresh-timestamp update timestamp in existing changelog

Замечания:

  • --macrodef используется для изменения значения макроса <name> внутри библиотеки (в таблице значений определенных в спеке макросов). Это нужно в случаях, когда внутренне вычесленные значения макросов некорректны.

Пример: пусть в спеке есть конструкция

%if %time_of_peace
%define PI 3.1415926
%else
%define PI 4
%endif
Source10: extra-%PI.tar

Пусть в сборочном окружении макрос %time_of_peace был определен, и в пакет был упакован файл extra-3.1415926.tar. Если библиотека обработает эту конструкцию некорректно, то во внутренней таблице значений макросов будет PI=4. Как следствие, например, библиотеке SourceAnalyzer не удастся найти файл extra-4.tar для анализа. --macrodef PI=3.1415926 это подправит. См. также altbug:32597.

Базовые утилиты

hashertarbuild

hashertarbuild -- frontend к default WRITER, "улучшенный" аналог rpmbuild -bs --nodeps.

Даже если spec файл полностью корректен, rpmbuild -bs --nodeps может завершиться неудачей, если в host системе не установлены пакеты с использованными в spec файле макросами. hashertarbuild -bs в таком случае соберет исходники в tar файл в формате ALT Linux hasher, который можно напрямую передать в hsh для пересборки.

Рекомендую для краткости ввести

alias htbuild=hashertarbuild

srpmnmu, srpmtool

Утилиты являются фронтендом к базовому набору плагинов.

srpmtool не имеет действий по умолчанию, все ее операции надо задать явно в виде опций.

srpmnmu то же, что и srpmtool, но имеет действие по умолчанию --- инкрементирование релиза как при NMU и добавление умолчального малосодержательного changelog (лучше всегда явно указывать changelog опцией --ch (--changelog).

Более подробно эти утилиты описаны на странице Packaging_Automation/Embedded_Language.