Rewrote UCI apply logic
authorSteven Barth <steven@midlink.org>
Sat, 6 Sep 2008 13:51:51 +0000 (13:51 +0000)
committerSteven Barth <steven@midlink.org>
Sat, 6 Sep 2008 13:51:51 +0000 (13:51 +0000)
13 files changed:
applications/luci-statistics/root/etc/uci-defaults/luci-statistics
applications/luci-uvc_streamer/root/etc/uci-defaults/luci-uvc_streamer
contrib/package/luci-addons/Makefile
contrib/package/luci-addons/dist/sbin/luci-reload [deleted file]
libs/cbi/luasrc/cbi.lua
libs/uci/luasrc/model/uci.lua
libs/uci/root/etc/config/ucitrack [new file with mode: 0644]
libs/uci/root/sbin/luci-reload [new file with mode: 0644]
libs/web/root/etc/config/luci
modules/admin-full/luasrc/controller/admin/uci.lua
modules/admin-full/luasrc/view/admin_uci/apply.htm
modules/admin-mini/luasrc/controller/mini/uci.lua
modules/admin-mini/luasrc/view/mini/uci_apply.htm

index 6903ddf..f89366f 100644 (file)
@@ -1,4 +1,7 @@
 #!/bin/sh
 
 #!/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
index 6ecea2c..42372f0 100644 (file)
@@ -1,4 +1,7 @@
 #!/bin/sh
 
 #!/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
index 19c15f3..04b1a2f 100644 (file)
@@ -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/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
 
        $(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 (file)
index 48b6778..0000000
+++ /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
index be591a8..b00ccf8 100644 (file)
@@ -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)
                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
 
                                -- Refresh data because commit changes section names
                                self.uci:load(config)
                        end
+                       self.uci:apply(self.parsechain)
 
                        -- Reparse sections
                        Node.parse(self, ...)
 
                        -- Reparse sections
                        Node.parse(self, ...)
index 659cd62..8852d1e 100644 (file)
@@ -54,14 +54,17 @@ end
 
 local Cursor = getmetatable(cursor())
 
 
 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
 
 end
 
+
 --- Delete all sections of a given type that match certain criteria.
 -- @param config               UCI config
 -- @param type                 UCI section type
 --- 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
 
 
 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
 --- 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 (file)
index 0000000..cba783d
--- /dev/null
@@ -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 (file)
index 0000000..a92c6eb
--- /dev/null
@@ -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
index 8b222aa..f78fbb0 100644 (file)
@@ -17,24 +17,7 @@ config extern flash_keep
        option ipkg     "/etc/ipkg.conf"
        option httpd    "/etc/httpd.conf"
        option firewall "/etc/firewall.user"
        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
 config internal languages
        
 config internal sauth
index 88c37d6..53b3464 100644 (file)
@@ -24,27 +24,23 @@ function index()
 end
 
 function convert_changes(changes)
 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
        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
                        end
                end
        end
-       return table.concat(ret, "\n")
+       return ret
 end
 
 function action_changes()
 end
 
 function action_changes()
@@ -54,52 +50,38 @@ end
 
 function action_apply()
        local path = luci.dispatcher.context.path
 
 function action_apply()
        local path = luci.dispatcher.context.path
-       
-       local output  = ""
        local uci = luci.model.uci.cursor()
        local changes = uci:changes()
        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
        
                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()
 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)})
        end
        
        luci.template.render("admin_uci/revert", {changes=convert_changes(changes)})
index e280947..8f5a8e3 100644 (file)
@@ -16,5 +16,13 @@ $Id$
 <h1><%:config%></h1>
 <p><%:uci_applied%>:</p>
 <code><%=(changes or "-")%>
 <h1><%:config%></h1>
 <p><%:uci_applied%>:</p>
 <code><%=(changes or "-")%>
-<%=output%></code>
+<%
+local fp = reload()
+local line = fp:read()
+while line do 
+       write(line.."\n")
+       line = fp:read()
+end
+fp:close()
+%></code>
 <%+footer%>
\ No newline at end of file
 <%+footer%>
\ No newline at end of file
index a5b3402..4e92056 100644 (file)
@@ -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"}, 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)
 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
        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
                        end
                end
        end
-       return table.concat(ret, "\n")
+       return ret
 end
 
 function action_changes()
 end
 
 function action_changes()
@@ -53,49 +49,37 @@ function action_changes()
 end
 
 function action_apply()
 end
 
 function action_apply()
+       local path = luci.dispatcher.context.path
        local uci = luci.model.uci.cursor()
        local changes = uci:changes()
        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
        
        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()
 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)})
        end
        
        luci.template.render("mini/uci_revert", {changes=convert_changes(changes)})
index e280947..8f5a8e3 100644 (file)
@@ -16,5 +16,13 @@ $Id$
 <h1><%:config%></h1>
 <p><%:uci_applied%>:</p>
 <code><%=(changes or "-")%>
 <h1><%:config%></h1>
 <p><%:uci_applied%>:</p>
 <code><%=(changes or "-")%>
-<%=output%></code>
+<%
+local fp = reload()
+local line = fp:read()
+while line do 
+       write(line.."\n")
+       line = fp:read()
+end
+fp:close()
+%></code>
 <%+footer%>
\ No newline at end of file
 <%+footer%>
\ No newline at end of file