Создание и публикация приложения в Launchpad
Последнюю неделю я активно стал разрабатывать небольшое приложение epever-tracer-influxdb. Оно позволяет читать параметры солнечного контроллера и отправлять данные в InfluxDB. Само приложение написано на C и предполагается, что оно будет работать на Raspberry PI. После того как я написал это приложение передо мной в очередной раз встала задача дистрибуции. Самый простой способ - попытаться добавить его в основной репозиторий Debian. Но тут есть несколько проблем:
- непонятно в какой момент пакет окажется в основном репозитории. Если мне, скажем, необходимо завтра начать использовать его, то мне точно не хочется ждать пока open source бюрократия пережуёт моё приложение
- что-то мне подсказывает, что нужно сделать очень много неявных приседаний прежде, чем моё приложение будет “каноничным” debian приложением. Это, конечно, полезно, но я не готов тратить сразу много времени на это.
Все эти проблемы решает Launchpad. Специальный сервис для хостинга своих персональных apt репозиториев. Это не первое моё приложение, которое я решил разместить там. До этого я размещал там apt-transport-swift.
Подготовка
Прежде, чем начать подготавливать приложение, необходимо знать одну важную деталь. На ней в документации нет сильного акцента и для новичка это может стать откровением. В debian/ubuntu мире есть очень чёткое различие между “оригинальным” приложением и “дебинизированным”. Оригинальное приложение - это фактически исходники приложения и то, что предоставляет разработчик приложения. “дебинизированное” приложение - это исходники (или .tar.gz) и метаинформация о самом приложении, необходимые скрипты для сборки и разворачивания его в операционной системе. Эту особенность необходимо постоянно держать в голове. Это особенно важно, если ты являешься одновременно разработчиком приложения и мейнтейнером.
Общая схема работы
PPA - это personal package archives. По сути репозиторий, где можно хранить свои собственные сборки разных пакетов или собственные приложения. Работает это следующим образом:
- Разработчик подготавливает пакет и исходные коды.
- Эти исходные коды заливаются в launchpad
- Launchpad начинает их собирать для разных архитектур и
- Выкладывает в персональный apt репозиторий
В самом Launchpad есть гигантская билд ферма, которая постоянно собирает новые пакеты под разные архитектуры. Очень круто и удобно. Понятное дело, что они поддерживают только open source проекты.
Погнали
Во-первых, необходимо создать аккаунт.
Во-вторых, в своём профиле на launchpad необходимо создать новый PPA. Тут опять всё очевидно.
В-третьих, необходимо привязать к своему аккаунту PGP ключ. Тут всё не так очевидно, но есть хороший мануал о том, как это сделать. В последствии этот ключ будет использоваться для того, чтобы подписать пакет и залить его launchpad.
Подготовка пакета
Для того чтобы собрать пакет, необходимо описать некоторую мета-информацию. Для этого необходимо создать папку debian в корне проекта. Я подробно не буду описывать каждый из необходимых файлов. Достаточно посмотреть пример того, как это сделано для epever-tracer-influxdb. Для разных приложений набор необходимых файлов может быть разный.
Локальная сборка пакета
Тут всё немножко сложнее. Поскольку я разрабатываю на маке, у меня нет всех необходимых инструментов, чтобы собирать .deb пакеты. В моём случае необходимо делать дополнительные шаги:
- создать виртуалку в облаке
- скопировать свои pgp ключи на виртуалку
После всего этого необходимо установить пакеты:
sudo apt-get install devscripts build-essential lintian
Создать архив с оригинальными исходными кодами:
tar czf epever-tracer-influxdb_1.0.0.orig.tar.gz epever-tracer-influxdb
Тут очень важно то, как называется этот архив. В нём обязательно должна быть версия и .orig.tar.gz. Скрипты сборки будут искать архив именно с таким именем.
После этого можно проверить, что пакет собирается:
debuild -i -us -uc -b
Также эта команда запускает lintian - линтер для .deb пакетов. Он очень продвинутый и может находить достаточно странные ошибки:
W: epever-tracer-influxdb: debian-changelog-has-wrong-day-of-week 2020-03-23 is a Monday
W: epever-tracer-influxdb: new-package-should-close-itp-bug
E: epever-tracer-influxdb: bad-permissions-for-etc-cron.d-script etc/cron.d/epeverTracerCron 0755 != 0644
По коду ошибки можно найти достаточно полное описание с вариантами исправления. Например, debian-changelog-has-wrong-day-of-week говорит о том, что в changelog файле у меня неправильный день недели. И это правда, потому что changelog был скопирован из другого проекта.
После того как сборка прошла успешно, можно собирать .changes файл. Для этого необходимо выполнить команду:
debuild -S -sa
Эта команда создаст несколько файлов директорией выше и подпишет их pgp ключом.
Публикация
Теперь всё готово, чтобы публиковать файлы в launchpad. Для этого нужно перейти на директорию выше и вызывать команду:
dput ppa:rodionovamp/epever-tracer-influxdb epever-tracer-influxdb_1.0.0-3_source.changes
Название PPA и файла .changes, конечно же, необходимо изменить на свои. Если всё прошло успешно, то launchpad пришлёт письмо:
[~rodionovamp/ubuntu/epever-tracer-influxdb/disco] epever-tracer-influxdb 1.0.2-5 (Accepted)
Это значит, что исходники получены и готовы к сборке. Статус сборки можно посмотреть в PPA. После того как собраны все пакеты для всех архитектур, они могут быть доступны для установки:
sudo add-apt-repository ppa:rodionovamp/epever-tracer-influxdb
sudo apt-get update
sudo apt-get install epever-tracer-influxdb
Что может пойти не так
Почти всё может пойти не так. Из-за того, что почти вся сборка основана на различных скриптах и негласных конвенциях, сломаться может любой из шагов выше. Я собрал очень много ошибок и потратил на их решение пару дней.
dpkg-source: info: building epever-tracer-influxdb using existing ./epever-tracer-influxdb_1.0.0.orig.tar.gz
dpkg-source: error: cannot represent change to docs/screen1.png: binary file contents changed
Почти всегда необходимо пересоздавать .orig.tar.gz после получения новых исходников из гита.
Rejected:
File epever-tracer-influxdb_1.0.0.orig.tar.gz already exists in epever-tracer-influxdb, but uploaded version has different contents. See more information about this error in https://help.launchpad.net/Packaging/UploadErrors.
Нельзя залить один и тот же архив с исходниками два раза. Даже если первый не собрался или в нём ошибка. При небольшом изменении исходников необходимо менять минорную версию и заново создавать архив.
Files specified in DSC are broken or missing, skipping package unpack verification.
debuild почему-то при ошибке подписывания исходников не падает, а продолжает работу. Если такие исходники попытаться залить в launchpad, то возникают странные ошибки.
* State: Failed to build
* Duration: 2 minutes
* Build Log: ....
Для старых дистрибутивов уже нельзя собрать проект.
Rejected:
disco is obsolete and will not accept new uploads.
epever-tracer-influxdb (1.0.3-2) disco; urgency=medium
То, что собралось на Mac OS необязательно соберётся на Ubuntu. Необходимо локально собирать проект и прогонять все тесты.
Выводы
- Очень много негласных конвенций и скриптов для сборки deb пакетов. Возможно, это связано с большим наследием самой системы. Возможно, это связано со сложностью поддержки такого большого количества пакетов в консистентном состоянии.
- Как следствие, нужно много читать или много тратить времени, чтобы исправить все ошибки деплоя
- Из плюсов, бесплатный хостинг вашего маленького приложения в публичном месте. Хотя я, конечно же, предпочёл что-нибудь посовременнее и проще.