Открыть список
Как стать автором
Обновить
1255,87
Рейтинг
VDSina.ru
Серверы в Москве и Амстердаме

Скринкаст терминала с помощью asciinema

Блог компании VDSina.ruНастройка LinuxOpen sourceСистемное администрированиеСерверное администрирование


Вы наверняка знакомы с asciinema (github), это удобный опенсорсный инструмент для записи действий в терминале. Записи сохраняются в простом для чтения текстовом формате, поэтому весят совсем немного, а веб-плеер по сути воспроизводит текст из терминала вместо видео, так что любой кусок можно скопировать и использовать. Готовый материал можно загрузить в одно нажатие на asciinema.org или сначала отредактировать локально. Плеер можно встроить на сайт буквально в три строки, бонусом прилагаются всякие плюшки с оформлением и совместимостью, и вообще по совокупности всех фич (и отсутствия головной боли) asciinema давно перерос все аналоги. Вот только есть несостыковка: записи в проекте называют asciicasts, по аналогии со скринкастами — но возможности стримить сессию в реальном времени не было несколько лет, пока не вышел релиз 2.0, в котором с помощью нового формата файлов удалось реализовать на удивление стабильную и удобную раздачу на любой терминал в реал-тайме. О том, как это работает, о подводных камнях и перспективах — под катом.

Один формат — много возможностей


В старых версиях данные записывались в JSON, что добавляло немало оверхеда, да и парсинг у него нетривиальный, а главное, объект неудобно дробить на чанки для частичной передачи и чтения данных. На смену пришёл кастомный формат:

  {"version": 2, "width": 236, "height": 54, "timestamp": 1613998795, "idle_time_limit": 1.0, "env": {"SHELL": "/bin/bash", "TERM": "screen"}}
  [0.023635, "o", "client@some-desktop:~$ "]
  [0.812065, "o", "h"]
  [1.087183, "o", "e"]
  [1.246706, "o", "l"]
  [1.473065, "o", "l"]
  [1.657363, "o", "o"]
  [4.114169, "o", "exit\r\n"]

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

Если раньше единственным способом синхронного вывода было перенаправление записи в stdin второго терминала, что подразумевало хранение всего каста в памяти и воспроизведение после полного получения и парсинга, то теперь воспроизведение начинается сразу после анализа первой строки. Поток можно, например, завернуть в юниксовый именованный канал:

  mkfifo /tmp/demo.pipe

  # viewing terminal
  asciinema play /tmp/demo.pipe
  
  # recording terminal
  asciinema rec /tmp/demo.pipe

Или можно передавать данные по сети с помощью netcat:

  # viewing terminal (hostname: node123)
  asciinema play <(nc -l localhost 9999)
  
  # recording terminal
  asciinema rec >(nc node123 9999)

Причём на принимающей стороне необязательно даже иметь установленный asciinema, с режимом --raw данные отправляются «как есть», без конвертации. Но там не будет метаданных, не будут сохранены тайминги и задержки, поэтому такой вариант не слишком привлекателен. Гораздо лучше шагнуть ещё дальше и стримить сессию по ssh! Но здесь лучше не торопиться и сначала разобраться в реализации.

Рисуем картинку локально


Установка asciinema:

  sudo apt install python3-pip
  sudo pip3 install asciinema

Запишем тестовый файл командой asciinema rec -i 1 file.cast. -i 1 — это параметр, обрезающий задержку при вводе до одной секунды.

Пример файла каста выше соответствует выводу cat file.cast, он статичен. Но если начать запись и в соседней вкладке запустить tail -f file.cast, строки будут появляться по мере дописывания в файл после изменений в терминале. Этот динамически обновляющийся вывод можно перенаправить в asciinema play:

  # принимающая вкладка
  tail -fn +1 file.cast | asciinema play -

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

  # принимающая вкладка
  (head -1 file.cast && tail -fn 0 file.cast) | asciinema play -

К сожалению, при этом ломается первая строка в «зеркале» — она начинается сразу с введённых символов, опуская префикс, но это не критично, да и достаточно одного переноса, чтобы всё вернулось:



В целом, для простых юзкейсов можно не запариваться head'ом, но если строить полноценную систему с подключением посередине стрима и восстановлением после обрыва соединения, конечно, передавать первую строку нужно обязательно.

Переносим отображение на удалённый сервер


Нам понадобится беспарольный доступ, поэтому в принимающей вкладке генерируем ключи RSA, добавляем публичный ключ на сервер и идём его настраивать:

  ssh-keygen -t rsa
  ssh-copy-id -i ~/.ssh/id_rsa.pub user@hostname
  ssh user@hostname

  # на сервере поставим также утилиту pv для буферизации
  sudo apt install python3-pip pv
  sudo pip3 install asciinema

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

  # клиент
  asciinema rec -i 1 >(ssh user@hostname tee /path/to/file.cast >/dev/null)


  # сервер
  tail -fn +1 /path/to/file.cast | asciinema play -

Готово! По сути, всё уже работает. Но стоит добавить ещё пару штрихов: во-первых, asciinema play — высокоуровневая команда, для которой можно определить скорость выполнения операций. Чем выше значение (опционального) параметра -s, тем меньше задержка и выше нагрузка. Для наших целей куда лучше подойдёт asciinema cat, который работает на запись как аналог режима --raw, но воспроизводится с сохранением метаданных и параметров. Кроме того, воспользуемся pv для создания буфера на случай скачков производительности или сетевых лагов:

  # сервер
  tail -fn +1 /home/benaryorg/.local/tmp/tmp.6nkIacxYqF/foo | pv -q -b 8m | asciinema cat -

Результат




Плеер не встраивается в Хабр, извините

Светлое будущее


Вообще вся эта чудесная функциональность появилась довольно давно: 2.0 вышел около трёх лет назад. Однако, хорошая новость в том, что весь предыдущий год команда asciinema-player переписывала плеер целиком чтобы добавить в него вебсокеты, event sourcing и полностью сделать его совместимым с настоящими скринкастами. И хотя в профильном issue нет активности с весны, по коммитам видно, что работа кипит. Будет очень интересно посмотреть на стриминговый сервис для воинов консоли, не находите?



На правах рекламы


Подыскиваете VDS для отладки проектов, сервер для разработки и размещения? Вы точно наш клиент :) Посуточная тарификация, создавайте собственный конфиг в несколько кликов.

Теги:скринкастasciinemaopen sourceтерминалssh
Хабы: Блог компании VDSina.ru Настройка Linux Open source Системное администрирование Серверное администрирование
Всего голосов 26: ↑25 и ↓1 +24
Просмотры2.3K

Комментарии 4

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Похожие публикации

Лучшие публикации за сутки

Информация

Дата основания
Местоположение
Россия
Сайт
vdsina.ru
Численность
11–30 человек
Дата регистрации
Представитель
Mikhail

Блог на Хабре