Конфигурационные пакеты
На устройство пользователя может быть установлено сразу несколько приложений одного вендора. Иногда возникает задача обеспечить эти приложения общими для всего вендора данными: настройками, лицензионными файлами, общими конфигурациями, ключами и прочими ресурсами, которые не должны дублироваться в каждом отдельном приложении и должны оставаться согласованными между ними. Для решения этой задачи используются конфигурационные пакеты.
Конфигурационный пакет — это отдельный RPM-пакет, который служит для доставки и хранения общих файлов вендора на устройстве. Такой пакет устанавливается независимо от других приложений и предоставляет доступ к своим данным по известному для вендора пути.
Общие файлы одного вендора располагаются по пути /usr/share/common/<orgname>,
где <orgname> — идентификатор организации-вендора.
Любое приложение этого вендора может обращаться к файлам в данной директории,
что позволяет один раз установить конфигурационный пакет
и переиспользовать его содержимое во всех приложениях вендора,
избегая дублирования данных и упрощая их обновление.
Помимо общего <orgname>, необходимым условием доступа к общим данным вендора является то,
что все приложения этого вендора, включая конфигурационный пакет,
должны быть подписаны одним и тем же ключом.
Это ограничение обеспечивает то, что доступ к общим данным вендора могут получить
только доверенные приложения этого же вендора, а не любое приложение, использующее совпадающий <orgname>.
Требования к конфигурационным пакетам
Конфигурационный пакет должен быть подписан тем же ключом, что и остальные приложения вендора. Без выполнения этого условия приложения вендора не могут получить доступ к данным конфигурационных пакетов.
Несмотря на то, что конфигурационный пакет предназначен в первую очередь для хранения и доставки общих файлов вендора, а не для взаимодействия с пользователем, он обязан иметь возможность запуститься как обычное приложение. Это требование связано с тем, что пакеты в системе устанавливаются и обновляются как приложения, и система должна иметь возможность корректно их запустить. При этом иконку конфигурационного пакета можно скрыть из меню приложений, чтобы не показывать её пользователю и не вводить его в заблуждение, что конфигурационный пакет является полноценным приложением.
Поскольку такому пакету не нужна сложная логика, для его реализации отлично подходит QML-only подход: приложение представляет собой один или несколько QML-файлов без необходимости сборки C++ кода, что заметно упрощает разработку и поддержку.
Рекомендуется, чтобы каждый конфигурационный пакет устанавливал свои файлы в отдельную, уникальную
для этого пакета директорию, например, по пути /usr/share/common/<orgname>/<appname>,
где <appname> — имя самого конфигурационного пакета, отличающее его от других пакетов того же вендора.
Данная рекомендация обусловлена тем, что если два разных конфигурационных пакета будут устанавливать
файлы в одно и то же место, то при установке одного из них система выдаст ошибку из-за конфликта файлов.
Использование отдельной поддиректории для каждого пакета исключает такие конфликты и позволяет нескольким
конфигурационным пакетам одного вендора спокойно сосуществовать на одном устройстве.
Алгоритм создания конфигурационного пакета
В данном разделе описана минимальная структура проекта конфигурационного пакета и содержимое ключевых файлов.
Минимальная структура проекта
├── <orgname>.<appname>.desktop
├── <orgname>.<appname>.pro
├── icons
│ ├── 108x108
│ │ └── <orgname>.<appname>.png
│ ├── 128x128
│ │ └── <orgname>.<appname>.png
│ ├── 172x172
│ │ └── <orgname>.<appname>.png
│ └── 86x86
│ └── <orgname>.<appname>.png
├── qml
│ └── <orgname>.<appname>.qml
├── rpm
│ └── <orgname>.<appname>.spec
└── configuration
├── <conf-file-1>
├── <conf-file-2>
└── ...
| Путь | Назначение |
|---|---|
<orgname>.<appname>.desktop |
Desktop файл приложения |
<orgname>.<appname>.pro |
Файл сборки Qmake |
icons/ |
Иконки приложения |
qml/ |
QML-файлы графического интерфейса приложения |
rpm/<orgname>.<appname>.spec |
Spec файл для сборки RPM пакета |
configuration/ |
Общие файлы конфигурации вендора, устанавливаемые вместе с пакетом |
Минимальная конфигурация сборки RPM
Содержимое файла <orgname>.<appname>.spec
Name: <orgname>.<appname>
Summary: Описание вашего пакета
Version: 0.1.0
Release: 1
License: BSD-3-Clause
BuildArch: noarch
Source0: %{name}-%{version}.tar.zst
Requires: libauroraapp-launcher
BuildRequires: qtchooser
%description
%{summary}.
%prep
%autosetup
%build
%qmake5
%install
%make_install
%files
%{_datadir}/%{name}/qml
%{_datadir}/applications/%{name}.desktop
%{_datadir}/icons/hicolor/*/apps/%{name}.png
%{_datadir}/common/<orgname>/<appname>
Ключевые для сборки qml-only пакета поля spec-файла:
| Поле | Комментарий |
|---|---|
BuildArch: noarch |
QML-only приложения должны быть архитектурно независимы |
Requires: libauroraapp-launcher |
Зависимость от раннера aurora-qml для запуска qml-only приложения |
BuildRequires: qtchooser |
Зависимость для сборки утилитой qmake |
Минимальная конфигурация сборки Qmake
Содержимое файла <orgname>.<appname>.pro
TEMPLATE = aux
TARGET = <orgname>.<appname>
DISTFILES += \
rpm/<orgname>.<appname>.spec \
<orgname>.<appname>.desktop \
$$files(qml/*, true)
qml.files = qml
qml.path = /usr/share/$${TARGET}
INSTALLS += qml
desktop.files = $${TARGET}.desktop
desktop.path = /usr/share/applications
INSTALLS += desktop
ICON_SIZES = 86x86 108x108 128x128 172x172
for(size, ICON_SIZES) {
icon$${size}.files = icons/$${size}/$${TARGET}.png
icon$${size}.path = /usr/share/icons/hicolor/$${size}/apps
INSTALLS += icon$${size}
}
configuration.files = $$files(configuration/*)
configuration.path = /usr/share/common/<orgname>/<appname>
INSTALLS += configuration
| Цель установки | Назначение |
|---|---|
qml |
Устанавливает QML-файлы приложения в /usr/share/<orgname>.<appname> |
desktop |
Устанавливает desktop-файл приложения в /usr/share/applications |
icon<size> |
Устанавливает иконку приложения в /usr/share/icons/hicolor/<size>/apps |
configuration |
Устанавливает конфигурационные файлы вендора в /usr/share/common/<orgname>/<appname> |
Минимальное содержимое desktop-файла
[Desktop Entry]
Type=Application
X-Nemo-Application-Type=silica-qt5
Icon=<orgname>.<appname>
Exec=aurora-qml <orgname>.<appname>
Name=Your application name
Name[ru]=Имя вашего приложения
NoDisplay=true
[X-Application]
OrganizationName=<orgname>
ApplicationName=<appname>
Стоит обратить внимание на два поля этого файла. Поле Exec=aurora-qml <orgname>.<appname> указывает
на то, что приложение запускается через раннер aurora-qml, а не отдельным скомпилированным бинарником,
что это характерно именно для qml-only приложений, у которых нет собственного исполняемого файла.
Поле NoDisplay=true скрывает приложение из меню приложений. Для конфигурационного пакета это поле
обычно устанавливается в значение True, поскольку он не предназначен для взаимодействия с пользователем
и не должен отображаться среди обычных приложений устройства.
Использование конфигурационных пакетов
Основные приложения могут получить доступ к файлам конфигурационного пакета того же вендора,
используя метод Aurora::Application::organizationPathTo(const QString &filename).
Параметр filename задаёт имя файла относительно директории /usr/share/common/<orgname>.
Метод возвращает путь к файлу вне зависимости от того, установлен ли на устройстве соответствующий конфигурационный пакет и существует ли файл по заданному пути. Перед использованием полученного пути необходимо убедиться в наличии файла.
Подробнее про метод organizationPathTo можно узнать в разделе Данные пользователя.