From 7aed1e4b9d3d608389a8b15ea800b8e75be967ef Mon Sep 17 00:00:00 2001 From: Steven Barth Date: Tue, 10 Nov 2009 16:02:48 +0000 Subject: [PATCH] NIU: More pages --- build/setup.lua | 3 + libs/cbi/luasrc/cbi.lua | 13 +- libs/uci/luasrc/model/uci.lua | 5 +- libs/web/luasrc/dispatcher.lua | 1 + modules/niu/luasrc/controller/niu/dashboard.lua | 2 - modules/niu/luasrc/controller/niu/network.lua | 20 +- modules/niu/luasrc/controller/niu/system.lua | 255 ++++++++++++++++++--- modules/niu/luasrc/model/cbi/niu/network/lan.lua | 10 +- modules/niu/luasrc/model/cbi/niu/system/reboot.lua | 1 + modules/niu/luasrc/view/niu/network.htm | 10 +- .../niu/luasrc/view/niu/network/warn_ip_change.htm | 2 + modules/niu/luasrc/view/niu/system/backup.htm | 41 ++++ modules/niu/luasrc/view/niu/system/reboot.htm | 14 ++ modules/niu/luasrc/view/niu/system/upgrade.htm | 105 +++++++++ 14 files changed, 433 insertions(+), 49 deletions(-) create mode 100644 modules/niu/luasrc/model/cbi/niu/system/reboot.lua create mode 100644 modules/niu/luasrc/view/niu/network/warn_ip_change.htm create mode 100644 modules/niu/luasrc/view/niu/system/backup.htm create mode 100644 modules/niu/luasrc/view/niu/system/reboot.htm create mode 100644 modules/niu/luasrc/view/niu/system/upgrade.htm diff --git a/build/setup.lua b/build/setup.lua index 4a771540d..f374da90f 100644 --- a/build/setup.lua +++ b/build/setup.lua @@ -12,6 +12,9 @@ uci_model.cursor_state = function() return uci_core.cursor(SYSROOT .. "/etc/config", SYSROOT .. "/var/state") end +uci_model.inst = uci_model.cursor() +uci_model.inst_state = uci_model.cursor_state() + -- override uvl access local uvl_model = require "luci.uvl" local uvl_init = uvl_model.UVL.__init__ diff --git a/libs/cbi/luasrc/cbi.lua b/libs/cbi/luasrc/cbi.lua index f6a2694b2..5a1d92385 100644 --- a/libs/cbi/luasrc/cbi.lua +++ b/libs/cbi/luasrc/cbi.lua @@ -222,6 +222,12 @@ function Node.__init__(self, title, description) end -- hook helper +function Node._run_hook(self, hook) + if type(self[hook]) == "function" then + return self[hook](self) + end +end + function Node._run_hooks(self, ...) local f local r = false @@ -528,9 +534,9 @@ function Delegator.add(self, name, node) end function Delegator.insert_after(self, name, after) - local n = #self.chain + local n = #self.chain + 1 for k, v in ipairs(self.chain) do - if v == state then + if v == after then n = k + 1 break end @@ -599,8 +605,7 @@ function Delegator.parse(self, ...) return FORM_NODATA elseif stat > FORM_PROCEED and (not newcurrent or not self:get(newcurrent)) then - self:_run_hooks("on_done") - return FORM_DONE + return self:_run_hook("on_done") or FORM_DONE else self.current = newcurrent or self.current self.active = self:get(self.current) diff --git a/libs/uci/luasrc/model/uci.lua b/libs/uci/luasrc/model/uci.lua index c927b4ca5..66bd0a026 100644 --- a/libs/uci/luasrc/model/uci.lua +++ b/libs/uci/luasrc/model/uci.lua @@ -58,7 +58,10 @@ function cursor_state() end -local Cursor = getmetatable(cursor()) +inst = cursor() +inst_state = cursor_state() + +local Cursor = getmetatable(inst) --- Applies UCI configuration changes -- @param configlist List of UCI configurations diff --git a/libs/web/luasrc/dispatcher.lua b/libs/web/luasrc/dispatcher.lua index e3d7ec974..8b7cdb828 100644 --- a/libs/web/luasrc/dispatcher.lua +++ b/libs/web/luasrc/dispatcher.lua @@ -34,6 +34,7 @@ local nixio = require "nixio", require "nixio.util" module("luci.dispatcher", package.seeall) context = util.threadlocal() +uci = require "luci.model.uci" authenticator = {} diff --git a/modules/niu/luasrc/controller/niu/dashboard.lua b/modules/niu/luasrc/controller/niu/dashboard.lua index e3270e4c6..f6c893980 100644 --- a/modules/niu/luasrc/controller/niu/dashboard.lua +++ b/modules/niu/luasrc/controller/niu/dashboard.lua @@ -36,8 +36,6 @@ function dashboard() local tpl = require "luci.template" local utl = require "luci.util" local uci = require "luci.model.uci" - local str = require "luci.store" - str.uci_state = str.uci_state or uci.cursor() local nds = dsp.node("niu").nodes tpl.render("niu/dashboard", {utl = utl, nodes = nds, dsp = dsp, tpl = tpl}) diff --git a/modules/niu/luasrc/controller/niu/network.lua b/modules/niu/luasrc/controller/niu/network.lua index cafed2567..36aff630d 100644 --- a/modules/niu/luasrc/controller/niu/network.lua +++ b/modules/niu/luasrc/controller/niu/network.lua @@ -16,17 +16,21 @@ local req = require module "luci.controller.niu.network" function index() - entry({"niu", "network"}, nil, "Network").dbtemplate = "niu/network" - - entry({"niu", "network", "lan"}, - cbi("niu/network/lan", {on_success_to={"niu"}}), "Configure LAN", 10) + entry({"niu", "network"}, nil, "Network", 10).dbtemplate = "niu/network" entry({"niu", "network", "wan"}, - cbi("niu/network/wan", {on_success_to={"niu"}}), "Configure Internet", 20) + cbi("niu/network/wan", {on_success_to={"niu"}}), "Configure Internet Connection", 10) + + entry({"niu", "network", "lan"}, + cbi("niu/network/lan", {on_success_to={"niu"}}), "Configure Local Network", 20) - entry({"niu", "network", "assign"}, cbi("niu/network/assign", - {on_success_to={"niu"}}), "Address Assignment", 30) + uci.inst_state:foreach("dhcp", "dhcp", function(s) + if s.interface == "lan" and s.ignore ~= "1" then + entry({"niu", "network", "assign"}, cbi("niu/network/assign", + {on_success_to={"niu"}}), "Assign local addresses", 30) + end + end) entry({"niu", "network", "routes"}, cbi("niu/network/routes", - {on_success_to={"niu"}}), "Custom Routing", 40) + {on_success_to={"niu"}}), "Assign custom routes", 40) end diff --git a/modules/niu/luasrc/controller/niu/system.lua b/modules/niu/luasrc/controller/niu/system.lua index 45f7cb615..5ffed306b 100644 --- a/modules/niu/luasrc/controller/niu/system.lua +++ b/modules/niu/luasrc/controller/niu/system.lua @@ -12,56 +12,249 @@ You may obtain a copy of the License at $Id$ ]]-- -local require, pairs, unpack = require, pairs, unpack +local require, pairs, unpack, tonumber = require, pairs, unpack, tonumber module "luci.controller.niu.system" function index() - entry({"niu", "system"}, nil, "System").dbtemplate = "niu/system" + entry({"niu", "system"}, nil, "System", 20).dbtemplate = "niu/system" entry({"niu", "system", "general"}, - cbi("niu/system/general", {on_success_to={"niu"}}), "General", 10) + cbi("niu/system/general", {on_success_to={"niu"}}), "Configure Device", 10) - entry({"niu", "system", "backup"}, call("backup"), "Backup Settings", 20) + entry({"niu", "system", "backup"}, call("backup"), "Backup or Restore Settings", 20) + entry({"niu", "system", "upgrade"}, call("upgrade"), "Upgrade Firmware", 40) end function backup() - local os = require "os" - local uci = require "luci.model.uci".cursor() + local dsp = require "luci.dispatcher" + local os, io = require "os", require "io" + local uci = require "luci.model.uci".inst local nixio, nutl = require "nixio", require "nixio.util" local fs = require "nixio.fs" local http = require "luci.http" + local tpl = require "luci.template" - - local call = {"/bin/tar", "-cz"} - for k, v in pairs(uci:get_all("luci", "flash_keep")) do - if k:byte() ~= 46 then -- k[1] ~= "." - nutl.consume(fs.glob(v), call) + local restore_fpi + http.setfilehandler( + function(meta, chunk, eof) + if not restore_fpi then + restore_fpi = io.popen("tar -xzC/ >/dev/null 2>&1", "w") + end + if chunk then + restore_fpi:write(chunk) + end + if eof then + restore_fpi:close() + end end - end + ) + local reset_avail = (fs.readfile("/proc/mtd") or ""):find('"rootfs_data"') + local upload = http.formvalue("archive") + local backup = http.formvalue("backup") + local reset = reset_avail and http.formvalue("reset") + local backup_cmd = "tar -cz %s 2>/dev/null" - http.header( - 'Content-Disposition', 'attachment; filename="backup-%s-%s.tar.gz"' % { - nixio.uname().nodename, os.date("%Y-%m-%d") - } - ) - http.prepare_content("application/x-targz") + if http.formvalue("cancel") then + return http.redirect(dsp.build_url("niu")) + end + if backup then + local call = {"/bin/tar", "-cz"} + for k, v in pairs(uci:get_all("luci", "flash_keep")) do + if k:byte() ~= 46 then -- k[1] ~= "." + nutl.consume(fs.glob(v), call) + end + end + + + http.header( + 'Content-Disposition', 'attachment; filename="backup-%s-%s.tar.gz"' % { + nixio.uname().nodename, os.date("%Y-%m-%d") + } + ) + http.prepare_content("application/x-targz") + + + local fdin, fdout = nixio.pipe() + local devnull = nixio.open("/dev/null", "r+") + local proc = nixio.fork() + + if proc == 0 then + fdin:close() + nixio.dup(devnull, nixio.stdin) + nixio.dup(devnull, nixio.stderr) + nixio.dup(fdout, nixio.stdout) + nixio.exec(unpack(call)) + os.exit(1) + end + + fdout:close() + http.splice(fdin) + http.close() + elseif (upload and #upload > 0) or reset then + tpl.render("niu/system/reboot") + if nixio.fork() == 0 then + nixio.nanosleep(1) + if reset then + nixio.execp("mtd", "-r", "erase", "rootfs_data") + else + nixio.execp("reboot") + end + os.exit(1) + end + else + tpl.render("niu/system/backup", {reset_avail = reset_avail}) + end +end + +function upgrade() + local io, os, table = require "io", require "os", require "table" + local uci = require "luci.store".uci_state + local http = require "luci.http" + local util = require "luci.util" + local tpl = require "luci.template" + local nixio = require "nixio", require "nixio.util", require "nixio.fs" + + + local tmpfile = "/tmp/firmware.img" + + local function image_supported() + -- XXX: yay... + return ( 0 == os.execute( + ". /etc/functions.sh; " .. + "include /lib/upgrade; " .. + "platform_check_image %q >/dev/null" + % tmpfile + ) ) + end - local fdin, fdout = nixio.pipe() - local devnull = nixio.open("/dev/null", "r+") - local proc = nixio.fork() + local function image_checksum() + return (util.exec("md5sum %q" % tmpfile):match("^([^%s]+)")) + end - if proc == 0 then - fdin:close() - nixio.dup(devnull, nixio.stdin) - nixio.dup(devnull, nixio.stderr) - nixio.dup(fdout, nixio.stdout) - nixio.exec(unpack(call)) - os.exit(1) + local function storage_size() + local size = 0 + if nixio.fs.access("/proc/mtd") then + for l in io.lines("/proc/mtd") do + local d, s, e, n = l:match('^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)"') + if n == "linux" then + size = tonumber(s, 16) + break + end + end + elseif nixio.fs.access("/proc/partitions") then + for l in io.lines("/proc/partitions") do + local x, y, b, n = l:match('^%s*(%d+)%s+(%d+)%s+([^%s]+)%s+([^%s]+)') + if b and n and not n:match('[0-9]') then + size = tonumber(b) * 1024 + break + end + end + end + return size end + + + -- Install upload handler + local file + http.setfilehandler( + function(meta, chunk, eof) + if not nixio.fs.access(tmpfile) and not file and chunk and #chunk > 0 then + file = io.open(tmpfile, "w") + end + if file and chunk then + file:write(chunk) + end + if file and eof then + file:close() + end + end + ) + + + -- Determine state + local keep_avail = true + local step = tonumber(http.formvalue("step") or 1) + local has_image = nixio.fs.access(tmpfile) + local has_support = image_supported() + local has_platform = nixio.fs.access("/lib/upgrade/platform.sh") + local has_upload = http.formvalue("image") + + -- This does the actual flashing which is invoked inside an iframe + -- so don't produce meaningful errors here because the the + -- previous pages should arrange the stuff as required. + if step == 4 then + if has_platform and has_image and has_support then + -- Mimetype text/plain + http.prepare_content("text/plain") + + local call = {} + for k, v in pairs(uci:get_all("luci", "flash_keep")) do + if k:byte() ~= 46 then -- k[1] ~= "." + nixio.util.consume(nixio.fs.glob(v), call) + end + end + + -- Now invoke sysupgrade + local keepcfg = keep_avail and http.formvalue("keepcfg") == "1" + local fd = io.popen("/sbin/luci-flash %s %q" %{ + keepcfg and "-k %q" % table.concat(call, " ") or "", tmpfile + }) + + if fd then + while true do + local ln = fd:read("*l") + if not ln then break end + http.write(ln .. "\n") + end + fd:close() + end + + -- Make sure the device is rebooted + if nixio.fork() == 0 then + nixio.nanosleep(1) + nixio.execp("reboot") + os.exit(1) + end + end + + + -- + -- This is step 1-3, which does the user interaction and + -- image upload. + -- + + -- Step 1: file upload, error on unsupported image format + elseif not has_image or not has_support or step == 1 then + -- If there is an image but user has requested step 1 + -- or type is not supported, then remove it. + if has_image then + nixio.fs.unlink(tmpfile) + end + + tpl.render("niu/system/upgrade", { + step=1, + bad_image=(has_image and not has_support or false), + keepavail=keep_avail, + supported=has_platform + } ) + + -- Step 2: present uploaded file, show checksum, confirmation + elseif step == 2 then + tpl.render("niu/system/upgrade", { + step=2, + checksum=image_checksum(), + filesize=nixio.fs.stat(tmpfile).size, + flashsize=storage_size(), + keepconfig=(keep_avail and http.formvalue("keepcfg") == "1") + } ) - fdout:close() - http.splice(fdin) - http.close() + -- Step 3: load iframe which calls the actual flash procedure + elseif step == 3 then + tpl.render("niu/system/upgrade", { + step=3, + keepconfig=(keep_avail and http.formvalue("keepcfg") == "1") + } ) + end end \ No newline at end of file diff --git a/modules/niu/luasrc/model/cbi/niu/network/lan.lua b/modules/niu/luasrc/model/cbi/niu/network/lan.lua index b5d97d2b1..6f6237e60 100644 --- a/modules/niu/luasrc/model/cbi/niu/network/lan.lua +++ b/modules/niu/luasrc/model/cbi/niu/network/lan.lua @@ -1,10 +1,12 @@ -local cursor = require "luci.model.uci".cursor() +local uci = require "luci.model.uci" +local cursor = uci.cursor() local d = Delegator() d.allow_finish = true d.allow_back = true d.allow_cancel = true d:add("lan1", load("niu/network/lan1")) +d:set("warnip", {Template("niu/network/warn_ip_change")}) function d.on_cancel() cursor:revert("network") @@ -12,6 +14,12 @@ function d.on_cancel() end function d.on_done() + if uci.inst_state:get("network", "lan", "ipaddr") ~= cursor:get("network", "lan", "ipaddr") then + local cs = uci.cursor_state() + cs:set("network", "lan", "_ipchanged", "1") + cs:save("network") + end + cursor:commit("network") cursor:commit("dhcp") end diff --git a/modules/niu/luasrc/model/cbi/niu/system/reboot.lua b/modules/niu/luasrc/model/cbi/niu/system/reboot.lua new file mode 100644 index 000000000..d8f852bdc --- /dev/null +++ b/modules/niu/luasrc/model/cbi/niu/system/reboot.lua @@ -0,0 +1 @@ +local f = Form("reboot", "Rebooting Device", "Device is rebooting. Please wait...") \ No newline at end of file diff --git a/modules/niu/luasrc/view/niu/network.htm b/modules/niu/luasrc/view/niu/network.htm index a022b0af8..864471231 100644 --- a/modules/niu/luasrc/view/niu/network.htm +++ b/modules/niu/luasrc/view/niu/network.htm @@ -1,13 +1,19 @@ <% local dsp = require "luci.dispatcher" local utl = require "luci.util" -local str = require "luci.store" +local uci = require "luci.model.uci" local nws = {} -str.uci_state:foreach("network", "interface", function(s) +uci.inst_state:foreach("network", "interface", function(s) nws[#nws+1] = s end) + +if uci.inst_state:get("network", "lan", "_ipchanged") and +uci.inst_state:revert("network", "lan", "_ipchanged") then + include("niu/network/warn_ip_change") +end %> +
Status:
<% diff --git a/modules/niu/luasrc/view/niu/network/warn_ip_change.htm b/modules/niu/luasrc/view/niu/network/warn_ip_change.htm new file mode 100644 index 000000000..b5ebdd73c --- /dev/null +++ b/modules/niu/luasrc/view/niu/network/warn_ip_change.htm @@ -0,0 +1,2 @@ +Warning!
+Device IP has changed.
\ No newline at end of file diff --git a/modules/niu/luasrc/view/niu/system/backup.htm b/modules/niu/luasrc/view/niu/system/backup.htm new file mode 100644 index 000000000..7e8c72823 --- /dev/null +++ b/modules/niu/luasrc/view/niu/system/backup.htm @@ -0,0 +1,41 @@ +<%# +LuCI - Lua Configuration Interface +Copyright 2008 Steven Barth +Copyright 2008 Jo-Philipp Wich + +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 + +$Id$ + +-%> +<%+header%> +

<%:System%>

+

<%:Backup / Restore%>

+

<%:Here you can backup and restore your router configuration and - if possible - reset the router to the default settings.%>

+
+
+ +
+ +
+ +
+
<%:Backup Archive%>:
+
+ +
+
+ + +
+ +<%+footer%> \ No newline at end of file diff --git a/modules/niu/luasrc/view/niu/system/reboot.htm b/modules/niu/luasrc/view/niu/system/reboot.htm new file mode 100644 index 000000000..4b356d61e --- /dev/null +++ b/modules/niu/luasrc/view/niu/system/reboot.htm @@ -0,0 +1,14 @@ +Rebooting. Please wait... + + \ No newline at end of file diff --git a/modules/niu/luasrc/view/niu/system/upgrade.htm b/modules/niu/luasrc/view/niu/system/upgrade.htm new file mode 100644 index 000000000..1083a1618 --- /dev/null +++ b/modules/niu/luasrc/view/niu/system/upgrade.htm @@ -0,0 +1,105 @@ +<%# +LuCI - Lua Configuration Interface +Copyright 2008 Steven Barth +Copyright 2008-2009 Jo-Philipp Wich + +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 + +$Id$ + +-%> + +<%+header%> + +

<%:System%>

+

<%:Flash Firmware%>

+ +<% if step == 1 then %> + <% if supported then %> +
+

+ <%:Upload an OpenWrt image file to reflash the device.%> + <% if bad_image then %> +

+

<%:The uploaded image file does not + contain a supported format. Make sure that you choose the generic + image format for your platform. %>
+ <% end %> +

+
+ <%:Firmware image%>:
+ + +
+
+ <% if keepavail then -%> + + <%:Keep configuration files%> + <% end -%> + +
+ +
+ + <% else %> +
<%_ Sorry. + OpenWrt does not support a system upgrade on this platform.
+ You need to manually flash your device. %>
+ <% end %> +<% elseif step == 2 then %> +

+ <%_ The flash image was uploaded. + Below is the checksum and file size listed, + compare them with the original file to ensure data integrity.
+ Click "Proceed" below to start the flash procedure. %> + + <% if flashsize > 0 and filesize > flashsize then %> +

+

<%:It appears that you try to + flash an image that does not fit into the flash memory, please verify + the image file! %>
+ <% end %> + +
+
    +
  • <%:Checksum%>: <%=checksum%>
  • +
  • <%:Size%>: <% + local w = require "luci.tools.webadmin" + write(w.byte_format(filesize)) + + if flashsize > 0 then + write(luci.i18n.translatef( + " (%s available)", + w.byte_format(flashsize) + )) + end + %>
  • +
+

+
+
+ + " /> + + +
+ + " /> + + +
+<% elseif step == 3 then %> +

<%_ The system is flashing now.
+ DO NOT POWER OFF THE DEVICE!
+ Wait a few minutes until you try to reconnect. + It might be necessary to renew the address of your computer to reach the device + again, depending on your settings. %>

+ + +<% end %> +<%+footer%> + -- 2.11.0