luci-base: implement session handling in luci.model.uci
Introduce luci.model.uci.set_session_id() and luci.model.uci.get_session_id() to set and get the effective session ID respectively. When a session ID is set, it is sent as `ubus_rpc_session` attribute to rpcd, causing it to use per-session change directories, isolating LuCI changes from the global system uci state. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
fc8f825e2f
commit
9b22c9c1e1
2 changed files with 193 additions and 156 deletions
|
@ -32,6 +32,15 @@ local ERRSTR = {
|
||||||
"Connection failed"
|
"Connection failed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local session_id = nil
|
||||||
|
|
||||||
|
local function call(cmd, args)
|
||||||
|
if type(args) == "table" and session_id then
|
||||||
|
args.ubus_rpc_session = session_id
|
||||||
|
end
|
||||||
|
return util.ubus("uci", cmd, args)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function cursor()
|
function cursor()
|
||||||
return _M
|
return _M
|
||||||
|
@ -54,6 +63,10 @@ function get_savedir(self)
|
||||||
return "/tmp/.uci"
|
return "/tmp/.uci"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function get_session_id(self)
|
||||||
|
return session_id
|
||||||
|
end
|
||||||
|
|
||||||
function set_confdir(self, directory)
|
function set_confdir(self, directory)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
@ -62,6 +75,11 @@ function set_savedir(self, directory)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function set_session_id(self, id)
|
||||||
|
session_id = id
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function load(self, config)
|
function load(self, config)
|
||||||
return true
|
return true
|
||||||
|
@ -77,7 +95,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
function changes(self, config)
|
function changes(self, config)
|
||||||
local rv = util.ubus("uci", "changes", { config = config })
|
local rv = call("changes", { config = config })
|
||||||
local res = {}
|
local res = {}
|
||||||
|
|
||||||
if type(rv) == "table" and type(rv.changes) == "table" then
|
if type(rv) == "table" and type(rv.changes) == "table" then
|
||||||
|
@ -116,12 +134,12 @@ end
|
||||||
|
|
||||||
|
|
||||||
function revert(self, config)
|
function revert(self, config)
|
||||||
local _, err = util.ubus("uci", "revert", { config = config })
|
local _, err = call("revert", { config = config })
|
||||||
return (err == nil), ERRSTR[err]
|
return (err == nil), ERRSTR[err]
|
||||||
end
|
end
|
||||||
|
|
||||||
function commit(self, config)
|
function commit(self, config)
|
||||||
local _, err = util.ubus("uci", "commit", { config = config })
|
local _, err = call("commit", { config = config })
|
||||||
return (err == nil), ERRSTR[err]
|
return (err == nil), ERRSTR[err]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -133,7 +151,7 @@ function apply(self, configs, command)
|
||||||
|
|
||||||
if type(configs) == "table" then
|
if type(configs) == "table" then
|
||||||
for _, config in ipairs(configs) do
|
for _, config in ipairs(configs) do
|
||||||
util.ubus("service", "event", {
|
call("service", "event", {
|
||||||
type = "config.change",
|
type = "config.change",
|
||||||
data = { package = config }
|
data = { package = config }
|
||||||
})
|
})
|
||||||
|
@ -145,7 +163,7 @@ end
|
||||||
|
|
||||||
function foreach(self, config, stype, callback)
|
function foreach(self, config, stype, callback)
|
||||||
if type(callback) == "function" then
|
if type(callback) == "function" then
|
||||||
local rv, err = util.ubus("uci", "get", {
|
local rv, err = call("get", {
|
||||||
config = config,
|
config = config,
|
||||||
type = stype
|
type = stype
|
||||||
})
|
})
|
||||||
|
@ -186,7 +204,7 @@ local function _get(self, operation, config, section, option)
|
||||||
if section == nil then
|
if section == nil then
|
||||||
return nil
|
return nil
|
||||||
elseif type(option) == "string" and option:byte(1) ~= 46 then
|
elseif type(option) == "string" and option:byte(1) ~= 46 then
|
||||||
local rv, err = util.ubus("uci", operation, {
|
local rv, err = call(operation, {
|
||||||
config = config,
|
config = config,
|
||||||
section = section,
|
section = section,
|
||||||
option = option
|
option = option
|
||||||
|
@ -220,7 +238,7 @@ function get_state(self, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_all(self, config, section)
|
function get_all(self, config, section)
|
||||||
local rv, err = util.ubus("uci", "get", {
|
local rv, err = call("get", {
|
||||||
config = config,
|
config = config,
|
||||||
section = section
|
section = section
|
||||||
})
|
})
|
||||||
|
@ -271,7 +289,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
function section(self, config, stype, name, values)
|
function section(self, config, stype, name, values)
|
||||||
local rv, err = util.ubus("uci", "add", {
|
local rv, err = call("add", {
|
||||||
config = config,
|
config = config,
|
||||||
type = stype,
|
type = stype,
|
||||||
name = name,
|
name = name,
|
||||||
|
@ -297,7 +315,7 @@ function set(self, config, section, option, value)
|
||||||
local sname, err = self:section(config, option, section)
|
local sname, err = self:section(config, option, section)
|
||||||
return (not not sname), err
|
return (not not sname), err
|
||||||
else
|
else
|
||||||
local _, err = util.ubus("uci", "set", {
|
local _, err = call("set", {
|
||||||
config = config,
|
config = config,
|
||||||
section = section,
|
section = section,
|
||||||
values = { [option] = value }
|
values = { [option] = value }
|
||||||
|
@ -319,7 +337,7 @@ function set_list(self, config, section, option, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
function tset(self, config, section, values)
|
function tset(self, config, section, values)
|
||||||
local _, err = util.ubus("uci", "set", {
|
local _, err = call("set", {
|
||||||
config = config,
|
config = config,
|
||||||
section = section,
|
section = section,
|
||||||
values = values
|
values = values
|
||||||
|
@ -353,7 +371,7 @@ function reorder(self, config, section, index)
|
||||||
return false, "Invalid argument"
|
return false, "Invalid argument"
|
||||||
end
|
end
|
||||||
|
|
||||||
local _, err = util.ubus("uci", "order", {
|
local _, err = call("order", {
|
||||||
config = config,
|
config = config,
|
||||||
sections = sections
|
sections = sections
|
||||||
})
|
})
|
||||||
|
@ -363,7 +381,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
function delete(self, config, section, option)
|
function delete(self, config, section, option)
|
||||||
local _, err = util.ubus("uci", "delete", {
|
local _, err = call("delete", {
|
||||||
config = config,
|
config = config,
|
||||||
section = section,
|
section = section,
|
||||||
option = option
|
option = option
|
||||||
|
@ -374,13 +392,13 @@ end
|
||||||
function delete_all(self, config, stype, comparator)
|
function delete_all(self, config, stype, comparator)
|
||||||
local _, err
|
local _, err
|
||||||
if type(comparator) == "table" then
|
if type(comparator) == "table" then
|
||||||
_, err = util.ubus("uci", "delete", {
|
_, err = call("delete", {
|
||||||
config = config,
|
config = config,
|
||||||
type = stype,
|
type = stype,
|
||||||
match = comparator
|
match = comparator
|
||||||
})
|
})
|
||||||
elseif type(comparator) == "function" then
|
elseif type(comparator) == "function" then
|
||||||
local rv = util.ubus("uci", "get", {
|
local rv = call("get", {
|
||||||
config = config,
|
config = config,
|
||||||
type = stype
|
type = stype
|
||||||
})
|
})
|
||||||
|
@ -389,7 +407,7 @@ function delete_all(self, config, stype, comparator)
|
||||||
local sname, section
|
local sname, section
|
||||||
for sname, section in pairs(rv.values) do
|
for sname, section in pairs(rv.values) do
|
||||||
if comparator(section) then
|
if comparator(section) then
|
||||||
_, err = util.ubus("uci", "delete", {
|
_, err = call("delete", {
|
||||||
config = config,
|
config = config,
|
||||||
section = sname
|
section = sname
|
||||||
})
|
})
|
||||||
|
@ -397,7 +415,7 @@ function delete_all(self, config, stype, comparator)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif comparator == nil then
|
elseif comparator == nil then
|
||||||
_, err = util.ubus("uci", "delete", {
|
_, err = call("delete", {
|
||||||
config = config,
|
config = config,
|
||||||
type = stype
|
type = stype
|
||||||
})
|
})
|
||||||
|
|
|
@ -14,224 +14,226 @@ module "luci.model.uci"
|
||||||
---[[
|
---[[
|
||||||
Create a new UCI-Cursor.
|
Create a new UCI-Cursor.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name cursor
|
@name cursor
|
||||||
@return UCI-Cursor
|
@return UCI-Cursor
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Create a new Cursor initialized to the state directory.
|
Create a new Cursor initialized to the state directory.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name cursor_state
|
@name cursor_state
|
||||||
@return UCI cursor
|
@return UCI cursor
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Applies UCI configuration changes
|
Applies UCI configuration changes
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.apply
|
@name Cursor.apply
|
||||||
@param configlist List of UCI configurations
|
@param configlist List of UCI configurations
|
||||||
@param command Don't apply only return the command
|
@param command Don't apply only return the command
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Delete all sections of a given type that match certain criteria.
|
Delete all sections of a given type that match certain criteria.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.delete_all
|
@name Cursor.delete_all
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param type UCI section type
|
@param type UCI section type
|
||||||
@param comparator Function that will be called for each section and
|
@param comparator Function that will be called for each section and returns
|
||||||
returns a boolean whether to delete the current section (optional)
|
a boolean whether to delete the current section (optional)
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Create a new section and initialize it with data.
|
Create a new section and initialize it with data.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.section
|
@name Cursor.section
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param type UCI section type
|
@param type UCI section type
|
||||||
@param name UCI section name (optional)
|
@param name UCI section name (optional)
|
||||||
@param values Table of key - value pairs to initialize the section with
|
@param values Table of key - value pairs to initialize the section with
|
||||||
@return Name of created section
|
@return Name of created section
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Updated the data of a section using data from a table.
|
Updated the data of a section using data from a table.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.tset
|
@name Cursor.tset
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param section UCI section name (optional)
|
@param section UCI section name (optional)
|
||||||
@param values Table of key - value pairs to update the section with
|
@param values Table of key - value pairs to update the section with
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Get a boolean option and return it's value as true or false.
|
Get a boolean option and return it's value as true or false.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.get_bool
|
@name Cursor.get_bool
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param section UCI section name
|
@param section UCI section name
|
||||||
@param option UCI option
|
@param option UCI option
|
||||||
@return Boolean
|
@return Boolean
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Get an option or list and return values as table.
|
Get an option or list and return values as table.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.get_list
|
@name Cursor.get_list
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param section UCI section name
|
@param section UCI section name
|
||||||
@param option UCI option
|
@param option UCI option
|
||||||
@return table. If the option was not found, you will simply get
|
@return table. If the option was not found, you will simply get an empty
|
||||||
-- an empty table.
|
table.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Get the given option from the first section with the given type.
|
Get the given option from the first section with the given type.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.get_first
|
@name Cursor.get_first
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param type UCI section type
|
@param type UCI section type
|
||||||
@param option UCI option (optional)
|
@param option UCI option (optional)
|
||||||
@param default Default value (optional)
|
@param default Default value (optional)
|
||||||
@return UCI value
|
@return UCI value
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Set given values as list. Setting a list option to an empty list
|
Set given values as list. Setting a list option to an empty list
|
||||||
has the same effect as deleting the option.
|
has the same effect as deleting the option.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.set_list
|
@name Cursor.set_list
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param section UCI section name
|
@param section UCI section name
|
||||||
@param option UCI option
|
@param option UCI option
|
||||||
@param value value or table. Raw values will become a single item table.
|
@param value Value or table. Non-table values will be set as single
|
||||||
@return Boolean whether operation succeeded
|
item UCI list.
|
||||||
|
@return Boolean whether operation succeeded
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Create a sub-state of this cursor. The sub-state is tied to the parent
|
Create a sub-state of this cursor.
|
||||||
|
|
||||||
curser, means it the parent unloads or loads configs, the sub state will
|
The sub-state is tied to the parent curser, means it the parent unloads or
|
||||||
do so as well.
|
loads configs, the sub state will do so as well.
|
||||||
@class function
|
|
||||||
@name Cursor.substate
|
@class function
|
||||||
@return UCI state cursor tied to the parent cursor
|
@name Cursor.substate
|
||||||
|
@return UCI state cursor tied to the parent cursor
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Add an anonymous section.
|
Add an anonymous section.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.add
|
@name Cursor.add
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param type UCI section type
|
@param type UCI section type
|
||||||
@return Name of created section
|
@return Name of created section
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Get a table of saved but uncommitted changes.
|
Get a table of saved but uncommitted changes.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.changes
|
@name Cursor.changes
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@return Table of changes
|
@return Table of changes
|
||||||
@see Cursor.save
|
@see Cursor.save
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Commit saved changes.
|
Commit saved changes.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.commit
|
@name Cursor.commit
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
@see Cursor.revert
|
@see Cursor.revert
|
||||||
@see Cursor.save
|
@see Cursor.save
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Deletes a section or an option.
|
Deletes a section or an option.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.delete
|
@name Cursor.delete
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param section UCI section name
|
@param section UCI section name
|
||||||
@param option UCI option (optional)
|
@param option UCI option (optional)
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Call a function for every section of a certain type.
|
Call a function for every section of a certain type.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.foreach
|
@name Cursor.foreach
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param type UCI section type
|
@param type UCI section type
|
||||||
@param callback Function to be called
|
@param callback Function to be called
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Get a section type or an option
|
Get a section type or an option
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.get
|
@name Cursor.get
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param section UCI section name
|
@param section UCI section name
|
||||||
@param option UCI option (optional)
|
@param option UCI option (optional)
|
||||||
@return UCI value
|
@return UCI value
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Get all sections of a config or all values of a section.
|
Get all sections of a config or all values of a section.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.get_all
|
@name Cursor.get_all
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param section UCI section name (optional)
|
@param section UCI section name (optional)
|
||||||
@return Table of UCI sections or table of UCI values
|
@return Table of UCI sections or table of UCI values
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Manually load a config.
|
Manually load a config.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.load
|
@name Cursor.load
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
@see Cursor.save
|
@see Cursor.save
|
||||||
@see Cursor.unload
|
@see Cursor.unload
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Revert saved but uncommitted changes.
|
Revert saved but uncommitted changes.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.revert
|
@name Cursor.revert
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
@see Cursor.commit
|
@see Cursor.commit
|
||||||
@see Cursor.save
|
@see Cursor.save
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Saves changes made to a config to make them committable.
|
Saves changes made to a config to make them committable.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.save
|
@name Cursor.save
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
@see Cursor.load
|
@see Cursor.load
|
||||||
@see Cursor.unload
|
@see Cursor.unload
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
|
@ -243,57 +245,74 @@ then a named section of the given type is created.
|
||||||
When invoked with four arguments `config`, `sectionname`, `optionname` and
|
When invoked with four arguments `config`, `sectionname`, `optionname` and
|
||||||
`optionvalue` then the value of the specified option is set to the given value.
|
`optionvalue` then the value of the specified option is set to the given value.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.set
|
@name Cursor.set
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@param section UCI section name
|
@param section UCI section name
|
||||||
@param option UCI option or UCI section type
|
@param option UCI option or UCI section type
|
||||||
@param value UCI value or nothing if you want to create a section
|
@param value UCI value or nothing if you want to create a section
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Get the configuration directory.
|
Get the configuration directory.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.get_confdir
|
@name Cursor.get_confdir
|
||||||
@return Configuration directory
|
@return Configuration directory
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Get the directory for uncomitted changes.
|
Get the directory for uncomitted changes.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.get_savedir
|
@name Cursor.get_savedir
|
||||||
@return Save directory
|
@return Save directory
|
||||||
|
]]
|
||||||
|
|
||||||
|
---[[
|
||||||
|
Get the effective session ID.
|
||||||
|
|
||||||
|
@class function
|
||||||
|
@name Cursor.get_session_id
|
||||||
|
@return String containing the session ID
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Set the configuration directory.
|
Set the configuration directory.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.set_confdir
|
@name Cursor.set_confdir
|
||||||
@param directory UCI configuration directory
|
@param directory UCI configuration directory
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Set the directory for uncommited changes.
|
Set the directory for uncommited changes.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.set_savedir
|
@name Cursor.set_savedir
|
||||||
@param directory UCI changes directory
|
@param directory UCI changes directory
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
|
]]
|
||||||
|
|
||||||
|
---[[
|
||||||
|
Set the effective session ID.
|
||||||
|
|
||||||
|
@class function
|
||||||
|
@name Cursor.set_session_id
|
||||||
|
@param id String containing the session ID to set
|
||||||
|
@return Boolean whether operation succeeded
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---[[
|
---[[
|
||||||
Discard changes made to a config.
|
Discard changes made to a config.
|
||||||
|
|
||||||
@class function
|
@class function
|
||||||
@name Cursor.unload
|
@name Cursor.unload
|
||||||
@param config UCI config
|
@param config UCI config
|
||||||
@return Boolean whether operation succeeded
|
@return Boolean whether operation succeeded
|
||||||
@see Cursor.load
|
@see Cursor.load
|
||||||
@see Cursor.save
|
@see Cursor.save
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue