* Updated UCI libraries

* Removed old UCI libraries
* Added new High-Level UCI API
This commit is contained in:
Steven Barth 2008-06-05 19:15:31 +00:00
parent d30d590ae8
commit 75f3dbaa61
6 changed files with 125 additions and 392 deletions

View file

@ -110,6 +110,16 @@ define Package/luci-cbi/install
endef endef
define Package/luci-uci
$(call Package/luci/libtemplate)
TITLE:=High-Level UCI API
endef
define Package/luci-uci/install
$(call Package/luci/install/template,$(1),libs/uci)
endef
define Package/luci-fastindex define Package/luci-fastindex
$(call Package/luci/libtemplate) $(call Package/luci/libtemplate)
TITLE:=Fastindex indexing module TITLE:=Fastindex indexing module
@ -122,7 +132,7 @@ endef
define Package/luci-web define Package/luci-web
$(call Package/luci/libtemplate) $(call Package/luci/libtemplate)
DEPENDS+=+luci-addons DEPENDS+=+luci-addons +luci-uci
TITLE:=MVC Webframework TITLE:=MVC Webframework
endef endef
@ -363,6 +373,9 @@ endif
ifneq ($(CONFIG_PACKAGE_luci-fastindex),) ifneq ($(CONFIG_PACKAGE_luci-fastindex),)
PKG_SELECTED_MODULES+=libs/fastindex PKG_SELECTED_MODULES+=libs/fastindex
endif endif
ifneq ($(CONFIG_PACKAGE_luci-uci),)
PKG_SELECTED_MODULES+=libs/uci
endif
ifneq ($(CONFIG_PACKAGE_luci-web),) ifneq ($(CONFIG_PACKAGE_luci-web),)
PKG_SELECTED_MODULES+=libs/web PKG_SELECTED_MODULES+=libs/web
endif endif
@ -425,6 +438,7 @@ MAKE_FLAGS += MODULES="$(PKG_SELECTED_MODULES)" LUA_TARGET="$(LUA_TARGET)" CFLAG
$(eval $(call BuildPackage,luci-core)) $(eval $(call BuildPackage,luci-core))
$(eval $(call BuildPackage,luci-cbi)) $(eval $(call BuildPackage,luci-cbi))
$(eval $(call BuildPackage,luci-fastindex)) $(eval $(call BuildPackage,luci-fastindex))
$(eval $(call BuildPackage,luci-uci))
$(eval $(call BuildPackage,luci-web)) $(eval $(call BuildPackage,luci-web))
$(eval $(call BuildPackage,luci-ff-halle)) $(eval $(call BuildPackage,luci-ff-halle))

View file

@ -1,92 +0,0 @@
--[[
LuCI - UCI mpdel
Description:
Generalized UCI model
FileId:
$Id$
License:
Copyright 2008 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
module("luci.model.uci", package.seeall)
-- Default savedir
savedir = "/tmp/.uci"
-- Test whether to load libuci-Wrapper or /sbin/uci-Wrapper
if pcall(require, "uci") then
Session = require("luci.model.uci.libuci").Session
else
Session = require("luci.model.uci.wrapper").Session
end
-- The default Session
local default = Session()
local state = Session("/var/state")
-- The state Session
function StateSession()
return state
end
-- Wrapper for "uci add"
function add(...)
return default:add(...)
end
-- Wrapper for "uci changes"
function changes(...)
return default:changes(...)
end
-- Wrapper for "uci commit"
function commit(...)
return default:commit(...)
end
-- Wrapper for "uci del"
function del(...)
return default:del(...)
end
-- Wrapper for "uci get"
function get(...)
return default:get(...)
end
-- Wrapper for "uci revert"
function revert(...)
return default:revert(...)
end
-- Wrapper for "uci show"
function sections(...)
return default:sections(...)
end
-- Wrapper for "uci set"
function set(...)
return default:set(...)
end

View file

@ -1,128 +0,0 @@
--[[
LuCI - UCI libuci wrapper
Description:
Wrapper for the libuci Lua bindings
FileId:
$Id$
License:
Copyright 2008 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
module("luci.model.uci.libuci", package.seeall)
require("uci")
require("luci.util")
require("luci.sys")
-- Session class
Session = luci.util.class()
-- Session constructor
function Session.__init__(self, savedir)
self.savedir = savedir or luci.model.uci.savedir
uci.set_savedir(self.savedir)
end
function Session.add(self, config, section_type)
return uci.add(config, section_type)
end
function Session.changes(self, config)
if config then
return uci.changes(config)
else
return uci.changes()
end
end
function Session.commit(self, config)
return self:t_commit(config)
end
function Session.del(self, config, section, option)
return uci.del(config, section, option)
end
function Session.get(self, config, section, option)
return self:t_get(config, section, option)
end
function Session.revert(self, config)
return self:t_revert(config)
end
function Session.sections(self, config)
return self:t_sections(config)
end
function Session.set(self, config, section, option, value)
return self:t_set(config, section, option, value) and self:t_save(config)
end
function Session.synchronize(self)
return uci.set_savedir(self.savedir)
end
-- UCI-Transactions
function Session.t_load(self, config)
return self:synchronize() and uci.load(config)
end
function Session.t_save(self, config)
return uci.save(config)
end
function Session.t_add(self, config, type)
return self:add(config, type)
end
function Session.t_commit(self, config)
return uci.commit(config)
end
function Session.t_del(self, config, section, option)
return self:del(config, section, option)
end
function Session.t_get(self, config, section, option)
if option then
return uci.get(config, section, option)
else
return uci.get(config, section)
end
end
function Session.t_revert(self, config)
return uci.revert(config)
end
function Session.t_sections(self, config)
return uci.get_all(config)
end
function Session.t_set(self, config, section, option, value)
if option then
return uci.set(config, section, option, value)
else
return uci.set(config, section, value)
end
end

View file

@ -1,171 +0,0 @@
--[[
LuCI - UCI wrapper library
Description:
Wrapper for the /sbin/uci application, syntax of implemented functions
is comparable to the syntax of the uci application
Any return value of false or nil can be interpreted as an error
FileId:
$Id$
License:
Copyright 2008 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
module("luci.model.uci.wrapper", package.seeall)
require("luci.util")
require("luci.sys")
-- Session class
Session = luci.util.class()
-- Session constructor
function Session.__init__(self, savedir)
self.ucicmd = savedir and "uci -P " .. savedir or "uci"
end
function Session.add(self, config, section_type)
return self:_uci("add " .. _path(config) .. " " .. _path(section_type))
end
function Session.changes(self, config)
return self:_uci("changes " .. _path(config))
end
function Session.commit(self, config)
return self:_uci2("commit " .. _path(config))
end
function Session.del(self, config, section, option)
return self:_uci2("del " .. _path(config, section, option))
end
function Session.get(self, config, section, option)
return self:_uci("get " .. _path(config, section, option))
end
function Session.revert(self, config)
return self:_uci2("revert " .. _path(config))
end
function Session.sections(self, config)
if not config then
return nil
end
local r1, r2 = self:_uci3("show " .. _path(config))
if type(r1) == "table" then
return r1, r2
else
return nil, r2
end
end
function Session.set(self, config, section, option, value)
return self:_uci2("set " .. _path(config, section, option, value))
end
function Session.synchronize(self) end
-- Dummy transaction functions
function Session.t_load(self) end
function Session.t_save(self) end
Session.t_add = Session.add
Session.t_commit = Session.commit
Session.t_del = Session.del
Session.t_get = Session.get
Session.t_revert = Session.revert
Session.t_sections = Session.sections
Session.t_set = Session.set
-- Internal functions --
function Session._uci(self, cmd)
local res = luci.sys.exec(self.ucicmd .. " 2>/dev/null " .. cmd)
if res:len() == 0 then
return nil
else
return res:sub(1, res:len()-1)
end
end
function Session._uci2(self, cmd)
local res = luci.sys.exec(self.ucicmd .. " 2>&1 " .. cmd)
if res:len() > 0 then
return false, res
else
return true
end
end
function Session._uci3(self, cmd)
local res = luci.sys.execl(self.ucicmd .. " 2>&1 " .. cmd)
if res[1] and res[1]:sub(1, self.ucicmd:len()+1) == self.ucicmd..":" then
return nil, res[1]
end
local tbl = {}
local ord = {}
for k,line in pairs(res) do
c, s, t = line:match("^([^.]-)%.([^.]-)=(.-)$")
if c then
tbl[s] = {}
table.insert(ord, s)
tbl[s][".type"] = t
end
c, s, o, v = line:match("^([^.]-)%.([^.]-)%.([^.]-)=(.-)$")
if c then
tbl[s][o] = v
end
end
return tbl, ord
end
-- Build path (config.section.option=value) and prevent command injection
function _path(...)
local result = ""
-- Not using ipairs because it is not reliable in case of nil arguments
arg.n = nil
for k,v in pairs(arg) do
if v then
v = tostring(v)
if k == 1 then
result = "'" .. v:gsub("['.]", "") .. "'"
elseif k < 4 then
result = result .. ".'" .. v:gsub("['.]", "") .. "'"
elseif k == 4 then
result = result .. "='" .. v:gsub("'", "") .. "'"
end
end
end
return result
end

2
libs/uci/Makefile Normal file
View file

@ -0,0 +1,2 @@
include ../../build/config.mk
include ../../build/module.mk

View file

@ -0,0 +1,108 @@
--[[
LuCI - UCI mpdel
Description:
Generalized UCI model
FileId:
$Id$
License:
Copyright 2008 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
local uci = require("uci")
local util = require("luci.util")
local setmetatable = setmetatable
local rawget = rawget
local rawset = rawset
local error = error
local tostring = tostring
module("luci.model.uci", function(m) setmetatable(m, {__index = uci}) end)
local configs_mt = {}
local sections_mt = {}
local options_mt = {}
config = {}
setmetatable(config, configs_mt)
-- Level 1 (configs)
function configs_mt.__index(self, key)
local node = rawget(self, key)
if not node then
node = {}
node[".name"] = key
setmetatable(node, sections_mt)
rawset(self, key, node)
end
return node
end
function configs_mt.__newindex()
error("invalid operation")
end
-- Level 2 (sections)
function sections_mt.__index(self, key)
local node = rawget(self, key)
if not node then
node = {}
node[".conf"] = self[".name"]
node[".name"] = key
node[".type"] = uci.get(self[".name"], key)
setmetatable(node, options_mt)
rawset(self, key, node)
end
return node
end
function sections_mt.__newindex(self, key, value)
if not value then
if uci.delete(self[".name"], key) then
rawset(self, key, nil)
else
error("unable to delete section")
end
elseif key == "" then
key = uci.add(self[".name"], tostring(value))
if key then
rawset(self, "", self[key])
else
error("unable to create section")
end
else
if not uci.set(self[".name"], key, value) then
error("unable to create section")
end
end
end
-- Level 3 (options)
function options_mt.__index(self, key)
return uci.get(self[".conf"], self[".name"], key)
end
function options_mt.__newindex(self, key, value)
if not value then
if not uci.delete(self[".conf"], self[".name"], key) then
error("unable to delete option")
end
else
if not uci.set(self[".conf"], self[".name"], key, tostring(value)) then
error("unable to write option")
end
end
end