User Tools

Site Tools


doc:techref:uci

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
doc:techref:uci [2013/01/26 14:12]
whuang formatting
doc:techref:uci [2016/02/04 15:19] (current)
karlp replace nbd.name refs with git.openwrt.org
Line 1: Line 1:
 +====== UCI (Unified Configuration Interface) – Technical Reference ======
  
 +  * [[http://​git.openwrt.org/?​p=project/​uci.git;​a=summary|Project'​s git: UCI (Unified Configuration Interface) library and utility]]
 +  * UCI is available in OpenWrt since [[https://​dev.openwrt.org/​changeset/​10367|R10367 (trunk)]]
 +  * Use ''​git''​ on your local GNU/Linux installation to retrieve the source code:<​code bash>
 +git clone https://​git.openwrt.org/​project/​uci.git
 +</​code>​
 +  * This is the Technical Reference. Please see **[[doc/​uci|UCI (Unified Configuration Interface) – Usage]]**
 +
 +==== What is UCI? ====
 +''​UCI''​ is a small utility written in [[wp>C (programming language)|C]] (a [[wp>​shell script]]-wrapper is available as well) and is intended to //​centralize//​ the whole configuration of a device running OpenWrt. UCI is the successor of the NVRAM based configuration found in the historical OpenWrt branch [[about:​history|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.
 +
 +| {{:​meta:​icons:​tango:​dialog-information.png?​nolink}} | UCI configuration files are located ​ in the directory **''/​etc/​config/''​**\\ Their documentation can be accessed online in the OpenWrt-Wiki under [[doc:​uci|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 [[doc:​techref:​LuCI]] e.g. uses Lua to manipulate them.
 +
 +==== Dependencies of UCI ====
 +  * ''​libuci''​ a small library for UCI written in [[wp>C (programming language)|C]]
 +    * ''​libuci-lua''​ is a libuci-plugin for [[wp>Lua (programming language)|Lua]] which is utilized by e.g. [[doc:​techref:​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.
 +^ Name    ^ Size in Bytes ^ Description ^
 +| uci        |   7196 | Utility for the Unified Configuration Interface (UCI)    |
 +| libuci ​    ​| ​ 18765 | C library for the Unified Configuration Interface (UCI)  |
 +| libuci-lua |  ~6000 | libuci-plugin for [[wp>Lua (programming language)|Lua]],​ e.g. [[doc:​techref:​LuCI]] makes use of it  |
 +
 +==== Installed Files ====
 +=== uci ===
 +^ path/​file ​                ^ file type ^ Description ​ ^
 +| /​sbin/​uci ​                ​| ​ binary ​       | uci executable ​ |
 +| /​lib/​config/​uci.sh ​       |  shell script ​ | Shell script compatibility wrappers for ''/​sbin/​uci'' ​ |
 +
 +=== libuci ===
 +^ path/​file ​                 ^ file type ^ Description ​ ^
 +| /​lib/​libuci.so ​            ​| ​ symlink ​ | symlink to libuci.so.xxx ​ |
 +| /​lib/​libuci.so.2011-01-19 ​ |  binary ​  | Library ​ |
 +
 +=== libuci-lua ===
 +^ path/​file ​                 ^ file type ^ Description ​ ^
 +| /​usr/​lib/​lua/​uci.so ​       |  binary ​ | Library ​ |
 +
 +
 +----
 +
 +===== 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 <code lua>​require("​uci"​)</​code>​
 +
 +===== API =====
 +The api is quite simple
 +
 +==== top level entry point ===
 +uci.cursor() ​ (that instantiates a uci context instance)
 +e.g. <code lua>x = uci.cursor()</​code>​ or <code lua>x = uci.cursor(nil,​ "/​var/​state"​)</​code>​
 +if you want to involve state vars
 +==== on that you can call the usual operations ====
 +<code lua>​x:​get("​config",​ "​sectionname",​ "​option"​)</​code>​
 +returns string or nil for not found
 +<code lua>​x:​set("​config",​ "​sectionname",​ "​option",​ "​value"​)</​code>​
 +sets simple string value
 +<code lua>​x:​set("​config",​ "​sectionname",​ "​option",​ { "​foo",​ "​bar"​ })</​code>​
 +sets list value
 +<code lua>​x:​delete("​config",​ "​section",​ "​option"​)</​code>​
 +deletes option
 +<code lua>​x:​delete("​config",​ "​section"​)</​code>​
 +deletes section
 +<code lua>​x:​add("​config",​ "​type"​)</​code>​
 +adds new anon section "​type"​ and returns its name
 +<code lua>​x:​set("​config",​ "​name",​ "​type"​)</​code>​
 +adds new section "​name"​ with type "​type"​
 +<code lua>​x:​foreach("​config",​ "​type",​ function(s) ... end)</​code>​
 +iterates over all sections of type "​type"​ and invokes callback function for each "​s"​ within the callback.  ​
 +s is a table containing all options and two special properties  ​
 +   * s['​.type'​] -> section type
 +   * s['​.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.
 +<code lua>​x:​reorder("​config",​ "​sectionname",​ position)</​code>​
 +Move a section to another position. Position starts at 0. 
 +This is for example handy to change the wireless config order (changing priority). ​
 +<code lua>​x:​revert("​config"​)</​code>​
 +discards any changes made to the configuration,​ that have not yet been committed
 +<code lua>​x:​commit("​config"​)</​code>​
 +commits (saves) the changed configuration to the corresponding file in /etc/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:
 +
 +<​code>#​uci show system
 +system.@system[0]=system
 +system.@system[0].hostname=OpenWrt
 +system.@system[0].timezone=UTC
 +system.@rdate[0]=rdate
 +system.@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
 +</​code>​
 +
 +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"​):​
 +
 +<code lua>{
 + ​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"​}}
 +}
 +</​code>​
 +
 +["​.type"​] gives the type of the section
 +
 +["​.name"​] gives the real name of the section. You can see here, that these names are generated.
 +
 +["​.index"​] is the index of the list (+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:
 +
 +<​code>​
 +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 ifce
 +end
 +</​code>​
 +
 +getConfType("​system","​rdate"​) returns:
 +<​code>​{{["​.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"​}}}</​code>​
 +
 +So if you want to modify system.@rdate[0].server you need to iterate the type then retreive the section name (["​.name"​]) then call x:​set("​system","​cfg04e10c","​server","​zzz.com"​)
 +
 +Hope this helps
 +
 +Sophana
 +
 +(Luci has however a [[http://​luci.subsignal.org/​api/​luci/​modules/​luci.model.uci.html#​Cursor.get_first|Cursor:​get_first]] function that is similiar to get except it takes a type instead as section as second argument.)
 +
 +===== Additional Information =====
 +
 +See also [[http://​luci.subsignal.org/​api/​luci/​modules/​luci.model.uci.html|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.
 +<​code>​git clone https://​git.openwrt.org/​project/​uci.git
 +</​code>​
 +
 +Go to the source directory (where the CMakeLists.txt lives) and optionally configure the build without Lua bindings:
 +<​code>​cd uci/; cmake [-D BUILD_LUA:​BOOL=OFF] .</​code>​
 +
 +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):​
 +<​code>​make install</​code>​
 +
 +Open /​etc/​ld.so.conf and add the place where you installed the uci library:
 +<​code>​vi /​etc/​ld.so.conf</​code>​
 +
 +Add this line somewhere to /​etc/​ld.so.conf
 +<​code>/​usr/​local/​lib</​code>​
 +
 +Execute ldconfig as root to apply the changes to /​etc/​ld.so.conf
 +<​code>​ldconfig</​code>​
 +
 +To compile your application you have to link it against the uci library. Append -luci in your Makefile:
 +<​code>​$(CC) test.o -o test -luci</​code>​
 +
 +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.
 +
 +{{tag>​wip}}