Как развернуть удаленную среду разработки под Аврору ОС

Как настроить удаленный конвейер сборки и отладки Flutter-приложений для ОС «Аврора»

Тирекс
Тирекс Самый зубастый автор
26 августа 2026

Пошаговое руководство по созданию мобильного рабочего места для разработки под «Аврору ОС». Разбираем развертывание code-server в облаке, настройку прокси-сервера Caddy и написание плагина VS Code на TypeScript для работы с Aurora Platform SDK и девайсами по SSH.

Изображение записи

По пути на презентацию я в очередной раз просматривал функции приложения и заметил небольшой баг. Ноутбука под рукой не оказалось, а исправить его нужно было срочно. Я вспомнил про тестовый стенд с онлайн-IDE, развернул там нужные инструменты и прямо с планшета оперативно поправил код.

Я мог бы закончить историю на этом, но идея мобильной разработки не давала мне покоя: получается, имея под рукой планшет с большим экраном, вы можете организовать полноценный рабочий процесс. Правда, инструменты для сборки, тестирования и работы с SDK обычно выпускают только для ПК. А можно ли скомпилировать код прямо на смартфоне? Можно — например, в ALT Mobile или «Авроре ОС», если установить дополнительные пакеты. Но удобно ли это? Любителям Vim — вполне.

Среди веб-решений (GigaIDE, GitLab Web IDE и другие) мне больше всего нравится code-server (coder) — полноценная веб-версия Visual Studio Code, которая поддерживает большинство привычных плагинов. В статье я подробно расскажу, как развернуть облачную среду разработки, привязать ее к планшету и написать собственный плагин для автоматизации сборки под «Аврору ОС».

Планшет с открытым Coder и смартфон с Flutter-приложением.

Настройка coder

Среду coder я разворачивал в рамках эксперимента по созданию удаленного рабочего места. Это не стало целевым решением, но виртуальная машина продолжала крутиться для других экспериментов. Серверу coder минимально требуется 1 ГБ ОЗУ и 2 ядра, однако для ускорения сборки приложения стоит увеличить эти параметры, хотя бы 4 ядра и 4 ГБ ОЗУ.

Формально code-server и сборочную среду можно упаковать в Docker, монтируя папки с проектами. Однако Aurora Platform SDK для работы с flutter-aurora штатно рассчитан на запуск вне контейнерной среды. Сценарий с Docker подходит для быстрой проверки гипотез, но для стабильной повседневной разработки лучше разворачивать SDK и IDE нативно на хост-системе.

Перед развертыванием IDE необходимо установить сам Aurora Platform SDK. Сделать это можно двумя способами:

После подготовки SDK переходим к развертыванию code-server. Разработчики подготовили удобный скрипт автоматической установки:


      curl -fsSL https://code-server.dev/install.sh | sh

В процессе работы скрипт затребует права sudo. По завершении инсталляции в консоли появится инструкция по добавлению сервера в systemd — это нужно, чтобы coder автоматически запускался после ребута.

Запустим службу от имени нашего пользователя и проверим сгенерированный пароль для входа в веб-интерфейс. При необходимости пароль в файле ~/.config/code-server/config.yaml можно сразу изменить на свой:


      sudo systemctl enable --now code-server@$USER
cat ~/.config/code-server/config.yaml

По умолчанию code-server запущен и доступен только внутри виртуальной машины (127.0.0.1:8080). Чтобы организовать доступ к Web IDE с других устройств через интернет, необходимо либо пробросить порт по SSH, либо настроить одно из прокси-решений. 

Мне понравился вариант с Caddy: он настраивается буквально в пару строк и берет на себя управление SSL-сертификатами.

Установка Caddy

Выполним установку из официального репозитория:


      sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Конфигурация прокси

Откроем файл конфигурации /etc/caddy/Caddyfile и добавим в него строки следующего вида:


      coder.doman.ru {
    reverse_proxy 127.0.0.1:8080
    tls /etc/caddy/code_ssl/fullchain.cer /etc/caddy/code_ssl/coder.key
}

Здесь coder.doman.ru — ваше доменное имя для сервера coder, 127.0.0.1:8080 – адрес и порт из конфигурации, а ~/.config/code-server/config.yaml, /etc/caddy/code_ssl – путь к файлам цепочки сертификатов и приватного ключа. 

Если у вас есть публичный домен, сертификат проще всего выпустить с помощью скрипта acme.sh. Достаточно запустить скрипт, получить TXT запись, добавить ее на стороне регистратора доменов и минут через 15 перезапросить ключи.

Если домена нет или доступ идет по IP-адресу (например, без управляемого DNS в VPN-сети), можно сгенерировать самоподписанный сертификат. Учитывайте, что браузер будет выдавать предупреждение о недействительном сертификате, но соединение все равно останется зашифрованным. Сгенерировать пару «ключ + сертификат» можно следующей командой:


      sudo mkdir -p /etc/caddy/code_ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048   -keyout /etc/caddy/code_ssl/coder.key   -out /etc/caddy/code_ssl/fullchain.cer   -subj "/CN=10.0.40.203"
sudo chown -R caddy:caddy /etc/caddy/code_ssl
sudo chmod 600 /etc/caddy/code_ssl/coder.key
sudo chmod 644 /etc/caddy/code_ssl/fullchain.cer
sudo systemctl restart caddy

На этом настройка сервера завершена. Перейдите в браузере вашего планшета по указанному домену или IP-адресу, введите пароль из config.yaml — и перед вами откроется полноценная облачная среда разработки, готовая к установке плагинов, языковых пакетов и сборке проектов.

Веб-интерфейс стартовой страницы VS Code Web в браузере.

Новый плагин

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

Мем с Дрейком про бесполезную автоматизацию рутинных задач.
Источник.

Для начала соберем плагин Hello World. В первую очередь необходимо установить yo (генератор шаблонов) и generator-code (расширение для yo, предназначенное для генерации плагинов VS Code): 


      npm install -g yo generator-code

А также инструментарий для упаковки и сборки пакетов:


      npm install -g vsce

Не хотите устанавливать Node.js и другие инструменты для сборки и разработки плагинов на TypeScript? Не беда, если у вас установлен Docker (Docker Desktop на macOS и Windows):


      DOCKER_BUILDKIT=1 docker build --tag codegen "https://github.com/Microsoft/vscode-generator-code.git#main"
DOCKER_BUILDKIT=1 docker build --tag vsce "https://github.com/microsoft/vscode-vsce.git#main"

Далее вызываем следующие команды для генерации и сборки:


      docker run -it -v $(pwd):/usr/src/app codegen

docker run --rm -it -v "$(pwd)":/workspace vsce publish

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


      ✔ What type of extension do you want to create? New Extension (TypeScript)
✔ What's the name of your extension? hello-world-plugin
✔ What's the identifier of your extension? hello-world-plugin
✔ What's the description of your extension? This is an example plugin.
✔ Initialize a git repository? Yes
`list` prompt is deprecated. Use `select` prompt instead.
✔ Which bundler to use? unbundled
`list` prompt is deprecated. Use `select` prompt instead.
✔ Which package manager to use? npm

Если вы не любите интерактивные формы ввода, можно сгенерировать конфигурацию одной строкой (не работает при использовании Docker):


      yo code ./hello-world-plugin -t=ts -q

После генерации откройте созданную папку в VS Code и нажмите F5 — запустится окно отладки с вашим плагином. 

Окно VS Code с запуском тестовой команды Hello World.

Как это работает

Весь основной код описан в файле src/extension.ts


      import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {

	console.log('Congratulations, your extension "hello-world-plugin" is now active!');
	const disposable = vscode.commands.registerCommand('hello-world-plugin.helloWorld', () => {
		vscode.window.showInformationMessage('Hello World from hello-world-plugin!');
	});
	context.subscriptions.push(disposable);
}

export function deactivate() {}

В первую очередь импортируется API VS Code — именно с ним взаимодействует плагин для регистрации команд, отображения диалоговых окон, кнопок и элементов интерфейса.

При инициализации плагина VS Code вызывает функцию activate(). В рамках процедуры активации срабатывает метод registerCommand(), в котором указываются уникальный идентификатор команды и исполняемая им функция.

Чтобы команду можно было вызвать из палитры вводом команды (Ctrl+Shift+P / Cmd+Shift+P), ее необходимо добавить в файл package.json (здесь же находятся название плагина, его описание, версия и зависимости). В разделе contributes указываются сама команда и ее название для пользователя:


        "contributes": {
    "commands": [
      {
        "command": "hello-world-plugin.helloWorld",
        "title": "Hello World"
      }
    ]
  },

Архитектура плагина

Теперь перейдем к основной реализации. Функциональность плагина я разделяю на три логических блока:

  1. Управление устройствами: добавление девайса с описанием, вызов консоли конкретного устройства, отправка файлов и установка приложения на него.
  2. Управление проектом: базовые функции Flutter (создание проекта, запуск анализатора и тестов) и сборка приложения под каждую архитектуру. В этом блоке важно учитывать особенности flutter-aurora, например передачу названия организации.
  3. Инструменты: настройки плагина и списка устройств (изменение IP-адресов, комментариев), а также функциональность подписания пакета сертификатами разработчика и организации.

Добавляем интерфейс (боковую панель) 

Чтобы не искать команды в палитре и не вводить их вручную, добавим боковую панель (View Container) с несколькими представлениями.

Для этого внесем в раздел contributes файла package.json следующую запись:


       "viewsContainers": {
      "activitybar": [
        {
          "id": "aurora-sidebar",
          "title": "Flutter for Aurora OS",
          "icon": "media/sidebar-icon.svg"
        }
      ]
    },

    "views": {
      "aurora-sidebar": [
        {
          "id": "aurora-devices-view",
          "name": "Устройства"
        },
        {
          "id": "aurora-project-view",
          "name": "Проект"
        },
        {
          "id": "aurora-tools-view",
          "name": "Инструменты"
        }
      ]
    },
Интерфейс панели управления плагина в VS Code с блоками элементов.

Простые действия с Flutter

Теперь нужно заполнить созданные представления функциями. Самое простое и быстрое — продублировать базовые команды flutter из консоли: создание проекта, добавление платформы, сборку под нужную архитектуру и запуск тестов.

Сначала зарегистрируем команды и настроим их отображение в интерфейсе:


      export function registerProjectCommands(context: vscode.ExtensionContext) {
    context.subscriptions.push(
        vscode.commands.registerCommand('ffa.create', createProject),
        vscode.commands.registerCommand('ffa.addPlatform', addAuroraPlatform),
        vscode.commands.registerCommand('ffa.pubGet', pubGet),
        vscode.commands.registerCommand('ffa.analyze', analyze),
        vscode.commands.registerCommand('ffa.test', runTests),
        vscode.commands.registerCommand('ffa.build', (arch: string) => { if (arch) build(arch); })
    );
}

…
export class ProjectProvider implements vscode.TreeDataProvider {
    getTreeItem(element: vscode.TreeItem) { return element; }
    getChildren(): vscode.ProviderResult {
        const items = [
            { label: 'Создать проект', cmd: 'ffa.create', icon: 'new-folder', args:[] },
            { label: 'Добавить платформу Аврора', cmd: 'ffa.addPlatform', icon: 'call-incoming', args:[] },
            { label: 'Pub Get', cmd: 'ffa.pubGet', icon: 'cloud-download', args:[] },
            { label: 'Анализатор', cmd: 'ffa.analyze', icon: 'beaker', args:[] },
            { label: 'Запуск тестов', cmd: 'ffa.test', icon: 'pass', args:[] },
            ...ARCHITECTURES.map(arch => ({ 
                label: arch.displayName, 
                cmd: 'ffa.build', 
                icon: 'play', 
                args: [arch.label] 
            }))
        ];

        return items.map(i => {
            const item = new vscode.TreeItem(i.label);
            item.command = { command: i.cmd, title: i.label, arguments: i.args };
            item.iconPath = new vscode.ThemeIcon(i.icon);
            return item;
        });
    }
}

Чтобы не перечислять варианты сборки в виде нескольких однотипных команд, вынесем список архитектур в отдельный массив:


      const ARCHITECTURES = [
    { label: 'aarch64', displayName: 'Сборка (aarch64)', psdkArch: "aurora-arm64" },
    { label: 'armv7', displayName: 'Сборка (armv7)', psdkArch: "aurora-arm" },
    { label: 'x86_64', displayName: 'Сборка (x86_64)', psdkArch: "aurora-x64" }
];

Далее опишем сами функции и их аргументы. Так как вызов команд консоли будет выполняться регулярно с разным набором параметров, для него создана небольшая вспомогательная обертка runCommand().

Самая объемная операция в этом блоке — сборка проекта. Из переданного аргумента выбирается целевая архитектура, а ее псевдоним подставляется в параметр --target-platform:


      function pubGet() { runCommand(flutterAurora, ['pub', 'get'], "AuroraFlutter"); }
function analyze() { runCommand(flutterAurora, ['analyze', '--no-fatal-infos'], "AuroraFlutter"); }
function runTests() { runCommand(flutterAurora, ['test'], "AuroraFlutter"); }

export function build(arch: string) {
    const archInfo = ARCHITECTURES.find(a => a.label === arch);
    if (!archInfo) return;
    runCommand(flutterAurora, ['build', 'aurora', '--release', `--target-platform=${archInfo.psdkArch}`], "AuroraFlutter");
}

Мастер создания проекта

Чтобы сделать процесс создания нового проекта более удобным, добавим немного «волшебства» — интерактивный мастер (Wizard). Поля, которые необходимо заполнить: название проекта, целевая папка и (опционально) идентификатор организации (по умолчанию для ОС «Аврора» используется ru.aurora).

API VS Code позволяет легко реализовать такие диалоговые окна с помощью vscode.window.showInputBox и vscode.window.showOpenDialog:


      async function createProject() {

    const appName = await vscode.window.showInputBox({
        prompt: 'Название проекта',
        value: 'app_demo',
        validateInput: (text) => !text?.trim() ? 'Название не может быть пустым' : null
    });
    if (!appName) return; // escape


    const org = await vscode.window.showInputBox({
        prompt: 'Организация',
        value: readAuroraConfig().developer?.app_prefix || 'ru.aurora',
        validateInput: (text) => !text?.trim() ? 'Организация не может быть пустой!' : null
    });
    if (!org) return;

    const parentDirUri = await vscode.window.showOpenDialog({
        canSelectFiles: false,
        canSelectFolders: true,
        canSelectMany: false,
        openLabel: 'Выберите папку для создания проекта'
    });
    if (!parentDirUri || parentDirUri.length === 0) return;
…

Аналогичным образом реализован класс ToolsProvider — представление для дополнительных инструментов. Он позволяет открывать настройки плагина, редактировать IP-адреса и параметры подключенных устройств, а также подписывать собранный RPM-пакет сертификатом разработчика или организации. 

Реверс IDE

Примерно по той же логике добавлен и класс DeviceProvider. Он содержит функции, которые выполняются непосредственно в связке с самим устройством:

  • Обмен SSH-ключами: упрощает подключение и позволяет в дальнейшем не вводить пароль (при использовании ключа без фразы-пароля);
  • SSH-терминал: для отладки и подключения к устройству;
  • Отправка файлов и пакетов приложения: загрузка собранных файлов на устройство;
  • Управление приложением: установка, запуск, просмотр логов и остановка процесса.

Каждая операция должна выполняться на конкретном устройстве по его IP-адресу. Перечень кнопок и устройств формируется из JSON-файла, а для его заполнения предусмотрено простое интерактивное меню: 


      export async function addDevice() {
    const host = await vscode.window.showInputBox({ prompt: 'Имя устройства (напр. R570E)' });
    if (!host) return;
    const hostname = await vscode.window.showInputBox({ prompt: 'IP адрес устройства' });
    if (!hostname) return;
    const archPick = await vscode.window.showQuickPick([
        { label: 'aarch64', detail: '64-bit ARM' }, { label: 'armv7', detail: '32-bit ARM' }, { label: 'x86_64', detail: 'x86_64' }
    ], { placeHolder: 'Архитектура' });
    if (!archPick) return;

    const devices = readDevices();
    devices.push({ host: host.trim(), hostname: hostname.trim(), user: 'defaultuser', arch: archPick.label });
    writeDevices(devices);
    vscode.window.showInformationMessage(`Устройство "${host}" добавлено.`);
}

Компания ОМП уделяет много внимания поддержке сообщества. В частности, они адаптировали популярную open-source IDE Qt Creator под нужды ОС «Аврора», заложив в нее готовые инструменты для сборки, доставки, установки и запуска приложений.

Доставить собранное приложение на устройство проще всего: достаточно передать полученный RPM-пакет по SSH командой scp:


          runCommand('scp', ['-o', 'StrictHostKeyChecking=no', '-o', 'UserKnownHostsFile=/dev/null', rpmPath, `${device.user}@${device.hostname}:${remotePath}`], "Deploy");

Далее начинаются нюансы. Установить пакет привычной командой rpm -i без повышения привилегий не так просто. Конечно, можно каждый раз запрашивать у пользователя пароль root, но это неудобно. Другой вариант — использовать утилиту sfdk.

Однако есть более изящное, неочевидное, но простое решение: установка пакета через встроенный системный сервис. Для этого достаточно отправить запрос службе ru.omp.APM через системную шину DBus:


          setTimeout(() => {
        runCommand('ssh', ['-o', 'StrictHostKeyChecking=no', '-o', 'UserKnownHostsFile=/dev/null', `${device.user}@${device.hostname}`,
            `gdbus call -y -d ru.omp.APM -o /ru/omp/APM -m ru.omp.APM.Install ${remotePath} '{}'`], "Deploy");
    }, 2000);

Занимательный факт: один из разработчиков ОМП опубликовал аналогичный подход на платформе CSDN.

Заключительный шаг — запуск приложения в пользовательском или отладочном режиме. Для этого используется системная утилита на устройстве или в эмуляторе (доступная также через DBus):


          let sshCommand: string;
    if (isDebug) {
        sshCommand = `/usr/bin/runtime-manager-tool Control startDebug ${appId} --output-to-console -e 'AURORA_APP_ID=${appId}' -e 'AURORA_PACKAGE_NAME=${appId}'`;
    } else {
        sshCommand = `/usr/bin/runtime-manager-tool Control start ${appId}`;
    }

Сборка, установка

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

Сборка выполняется стандартной командой:


      npx @vscode/vsce package

Программа vsce выполнит валидацию файлов и соберет пакет плагина в папку out. Чтобы пройти проверку пакета при наличии локальных ключей и сертификатов, добавлен флаг --allow-package-secrets privatekey.
Вы также можете опубликовать плагин в официальном маркетплейсе VS Code (инструкция доступна в документации). После публикации расширение проходит автоматическую проверку и становится доступно для установки в течение нескольких минут. 

Страница расширения FlutterForAurora в маркетплейсе VS Code.

Финальный этап — установка плагина. Для онлайн- и офлайн-сред поддерживается установка как из локального файла, так и напрямую из маркетплейса:


      code --install-extension  ffa-0.0.3.vsix # установить из файла 
code --install-extension techvlad.ffa # установить из маркетплейса (если расширение туда загружено)

После установки вы получаете полностью рабочий инструмент в интерфейсе вашей IDE:

Интерфейс плагина в VS Code с боковой панелью команд и открытым файлом devices.json.

Исходный код плагина опубликован в открытом Git-репозитории. Вы можете скачать его, изучить архитектуру или адаптировать под свои задачи. 

Заключение

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

Под подобные задачи всегда можно разработать собственный плагин: достаточно немного времени, и вот рутинные консольные команды легко превращаются в понятные кнопки интерфейса. Это напоминает создание специализированной оснастки для обработки деталей. Представленный плагин — лишь наглядная демонстрация того, что автоматизация VS Code доступна каждому. В целом, типовой список команд и сценариев можно доверить нейросети: она сгенерирует базовый шаблон, после чего останется лишь отладить логику и собрать готовый VSIX-пакет.