From: Steven Barth Date: Sat, 6 Sep 2008 13:51:51 +0000 (+0000) Subject: Rewrote UCI apply logic X-Git-Tag: 0.9.0~1419 X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=commitdiff_plain;h=dbde0216c29148520226a96a57be20ceb2406f45 Rewrote UCI apply logic --- diff --git a/applications/luci-statistics/root/etc/uci-defaults/luci-statistics b/applications/luci-statistics/root/etc/uci-defaults/luci-statistics index 6903ddfcb..f89366f1b 100644 --- a/applications/luci-statistics/root/etc/uci-defaults/luci-statistics +++ b/applications/luci-statistics/root/etc/uci-defaults/luci-statistics @@ -1,4 +1,7 @@ #!/bin/sh -uci set luci.uci_oncommit.luci_statistics='/etc/init.d/luci_statistics restart' -uci commit luci +uci batch <<-EOF + add ucitrack luci_statistics + set ucitrack.@luci_statistics[-1].init=luci_statistics + commit ucitrack +EOF diff --git a/applications/luci-uvc_streamer/root/etc/uci-defaults/luci-uvc_streamer b/applications/luci-uvc_streamer/root/etc/uci-defaults/luci-uvc_streamer index 6ecea2c42..42372f051 100644 --- a/applications/luci-uvc_streamer/root/etc/uci-defaults/luci-uvc_streamer +++ b/applications/luci-uvc_streamer/root/etc/uci-defaults/luci-uvc_streamer @@ -1,4 +1,7 @@ #!/bin/sh -uci set luci.uci_oncommit.uvc_streamer='/sbin/luci-reload uvc-streamer' -uci commit luci +uci batch <<-EOF + add ucitrack uvc-streamer + set ucitrack.@uvc-streamer[-1].init=uvc-streamer + commit ucitrack +EOF diff --git a/contrib/package/luci-addons/Makefile b/contrib/package/luci-addons/Makefile index 19c15f3f1..04b1a2f45 100644 --- a/contrib/package/luci-addons/Makefile +++ b/contrib/package/luci-addons/Makefile @@ -30,7 +30,6 @@ define Package/luci-addons/install $(INSTALL_BIN) ./dist/usr/bin/run-parts $(1)/usr/bin $(INSTALL_BIN) ./dist/sbin/luci-flash $(1)/sbin - $(INSTALL_BIN) ./dist/sbin/luci-reload $(1)/sbin $(INSTALL_BIN) ./dist/etc/init.d/luci_fixtime $(1)/etc/init.d $(INSTALL_BIN) ./dist/etc/init.d/luci_ethers $(1)/etc/init.d diff --git a/contrib/package/luci-addons/dist/sbin/luci-reload b/contrib/package/luci-addons/dist/sbin/luci-reload deleted file mode 100644 index 48b6778bc..000000000 --- a/contrib/package/luci-addons/dist/sbin/luci-reload +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -for i in $* -do - [ -x /etc/init.d/$i ] && { - echo -n "Reloading $i... " - /etc/init.d/$i restart >/dev/null 2>&1 && echo "done." || echo "failed!" - } -done \ No newline at end of file diff --git a/libs/cbi/luasrc/cbi.lua b/libs/cbi/luasrc/cbi.lua index be591a80e..b00ccf8d2 100644 --- a/libs/cbi/luasrc/cbi.lua +++ b/libs/cbi/luasrc/cbi.lua @@ -248,11 +248,11 @@ function Map.parse(self, ...) if luci.http.formvalue("cbi.apply") then for i, config in ipairs(self.parsechain) do self.uci:commit(config) - self.uci:apply(config) -- Refresh data because commit changes section names self.uci:load(config) end + self.uci:apply(self.parsechain) -- Reparse sections Node.parse(self, ...) diff --git a/libs/uci/luasrc/model/uci.lua b/libs/uci/luasrc/model/uci.lua index 659cd6254..8852d1e5f 100644 --- a/libs/uci/luasrc/model/uci.lua +++ b/libs/uci/luasrc/model/uci.lua @@ -54,14 +54,17 @@ end local Cursor = getmetatable(cursor()) ---- Applies the new config --- @param config UCI config -function Cursor.apply(self, config) - local conf = require "luci.config" - return conf.uci_oncommit[config] and - os.execute(conf.uci_oncommit[config] .. " >/dev/null 2>&1") +--- Applies UCI configuration changes +-- @param configlist List of UCI configurations +-- @param command Don't apply only return the command +function Cursor.apply(self, configlist, command) + configlist = self:_affected(configlist) + local reloadcmd = "/sbin/luci-reload " .. table.concat(configlist, " ") + + return command and reloadcmd or os.execute(reloadcmd .. " >/dev/null 2>&1") end + --- Delete all sections of a given type that match certain criteria. -- @param config UCI config -- @param type UCI section type @@ -180,6 +183,51 @@ function Cursor.changes(self, config) end +-- Return a list of initscripts affected by configuration changes. +function Cursor._affected(self, configlist) + configlist = type(configlist) == "table" and configlist or {configlist} + + local c = cursor() + c:load("ucitrack") + + -- Resolve dependencies + local reloadlist = {} + + local function _resolve_deps(name) + local reload = {name} + local deps = {} + + c:foreach("ucitrack", name, + function(section) + if section.affects then + for i, aff in ipairs(section.affects) do + table.insert(deps, aff) + end + end + end) + + for i, dep in ipairs(deps) do + for j, add in ipairs(_resolve_deps(dep)) do + table.insert(reload, add) + end + end + + return reload + end + + -- Collect initscripts + for j, config in ipairs(configlist) do + for i, e in ipairs(_resolve_deps(config)) do + if not util.contains(reloadlist, e) then + table.insert(reloadlist, e) + end + end + end + + return reloadlist +end + + --- Add an anonymous section. -- @class function -- @name Cursor.add diff --git a/libs/uci/root/etc/config/ucitrack b/libs/uci/root/etc/config/ucitrack new file mode 100644 index 000000000..cba783d8b --- /dev/null +++ b/libs/uci/root/etc/config/ucitrack @@ -0,0 +1,47 @@ +config network + option init network + list affects dhcp + +config wireless + list affects network + +config firewall + option init firewall + list affects luci-splash + list affects qos + +config olsr + option init olsrd + +config dhcp + option init dnsmasq + +config dropbear + option init dropbear + +config httpd + option init httpd + +config fstab + option init fstab + +config qos + option init qos + +config system + option init led + +config luci_ethers + option init luci_ethers + +config luci_splash + option init luci_splash + +config upnpd + option init miniupnpd + +config ntpclient + option init ntpclient + +config samba + option init samba \ No newline at end of file diff --git a/libs/uci/root/sbin/luci-reload b/libs/uci/root/sbin/luci-reload new file mode 100644 index 000000000..a92c6eb7f --- /dev/null +++ b/libs/uci/root/sbin/luci-reload @@ -0,0 +1,31 @@ +#!/bin/sh +. /etc/functions.sh + +apply_config() { + config_get init "$1" init + config_get exec "$1" exec + + [ -n "$init" ] && reload_init "$2" "$init" + [ -n "$exec" ] && reload_exec "$2" "$exec" +} + +reload_exec() { + [ -x $2 ] && { + echo -n "Reloading $1... " + $2 >/dev/null 2>&1 && echo "done." || echo "failed!" + } +} + +reload_init() { + [ -x /etc/init.d/$2 ] && /etc/init.d/$2 enabled && { + echo -n "Reloading $1... " + /etc/init.d/$2 reload >/dev/null 2>&1 && echo "done." || echo "failed!" + } +} + +config_load ucitrack + +for i in $* +do + config_foreach apply_config $i +done \ No newline at end of file diff --git a/libs/web/root/etc/config/luci b/libs/web/root/etc/config/luci index 8b222aaaa..f78fbb02b 100644 --- a/libs/web/root/etc/config/luci +++ b/libs/web/root/etc/config/luci @@ -17,24 +17,7 @@ config extern flash_keep option ipkg "/etc/ipkg.conf" option httpd "/etc/httpd.conf" option firewall "/etc/firewall.user" - -config event uci_oncommit - option network "/sbin/luci-reload network firewall dnsmasq luci_splash" - option wireless "/sbin/luci-reload network firewall dnsmasq luci_splash" - option olsr "/sbin/luci-reload olsrd" - option dhcp "/sbin/luci-reload dnsmasq" - option dropbear "/sbin/luci-reload dropbear" - option httpd "/sbin/luci-reload httpd" - option fstab "/sbin/luci-reload fstab" - option qos "/sbin/luci-reload qos" - option system "/sbin/luci-reload led" - option firewall "/sbin/luci-reload firewall luci_splash" - option luci_ethers "/sbin/luci-reload luci_ethers dnsmasq" - option luci_splash "/sbin/luci-reload firewall luci_splash" - option upnpd "/etc/init.d/miniupnpd enabled && /sbin/luci-reload miniupnpd || /etc/init.d/miniupnpd stop" - option ntpclient "/sbin/luci-reload ntpclient" - option samba "/sbin/luci-reload samba" - + config internal languages config internal sauth diff --git a/modules/admin-full/luasrc/controller/admin/uci.lua b/modules/admin-full/luasrc/controller/admin/uci.lua index 88c37d650..53b3464f6 100644 --- a/modules/admin-full/luasrc/controller/admin/uci.lua +++ b/modules/admin-full/luasrc/controller/admin/uci.lua @@ -24,27 +24,23 @@ function index() end function convert_changes(changes) - local ret = {} + local util = require "luci.util" + + local ret for r, tbl in pairs(changes) do for s, os in pairs(tbl) do for o, v in pairs(os) do - local val, str - if (v == "") then - str = "-" - val = "" - else - str = "" - val = "="..luci.util.pcdata(v) - end - str = r.."."..s - if o ~= ".type" then - str = str.."."..o - end - table.insert(ret, str..val) + ret = (ret and ret.."\n" or "") .. "%s%s.%s%s%s" % { + v == "" and "-" or "", + r, + s, + o ~= ".type" and "."..o or "", + v ~= "" and "="..util.pcdata(v) or "" + } end end end - return table.concat(ret, "\n") + return ret end function action_changes() @@ -54,52 +50,38 @@ end function action_apply() local path = luci.dispatcher.context.path - - local output = "" local uci = luci.model.uci.cursor() local changes = uci:changes() - - if changes then - local com = {} - local run = {} - - -- Collect files to be applied and commit changes - for r, tbl in pairs(changes) do - if r then - if path[#path] ~= "apply" then - uci:load(r) - uci:commit(r) - uci:unload(r) - end - if luci.config.uci_oncommit and luci.config.uci_oncommit[r] then - run[luci.config.uci_oncommit[r]] = true - end - end - end - - -- Search for post-commit commands - for cmd, i in pairs(run) do - output = output .. cmd .. ":\n" .. luci.util.exec(cmd) .. "\n" + local reload = {} + + -- Collect files to be applied and commit changes + for r, tbl in pairs(changes) do + table.insert(reload, r) + if path[#path] ~= "apply" then + uci:load(r) + uci:commit(r) + uci:unload(r) end end + local function _reload() + local cmd = uci:apply(reload, true) + return io.popen(cmd) + end - luci.template.render("admin_uci/apply", {changes=convert_changes(changes), output=output}) + luci.template.render("admin_uci/apply", {changes=convert_changes(changes), reload=_reload}) end function action_revert() local uci = luci.model.uci.cursor() local changes = uci:changes() - if changes then - local revert = {} - - -- Collect files to be reverted - for r, tbl in pairs(changes) do - uci:load(r) - uci:revert(r) - uci:unload(r) - end + + -- Collect files to be reverted + for r, tbl in pairs(changes) do + uci:load(r) + uci:revert(r) + uci:unload(r) end luci.template.render("admin_uci/revert", {changes=convert_changes(changes)}) diff --git a/modules/admin-full/luasrc/view/admin_uci/apply.htm b/modules/admin-full/luasrc/view/admin_uci/apply.htm index e28094728..8f5a8e37a 100644 --- a/modules/admin-full/luasrc/view/admin_uci/apply.htm +++ b/modules/admin-full/luasrc/view/admin_uci/apply.htm @@ -16,5 +16,13 @@ $Id$

<%:config%>

<%:uci_applied%>:

<%=(changes or "-")%> -<%=output%> +<% +local fp = reload() +local line = fp:read() +while line do + write(line.."\n") + line = fp:read() +end +fp:close() +%> <%+footer%> \ No newline at end of file diff --git a/modules/admin-mini/luasrc/controller/mini/uci.lua b/modules/admin-mini/luasrc/controller/mini/uci.lua index a5b3402ad..4e920563a 100644 --- a/modules/admin-mini/luasrc/controller/mini/uci.lua +++ b/modules/admin-mini/luasrc/controller/mini/uci.lua @@ -20,31 +20,27 @@ function index() entry({"mini", "uci"}, nil, i18n("config")) entry({"mini", "uci", "changes"}, call("action_changes"), i18n("changes"), 30) entry({"mini", "uci", "revert"}, call("action_revert"), i18n("revert"), 20) - entry({"mini", "uci", "apply"}, call("action_apply"), i18n("saveapply"), 10) + entry({"mini", "uci", "saveapply"}, call("action_apply"), i18n("saveapply"), 10) end function convert_changes(changes) - local ret = {} + local util = require "luci.util" + + local ret for r, tbl in pairs(changes) do for s, os in pairs(tbl) do for o, v in pairs(os) do - local val, str - if (v == "") then - str = "-" - val = "" - else - str = "" - val = "="..luci.util.pcdata(v) - end - str = r.."."..s - if o ~= ".type" then - str = str.."."..o - end - table.insert(ret, str..val) + ret = (ret and ret.."\n" or "") .. "%s%s.%s%s%s" % { + v == "" and "-" or "", + r, + s, + o ~= ".type" and "."..o or "", + v ~= "" and "="..util.pcdata(v) or "" + } end end end - return table.concat(ret, "\n") + return ret end function action_changes() @@ -53,49 +49,37 @@ function action_changes() end function action_apply() + local path = luci.dispatcher.context.path local uci = luci.model.uci.cursor() local changes = uci:changes() - local output = "" - - if changes then - local com = {} - local run = {} - - -- Collect files to be applied and commit changes - for r, tbl in pairs(changes) do - if r then - uci:load(r) - uci:commit(r) - uci:unload(r) - if luci.config.uci_oncommit and luci.config.uci_oncommit[r] then - run[luci.config.uci_oncommit[r]] = true - end - end - end - - -- Search for post-commit commands - for cmd, i in pairs(run) do - output = output .. cmd .. ":\n" .. luci.util.exec(cmd) .. "\n" - end + local reload = {} + + -- Collect files to be applied and commit changes + for r, tbl in pairs(changes) do + table.insert(reload, r) + uci:load(r) + uci:commit(r) + uci:unload(r) end - - luci.template.render("mini/uci_apply", {changes=convert_changes(changes), output=output}) + local function _reload() + local cmd = uci:apply(reload, true) + return io.popen(cmd) + end + + luci.template.render("mini/uci_apply", {changes=convert_changes(changes), reload=_reload}) end function action_revert() local uci = luci.model.uci.cursor() local changes = uci:changes() - if changes then - local revert = {} - - -- Collect files to be reverted - for r, tbl in pairs(changes) do - uci:load(r) - uci:revert(r) - uci:unload(r) - end + + -- Collect files to be reverted + for r, tbl in pairs(changes) do + uci:load(r) + uci:revert(r) + uci:unload(r) end luci.template.render("mini/uci_revert", {changes=convert_changes(changes)}) diff --git a/modules/admin-mini/luasrc/view/mini/uci_apply.htm b/modules/admin-mini/luasrc/view/mini/uci_apply.htm index e28094728..8f5a8e37a 100644 --- a/modules/admin-mini/luasrc/view/mini/uci_apply.htm +++ b/modules/admin-mini/luasrc/view/mini/uci_apply.htm @@ -16,5 +16,13 @@ $Id$

<%:config%>

<%:uci_applied%>:

<%=(changes or "-")%> -<%=output%> +<% +local fp = reload() +local line = fp:read() +while line do + write(line.."\n") + line = fp:read() +end +fp:close() +%> <%+footer%> \ No newline at end of file