Сборка и запуск Zigbee2mqtt для OpenWRT
Инструкция по сборке Zigbee2MQTT под musl/aarch64 на хост-машине с Docker и запуску на OpenWrt.
Почему это нетривиально
OpenWrt использует musl libc вместо стандартного glibc. Это означает:
- Официальные бинарники Node.js с nodejs.org (glibc) не запустятся
- Пакет
nodeв фидах OpenWrt — только host-инструмент для сборки (PKG_HOST_ONLY=1), в прошивку не попадает - Entware для aarch64 не содержит Node.js
- Нативные модули (
@serialport/bindings-cpp) нужно компилировать под musl
Решение: собирать всё в Docker-контейнере на базе Alpine Linux (тоже использует musl).
Требования
Железо
Проверено на NAPI-C (rk3308\512Мб\4Гб Nand) c прошивкой OpenWRT (NapiWRT). Репозиторий: https://github.com/lab240/napi-openwrt-build/
Программное обеспечение на хост-машине
- Docker
- Git
Шаг 1: Подготовка носителя
OpenWrt по умолчанию создаёт rootfs раздел ~104 МБ. Для Zigbee2MQTT нужно минимум 500 МБ свободного места.
В нашей сборке NapiWRT это решено автоматически через два uci-defaults скрипта которые при первой загрузке расширяют rootfs до конца носителя:
files/etc/uci-defaults/70-rootpt-resize — расширяет раздел и перезагружается:
if [ ! -e /etc/rootpt-resize ] \
&& type parted > /dev/null \
&& lock -n /var/lock/root-resize
then
ROOT_BLK="$(readlink -f /sys/dev/block/"$(awk -e \
'$9=="/dev/root"{print $3}' /proc/self/mountinfo)")"
ROOT_DISK="/dev/$(basename "${ROOT_BLK%/*}")"
ROOT_PART="${ROOT_BLK##*[^0-9]}"
echo "70-rootpt-resize: expanding ${ROOT_DISK} partition ${ROOT_PART} to 100%..."
parted -f -s "${ROOT_DISK}" resizepart "${ROOT_PART}" 100%
echo "70-rootpt-resize: done, rebooting..."
mount_root done
touch /etc/rootpt-resize
reboot
fi
exit 1
files/etc/uci-defaults/80-rootfs-resize — расширяет файловую систему через losetup и перезагружается:
if [ ! -e /etc/rootfs-resize ] \
&& [ -e /etc/rootpt-resize ] \
&& type losetup > /dev/null \
&& type resize2fs > /dev/null \
&& lock -n /var/lock/root-resize
then
ROOT_BLK="$(readlink -f /sys/dev/block/"$(awk -e \
'$9=="/dev/root"{print $3}' /proc/self/mountinfo)")"
ROOT_DEV="/dev/${ROOT_BLK##*/}"
echo "80-rootfs-resize: resizing filesystem on ${ROOT_DEV}..."
LOOP_DEV="$(losetup -f)"
losetup "${LOOP_DEV}" "${ROOT_DEV}"
resize2fs -f "${LOOP_DEV}"
losetup -d "${LOOP_DEV}"
echo "80-rootfs-resize: done, rebooting..."
mount_root done
touch /etc/rootfs-resize
reboot
fi
exit 1
Необходимые пакеты в .config сборки:
CONFIG_PACKAGE_parted=y
CONFIG_PACKAGE_losetup=y
CONFIG_PACKAGE_resize2fs=y