Авторские статьи

Личное общение с инструментом snapcraft.


Вечно мне хочется написать слово snapcraft в виде StarCraft, уж так похожи слова. В англонете даже появились слова снапкрафтер (кто делает пакеты snap) и глагол снапкрафтить (процесс упаковки софта). Нет ничего лучше для понимания сути процесса, как погрузиться в него. Решил создать пакет snap и посмотреть весь процесс от создания до заливки в Ubuntu Store.

Первым делом нужно определиться с подопытным кроликом, которого мы будем мучать. Хотелось не просто для себя что-то поделать, но и принести пользу сообществу, если всё получится. Осмотрелся вокруг и решил взяться за LanguageTool. Прекрасный инструмент, который позволяет исправить не только орфографические, но и грамматические ошибки, давая советы по стилистическому оформлению текста. Но его Java природа меня чуток пугала, так как программист во мне умер довольно давно и с джавой никогда не работал. Но подкупало то, что LanguageTool не представлен в репозиториях и оформить его в виде snap для людей - это круто.

С чего начать? Лезем на официальный сайт languagetool.org в раздел development. Итак, у нас есть исходники на github.com/languagetool-org/languagetool. Wiki проекта пишет, что используется система сборки Maven.

Теперь знакомимся с инструментом сборки и упаковки snapcraft. Он умеет собирать различный софт, написанный на различных языках программирования. Расширяется это через систему плагинов и команда snapcraft list-plugins выводит на данный момент:

ant        catkin  copy  jdk     kernel  maven  nodejs   python3  tar-content
autotools  cmake   go    kbuild  make    nil    python2  scons  

Maven есть и это обнадёживает. Создаю черновой вариант snapcraft.yaml и знакомлюсь с первым понятием - Parts. Это кусочек того, что будет обрабатывать снапкрафт. Кусочков можно делать несколько и они, обычно, независимы друг от друга. Помимо основной информации, создал кусочек languagetool и приказал обрабатывать его плагином maven, указав адрес исходного кода. В идеале, снапкрафт скачает, соберёт и упакует одной командой, но жизнь суровее.

parts:
  languagetool:
    plugin: maven
    source: https://github.com/languagetool-org/languagetool.git
    source-type: git

Каждый кусочек проходит следующие этапы при вызове из снапкрафт:

  • Pull. Вначале нужно скачать требуемое. Каждый parts будет стянут (checkout для git, простое скачивание для Java SDK и т.д) и помещён в свой подкаталог parts/ в виде parts/part-name/src/
  • Build. Каждый кусочек будет собран в parts/part-name/build/ и "установлен" parts/part-name/install/
  • Stage. После предыдущего этапа каждый кусочек будет объединён с другими в одном каталоге stage/, образно называемым staging area. Каталог stage/ обычно используется для построения своего кода, который не описан в snapcraft.yaml, хотя настоятельно рекомендуется просто добавить source: path для своих хотелок
  • Prime. Старое название этапа - Strip. Данный этап в каталоге prime/ создаст прообраз будущего пакета в виде папок и файлов, без каких-либо лишних файлов (к примеру заголовочные файлы). Файл prime/meta/snap.yaml - это ваш snapcraft.yaml
  • Snap. Этап, который непосредственно оформляет готовый пакет snap

Данные этапы parts проходит как они описаны выше. Если просто вызвать snapcraft в каталоге где лежит одинокий snapcraft.yaml, то вы неявно вызываете snapcraft snap, а этап snap вызовет все этапы перед ним. Этапы можно вызвать и явно - snapcraft build.

И что мы имеем? Оказалось, что имеют нас.

...
[INFO] LanguageTool common GUI classes .................... SUCCESS [  1.303 s]
[INFO] LanguageTool command-line version .................. SUCCESS [ 17.175 s]
[INFO] LanguageTool embedded HTTP server .................. SUCCESS [ 30.993 s]
[INFO] LanguageTool tools for building dictionaries ....... SUCCESS [ 31.072 s]
[INFO] LanguageTool stand-alone GUI ....................... SUCCESS [01:19 min]
[INFO] LanguageTool LibreOffice/OpenOffice extension ...... SUCCESS [ 23.636 s]
[INFO] Hunspell native libs for LanguageTool .............. SUCCESS [  0.306 s]
[INFO] LanguageTool Wikipedia tools ....................... SUCCESS [01:19 min]
[INFO] LanguageTool HTTP API client ....................... SUCCESS [ 13.500 s]
[INFO] LanguageTool development tools ..................... SUCCESS [ 40.936 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14:19 min
[INFO] Finished at: 2016-06-14T16:03:17+03:00
[INFO] Final Memory: 46M/141M
[INFO] ------------------------------------------------------------------------
could not find any built jar files for part

Очень долгая из-за тестов сборка Maven завершилась успешно, но общий итог плачевен. Строка could not find any built jar files for part принадлежит коду плагина maven у snapcraft и косяк где-то там - он не может найти итоговые jar файлы. Тут решил взять таймаут и разрешить часть проблем:

  • С первого раза, вот так взял и собрал софт в snap - это утопия. Будет много итераций. Иногда автоматически или твой snapcraft clean удалит все ошмётки и тянуть нужно заново. Сборочный сервер был натравлен на отдельный apt-cacher-ng, чтобы сэкономить время и нервы. cat /etc/apt/apt.conf.d/01proxy
    Acquire::http { Proxy "http://1.2.3.4:3142"; };
  • Уже стало понятно, что нужно как-то приказать Maven не проверять больше проект LanguageTool и пропустить все тесты. Нашёл на просторах Интернета, что <skipTests>true</skipTests> поможет. Догадался добавить в parts/languagetool/src/pom.xml. Теперь сборка в разы ускорилась.

Меня смущала проблема с плагином maven и не знал как поступить правильно. Добавьте сюда что мне нужна была лишь часть проекта в лице languagetool-standalone, а там ещё:
hunspell-native-libs
languagetool-client-example
languagetool-commandline
languagetool-core
languagetool-dev
languagetool-gui-commons
languagetool-http-client
languagetool-language-modules
languagetool-office-extension
languagetool-server
languagetool-tools
languagetool-wikipedia

Сначала позанимался форменным садо-мазо и, не зная ни Java, ни как собираются её проекты с помощью Maven, решил подправить в parts/languagetool/src/pom.xml строки. Стало ещё хуже. Теперь и Maven начал справедливо ругаться на меня матом. Почти случайно обнаружил, что maven свою работу сделал на все 100% и даже подготовил в parts/languagetool/build/languagetool-standalone/target/ готовый архив LanguageTool-3.4-SNAPSHOT.zip с откомпилированной в jar версией отдельного инструмента LanguageTool.

Тогда вспыхнула надежда, что не всё потеряно. Мысль заработала так. Не могу сейчас починить плагин maven, тогда создам новый пустой каталог и сделаю другой snapcraft.yaml. Мне нужно готовый проект в виде jar скрепить с Java в виде snap пакета, поэтому в новом файле snapcraft.yaml пишу следующее:

parts:
  jdkfiles:
    plugin: jdk
    source: lt-snapshot
  lt:
    plugin: tar-content
    source: lt-snapshot.tar.gz
    destination: usr/bin

LanguageTool-3.4-SNAPSHOT.zip перепаковал в lt-snapshot.tar.gz и создал ДВА кусочка: jdkfiles и lt (сократил имя). Кусочек jdkfiles использует плагин jdk и мой неправильный путь в source. Не знаю как правильно, но фигня работает. Кусочек lt использует deprecated плагин tar-content (его советуют заменить на copy) и разворачивает весь lt-snapshot.tar.gz в usr/bin. Тут я нарушил все известные стандарты иерархии файловой системы (Filesystem Hierarchy Standard - FHS), накакав в папку для бинарников всем чем можно, но в оправдание скажу, что программа всё равно будет изолирована и её usr/bin это не наш системный /usr/bin/ и мне хотелось чтобы хоть что-то заработало.

Результат? Программа LanguageTool корректно ставилась на моём рабочем компьютере из snap пакета, но не запускалась, выводя Bad system call. В логах AppArmor действительно ругался на системный вызов под номером 45, который утилита scmp_sys_resolver 45 расшифровала в recvfrom. Что-то не так с разрешением мной сокетов. Дело в том, что в разделе apps дал добро на стыковку с сетью, домом, X11 и Unity7.

apps:
  languagetool:
    command: java -jar usr/bin/languagetool.jar
    plugs: [network, network-bind, x11, home, unity7]

Но все эти plugs в декларативной форме будут развёрнуты в правила AppArmor, а там помимо его ещё трудится фильтр seccomp. В данном моменте чуть не ушёл не туда. Начал начитываться про системные вызовы и как их нужно оформлять декларативно в snapcraft.yaml, но тестовые примеры от разрабов на все случаи жизни не содержали подобного и значит мыслю я неверно.

Тут гуглёж вывел на такие темы, что руки опустились и стало грустно. Snapcraft сам готовит враппер-обёртку, но переменных там не достаточно для корректного запуска именно Java программ. Люди пишут, что необходимы как минимум строки

# Not good, needed for fontconfig
export XDG_DATA_HOME=$SNAP/usr/share
# Font Config
export FONTCONFIG_PATH=$SNAP/etc/fonts/config.d
export FONTCONFIG_FILE=$SNAP/etc/fonts/fonts.conf
export HOME=$SNAP_USER_DATA

И тогда решил сделать ход конём. Запускать будем шелл скрипт, который дополнит нужное и уже сам запустит джава программу. Меняем строку command: java -jar usr/bin/languagetool.jar на command: usr/bin/run.sh. Создаём скрипт lt-snapshot/run.sh с содержимым

#!/bin/sh
# Not good, needed for fontconfig
export XDG_DATA_HOME=$SNAP/usr/share
# Font Config
export FONTCONFIG_PATH=$SNAP/etc/fonts/config.d
export FONTCONFIG_FILE=$SNAP/etc/fonts/fonts.conf
export HOME=$SNAP_USER_DATA
java -jar $SNAP/usr/bin/languagetool.jar

И снова пакуем lt-snapshot/ в lt-snapshot.tar.gz .... ииииииииии? Запуск программы! Аллилуйя, запрыгал как горный козёл в шаманской пляске. Неужели сделал? На тебе под дых, чтобы жизнь мёдом не казалась. Софт при закрытии ругается и ругается если сползать в Опции. Просто в этой новой версии LanguageTool 3.4, которая выйдет в свет только 27 июня 2016 года, реализовали сохранение настроек внешнего вида и файл настроек лежит там куда нельзя писать софту из snap пакетов.

Финальный аккорд - переопределяем джава программе её домашнюю папку и меняем последнюю строку в run.sh на
java -jar -Duser.home=$SNAP_USER_DATA $SNAP/usr/bin/languagetool.jar
И всё! Реально всё. LanguageTool корректно сохраняет всё что ему нужно в вашей-и-его домашней папке ~/snap/languagetool/.

Побежал заливать snap пакет и тут проверка выдала 1 помарку, которую я проигнорировал от snapcraft. Затесалась ссылка на несуществующий файл - usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts вердикт lint-snap-v2_external_symlinks
Автоматическое одобрение прервалось. Нужно было или исправлять, но моё удаление тупой ссылки вызвало ругань от snapcraft - дескать не ты делал, чего ручонки пихаешь? Я выбрал - запрос на проверку специалистом.

LanguageTool в snap

Прошло немного времени и LanguageTool-3.4 для 64 битных систем стал доступен в Ubuntu Store.
snap find language

languagetool               3.4                        -        LanguageTool

Впереди работа над ошибками, так как специалист вынес мне вердикт - разрешу сейчас, но исправьте ситуацию. If your app is java and needs to use ssl, it will fail due to this. You'll need to resolve this in the snap. One way is to ship usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts as an actual file and not a symlink. I suggest talking to the snapcraft developers and/or filing a bug. I'm going to approve this for now, but please get this resolved in your next upload. — Jamie Strandboge

Нужно подумать над единым пакетом для 32 и 64 битных платформ. Сердце бьётся от такого факта, что мои кривые ручки смогли преодолеть все проблемы, не разбираясь ни в джаве ни в maven. Это ли не показатель крутости Snapcraft?

Второй snap пакет. GTK программа DeaDBeeF. sudo snap install deadbeef-vs
Третий snap пакет. Java программа TuxGuitar. sudo snap install tuxguitar-vs
Четвёртый snap пакет. Java программа Vuze. sudo snap install vuze-vs
Пятый snap пакет. Java программа osddm. sudo snap install osddm
Шестой snap пакет. PAC (Perl Auto Connector). sudo snap install pac-vs

Дата последней правки: 2024-03-28 09:38:50

RSS vasilisc.com   


Разделы

Главная
Новости
Ворох бумаг
Видео Linux
Игры в Linux
Безопасность
Статьи об Astra Linux
Статьи о FreeBSD
Статьи об Ubuntu
Статьи о Snappy
Статьи об Ubuntu Phone
Статьи о Kubuntu
Статьи о Xubuntu
Статьи о Lubuntu
Статьи об Open Source
Карта сайта