openwrt UCI API lua wiki
来源:互联网 发布:登录我的淘宝账号 编辑:程序博客网 时间:2024/06/04 19:48
转载自https://wiki.openwrt.org/doc/techref/uci#usage_outside_of_openwrt
UCI (Unified Configuration Interface) – Technical Reference
- Project's git: UCI (Unified Configuration Interface) library and utility
- UCI is available in OpenWrt since R10367 (trunk)
- Use
git
on your local GNU/Linux installation to retrieve the source code:git clone https://git.openwrt.org/project/uci.git
- This is the Technical Reference. Please see UCI (Unified Configuration Interface) – Usage
What is UCI?
UCI
is a small utility written in C (a shell script-wrapper is available as well) and is intended tocentralize the whole configuration of a device running OpenWrt. UCI is the successor of the NVRAM based configuration found in the historical OpenWrt branch White Russian and a wrapper for the standard configuration files programs bring with them, like e.g. /etc/network/interfaces
, /etc/exports
,/etc/dnsmasq.conf
, /etc/samba/samba.conf
etc.
/etc/config/
Their documentation can be accessed online in the OpenWrt-Wiki under UCI configuration files.
They can be altered with any text editor or with the command line utility program uci
or through various programming APIs (like Shell, Lua and C). The WUI LuCI e.g. uses Lua to manipulate them.
Dependencies of UCI
libuci
a small library for UCI written in Clibuci-lua
is a libuci-plugin for Lua which is utilized by e.g. LuCI
Both are maintained in the same git as UCI.
Packages
The functionality is provided by the two packages uci
and libuci
. The package libuci-lua
is also available.
Installed Files
uci
/sbin/uci
libuci
libuci-lua
Lua Bindings for UCI
For those who like lua, UCI can be accessed in your code via the package libuci-lua. Just install the package then, in your lua code do
require("uci")
API
The api is quite simple
top level entry point
uci.cursor() instantiates a uci context instance, e.g:
x = uci.cursor()
if you want to involve state vars:
x = uci.cursor(nil, "/var/state")
if you need to work on UCI config files that are located in a non standard directory:
x = uci.cursor("/etc/mypackage/config", "/tmp/mypackage/.uci")
on that you can call the usual operations
Get value (returns string
or nil
if not found):
x:get("config", "sectionname", "option") -- real world example:x:get("network", "lan", "proto")
Set simple string value:
x:set("config", "sectionname", "option", "value") -- real world example:x:set("network", "lan", "proto", "dhcp")
Set list value:
x:set("config", "sectionname", "option", { "foo", "bar" }) -- real world example:x:set("system", "ntp", "server", { "0.openwrt.pool.ntp.org", "1.openwrt.pool.ntp.org", "2.openwrt.pool.ntp.org", "3.openwrt.pool.ntp.org"})
Delete option:
x:delete("config", "section", "option") -- real world example:x:delete("network", "lan", "force_link")
Delete section:
x:delete("config", "section") -- real world example:x:delete("network", "wan6")
Add new anonymous section "type" and return its name:
x:add("config", "type")
> -- real world example from interpreter:> name = x:add("network", "switch")> print(name)cfg0e3777
Add new section "name" with type "type":
x:set("config", "name", "type") -- real world example:x:set("network", "wan6", "interface")
Iterate over all section of type "type" and invoke a callback function:
x:foreach("config", "type", function(s) ... end)
In the preceding example, s is a table containing all options and two special properties:
s['.type']
→ section types['.name']
→ section name
If the callback function returns false
[NB: not nil
!], foreach()
will terminate at that point without iterating over any remaining sections.foreach()
returns true
if at least one section exists and the callback function didn't raise an error for it; false
otherwise.
Here's another example:
> -- real world example from interpreter:> x:foreach("system", "led", function(s)>> print('------------------')>> for key, value in pairs(s) do>> print(key .. ': ' .. tostring(value))>> end>> end)------------------dev: 1-1.1.anonymous: falsetrigger: usbdev.index: 2name: USB1interval: 50.name: led_usb1.type: ledsysfs: tp-link:green:usb1------------------dev: 1-1.2.anonymous: falsetrigger: usbdev.index: 3name: USB2interval: 50.name: led_usb2.type: ledsysfs: tp-link:green:usb2------------------.name: led_wlan2g.type: ledname: WLAN2Gtrigger: phy0tptsysfs: tp-link:blue:wlan2g.anonymous: false.index: 4
Move a section to another position. Position starts at 0. This is for example handy to change the wireless config order (changing priority).
x:reorder("config", "sectionname", position)
Discard any changes made to the configuration, that have not yet been committed:
x:revert("config")
commits (saves) the changed configuration to the corresponding file in /etc/config
x:commit("config")
That's basically all you need.
About uci structure
It took me some time to understand the difference between "section" and "type". Let's start with an example:
#uci show systemsystem.@system[0]=systemsystem.@system[0].hostname=OpenWrtsystem.@system[0].timezone=UTCsystem.@rdate[0]=rdatesystem.@rdate[0].server=ac-ntp0.net.cmu.edu ptbtime1.ptb.de ac-ntp1.net.cmu.edu ntp.xs4all.nl ptbtime2.ptb.de cudns.cit.cornell.edu ptbtime3.ptb.de
Here, x:get("system","@rdate[0]","server")
won't work. rdate is a type, not a section.
Here is the return of x:get_all("system")
:
{ cfg02f02f = { [".name"] = "cfg02f02f", [".type"] = "system", hostname = "OpenWrt", [".index"] = 0, [".anonymous"] = true, timezone = "UTC" }, cfg04e10c = { [".name"] = "cfg04e10c", [".type"] = "rdate", [".index"] = 1, [".anonymous"] = true, server = { "ac-ntp0.net.cmu.edu", "ptbtime1.ptb.de", "ac-tp1.net.cmu.edu", "ntp.xs4all.nl", "ptbtime2.ptb.de", "cudns.cit.cornell.edu", "ptbtime3.ptb.de" } }}
[".type"]
gives the type of the section;
[".name"]
gives the real name of the section (note that these names are auto-generated);
[".index"]
is the index of the list (starting from 1);
From what I know, there seem to be no way to access "@rdate[0]"
directly. You have to iterate with x:foreach
to list all the elements of a given type.
I use the following function:
uci=require("uci")function getConfType(conf,type) local curs=uci.cursor() local ifce={} curs:foreach(conf,type,function(s) ifce[s[".index"]]=s end) return ifceend
getConfType("system","rdate")
returns:
{ { [".name"] = "cfg04e10c", [".type"] = "rdate", [".index"] = 1, [".anonymous"] = true, server = { "ac-ntp0.net.cmu.edu", "ptbtime1.ptb.de", "ac-ntp1.net.cmu.edu", "ntp.xs4all.nl", "ptbtime2.ptb.de", "cudns.cit.cornell.edu", "ptbtime3.ptb.de" } }}
So if you want to modify system.@rdate[0].server
you need to iterate the type, retrieve the section name [".name"]
and then call:
x:set("system","cfg04e10c","server","zzz.com")
Hope this helps.
Sophana
(Luci has however a Cursor:get_first function that is similiar to get except it takes a type instead as section as second argument.)
Additional Information
See also LuCI UCI model functions. Thats what LuCI uses. It extends the uci cursor class with a few more convenience functions.
Usage outside of OpenWrt
If you want to use the libuci apart from OpenWrt (for e.g. you are developing an application in C on your host computer) then prepare as follows:
Grab the source.
git clone https://git.openwrt.org/project/uci.git
Go to the source directory (where the CMakeLists.txt lives) and optionally configure the build without Lua bindings:
cd uci/; cmake [-D BUILD_LUA:BOOL=OFF] .
Build and install uci as root (this will install uci into /usr/local/, see this thread on how to install and use uci without root permissions in your home directory: https://forum.openwrt.org/viewtopic.php?id=40547):
make install
Open /etc/ld.so.conf and add the place where you installed the uci library:
vi /etc/ld.so.conf
Add this line somewhere to /etc/ld.so.conf
/usr/local/lib
Execute ldconfig as root to apply the changes to /etc/ld.so.conf
ldconfig
To compile your application you have to link it against the uci library. Append -luci in your Makefile:
$(CC) test.o -o test -luci
And examples on how to use UCI in C can be found in this thread: https://forum.openwrt.org/viewtopic.php?pid=183335#p183335 To get more examples look into the source directory of uci which you got by git clone and open cli.c or ucimap-example.c
Functioning
All uci set
, uci add
, uci rename
and uci delete
commands are staged in /tmp
and written to flash at once with uci commit
. This obviously does not apply to people using text editors, but to scripts, guis and other programs working with uci files.
- openwrt UCI API lua wiki
- OpenWRT UCI API的使用
- OpenWRT UCI API的使用
- OpenWRT UCI API的使用
- Openwrt UCI API的使用
- 为什么openwrt要使用Luci (lua + uci)
- [openwrt] uci 的shell和lua接口
- [转载]OpenWRT UCI API的使用
- Openwrt下C调用UCI API
- [UCI] OpenWrt-uci命令系统
- [UCI] OpenWrt-uci命令系统
- OpenWRT UCI API的使用——C语言
- C代码调用uci的API读openwrt配置文件指南
- openwrt uci api续: 找出匿名节点的"名字"
- openwrt uci api: 配置文件匿名节点的操作(2)
- Openwrt开发日志——UCI API编…
- 我的openwrt学习笔记(三十五):Openwrt 之luci-lua调用uci的测试
- openwrt uci常用命令
- Gson解析Json数据的通用方法
- hiho 55 连通性·四
- 83_自定义FastJsonRequest
- WWW加载文件
- 欢迎使用CSDN-markdown编辑器
- openwrt UCI API lua wiki
- 解决VS2013找不到windows.h文件方法
- 1,网络开发必备的HTTP协议知识
- Quartz2D的基本使用(一)
- 84_飞入飞出效果的集成
- JDBC技术总结(一)
- Prim算法的实现及应用( 最小生成树)
- 找到第一个只出现一次的字符
- hdoj-2037-今年暑假不AC