X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=modules%2Fluci-base%2Fluasrc%2Fmodel%2Fuci.lua;h=461ba9d5a38efae2c042829dce83d5aaeec13749;hb=9ed48ef2a62df5406c589ef9a43da51df8d9645c;hp=7e1c8f5952ccbc79fd1f28aa56b4c8c8cd51d64e;hpb=24ac0d81ee56c5630b38aefbb5526e8bfcf6cd88;p=project%2Fluci.git diff --git a/modules/luci-base/luasrc/model/uci.lua b/modules/luci-base/luasrc/model/uci.lua index 7e1c8f595..461ba9d5a 100644 --- a/modules/luci-base/luasrc/model/uci.lua +++ b/modules/luci-base/luasrc/model/uci.lua @@ -32,6 +32,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 +63,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 +75,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 +95,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 +134,99 @@ 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 conf = require "luci.config" + local timeout = tonumber(conf and 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 }) @@ -242,7 +323,7 @@ end function get_first(self, config, stype, option, default) local rv = default - self:foreach(conf, stype, function(s) + self:foreach(config, stype, function(s) local val = not option and s[".name"] or s[option] if type(default) == "number" then @@ -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