Cluster · разработчикам

Терминал

Терминал открывает Bash для выбранного юзербота. Он доступен овнерам на сайте и через !exec. Доверка и модули запускать его не могут.

Внутри есть обычные команды Linux, Python и команда cluster для управления юзерботом. Рабочая папка /work сохраняется после закрытия сеанса и перезапуска службы. Домашняя папка также указывает на /work. Процессы терминала используют общие лимиты юзербота.

Первый запуск

На сайте открой «Терминал» и нажми «Открыть терминал». Нажми на экран и вводи команды:

pwd
whoami
cluster help
cluster status
cluster modules

whoami вернёт nobody. Это системный пользователь изолированной среды с UID 65534. Полномочия овнера проверяет ядро, они не зависят от имени пользователя Linux. В приглашении Bash отображается nobody@cluster:~$.

В новой папке может находиться lost+found. Это служебная папка ext4. Свои файлы можно создавать рядом:

mkdir scripts
printf 'print("Hello")\n' > scripts/hello.py
python scripts/hello.py

Ctrl+C прерывает текущую команду. Tab дополняет команды и пути, стрелки вверх и вниз перебирают команды текущего сеанса. После перехода на другую страницу сеанс продолжает работать. Кнопка «Остановить» завершает всю среду терминала, включая фоновые процессы. После перезапуска ядра нужен новый сеанс.

Модули

cluster modules
cluster modules show MODULE/main
cluster modules stop MODULE/main
cluster modules start MODULE/main
cluster modules restart MODULE/main

Вместо MODULE/main укажи идентификатор экземпляра из cluster modules. В списке также отображается название модуля. При повторном запуске сохраняются его данные и настройки.

Получить копию файлов установленного пакета:

cluster modules export MODULE/main module-copy
cd module-copy
ls

Каталог назначения должен быть новым. Это копия, изменения в ней не меняют запущенный модуль. Каталог установленных зависимостей .deps в копию не включается. Чтобы изменить опубликованный модуль, подготовь новую версию и опубликуй её через каталог.

Настройки и права

cluster config get MODULE/main
cluster config set MODULE/main '{"enabled":true}'
cluster permissions get MODULE/main
cluster permissions set MODULE/main '{"db.read":{},"db.write":{}}'
cluster settings get
cluster settings set '{"prefix":".","language":"ru"}'

Названия полей конфигурации задаёт автор модуля. config get возвращает описание полей, значения и номер редакции. Овнер может получить в терминале также значения секретных полей, поэтому не публикуй такой вывод.

config set меняет только переданные поля. Ядро проверяет их типы и сообщает модулю об изменении. Для применения заранее подготовленных изменений можно указать --revision 3. Если настройки с тех пор изменились, команда вернёт ошибку конфликта.

permissions set заменяет весь набор выданных прав. Пропущенные права будут отозваны. Выдать право, которое модуль не запрашивал, нельзя. Ограничения записываются в значениях прав, например {"telegram.read":{"chats":[123456789]}}.

Значения можно передавать из файла или стандартного ввода:

cluster config set MODULE/main @settings.json
printf '{"prefix":"!"}' | cluster settings set -

Данные

cluster data keys --instance MODULE/main
cluster data get note --instance MODULE/main
cluster data set note '{"text":"Привет"}' --instance MODULE/main
cluster data rm note --instance MODULE/main

Без --instance используется раздел core/main. Команды работают с прикладными записями, физический файл базы в терминал не передаётся. Запись учитывается в квоте юзербота. keys возвращает страницу ключей; значение after передаётся следующему вызову через --after.

Файлы

Хранилище юзербота и /work находятся в разных разделах. Для переноса файлов есть команды:

cluster files ls
cluster files put report.txt
cluster files put report.txt report-copy.txt --instance MODULE/main
cluster files get FILE_ID downloaded.txt
cluster files rm FILE_ID

files ls показывает файлы всего выбранного юзербота, включая принадлежность экземпляру. Для следующей страницы используй --after со значением из ответа. put возвращает идентификатор загруженного файла. Без --instance он принадлежит core/main.

Файлы передаются частями по 64 KiB. Загрузка проверяет размер, контрольную сумму и свободное место. При неудачной передаче её резерв освобождается. Скачивание не заменяет существующий файл, незавершённая копия при ошибке удаляется.

Копия в /work занимает место рабочего диска терминала. Если файл также сохранён в хранилище юзербота, учитываются обе копии.

Журнал и расписание

cluster logs --limit 50
cluster tasks list
cluster tasks get TASK_ID
cluster tasks cancel TASK_ID
cluster tasks delete TASK_ID

Создать задачу можно через SDK в разделе нужного модуля. Название обработчика и его аргументы должны соответствовать определению модуля.

Python

Client предоставляет объекты SDK через локальное соединение с ядром. Логин, пароль сайта и ключ API для этого не нужны:

import asyncio
from terminal_client import Client

async def main() -> None:
    app = Client("MODULE/main")

    async with app.db("scripts/").record("counter", {"value": 0}) as record:
        record.set("value", record.get("value") + 1)

    print(await app.config.all())
    print(await app.client.get_me())

asyncio.run(main())

Client() без аргумента использует раздел core/main. В Client("MODULE/main") данные, файлы и расписание по умолчанию относятся к этому экземпляру. Полномочия остаются полномочиями овнера.

Доступны записи и пакеты изменений базы, файлы, вебклиент, Telegram, личный бот, расписание, вызовы функций модулей, обмен и запись в журнал. Регистрация обработчиков, получение очереди команд и запуск другого терминала через это соединение недоступны. Методы app.core для конфигуратора внутри Telegram требуют события команды; в терминале используй cluster config, cluster settings и app.request("terminal/configure", ...).

Прямой вызов

cluster api telegram/request '{"method":"get_me"}'
cluster api module/limits '{"instance":"MODULE/main","values":{"cpu":0.5}}'
python -m terminal_client db/get '{"key":"note"}'

Аргументы соответствуют операциям ядра. Доступны операции перечисленных выше объектов SDK, а также module/state, module/grant, module/limits, unit/settings, unit/trust, preferences, logs/list, logs/clear, notifications, tasks/list, tasks/get, tasks/cancel и tasks/delete. Произвольный вызов операторских и административных методов запрещён.

terminal/status, terminal/modules, terminal/configuration, terminal/configure и terminal/source обслуживают команды терминала. Выбрать другой юзербот подменой параметра нельзя. Полная резервная копия создаётся на сайте: перед копированием ядро останавливает терминал, чтобы сохранить его файлы согласованно.

Изоляция

Системный диск доступен только для чтения. /work предназначен для своих файлов, /tmp содержит временные файлы. Сеть предоставляется через app.web, прямого сетевого подключения у процесса Bash нет. Подключённые модули, база и хранилище меняются через операции ядра, файлы сервера управления к Bash не подключаются.

Фактическая Telegram-сессия, токены ботов, ключ службы и данные других юзерботов недоступны. При изменении состава овнеров прежняя среда закрывается. Каждое обращение проверяет состояние юзербота, полномочия и блокировку профиля. Для поддержки отдельно проверяется выданный доступ.