libs/uci: Pipe output of reload commands to /dev/null
[project/luci.git] / libs / uci / luasrc / model / uci.lua
1 --[[
2 LuCI - UCI model
3
4 Description:
5 Generalized UCI model
6
7 FileId:
8 $Id$
9
10 License:
11 Copyright 2008 Steven Barth <steven@midlink.org>
12
13 Licensed under the Apache License, Version 2.0 (the "License");
14 you may not use this file except in compliance with the License.
15 You may obtain a copy of the License at
16
17         http://www.apache.org/licenses/LICENSE-2.0
18
19 Unless required by applicable law or agreed to in writing, software
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24
25 ]]--
26 local os    = require "os"
27 local uci   = require "uci"
28 local util  = require "luci.util"
29 local table = require "table"
30
31
32 local setmetatable, rawget, rawset = setmetatable, rawget, rawset
33 local error, pairs, ipairs, tostring = error, pairs, ipairs, tostring
34 local require, getmetatable = require, getmetatable
35
36 --- LuCI UCI model library.
37 -- @cstyle      instance
38 module("luci.model.uci")
39
40 --- Create a new UCI-Cursor.
41 -- @class function
42 -- @name cursor
43 -- @return      UCI-Cursor
44 cursor = uci.cursor
45
46 APIVERSION = uci.APIVERSION
47
48 --- Create a new Cursor initialized to the state directory.
49 -- @return UCI cursor
50 function cursor_state()
51         return cursor(nil, "/var/state")
52 end
53
54
55 local Cursor = getmetatable(cursor())
56
57 --- Applies the new config
58 -- @param config                UCI config
59 function Cursor.apply(self, config)
60         local conf = require "luci.config"
61         return conf.uci_oncommit[config] and
62          os.execute(conf.uci_oncommit[config] .. " >/dev/null 2>&1")
63 end
64
65 --- Delete all sections of a given type that match certain criteria.
66 -- @param config                UCI config
67 -- @param type                  UCI section type
68 -- @param comparator    Function that will be called for each section and
69 -- returns a boolean whether to delete the current section (optional)
70 function Cursor.delete_all(self, config, type, comparator)
71         local del = {}
72         local function helper (section)
73                 if not comparator or comparator(section) then
74                         table.insert(del, section[".name"])
75                 end
76         end
77
78         self:foreach(config, type, helper)
79
80         for i, j in ipairs(del) do
81                 self:delete(config, j)
82         end
83 end
84
85 --- Create a new section and initialize it with data.
86 -- @param config        UCI config
87 -- @param type          UCI section type
88 -- @param name          UCI section name (optional)
89 -- @param values        Table of key - value pairs to initialize the section with
90 -- @return                      Name of created section
91 function Cursor.section(self, config, type, name, values)
92         local stat = true
93         if name then
94                 stat = self:set(config, name, type)
95         else
96                 name = self:add(config, type)
97                 stat = name and true
98         end
99
100         if stat and values then
101                 stat = self:tset(config, name, values)
102         end
103
104         return stat and name
105 end
106
107 --- Updated the data of a section using data from a table.
108 -- @param config        UCI config
109 -- @param section       UCI section name (optional)
110 -- @param values        Table of key - value pairs to update the section with
111 function Cursor.tset(self, config, section, values)
112         local stat = true
113         for k, v in pairs(values) do
114                 if k:sub(1, 1) ~= "." then
115                         stat = stat and self:set(config, section, k, v)
116                 end
117         end
118         return stat
119 end
120
121 --- Get an option or list and return values as table.
122 -- @param config        UCI config
123 -- @param section       UCI section name
124 -- @param option        UCI option
125 -- @return                      UCI value
126 function Cursor.get_list(self, config, section, option)
127         if config and section and option then
128                 local val = self:get(config, section, option)
129                 return ( type(val) == "table" and val or { val } )
130         end
131         return nil
132 end
133
134 --- Set given values as list.
135 -- @param config        UCI config
136 -- @param section       UCI section name
137 -- @param option        UCI option
138 -- @param value         UCI value
139 -- @return                      Boolean whether operation succeeded
140 function Cursor.set_list(self, config, section, option, value)
141         if config and section and option then
142                 return self:set(
143                         config, section, option,
144                         ( type(value) == "table" and value or { value } )
145                 )
146         end
147         return false
148 end
149
150
151 --- Add an anonymous section.
152 -- @class function
153 -- @name Cursor.add
154 -- @param config        UCI config
155 -- @param type          UCI section type
156 -- @return                      Name of created section
157
158 --- Get a table of unsaved changes.
159 -- @class function
160 -- @name Cursor.changes
161 -- @param config        UCI config
162 -- @return                      Table of changes
163
164 --- Commit unsaved changes.
165 -- @class function
166 -- @name Cursor.commit
167 -- @param config        UCI config
168 -- @return                      Boolean whether operation succeeded
169 -- @see Cursor.revert
170
171 --- Deletes a section or an option.
172 -- @class function
173 -- @name Cursor.delete
174 -- @param config        UCI config
175 -- @param section       UCI section name
176 -- @param option        UCI option (optional)
177 -- @return                      Boolean whether operation succeeded
178
179 --- Call a function for every section of a certain type.
180 -- @class function
181 -- @name Cursor.foreach
182 -- @param config        UCI config
183 -- @param type          UCI section type
184 -- @param callback      Function to be called
185 -- @return                      Boolean whether operation succeeded
186
187 --- Get a section type or an option
188 -- @class function
189 -- @name Cursor.get
190 -- @param config        UCI config
191 -- @param section       UCI section name
192 -- @param option        UCI option (optional)
193 -- @return                      UCI value
194
195 --- Get all sections of a config or all values of a section.
196 -- @class function
197 -- @name Cursor.get_all
198 -- @param config        UCI config
199 -- @param section       UCI section name (optional)
200 -- @return                      Table of UCI sections or table of UCI values
201
202 --- Manually load a config.
203 -- @class function
204 -- @name Cursor.load
205 -- @param config        UCI config
206 -- @return                      Boolean whether operation succeeded
207 -- @see Cursor.save
208 -- @see Cursor.unload
209
210 --- Revert unsaved changes.
211 -- @class function
212 -- @name Cursor.revert
213 -- @param config        UCI config
214 -- @return                      Boolean whether operation succeeded
215 -- @see Cursor.commit
216
217 --- Saves changes made to a config to make them committable.
218 -- @class function
219 -- @name Cursor.save
220 -- @param config        UCI config
221 -- @return                      Boolean whether operation succeeded
222 -- @see Cursor.load
223 -- @see Cursor.unload
224
225 --- Set a value or create a named section.
226 -- @class function
227 -- @name Cursor.set
228 -- @param config        UCI config
229 -- @param section       UCI section name
230 -- @param option        UCI option or UCI section type
231 -- @param value         UCI value or nil if you want to create a section
232 -- @return                      Boolean whether operation succeeded
233
234 --- Get the configuration directory.
235 -- @class function
236 -- @name Cursor.get_confdir
237 -- @return                      Configuration directory
238
239 --- Get the directory for uncomitted changes.
240 -- @class function
241 -- @name Cursor.get_savedir
242 -- @return                      Save directory
243
244 --- Set the configuration directory.
245 -- @class function
246 -- @name Cursor.set_confdir
247 -- @param directory     UCI configuration directory
248 -- @return                      Boolean whether operation succeeded
249
250 --- Set the directory for uncommited changes.
251 -- @class function
252 -- @name Cursor.set_savedir
253 -- @param directory     UCI changes directory
254 -- @return                      Boolean whether operation succeeded
255
256 --- Discard changes made to a config.
257 -- @class function
258 -- @name Cursor.unload
259 -- @param config        UCI config
260 -- @return                      Boolean whether operation succeeded
261 -- @see Cursor.load
262 -- @see Cursor.save