← Заметки

Перевод community.openwrt с shell на ucode

· openwrt, ansible, ucode

Я управляю небольшим парком роутеров на OpenWrt через Ansible: облачные роутеры, VPS и домашние коробки. Инструмент для этого — community.openwrt, наследник старой роли gekmihesg.openwrt. Его фишка в том, что на роутере не нужен Python: модули были shell-скриптами, которые контроллер копировал по SSH и запускал в BusyBox самого роутера.

Это работает, но медленно — именно скорость и заставила меня его переписать. В shell-модуле uci каждая опция означала ещё несколько вызовов uci и jsonfilter, а моей mesh-сети нужно много опций на каждом роутере — по задаче и по пачке процессов на каждую. Вдобавок JSON собирается из shell-строк, экранирование — минное поле, а тестировать такие модули тяжело.

Почему ucode

На каждом устройстве с OpenWrt уже есть рантайм получше: ucode — небольшой JavaScript-подобный язык, на котором написан firewall4. В нём есть встроенный JSON и привязки к fs, uci и ubus, так что модуль читает и пишет конфигурацию напрямую, а не запускает внешнюю команду ради каждого значения.

Что произошло

Дальше: WireGuard и AmneziaWG

Моя домашняя mesh-сеть построена на туннелях WireGuard и AmneziaWG, и до сих пор вся их обвязка жила в большой Ansible-роли. Новые модули wg_interface и wg_peer (#281, на ревью) забирают на себя логику на стороне устройства: генерацию ключей, общие PSK, пиров и удаление ненужных интерфейсов. Я уже использую их из своего форка, а интеграционными тестами служат сценарии Molecule на настоящей прошивке роутеров в виртуальных машинах.

Несколько подводных камней ucode