luckyyyyy / blog

William Chan's Blog
https://williamchan.me/
175 stars 28 forks source link

openwrt lua 接口遇到的一些坑 #48

Open luckyyyyy opened 4 years ago

luckyyyyy commented 4 years ago

这段时间活跃在openwrt社区,其实时间也不久 不过还是记录一下遇到的一个最大的坑。

首先由于各种原因,openwrt国内都把luci稳定在17或18的版本上,大家开发应用其实都是互相抄官方的写法,因为文档其实很稀缺或者说大多数都已经过时了。

近期用rust写了一个简单的demo(过段时间公开),但是开发时候遇到了不少问题总结一下。

1、首先大多数应用都是shell脚本读取配置交由应用来完成,会lua的同学其实不多,导致shell脚本会调用大量的grep sed等命令,性能不是很好。 2、大家的luci的lua脚本其实都是来自于官方,甚至找不到api直接exec shell脚本来实现。 3、官方的luci,19版本改造的前后端分离,导致大量老应用不兼容的情况。

今天发现,其实官方的API也非常坑,对于不了解lua的同学来说非常不友好。 我们后面再来介绍 openwrt uci 与 ubus之间的关系,这一篇且说遇到的坑。

luci.model.uci其实最终调用是ubus而非uci 这是最终触达代码

local _ubus_connection = nil
local function ubus(object, method, data)
    if not _ubus_connection then
        _ubus_connection = _ubus.connect()
    end
    _ubus_connection:call(object, method, data)
end
ubus("uci", "commit", { config = "config" })

等价于

ubus call uci commit '{"config":"config"}'

其实大家对ubus的C/S,跨进程通讯架构在应用中用到的并不到,大部分都是shell(应用控制)+lua(界面+控制器)的形式。 包括shell脚本,大家也都是直接 uci get xxx。

其实完全可以直接调用uci,下方列出一些API供参考。

// lua/uci.c
static const luaL_Reg uci[] = {
    { "__gc", uci_lua_gc },
    { "close", uci_lua_gc },
    { "cursor", uci_lua_cursor },
    { "load", uci_lua_load },
    { "unload", uci_lua_unload },
    { "get", uci_lua_get },
    { "get_all", uci_lua_get_all },
    { "add", uci_lua_add },
    { "set", uci_lua_set },
    { "rename", uci_lua_rename },
    { "save", uci_lua_save },
    { "delete", uci_lua_delete },
    { "commit", uci_lua_commit },
    { "revert", uci_lua_revert },
    { "reorder", uci_lua_reorder },
    { "changes", uci_lua_changes },
    { "foreach", uci_lua_foreach },
    { "add_history", uci_lua_add_delta },
    { "add_delta", uci_lua_add_delta },
    { "get_confdir", uci_lua_get_confdir },
    { "set_confdir", uci_lua_set_confdir },
    { "get_savedir", uci_lua_get_savedir },
    { "set_savedir", uci_lua_set_savedir },
    { "list_configs", uci_lua_list_configs },
    { NULL, NULL },
};