X-Git-Url: http://git.archive.openwrt.org/?a=blobdiff_plain;f=modules%2Fluci-base%2Fluasrc%2Fmodel%2Fuci.lua;h=34323f08bd1d8657e6b130e82d5c22f7d4d830e9;hb=8deb9495515b97898514e8ffb8f002c8afe3bfa7;hp=0e3950c0bd5158c534fe51a29b1df57d30ffa2fd;hpb=8c636c87ee14d4d0bac904b23f35b016b8cf19e0;p=project%2Fluci.git diff --git a/modules/luci-base/luasrc/model/uci.lua b/modules/luci-base/luasrc/model/uci.lua index 0e3950c0b..34323f08b 100644 --- a/modules/luci-base/luasrc/model/uci.lua +++ b/modules/luci-base/luasrc/model/uci.lua @@ -3,6 +3,7 @@ local os = require "os" local util = require "luci.util" +local conf = require "luci.config" local table = require "table" @@ -32,6 +33,15 @@ local ERRSTR = { "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() return _M @@ -54,6 +64,10 @@ function get_savedir(self) return "/tmp/.uci" end +function get_session_id(self) + return session_id +end + function set_confdir(self, directory) return false end @@ -62,6 +76,11 @@ function set_savedir(self, directory) return false end +function set_session_id(self, id) + session_id = id + return true +end + function load(self, config) return true @@ -77,7 +96,7 @@ end function changes(self, config) - local rv = util.ubus("uci", "changes", { config = config }) + local rv = call("changes", { config = config }) local res = {} if type(rv) == "table" and type(rv.changes) == "table" then @@ -116,36 +135,98 @@ end function revert(self, config) - local _, err = util.ubus("uci", "revert", { config = config }) + local _, err = call("revert", { config = config }) return (err == nil), ERRSTR[err] end function commit(self, config) - local _, err = util.ubus("uci", "commit", { config = config }) + local _, err = call("commit", { config = config }) return (err == nil), ERRSTR[err] end ---[[ -function apply(self, configs, command) - local _, config +function apply(self, rollback) + local _, err + + if rollback then + local timeout = tonumber(conf.apply and conf.apply.rollback or "") or 0 - assert(not command, "Apply command not supported anymore") + _, err = call("apply", { + timeout = (timeout > 30) and timeout or 30, + rollback = true + }) - if type(configs) == "table" then - for _, config in ipairs(configs) do - util.ubus("service", "event", { - type = "config.change", - data = { package = config } + if not err then + util.ubus("session", "set", { + ubus_rpc_session = session_id, + values = { rollback = os.time() + timeout } }) end + else + _, err = call("changes", {}) + + if not err then + if type(_) == "table" and type(_.changes) == "table" then + local k, v + for k, v in pairs(_.changes) do + _, err = call("commit", { config = k }) + if err then + break + end + end + end + end + + if not err then + _, err = call("apply", { rollback = false }) + end + end + + return (err == nil), ERRSTR[err] +end + +function confirm(self) + local _, err = call("confirm", {}) + if not err then + util.ubus("session", "set", { + ubus_rpc_session = session_id, + values = { rollback = 0 } + }) + end + return (err == nil), ERRSTR[err] +end + +function rollback(self) + local _, err = call("rollback", {}) + if not err then + util.ubus("session", "set", { + ubus_rpc_session = session_id, + values = { rollback = 0 } + }) end + return (err == nil), ERRSTR[err] +end + +function rollback_pending(self) + local deadline, err = util.ubus("session", "get", { + ubus_rpc_session = session_id, + keys = { "rollback" } + }) + + if type(deadline) == "table" and + type(deadline.values) == "table" and + type(deadline.values.rollback) == "number" and + deadline.values.rollback > os.time() + then + return true, deadline.values.rollback - os.time() + end + + return false, ERRSTR[err] end -]] function foreach(self, config, stype, callback) if type(callback) == "function" then - local rv, err = util.ubus("uci", "get", { + local rv, err = call("get", { config = config, type = stype }) @@ -186,7 +267,7 @@ local function _get(self, operation, config, section, option) if section == nil then return nil elseif type(option) == "string" and option:byte(1) ~= 46 then - local rv, err = util.ubus("uci", operation, { + local rv, err = call(operation, { config = config, section = section, option = option @@ -220,7 +301,7 @@ function get_state(self, ...) end function get_all(self, config, section) - local rv, err = util.ubus("uci", "get", { + local rv, err = call("get", { config = config, section = section }) @@ -271,7 +352,7 @@ end function section(self, config, stype, name, values) - local rv, err = util.ubus("uci", "add", { + local rv, err = call("add", { config = config, type = stype, name = name, @@ -297,7 +378,7 @@ function set(self, config, section, option, value) local sname, err = self:section(config, option, section) return (not not sname), err else - local _, err = util.ubus("uci", "set", { + local _, err = call("set", { config = config, section = section, values = { [option] = value } @@ -319,7 +400,7 @@ function set_list(self, config, section, option, value) end function tset(self, config, section, values) - local _, err = util.ubus("uci", "set", { + local _, err = call("set", { config = config, section = section, values = values @@ -353,7 +434,7 @@ function reorder(self, config, section, index) return false, "Invalid argument" end - local _, err = util.ubus("uci", "order", { + local _, err = call("order", { config = config, sections = sections }) @@ -363,7 +444,7 @@ end function delete(self, config, section, option) - local _, err = util.ubus("uci", "delete", { + local _, err = call("delete", { config = config, section = section, option = option @@ -374,13 +455,13 @@ end function delete_all(self, config, stype, comparator) local _, err if type(comparator) == "table" then - _, err = util.ubus("uci", "delete", { + _, err = call("delete", { config = config, type = stype, match = comparator }) elseif type(comparator) == "function" then - local rv = util.ubus("uci", "get", { + local rv = call("get", { config = config, type = stype }) @@ -389,7 +470,7 @@ function delete_all(self, config, stype, comparator) local sname, section for sname, section in pairs(rv.values) do if comparator(section) then - _, err = util.ubus("uci", "delete", { + _, err = call("delete", { config = config, section = sname }) @@ -397,7 +478,7 @@ function delete_all(self, config, stype, comparator) end end elseif comparator == nil then - _, err = util.ubus("uci", "delete", { + _, err = call("delete", { config = config, type = stype }) @@ -407,59 +488,3 @@ function delete_all(self, config, stype, comparator) return (err == nil), ERRSTR[err] end - - -function apply(self, configlist, command) - configlist = self:_affected(configlist) - if command then - return { "/sbin/luci-reload", unpack(configlist) } - else - return os.execute("/sbin/luci-reload %s >/dev/null 2>&1" - % util.shellquote(table.concat(configlist, " "))) - end -end - --- Return a list of initscripts affected by configuration changes. -function _affected(self, configlist) - configlist = type(configlist) == "table" and configlist or { configlist } - - -- Resolve dependencies - local reloadlist = { } - - local function _resolve_deps(name) - local reload = { name } - local deps = { } - - self:foreach("ucitrack", name, - function(section) - if section.affects then - for i, aff in ipairs(section.affects) do - deps[#deps+1] = aff - end - end - end) - - local i, dep - for i, dep in ipairs(deps) do - local j, add - for j, add in ipairs(_resolve_deps(dep)) do - reload[#reload+1] = add - end - end - - return reload - end - - -- Collect initscripts - local j, config - for j, config in ipairs(configlist) do - local i, e - for i, e in ipairs(_resolve_deps(config)) do - if not util.contains(reloadlist, e) then - reloadlist[#reloadlist+1] = e - end - end - end - - return reloadlist -end