No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Maria Alexeeva f85d8d7e44 0.1.1-alt2
- Add missing dependency on alterator-interface-application required by
  ResolveLaunchers.
2026-09-30 14:21:46 +04:00
.gear 0.1.1-alt2 2026-09-30 14:21:46 +04:00
backend feat: return handled interface for providers 2026-09-08 01:58:27 +04:00
docs feat: return handled interface for providers 2026-09-08 01:58:27 +04:00
interface feat: add backend skeleton 2026-07-30 14:18:01 +04:00
.gitignore feat: add backend skeleton 2026-07-30 14:18:01 +04:00
pyproject.toml 0.1.1-alt1 2026-09-17 18:00:28 +04:00
readme.md feat: return handled interface for providers 2026-09-08 01:58:27 +04:00

Браузинг компонентов

notes: можно ввести группировку по интерфейсу, но схема становится сложнее => возникновение сложностей с дополнением компонентов у сторонних разработчиков

Сейчас .component-описатель перечисляет только пакеты компонента, но не говорит, какой D-Bus объект/интерфейс появится в системе после установки каждого пакета. Из-за этого:

  • фронты не могут подсказать пользователю пакеты, которые ещё не установлены, но дали бы доступ к нужному приложению/интерфейсу;
  • модули вроде alt-components не могут после установки компонента предложить сразу перейти в только что появившееся приложение — переход возможен только через explorer.

alterator-entry

В сущность .component предлагается добавить массив таблиц [[provides]] на уровне компонента:

name = "alterator-explorer"
...
[[provides]]
package = "alt-components"
object_path = "/org/altlinux/alterator/componentsApp"
interface = "org.altlinux.alterator.application1"
handled_interface = "org.altlinux.alterator.components1"
display_name.en = "ALT Components"
display_name.ru = "Альт Компоненты"

[[provides]]
package = "alt-services"
object_path = "/org/altlinux/alterator/alt_services"
interface = "org.altlinux.alterator.application1"
handled_interface = "org.altlinux.alterator.service1"
display_name.en = "ALT Services"
display_name.ru = "Альт Сервисы"
...
Поле Тип Обязательное Смысл
package string да ключ из [packages] этого же компонента, установка которого дает объект
object_path string да D-Bus object path, который появится после установки package
interface string да полное имя D-Bus интерфейса на этом объекте
handled_interface string нет интерфейс объектов, которые открывает предоставляемое приложение
display_name table да имя для отображения в UI

Ограничений "один пакет — одна запись" и "один object_path — одна запись" нет: пакет может регистрировать несколько объектов (несколько записей с одинаковым package), а один объект — реализовывать несколько интерфейсов одновременно (несколько записей с одинаковым object_path, разным interface).

  • в alterator-entry в скрипт валидации нужно добавить проверку, что указанные пакеты есть в [packages]

Альтернатива: группировка по интерфейсу

Рассматривался вариант группировки записей по interface прямо в описателе ([provides."org.altlinux.alterator.application1"] → вложенный массив объектов), что удобнее для бекенда — не нужно на старте сканировать все записи всех компонентов и строить индекс interface → [объекты] самому.

НО: такая схема требует вложенных таблиц с ключами-строками ([[provides."org.altlinux.alterator.application1".objects]]), что неудобно писать и поддерживать вручную составителям .component-файлов, особенно сторонним. Плоский [[provides]] проще расширять и ревьюить в PR, а построение любых нужных индексов (по interface, по package) — задача бекенда при чтении описателей, а не формата хранения.

backend

Предлагается создать новый пакет alterator-backend-browsing, предоставляющий методы на D-Bus для браузинга компонентов. Объект окажется на /org/altlinux/alterator/global.

Методы

ListProvides (interfaces: as) -> s (JSON-строка)

За один вызов позволяет получить кандидатов сразу по нескольким интерфейсам (application1, diag1, service1, ...). Пустой список интерфейсов возвращает все [[provides]]-записи.

Вход: ["org.altlinux.alterator.application1", "org.altlinux.alterator.diag1"] Выход:

{
  "org.altlinux.alterator.application1": [
    {
      "component": "alterator-explorer",
      "package": "alt-components",
      "object_path": "/org/altlinux/alterator/componentsApp",
      "display_name": {"en": "ALT Components", "ru": "Альт Компоненты"},
      "handled_interface": "org.altlinux.alterator.components1",
      "available": true
    },
    {
      "component": "alterator-explorer",
      "package": "alt-services",
      "object_path": "/org/altlinux/alterator/alt_services",
      "display_name": {"en": "ALT Services", "ru": "Альт Сервисы"},
      "handled_interface": "org.altlinux.alterator.service1",
      "available": false
    }
  ],
  "org.altlinux.alterator.diag1": []
}
Поле Тип Обязательное Источник / смысл
component string да name из .component-описателя, которому принадлежит запись [[provides]]
package string да ключ из [packages] того же компонента (см. поле package в [[provides]])
object_path string да значение object_path из записи [[provides]]
display_name object {locale: string} да, минимум ключ en из display_name записи [[provides]], те же правила, что у field_with_locale в схеме (en обязателен, остальные — опционально)
handled_interface string нет интерфейс объектов, которые открывает предоставляемое приложение; отсутствует в ответе, если не задан в [[provides]]
available bool да объект сейчас доступен: object_path присутствует в результате GetObjects(interface)

* draft-компоненты не участвуют в браузинге

ResolveLaunchers (object_paths: as) -> s (JSON-строка)

Метод позволяет по пути до объекта получить информацию о том, как и с помощью какого приложения можно запустить объект.

Вход: ["/org/altlinux/alterator/service1/sshd", "/org/altlinux/alterator/unknown/thing"]

Выход:

{
  "/org/altlinux/alterator/service1/sshd": [
    {
      "name": "alt-services",
      "exec": "alt-services -o %o",
      "display_name": {"en": "Alt Services", "ru": "Alt Сервисы"}
    }
  ],
  "/org/altlinux/alterator/unknown/thing": []
}
Поле Тип Обязательное Источник / смысл
name string или null да техническое имя из .application; null, если имя отсутствует
exec string да Команда запуска приложения (из .application/exec), может содержать %o — подставляется object_path клиентом перед запуском.
display_name object {locale: string} да, минимум ключ en из display_name .application описателя

Запуск приложений

Так как бекенд висит на системной шине, то запуск из-под него графических приложений затруднителен. Можно вынести логику самого запуска в libalterator-glib или перенести на клиентов.

Пайплайны использования

Показ доступных компонентов (включая неустановленные)

  1. Собрать список интересующих интерфесов: ["org.altlinux.alterator.application1", ...]
  2. Получить кандидатов через ListProvides(interfaces)
  3. Отрисовка:
    1. available = true -> объект доступен прямо сейчас (можно открыть или не отображать среди кандидатов на установку)
    2. available = false -> объект сейчас недоступен; можно предложить установку пакета через apt1/rpm1

Открытие нужного приложения после установки компонента

  1. Установка пакета(ов) через apt1/rpm1 (как обычно)
  2. Из описателя компонента получить задействованные object_path
  3. Получить способы запуска объектов через ResolveLaunchers([object_path, ...])
  4. Для каждого элемента непустого списка → кнопка "Перейти в <display_name>" → клик → %o-подстановка → запуск