- Tutorial
Широко известный в узких кругах легковесный менеджер пакетов opkg получил распространение в embedded Linux не случайно. Opkg используется во многих встраиваемых дистрибутивах и проектах, например, в OpenEmbedded, Yocto Project, OpenWRT, Ångström, Arago Project и некоторых других. Менеджер прост в эксплуатации, для полноценной работы вполне достаточно встроенной справки, а на просторах всемирной паутины множество статей о том, как устроен сам пакет ipk (opkg работает с таким форматом): как его создать, как установить и т.д и т.п. Однако подавляющее большинство информации посвящено тому, как работать на уже установленной на целевую платформу (target) системе в online-режиме, но специфика Embedded подразумевает, что образ корневой файловой системы, а также ядро готовятся заранее на некоторой инструментальной платформе (host), отличной от целевой. Иными словами, собираем ядро и файловую систему на рабочем компьютере, упаковываем в образ, образ тиражируем на железо. Эта статья посвящена тому, как с помощью менеджера opkg установить пакеты в подготавливаемый образ rootfs.
Путь граблей и велосипедов
Много лет назад в бытность инженера одного небольшого завода, когда я запустил Linux на первой платке собственного производства, с помощью opkg установил из удаленного репозитория все требуемые пакеты, настроил все приложения, начальник лаборатории сказал: «Отлично! Теперь сделай то же самое на всех устройствах в партии». «Да не вопрос!» – ответил я. Система же есть, она запущена, она работает. Копируем все файлы из корня на внешний носитель, затем упаковываем в образ и радуемся жизни! В то время я не понимал, что при работе операционная система выполняет ряд локальных настроек, создает временные файлы, файлы конфигурации, генерирует какие-то ключи, а при первом запуске выполняет еще и скрипты инициализации. Хотя перенос файлов с одной работающей системы на другую методом тупого копирования с носителя и давал результат, но эффективность данного метода очень скоро для меня стала сомнительной. Получить «чистую» систему таким образом невозможно: система помнит свою предыдущую жизнь в другом аппаратном теле, и время от времени ее душат фантомные боли.Еще одна бредовая идеяНа target смонтировать внешний накопитель с rootfs, выполнить chroot и ставить пакеты. Комментировать не буду. Следующим шагом для меня стало понимание структуры самого покета *.ipk. По сути вещей, пакет ipk является архивом, распаковать который можно легко с помощью команды:
ar -x *.ipk
В результате получим:
. ├── control.tar.gz ├── data.tar.gz └── debian-binary
В архиве data.tar.gz содержатся файлы, которые должны быть помещены в корневую директорию target’а. В архиве control.tar.gz содержатся служебные файлы: файл с описанием и скрипты. Идея простая: так как ipk – это всего лишь архив со скриптами, то мы можем всегда руками распаковать его в директорию с файловой системой, а потом запустить (если есть в этом необходимость) скрипты. Вот только все зависимости пакета нам придется устанавливать также вручную. А если зависимости имеют еще зависимости? Возникает идея, может быть написать скрипт для автоматизации процесса? Как это часто бывает в мире linux, если перед тобой возникла задача, то, скорее всего, такая задача возникла не перед тобой одним, и, скорее всего, ты в этом деле не первый. Далеко ходить не пришлось, на самом деле в сам менеджер пакетов opkg заложен такой режим, когда пакеты устанавливаются в неактивную файловую систему rootfs. При этом, архитектура host-машины (где запускаются утилиты opkg) и target-машины могут быть отличными. Такой режим называется Offline mode. В таком режиме opkg становится мощнейшим инструментом кросс-разработки.
Собираем opkg для host
Для работы в режиме Offline opkg должен запускаться на host’е. С давних пор на моем рабочем компьютере обосновалась Ubuntu (сейчас стоит Ubuntu 14.04 LTS), на ней и будем строить наш инструментарий. Мне не удалось найти репозиторий с opkg для Ubuntu, потому собираем набор утилит из исходников. Получить исходные коды можно с git репозитория Yocto Project:
git clone git://git.yoctoproject.org/opkg.git cd opkg
Для тех кого пугает git можно обойтись и без него. На момент написания статьи, актуальная версия утилиты – opkg-0.3.1. Качаем исходники с сайта и распаковываем:
tar xzf opkg-0.3.1.tar.gz cd opkg-0.3.1/
На самом деле настройка и компиляция проекта выполняется достаточно стандартным способом, но есть некоторые нюансы, и потому все по порядку. Запускаем:
./autogen.sh
На заметку: если запустить ./autogen.sh
с параметром --clean
, то удалятся все труды по конфигурации проекта. После выполнения ./autogen.sh
в директории с исходниками появляется скрипт configure
, он выполнит настройку пакета, определит и задаст системозависимые переменные. В результате работы скрипта создается Makefile. Посмотреть все опции скрипта можно стандартным способом:
./configure --help
Собирать пакет будем под текущую платформу, потому опции настройки кросс-компиляции пропускаем. Озаботимся инсталляцией. По умолчанию, выполнив make install
, скрипт раскидает все полезные файлы (бинарники, скрипты, документация) по корневой директории: /etc
, /usr/local
, а это нам совершенно ни к чему. Мы ведь не собираемся использовать opkg для настройки пакетов в текущей системе? Кроме того, установив менеджер в системные папки, для использования утилит потребуются права суперпользователя, на мой взгляд, это излишне при настройке образа embedded linux. Скрипт configure.sh
позволяет задать префикс для директории установки пакета. Указав в качестве префикса любую рабочую директорию, мы сообщим инсталлятору куда ставить пакет. При необходимости можно отдельно задать префикс для архитектурозависимых (бинарники и библиотеки) и архитектуронезависимых (скрипты и документация) файлов. С фантазией у меня всегда было слабовато, потому для инсталляции в домашнем каталоге создадим каталог opkg_offline.
mkdir ${HOME}/opkg_offline
Выполним конфигурацию:
./configure --prefix=${HOME}/opkg_offline
При необходимости доставляем требуемые зависимости. Так мне на Ubuntu 14.04 для успешной сборки понадобилось доставить libarchive-dev
, libcurl4-gnutls-dev
, libssl-dev
, libgpgme11-dev
.А как это сделать?
sudo apt-get install libarchive-dev sudo apt-get install libcurl4-gnutls-dev sudo apt-get install libssl-dev sudo apt-get install libgpgme11-dev
Компилируем и устанавливаем opkg:
make make install
В результате в директории opkg_offline имеем:
opkg_offline ├── bin │ ├── opkg │ ├── opkg-check-config │ └── opkg-key ├── lib │ ├── libopkg.a │ ├── libopkg.la │ ├── libopkg.so -> libopkg.so.1.0.0 │ ├── libopkg.so.1 -> libopkg.so.1.0.0 │ ├── libopkg.so.1.0.0 │ └── pkgconfig │ └── libopkg.pc └── share ├── man │ └── man1 │ ├── opkg.1 │ └── opkg-key.1 └── opkg └── intercept ├── depmod ├── ldconfig └── update-modules
Менеджер пакетов собран и установлен. Исполняемые файлы находятся в директории opkg_offline/bin. Для работы с ними можно в переменную PATH прописать путь, либо для каждой сессии терминала вызывать экспорт (export
), либо делать как я делаю – перейти в каталог opkg_offline и запустить непосредственно ./bin/opkg
.
Краткий курс анатомии
Коротко рассмотрим как работает менеджер пакетов в стандартном режиме. После выполнения команды opkg update
, утилита читает файлы конфигураций, которые по умолчанию расположены в /etc/opkg
и имеют расширение .conf. Из этих файлов система определяет тип архитектуры, например armv5hf-vfp или armv5tehf-vfp (поддерживаемых архитектур может быть несколько, для каждой можно задать приоритет), список репозиториев и некоторые настройки самой программы. Далее для каждого репозитория из списка скачивается архив типа *_Packages.gz
. Архивы по умолчанию помещаются в директорию var/cache/opkg/
. После распаковки содержимое помещается в var/lib/opkg/lists
. В каждом архиве лежит текстовый файл со списком пакетов в репозитории. Для каждого пакета помимо названия указана версия, архитектура, размер, краткое описание, лицензия, а самое главное – зависимости. На основании этих файлов менеджер пакетов по запросу может выдать информацию о требуемом пакете, а при его установке определить все зависимости и разрешить их. Команда opkg list
выдаст все доступные для установки пакеты; команда opkg list-installed
покажет только установленные пакеты, команда opkg info
покажет информацию об указаном пакете, а если он установлен, то и время установки. Для установки пакета следует выполнить opkg install packname
. В результате требуемый пакет из репозитория будет скачен во временную директрию и распокован. Все файлы из архива data.tar.gz разойдутся по своим местам в rootfs, а на основании содержимого control.tar.gz в каталоге var/lib/opkg/info
будут созданы служебные файлы: packname.control
– полная информация о пакете, packname.list
— список директорий, по которым разошлись файлы из data.tar.gz (по этому списку пройдется opkg при удалении пакета), и файлы скриптов, типа packname.postinst
, packname.preinst
, packname.prerm
, packname.postrm
, назначения которых понятны из названия. Информация об установленном пакете будет добавлена в файле var/lib/opkg/status
в виде (пример для популярного minicom):
Package: minicom Version: 2.6.2-r0.2 Depends: libtinfo5 (>= 5.9), libc6 (>= 2.17) Status: install ok installed Architecture: armv7ahf-vfp-neon Installed-Time: 1454529423
Важно обратить внимание на Status
. Если пакет был установлен по всем правилам: все файлы скопированы на свое место, все скрипты выполнены, то статус будет Status: install ok installed
. При работе в режиме offline все файлы будут скопированы, но скрипты не выполнятся, такие пакеты будут помечены как Status: install ok unpacked
. На этот случай в opkg предусмотрен специальный механизм пост конфигурации пакетов. Запускается он командой opkg configure
. Если указать имя определенного пакета, то будут выполнены скрипты из var/lib/opkg/info для этого пакета; если имя опустить, то менеджер произведет конфигурацию для всех пакетов, у которых статус Status: install ok unpacked
. Таким образом, при установке пакетов на host в режиме offline, при первой загрузке операционной системы на target следует выполнить opkg configure
. Доверить это можно либо специальному скрипту, либо, если используется systemd, специальному сервису.
Работа с целевой rootfs
Настало время попробовать систему в деле. Для примера установим эмулятор терминала последовательного порта minicom. Для установки пакетов нам понадобится распакованный образ корневой файловой системы целевой платформы rootfs. Предположим, что в rootfs установлен менеджер opkg, a в директории etc/opkg
существуют файлы конфигурации *.conf. Если же его там нет, или по какой-то причине мы не хотим использовать конфигурацию из rootfs, мы можем через параметр указать какой файл настроек использовать: -f etc/opkg/opkg.conf
. Путь к целевой файловой системе передаем через параметр --offline-root /path/to/rootfs
. Обновляем списки пакетов:
bin/opkg update --offline-root /path/to/rootfs
Просматриваем список доступных пакетов, ищем minicom.
bin/opkg list --offline-root ~/board/rootfs/angstrom/rootfs-v2015.10 | grep minicom minicom - 2.7-r0.0 - Text-based modem control and terminal emulation program Minicom is a minicom-dbg - 2.7-r0.0 - Text-based modem control and terminal emulation program - Debugging files minicom-dev - 2.7-r0.0 - Text-based modem control and terminal emulation program - Development minicom-doc - 2.7-r0.0 - Text-based modem control and terminal emulation program - Documentation
Смотрим информацию о пакете:
bin/opkg info minicom --offline-root ~/board/rootfs/angstrom/rootfs-v2015.10
Package: minicom Version: 2.7-r0.0 Depends: libtinfo5 (>= 5.9), libc6 (>= linaro-2.20) Status: unknown ok not-installed Section: console/network Architecture: armv7at2hf-vfp-neon Maintainer: Angstrom Developers <angstrom>m: e4d11b7277fbc1c7db6bbd97ac52ca2c Size: 79354 Filename: minicom_2.7-r0.0_armv7at2hf-vfp-neon.ipk Description: Text-based modem control and terminal emulation program Minicom is a text-based modem control and terminal emulation program for Unix-like operating systems</angstrom>
Устанавливаем пакет:
bin/opkg install minicom --offline-root ~/board/rootfs/angstrom/rootfs-v2015.10
В файле var/lib/opkg
появилась запись:
Package: minicom Version: 2.7-r0.0 Depends: libtinfo5 (>= 5.9), libc6 (>= linaro-2.20) Status: install user unpacked Architecture: armv7at2hf-vfp-neon Installed-Time: 1454594718
После того, как с созданного образа была запущена система и отработала команда opkg configure
, запись в файле изменилась:
Package: minicom Version: 2.7-r0.0 Depends: libtinfo5 (>= 5.9), libc6 (>= linaro-2.20) Status: install user installed Architecture: armv7at2hf-vfp-neon Installed-Time: 1454594718
Так как настраиваемая rootfs предназначена для встраиваемого компьютера, конечный размер образа имеет значение. Поэтому рекомендую, после того как все нужные пакеты были установлены, удалить скаченные списки и почистить кэш:
rm -rvf ~/board/rootfs/angstrom/rootfs-v2015.10/var/cache/opkg/* rm -rvf ~/board/rootfs/angstrom/rootfs-v2015.10/var/lib/opkg/lists/*
На заметку: опция --volatile-cache
позволит очистить кэш автоматически при завершении работы.
Вместо заключения
Несмотря на работоспособность, у Offline mode есть некоторые недостатки. Дело в том, что команда opkg configure
запускает на выполнение только *.postinst
, но остается нерешенным вопрос с выполнением скриптов *.preinst
. В силу того, что *.preinst
встречается достаточно редко в пакетах, для меня является приемлемым в ручном режиме просмотреть скрипты, и при необходимости отработать их при первом запуске целевой системы (специальны service для systemd). Буду благодарен за совет.
Почитать по теме:
- IPK-пакет или с чем его едят
- OpenWrt.OPKG Package Manager. Наиболее внятный help.
- Yocto Project. Репозиторий. Исходники
Всем привет. Поговорим сегодня о таком как Opkg, я расскажу простыми словами что это вообще такое. Значит на одном сайте читаю что Opkg это свободный менеджер пакетов для встраиваемых систем. Мда уж, не совсем понятно. Вот еще читаю что Opkg пакеты позволяют как бы расширить функционал интернет-центра, но что это за центр не особо понятно.
Так, вот что я еще понял. Значит есть такая штука как OpenWrt, это встроенная операционка на ядре Линукс и она нужна в первую очередь для маршрутизаторов. Так, и вот конфигурирование это операционки производится при помощи командной строки, набора скриптов UCI и вот еще написано… что в репозитории доступно 3500 опциональных пакетов, которые видимо нужны для добавления новых функций, но самое главное.. что эти пакеты можно установить при помощи менеджера opkg. То есть вывод можно сделать такой, что opkg это менеджер установки пакетов для операционки OpenWrt.
Кстати ребята вот и сам менеджер:
Вот еще одна картинка, это какая-то прога от ZyXEL ну или это операционка OpenWrt, точно не знаю, но здесь есть вкладка OPKG:
Так ребята, а вот тут так и написано что менеджер пакетов OPKG позволяет загрузить и установить пакеты OpenWRT для расширения функционала:
На этом все. Я надеюсь что немного мы все таки смогли разобраться с тем что такое Opkg? Желаю удачи вам и будьте счастливы!
Используемые источники:
- https://habr.com/post/276609/
- https://990x.top/opkg-chto-eto.html