Платформа изнутри
Console API v2, формат файла сборки и особенности поведения платформы, о которых стоит знать.
На этой странице – про платформу, а не про инструмент: как устроен Console API, из чего
состоит файл сборки и как платформа ведёт себя в случаях, которые с первого раза удивляют.
Всё это записано потому, что документация платформы такие углы не покрывает, а elemctl
пришлось их изучить на практике.
Для работы с инструментом эта страница не нужна. Она пригодится, когда что-то ведёт себя странно и хочется понять, что происходит внутри, – или когда вы пишете собственный клиент.
Контракт Console API v2
Общий префикс: {base}/console/api/v2. Тела запросов и ответов - JSON
(кроме загрузки сборки). Имена полей - в kebab-case.
Приложения
GET /applications- список; необязательный queryname(фильтр).GET /applications/{id}- карточка. Значимые поля ответа:id,status,uri(адрес работающего приложения),error(текст ошибки, если есть),technology-version,date-updated,display-name,publication-context,source(объект с информацией об источнике, содержит в т.ч.project-version- версию применённой сборки).POST /applications- создать. Тело:source- объект{"type": "repository"}плюс ровно один из ключей:project-version-id(id сборки-источника) либоimage-id(id проекта);display-name,publication-context- имя и путь публикации;development-mode- булево, создавать ли среду разработки;- необязательные
space-id,technology-version.
DELETE /applications/{id}- удалить.PUT /applications/{id}/status/start- запустить.PUT /applications/{id}/status/stop- остановить.POST /applications/{id}/actions/debug- данные для сессии отладки (ApplicationDebugInfo:{"debug-token": ..., "debug-address": ...}). Тело запроса пустое; требует включённой отладки на сервере (config/debug.ymlenabled: true).POST /applications/{id}/project/update- применить сборку к приложению. Тело:{"source": {"type": "repository", "image-id": "<id сборки>"}}либо{"source": {"type": "repository", "project-id": "<id>", "assembly-version": "<версия>"}}(assembly-version необязательна).POST /applications/{id}/dumps- создать дамп. Тело:include-users,include-binary-data(булевы),description(строка).GET /applications/{id}/dumps/{dumpId}- статус дампа.
Статусы приложения: стабильные Running, Stopped, Error; переходные
Starting, Stopping, Initializing, Updating, Frozen, Creating.
Во время переходов поле status может быть и пустым.
Версия технологии
- Чтение - из поля
technology-versionкарточки приложения (отдельный endpoint чтения есть не во всех версиях платформы - не использовать). - Обновление:
POST /tasks/group-tasks/update-applications-technology, тело{"technology-version": "<версия>", "applications": ["<app-id>"]}. Возвращает групповую задачу; её статус -GET /tasks/group-tasks/{taskId}.
Пространства и проекты
GET /spaces- список пространств.GET /projects- список проектов;GET /projects/{id}- карточка;DELETE /projects/{id}- удаление.
Сборки проекта (assemblies)
- Загрузка файла сборки - бинарный POST (Content-Type
application/octet-stream, тело - байты файла):POST /projects/{id}/assemblies- добавить сборку в существующий проект;POST /projects- создать новый проект из сборки. Query-параметры (все необязательные):SpaceId,BranchName,CommitId,CommitMessage. Внимание: имена этих query-параметров - в PascalCase. Ответ содержит id созданной сборки в одном из полей:image-id,assembly-idилиid(проверять в этом порядке).
GET /projects/{id}/assemblies- список сборок. Элемент содержитassembly-version(строка вида1.0-42) и id (idлибоimage-id). Ответ может быть как массивом, так и объектом со списком в полеitemsилиassemblies.GET /projects/{id}/assemblies/{assembly-id}- карточка сборки;DELETE .../{assembly-id}- удаление. API адресует сборку ТОЛЬКО UUID: на версию отвечает 400 “Version is not a valid UUID”. Клиент обязан принимать и версию (пользователь видит именно её), резолвя её в id по списку сборок (assembly-version/project-version); учитывать, что версию из манифеста платформа при загрузке перенумеровывает по-своему. Удаление сборки, участвовавшей в применении (даже откатившемся), платформа отклоняет с 500.
Сравнение версий сборок: по числовому суффиксу после последнего дефиса
(1.0-10 новее 1.0-9; лексикографическое сравнение даёт неверный порядок).
Ветки среды разработки
GET /branches- список; необязательные queryproject-id,name.GET /branches/{id}- карточка. Поля:name,kind,project,application,source-branch,deletion-mark,version-stamp.POST /branches- создать. Тело:name,kind: "development",project: {"id": "<id>"}, необязательноapplication: {"id": "<id>"}.PUT /branches/{id}- изменить. Платформа использует оптимистическую блокировку: сначала прочитать карточку, затем отправить тело, собранное из текущих значений -name,kind,deletion-mark,version-stamp(обязательно вернуть как есть),source-branchиapplication- свернуть до{"id": ...}(или{"name": ...}, если id нет). Для перепривязки к приложению заменитьapplicationна{"id": "<новый app-id>"}.- Принятие изменений ветки (merge) - тот же
PUT /branches/{id}с дополнительным ключом телаwrite-parameters: {"merge": true}. DELETE /branches/{id}- удалить ветку.
Инструмент работает ТОЛЬКО с документированным Console API v2. Внутренние (недокументированные) API консоли платформы не используются и не описываются.
Задачи приложений
GET /tasks/application-tasks - список задач всех приложений (серверного
фильтра нет - фильтровать на клиенте). Поля задачи: id, application-id,
status (в т.ч. Error, Failed), operation-type, error-message,
start-date (ISO 8601, может оканчиваться на Z).
Формат файла сборки (.xasm / .xlib)
Файл сборки - ZIP-архив (deflate):
-
в корне
Assembly.yaml- манифест, плоские пары ключ-значение:ManifestVersion: 1.0 ProjectKind: Application | Library Vendor: <поставщик> Name: <имя проекта> Version: <версия, например 1.0-42> Created: <UTC, формат YYYY.MM.DD HH:MM:SS> BranchName: <имя git-ветки> CommitId: <хэш коммита>Для библиотеки (
ProjectKind: Library) в конце добавляется строкаRelease:(пустое значение); расширение файла.xlib, для приложения -.xasm. -
далее файлы проекта путями
{vendor}/{name}/...- относительно корня репозитория. Каталог проекта обязан лежать по схеме{repo}/{vendor}/{name}/Проект.yaml. Разделители путей в архиве - прямые слэши (и на Windows).
Имя файла сборки: {Имя} {Version}.xasm (через пробел).
Метаданные проекта - из Проект.yaml (YAML, достаточно разбора плоских пар
ключ: значение верхнего уровня, вложенные строки с отступом пропускать):
Имя, Поставщик, Версия (базовая, например 1.0), ВидПроекта
(значение Библиотека означает библиотеку, иначе приложение).
Версия сборки, если не задана явно: {базовая версия}-{N+1}, где N - счётчик
из версии последней сборки проекта; если сборок нет - {базовая версия}-1.
Git-метаданные (хэш коммита, имя ветки) - из git-репозитория, содержащего каталог проекта; при недоступности git оставить пустыми.
Отбор файлов в архив:
- включаются только расширения:
.yaml .xbsl .xbql .md .txt .json(исходники),.png .svg .jpg .jpeg .gif .webp .ico(изображения),.css .html .js .woff .woff2 .ttf .eot(веб-ресурсы); - исключаются каталоги
.git,.claude,.github,__pycache__,node_modules,.venvи все скрытые (начинающиеся с точки); - исключаются файлы
.gitignore,.env,.DS_Storeи файлы*.xasm,*.xlib.
Разбор готового архива
Операция, обратная сборке: по файлу .xasm/.xlib - манифест, свойства
проекта из его Проект.yaml внутри архива, состав. Нужна, чтобы подключить
библиотеку к проекту, не разворачивая её исходники.
Раскладка внутри проекта (единственный источник истины о составе - каталоги):
- каталог первого уровня - подсистема;
Подсистема.yamlнеобязателен (у подсистемы библиотеки его может не быть вовсе), поэтому опираться на него при поиске подсистем нельзя; - вложенный каталог подсистемы - пакет; файла-описания у пакета нет, каждый каталог даёт сегмент имени;
- полное имя типа:
{vendor}::{name}::{подсистема}[::{пакет}]::{ИмяТипа}. То же имя без последнего сегмента указывается вИспользованиеиимпорт.
Наружу, в подключивший проект, видны только типы с ОбластьВидимости: Глобально (умолчание - ВПодсистеме, глобальная область пишется явно).
Совместимость проверяется по свойству РежимСовместимости файла Проект.yaml.
Свойства ВерсияТехнологии в Проект.yaml не существует - оно относится к
телу запроса Console API на создание приложения, а не к файлу проекта.
Поведенческие особенности платформы (обязательны к учёту)
- Тихий откат применения. Если применение сборки к приложению падает
(например, ошибка компиляции), платформа молча откатывает приложение на
предыдущую сборку и запускает его - статус
RunningНЕ означает успех. Достоверная проверка результата деплоя:- задачи приложения (п. 4.6) со статусом
Error/Failed, у которыхstart-dateне раньше момента начала деплоя (старые ошибки из истории не учитывать!); - сверка фактически применённой версии (
source.project-versionкарточки приложения) с версией загруженной сборки; - информационно - контрольный GET по
uriприложения (коды 401/403 нормальны для закрытых приложений и успеху не противоречат).
- задачи приложения (п. 4.6) со статусом
- Пустой каркас при создании. Создание приложения с источником “проект”
(
image-id= id проекта) на части конфигураций платформы даёт пустое приложение без данных проекта. Надёжный источник - конкретная сборка (project-version-id), например последняя сборка проекта. - Удаление с черновиками. Если в среде разработки приложения есть
неопубликованные правки,
DELETE /applications/{id}возвращает 400 сFAILED_PRECONDITIONв теле. Принудительного удаления в API нет - только панель управления; инструмент обязан дать понятную подсказку. - Готовность нового приложения. После создания приложение какое-то время
в переходных статусах и без
uri- предусмотреть ожидание готовности (появилсяuriи стабильный статус). СтатусErrorпри ожидании - немедленная ошибка. - Перезапуск после применения.
project/updateможет сам перезапустить приложение. После вызова дождаться выхода из переходных статусов; если итог неRunning- остановить (если неStopped), дождатьсяStopped, запустить, дождатьсяRunning. Разумные таймауты: ожидание остановки ~3 мин, запуска/стабилизации ~5 мин, опрос каждые ~10 с. - Windows. Временные файлы и кеши - только через
tempfile; вывод консоли перевести в UTF-8 (reconfigureдля stdout/stderr), иначе кириллица ломается.