modules/admin-full: rework system menu area

This commit is contained in:
Jo-Philipp Wich 2011-10-24 01:10:34 +00:00
parent eb6e37ebb7
commit 6245ad6a73
11 changed files with 567 additions and 368 deletions

View file

@ -18,6 +18,8 @@ module("luci.controller.admin.system", package.seeall)
function index() function index()
entry({"admin", "system"}, alias("admin", "system", "system"), _("System"), 30).index = true entry({"admin", "system"}, alias("admin", "system", "system"), _("System"), 30).index = true
entry({"admin", "system", "system"}, cbi("admin_system/system"), _("System"), 1) entry({"admin", "system", "system"}, cbi("admin_system/system"), _("System"), 1)
entry({"admin", "system", "clock_status"}, call("action_clock_status"))
entry({"admin", "system", "admin"}, cbi("admin_system/admin"), _("Administration"), 2) entry({"admin", "system", "admin"}, cbi("admin_system/admin"), _("Administration"), 2)
if nixio.fs.access("/bin/opkg") then if nixio.fs.access("/bin/opkg") then
@ -37,11 +39,30 @@ function index()
entry({"admin", "system", "leds"}, cbi("admin_system/leds"), _("<abbr title=\"Light Emitting Diode\">LED</abbr> Configuration"), 60) entry({"admin", "system", "leds"}, cbi("admin_system/leds"), _("<abbr title=\"Light Emitting Diode\">LED</abbr> Configuration"), 60)
end end
entry({"admin", "system", "backup"}, call("action_backup"), _("Backup / Restore"), 70) entry({"admin", "system", "flashops"}, call("action_flashops"), _("Backup / Flash Firmware"), 70)
entry({"admin", "system", "upgrade"}, call("action_upgrade"), _("Flash Firmware"), 80) entry({"admin", "system", "flashops", "backupfiles"}, form("admin_system/backupfiles"))
entry({"admin", "system", "reboot"}, call("action_reboot"), _("Reboot"), 90) entry({"admin", "system", "reboot"}, call("action_reboot"), _("Reboot"), 90)
end end
function action_clock_status()
local set = tonumber(luci.http.formvalue("set"))
if set ~= nil and set > 0 then
local date = os.date("*t", set)
if date then
-- prevent session timeoutby updating mtime
nixio.fs.utimes(luci.sauth.sessionpath .. "/" .. luci.dispatcher.context.authsession, set, set)
luci.sys.call("date -s '%04d-%02d-%02d %02d:%02d:%02d'" %{
date.year, date.month, date.day, date.hour, date.min, date.sec
})
end
end
luci.http.prepare_content("application/json")
luci.http.write_json({ timestring = os.date("%c") })
end
function action_packages() function action_packages()
local ipkg = require("luci.model.ipkg") local ipkg = require("luci.model.ipkg")
local submit = luci.http.formvalue("submit") local submit = luci.http.formvalue("submit")
@ -120,6 +141,22 @@ function action_packages()
end end
-- List state
local no_lists = true
local old_lists = false
local tmp = nixio.fs.dir("/var/opkg-lists/")
if tmp then
for tmp in tmp do
no_lists = false
tmp = nixio.fs.stat("/var/opkg-lists/"..tmp)
if tmp and tmp.mtime < (os.time() - (24 * 60 * 60)) then
old_lists = true
break
end
end
end
luci.template.render("admin_system/packages", { luci.template.render("admin_system/packages", {
display = display, display = display,
letter = letter, letter = letter,
@ -128,6 +165,8 @@ function action_packages()
remove = remove, remove = remove,
update = update, update = update,
upgrade = upgrade, upgrade = upgrade,
no_lists = no_lists,
old_lists = old_lists,
stdout = table.concat(stdout, ""), stdout = table.concat(stdout, ""),
stderr = table.concat(stderr, "") stderr = table.concat(stderr, "")
}) })
@ -138,45 +177,83 @@ function action_packages()
end end
end end
function action_backup() function action_flashops()
local sys = require "luci.sys" local sys = require "luci.sys"
local fs = require "luci.fs" local fs = require "luci.fs"
local upgrade_avail = nixio.fs.access("/lib/upgrade/platform.sh")
local reset_avail = os.execute([[grep '"rootfs_data"' /proc/mtd >/dev/null 2>&1]]) == 0 local reset_avail = os.execute([[grep '"rootfs_data"' /proc/mtd >/dev/null 2>&1]]) == 0
local restore_cmd = "tar -xzC/ >/dev/null 2>&1" local restore_cmd = "tar -xzC/ >/dev/null 2>&1"
local backup_cmd = "tar -czT %s 2>/dev/null" local backup_cmd = "tar -czT %s 2>/dev/null"
local image_tmp = "/tmp/firmware.img"
local restore_fpi local function image_supported()
-- XXX: yay...
return ( 0 == os.execute(
". /etc/functions.sh; " ..
"include /lib/upgrade; " ..
"platform_check_image %q >/dev/null"
% image_tmp
) )
end
local function image_checksum()
return (luci.sys.exec("md5sum %q" % image_tmp):match("^([^%s]+)"))
end
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" or n == "firmware" 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
local fp
luci.http.setfilehandler( luci.http.setfilehandler(
function(meta, chunk, eof) function(meta, chunk, eof)
if not restore_fpi then if not fp then
restore_fpi = io.popen(restore_cmd, "w") if meta and meta.name == "image" then
fp = io.open(image_tmp, "w")
else
fp = io.popen(restore_cmd, "w")
end
end end
if chunk then if chunk then
restore_fpi:write(chunk) fp:write(chunk)
end end
if eof then if eof then
restore_fpi:close() fp:close()
end end
end end
) )
local upload = luci.http.formvalue("archive") if luci.http.formvalue("backup") then
local backup = luci.http.formvalue("backup") --
local reset = reset_avail and luci.http.formvalue("reset") -- Assemble file list, generate backup
--
if upload and #upload > 0 then
luci.template.render("admin_system/applyreboot")
luci.sys.reboot()
elseif backup then
local filelist = "/tmp/luci-backup-list.%d" % os.time() local filelist = "/tmp/luci-backup-list.%d" % os.time()
sys.call( sys.call(
"( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' /etc/sysupgrade.conf " .. "( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' /etc/sysupgrade.conf " ..
"/lib/upgrade/keep.d/* 2>/dev/null) -type f 2>/dev/null; " .. "/lib/upgrade/keep.d/* 2>/dev/null) -type f 2>/dev/null; " ..
"opkg list-changed-conffiles ) | sort -u > %s" % filelist "opkg list-changed-conffiles ) | sort -u > %s" % filelist
) )
if fs.access(filelist) then if fs.access(filelist) then
local reader = ltn12_popen(backup_cmd:format(filelist)) local reader = ltn12_popen(backup_cmd:format(filelist))
luci.http.header('Content-Disposition', 'attachment; filename="backup-%s-%s.tar.gz"' % { luci.http.header('Content-Disposition', 'attachment; filename="backup-%s-%s.tar.gz"' % {
@ -185,11 +262,66 @@ function action_backup()
luci.ltn12.pump.all(reader, luci.http.write) luci.ltn12.pump.all(reader, luci.http.write)
fs.unlink(filelist) fs.unlink(filelist)
end end
elseif reset then elseif luci.http.formvalue("restore") then
--
-- Unpack received .tar.gz
--
local upload = luci.http.formvalue("archive")
if upload and #upload > 0 then
luci.template.render("admin_system/applyreboot") luci.template.render("admin_system/applyreboot")
luci.util.exec("mtd -r erase rootfs_data") luci.sys.reboot()
end
elseif luci.http.formvalue("image") or luci.http.formvalue("step") then
--
-- Initiate firmware flash
--
local step = tonumber(luci.http.formvalue("step") or 1)
if step == 1 then
if image_supported() then
luci.template.render("admin_system/upgrade", {
checksum = image_checksum(),
storage = storage_size(),
size = nixio.fs.stat(image_tmp).size,
keep = (not not luci.http.formvalue("keep"))
})
else else
luci.template.render("admin_system/backup", {reset_avail = reset_avail}) nixio.fs.unlink(image_tmp)
luci.template.render("admin_system/flashops", {
reset_avail = reset_avail,
upgrade_avail = upgrade_avail,
image_invalid = true
})
end
--
-- Start sysupgrade flash
--
elseif step == 2 then
local keep = (luci.http.formvalue("keep") == "1") and "" or "-n"
luci.template.render("admin_system/applyreboot", {
title = luci.i18n.translate("Flashing..."),
msg = luci.i18n.translate("The system is flashing now.<br /> DO NOT POWER OFF THE DEVICE!<br /> 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."),
addr = (#keep > 0) and "192.168.1.1" or nil
})
fork_exec("killall dropbear uhttpd; sleep 1; /sbin/sysupgrade %s %q" %{ keep, image_tmp })
end
elseif reset_avail and luci.http.formvalue("reset") then
--
-- Reset system
--
luci.template.render("admin_system/applyreboot", {
title = luci.i18n.translate("Erasing..."),
msg = luci.i18n.translate("The system is erasing the configuration partition now and will reboot itself when finished."),
addr = "192.168.1.1"
})
fork_exec("killall dropbear uhttpd; sleep 1; mtd -r erase rootfs_data")
else
--
-- Overview
--
luci.template.render("admin_system/flashops", {
reset_avail = reset_avail,
upgrade_avail = upgrade_avail
})
end end
end end
@ -217,130 +349,27 @@ function action_reboot()
end end
end end
function action_upgrade() function fork_exec(command)
require("luci.model.uci") local pid = nixio.fork()
if pid > 0 then
return
elseif pid == 0 then
-- change to root dir
nixio.chdir("/")
local tmpfile = "/tmp/firmware.img" -- patch stdin, out, err to /dev/null
local null = nixio.open("/dev/null", "w+")
local function image_supported() if null then
-- XXX: yay... nixio.dup(null, nixio.stderr)
return ( 0 == os.execute( nixio.dup(null, nixio.stdout)
". /etc/functions.sh; " .. nixio.dup(null, nixio.stdin)
"include /lib/upgrade; " .. if null:fileno() > 2 then
"platform_check_image %q >/dev/null" null:close()
% tmpfile
) )
end
local function image_checksum()
return (luci.sys.exec("md5sum %q" % tmpfile):match("^([^%s]+)"))
end
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
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
-- replace with target command
-- Install upload handler nixio.exec("/bin/sh", "-c", command)
local file
luci.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(luci.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 = luci.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
luci.http.prepare_content("text/plain")
luci.http.write("Starting sysupgrade...\n")
io.flush()
-- Now invoke sysupgrade
local keepcfg = keep_avail and luci.http.formvalue("keepcfg") == "1"
local flash = ltn12_popen("/sbin/sysupgrade %s %q" %{
keepcfg and "" or "-n", tmpfile
})
luci.ltn12.pump.all(flash, luci.http.write)
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
luci.template.render("admin_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
luci.template.render("admin_system/upgrade", {
step=2,
checksum=image_checksum(),
filesize=nixio.fs.stat(tmpfile).size,
flashsize=storage_size(),
keepconfig=(keep_avail and luci.http.formvalue("keepcfg") == "1")
} )
-- Step 3: load iframe which calls the actual flash procedure
elseif step == 3 then
luci.template.render("admin_system/upgrade", {
step=3,
keepconfig=(keep_avail and luci.http.formvalue("keepcfg") == "1")
} )
end end
end end

View file

@ -0,0 +1,92 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2011 Jo-Philipp Wich <xm@subsignal.org>
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$
]]--
if luci.http.formvalue("cbid.luci.1._list") then
luci.http.redirect(luci.dispatcher.build_url("admin/system/flashops/backupfiles") .. "?display=list")
elseif luci.http.formvalue("cbid.luci.1._edit") then
luci.http.redirect(luci.dispatcher.build_url("admin/system/flashops/backupfiles") .. "?display=edit")
return
end
m = SimpleForm("luci", "%s - %s - %s" %{ translate("System"), translate("Flash operations"), translate("Backup file list") })
m:append(Template("admin_system/backupfiles"))
if luci.http.formvalue("display") ~= "list" then
f = m:section(SimpleSection, nil, translate("This is a list of shell glob patterns for matching files and directories to include during sysupgrade. Modified files in /etc/config/ and certain other configurations are automatically preserved."))
l = f:option(Button, "_list", translate("Show current backup file list"))
l.inputtitle = translate("Open list...")
l.inputstyle = "apply"
c = f:option(TextValue, "_custom")
c.rmempty = false
c.cols = 70
c.rows = 30
c.cfgvalue = function(self, section)
return nixio.fs.readfile("/etc/sysupgrade.conf")
end
c.write = function(self, section, value)
value = value:gsub("\r\n?", "\n")
return nixio.fs.writefile("/etc/sysupgrade.conf", value)
end
else
m.submit = false
m.reset = false
f = m:section(SimpleSection, nil, translate("Below is the determined list of files to backup. It consists of changed configuration files marked by opkg, essential base files and the user defined backup patterns."))
l = f:option(Button, "_edit", translate("Back to configuration"))
l.inputtitle = translate("Close list...")
l.inputstyle = "link"
d = f:option(DummyValue, "_detected")
d.rawhtml = true
d.cfgvalue = function(s)
local list = io.popen(
"( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' /etc/sysupgrade.conf " ..
"/lib/upgrade/keep.d/* 2>/dev/null) -type f 2>/dev/null; " ..
"opkg list-changed-conffiles ) | sort -u"
)
if list then
local files = { "<ul>" }
while true do
local ln = list:read("*l")
if not ln then
break
else
files[#files+1] = "<li>"
files[#files+1] = luci.util.pcdata(ln)
files[#files+1] = "</li>"
end
end
list:close()
files[#files+1] = "</ul>"
return table.concat(files, "")
end
return "<em>" .. translate("No files found") .. "</em>"
end
end
return m

View file

@ -2,7 +2,7 @@
LuCI - Lua Configuration Interface LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org> Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net> Copyright 2008-2011 Jo-Philipp Wich <xm@subsignal.org>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -12,10 +12,13 @@ You may obtain a copy of the License at
$Id$ $Id$
]]-- ]]--
local ipkgfile = "/etc/opkg.conf" local ipkgfile = "/etc/opkg.conf"
f = SimpleForm("ipkgconf", translate("OPKG-Configuration")) f = SimpleForm("ipkgconf", translate("OPKG-Configuration"))
f:append(Template("admin_system/ipkg"))
t = f:field(TextValue, "lines") t = f:field(TextValue, "lines")
t.rows = 10 t.rows = 10
function t.cfgvalue() function t.cfgvalue()
@ -26,8 +29,6 @@ function t.write(self, section, data)
return nixio.fs.writefile(ipkgfile, data:gsub("\r\n", "\n")) return nixio.fs.writefile(ipkgfile, data:gsub("\r\n", "\n"))
end end
f:append(Template("admin_system/ipkg"))
function f.handle(self, state, data) function f.handle(self, state, data)
return true return true
end end

View file

@ -44,38 +44,13 @@ s:tab("language", translate("Language and Style"))
-- System Properties -- System Properties
-- --
local system, model, memtotal, memcached, membuffers, memfree = luci.sys.sysinfo() clock = s:taboption("general", DummyValue, "_systime", translate("Local Time"))
local uptime = luci.sys.uptime() clock.template = "admin_system/clock_status"
s:taboption("general", DummyValue, "_system", translate("System")).value = system
s:taboption("general", DummyValue, "_cpu", translate("Processor")).value = model
s:taboption("general", DummyValue, "_kernel", translate("Kernel")).value =
luci.util.exec("uname -r") or "?"
local load1, load5, load15 = luci.sys.loadavg()
s:taboption("general", DummyValue, "_la", translate("Load")).value =
string.format("%.2f, %.2f, %.2f", load1, load5, load15)
s:taboption("general", DummyValue, "_memtotal", translate("Memory")).value =
string.format("%.2f MB (%.0f%% %s, %.0f%% %s, %.0f%% %s)",
tonumber(memtotal) / 1024,
100 * memcached / memtotal,
tostring(translate("cached")),
100 * membuffers / memtotal,
tostring(translate("buffered")),
100 * memfree / memtotal,
tostring(translate("free"))
)
s:taboption("general", DummyValue, "_systime", translate("Local Time")).value =
os.date("%c")
s:taboption("general", DummyValue, "_uptime", translate("Uptime")).value =
luci.tools.webadmin.date_format(tonumber(uptime))
hn = s:taboption("general", Value, "hostname", translate("Hostname")) hn = s:taboption("general", Value, "hostname", translate("Hostname"))
hn.datatype = "hostname" hn.datatype = "hostname"
function hn.write(self, section, value) function hn.write(self, section, value)
Value.write(self, section, value) Value.write(self, section, value)
luci.sys.hostname(value) luci.sys.hostname(value)
@ -184,8 +159,8 @@ end
-- --
if has_rdate then if has_rdate then
m3= Map("timeserver", translate("Time Server (rdate)")) m2 = Map("timeserver", translate("Time Server (rdate)"))
s = m3:section(TypedSection, "timeserver") s = m2:section(TypedSection, "timeserver")
s.anonymous = true s.anonymous = true
s.addremove = true s.addremove = true
s.template = "cbi/tblsection" s.template = "cbi/tblsection"
@ -196,7 +171,7 @@ if has_rdate then
i = s:option(ListValue, "interface", translate("Interface")) i = s:option(ListValue, "interface", translate("Interface"))
i.rmempty = true i.rmempty = true
i:value("", translate("Default")) i:value("", translate("Default"))
m3.uci:foreach("network", "interface", m2.uci:foreach("network", "interface",
function (section) function (section)
local ifc = section[".name"] local ifc = section[".name"]
if ifc ~= "loopback" then if ifc ~= "loopback" then
@ -207,61 +182,4 @@ if has_rdate then
end end
m2 = Map("luci") return m, m2
f = m2:section(NamedSection, "main", "core", translate("Files to be kept when flashing a new firmware"))
f:tab("detected", translate("Detected Files"),
translate("The following files are detected by the system and will be kept automatically during sysupgrade"))
f:tab("custom", translate("Custom Files"),
translate("This is a list of shell glob patterns for matching files and directories to include during sysupgrade"))
d = f:taboption("detected", DummyValue, "_detected", translate("Detected files"))
d.rawhtml = true
d.cfgvalue = function(s)
local list = io.popen(
"( find $(sed -ne '/^[[:space:]]*$/d; /^#/d; p' /etc/sysupgrade.conf " ..
"/lib/upgrade/keep.d/* 2>/dev/null) -type f 2>/dev/null; " ..
"opkg list-changed-conffiles ) | sort -u"
)
if list then
local files = { "<ul>" }
while true do
local ln = list:read("*l")
if not ln then
break
else
files[#files+1] = "<li>"
files[#files+1] = luci.util.pcdata(ln)
files[#files+1] = "</li>"
end
end
list:close()
files[#files+1] = "</ul>"
return table.concat(files, "")
end
return "<em>" .. translate("No files found") .. "</em>"
end
c = f:taboption("custom", TextValue, "_custom", translate("Custom files"))
c.rmempty = false
c.cols = 70
c.rows = 30
c.cfgvalue = function(self, section)
return nixio.fs.readfile("/etc/sysupgrade.conf")
end
c.write = function(self, section, value)
value = value:gsub("\r\n?", "\n")
return nixio.fs.writefile("/etc/sysupgrade.conf", value)
end
return m, m3 or m2, m3 and m2

View file

@ -12,10 +12,39 @@ You may obtain a copy of the License at
$Id$ $Id$
-%> -%>
<%+header%>
<h2><a id="content" name="content"><%:System%></a></h2> <html>
<br /> <head>
<p><% if msg then %><%=msg%><% else %><%:Changes applied.%><% end %></p> <title><%=luci.sys.hostname()%> - <% if title then %><%=title%><% else %><%:Rebooting...%><% end %></title>
<p><%:Please wait: Device rebooting...%></p> <link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
<script type="text/javascript">setTimeout("location='<%=controller%>'", 60000)</script> <script type="text/javascript" src="<%=resource%>/xhr.js"></script>
<%+footer%> <script type="text/javascript">//<![CDATA[
var interval = window.setInterval(function() {
var img = new Image();
img.onload = function() {
window.clearInterval(interval);
location.href = 'http://<%=addr or luci.http.getenv("SERVER_NAME")%>/';
};
img.src = 'http://<%=addr or luci.http.getenv("SERVER_NAME")%><%=resource%>/icons/loading.gif?' + Math.random();
}, 5000);
//]]></script>
</head>
<body>
<div id="maincontainer">
<div id="maincontent">
<h2><a id="content" name="content"><%:System%> - <% if title then %><%=title%><% else %><%:Rebooting...%><% end %></a></h2>
<fieldset class="cbi-section">
<p>
<% if msg then %><%=msg%><% else %><%:Changes applied.%><% end %>
</p>
<p>
<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />
<%:Waiting for router...%>
</p>
</fieldset>
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,19 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
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$
-%>
<ul class="cbi-tabmenu">
<li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/system/flashops")%>"><%:Actions%></a></li>
<li class="cbi-tab"><a href="#"><%:Configuration%></a></li>
</ul>

View file

@ -0,0 +1,36 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "system", "clock_status")%>', null,
function(x, rv)
{
var s = document.getElementById('<%=self.option%>-clock-status');
if (s)
{
s.innerHTML = rv.timestring || '?';
}
}
);
function sync_clock(btn)
{
btn.disabled = true;
btn.value = '<%:Synchronizing...%>';
XHR.get('<%=luci.dispatcher.build_url("admin", "system", "clock_status")%>',
{ set: Math.floor((new Date()).getTime() / 1000) },
function()
{
btn.disabled = false;
btn.value = '<%:Sync with browser%>';
}
);
return false;
}
//]]></script>
<span id="<%=self.option%>-clock-status"><em><%:Collecting data...%></em></span>
<input type="button" class="cbi-button cbi-button-apply" value="<%:Sync with browser%>" onclick="return sync_clock(this)" />
<%+cbi/valuefooter%>

View file

@ -0,0 +1,94 @@
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
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%>
<h2><a id="content" name="content"><%:System%> - <%:Flash operations%></a></h2>
<ul class="cbi-tabmenu">
<li class="cbi-tab"><a href="#"><%:Actions%></a></li>
<li class="cbi-tab-disabled"><a href="<%=REQUEST_URI%>/backupfiles"><%:Configuration%></a></li>
</ul>
<fieldset class="cbi-section">
<fieldset class="cbi-section">
<legend><%:Backup / Restore%></legend>
<form method="post" action="<%=REQUEST_URI%>" enctype="multipart/form-data">
<div class="cbi-section-descr"><%:Click "Generate archive" to download a tar archive of the current configuration files. To reset the firmware to its initial state, click "Perform reset" (only possible with squashfs images).%></div>
<div class="cbi-section-node">
<div class="cbi-value<% if not reset_avail then %> cbi-value-last<% end %>">
<label class="cbi-value-title" for="image"><%:Download backup%>:</label>
<div class="cbi-value-field">
<input class="cbi-button cbi-button-apply" type="submit" name="backup" value="<%:Generate archive%>" />
</div>
</div>
<% if reset_avail then %>
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title"><%:Reset to defaults%>:</label>
<div class="cbi-value-field">
<input onclick="return confirm('<%:Really reset all changes?%>')" class="cbi-button cbi-button-reset" type="submit" name="reset" value="<%:Perform reset%>" />
</div>
</div>
<% end %>
</div>
<br />
<div class="cbi-section-descr"><%:To restore configuration files, you can upload a previously generated backup archive here.%></div>
<div class="cbi-section-node">
<div class="cbi-value cbi-value-last">
<label class="cbi-value-title" for="archive"><%:Restore backup%>:</label>
<div class="cbi-value-field">
<input type="file" name="archive" id="archive" />
<input type="submit" class="cbi-button cbi-input-apply" name="restore" value="<%:Upload archive...%>" />
</div>
</div>
</div>
</form>
</fieldset>
<br />
<fieldset class="cbi-section">
<legend><%:Flash new firmware image%></legend>
<% if upgrade_avail then %>
<form method="post" action="<%=REQUEST_URI%>" enctype="multipart/form-data">
<div class="cbi-section-descr"><%:Upload a sysupgrade-compatible image here to replace the running firmware. Check "Keep settings" to retain the current configuration (requires an OpenWrt compatible firmware image).%></div>
<div class="cbi-section-node">
<div class="cbi-value">
<label class="cbi-value-title" for="keep"><%:Keep settings%>:</label>
<div class="cbi-value-field">
<input type="checkbox" name="keep" id="keep" checked="checked" />
</div>
</div>
<div class="cbi-value cbi-value-last<% if image_invalid then %> cbi-value-error<% end %>">
<label class="cbi-value-title" for="image"><%:Image%>:</label>
<div class="cbi-value-field">
<input type="file" name="image" id="image" />
<input type="submit" class="cbi-button cbi-input-apply" value="<%:Flash image...%>" />
</div>
</div>
</div>
<% if image_invalid then %>
<div class="cbi-section-error"><%:The uploaded image file does not contain a supported format. Make sure that you choose the generic image format for your platform. %></div>
<% end %>
</form>
<% else %>
<div class="cbi-section-descr"><%:Sorry, there is no sysupgrade support present, a new firmware image must be flashed manually. Please refer to the OpenWrt wiki for device specific install instructions.%></div>
<% end %>
</fieldset>
</fieldset>
<%+footer%>

View file

@ -12,7 +12,8 @@ You may obtain a copy of the License at
$Id$ $Id$
-%> -%>
<ul>
<li><strong><%:Package lists%>:</strong> <code>src <em>Name</em> <em>URL</em></code></li> <ul class="cbi-tabmenu">
<li><strong><%:Installation targets%>:</strong> <code>dest <em>Name</em> <em>Pfad</em></code></li> <li class="cbi-tab-disabled"><a href="<%=luci.dispatcher.build_url("admin/system/packages")%>"><%:Actions%></a></li>
<li class="cbi-tab"><a href="#"><%:Configuration%></a></li>
</ul> </ul>

View file

@ -53,13 +53,55 @@ end
<form method="post" action="<%=REQUEST_URI%>"> <form method="post" action="<%=REQUEST_URI%>">
<div class="cbi-map"> <div class="cbi-map">
<fieldset class="cbi-section">
<ul> <ul class="cbi-tabmenu">
<li><a href="<%=REQUEST_URI%>/ipkg"><%:Edit package lists and installation targets%></a></li> <li class="cbi-tab"><a href="#"><%:Actions%></a></li>
<li><a href="<%=REQUEST_URI%>?update=1"><%:Update package lists%></a></li> <li class="cbi-tab-disabled"><a href="<%=REQUEST_URI%>/ipkg"><%:Configuration%></a></li>
</ul> </ul>
<br />
<fieldset class="cbi-section">
<fieldset class="cbi-section-node"> <fieldset class="cbi-section-node">
<% if (install and next(install)) or (remove and next(remove)) or update or upgrade then %>
<div class="cbi-value">
<% if #stdout > 0 then %><pre><%=pcdata(stdout)%></pre><% end %>
<% if #stderr > 0 then %><pre class="error"><%=pcdata(stderr)%></pre><% end %>
</div>
<% end %>
<% if querypat then %>
<div class="cbi-value">
<%:Displaying only packages containing%> <strong>"<%=pcdata(query)%>"</strong>
<input type="button" onclick="location.href='?display=<%=pcdata(display)%>'" href="#" class="cbi-button cbi-button-reset" style="margin-left:1em" value="<%:Reset%>" />
<br style="clear:both" />
</div>
<% end %>
<% if no_lists or old_lists then %>
<div class="cbi-value">
<% if old_lists then %>
<%:Package lists are older than 24 hours%>
<% else %>
<%:No package lists available%>
<% end %>
<input type="button" onclick="location.href='?update=1'" href="#" class="cbi-button cbi-button-apply" style="margin-left:3em" value="<%:Update lists%>" />
</div>
<% end %>
<div class="cbi-value cbi-value-last">
<%:Free space%>: <strong><%=(100-used_perc)%>%</strong> (<strong><%=wa.byte_format(free_byte)%></strong>)
<div style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080">
<div style="background-color:#F08080; border-right:1px solid #000000; height:100%; width:<%=used_perc%>%">&#160;</div>
</div>
</div>
</fieldset>
<br />
<fieldset class="cbi-section-node">
<input type="hidden" name="display" value="<%=pcdata(display)%>" />
<div class="cbi-value"> <div class="cbi-value">
<label class="cbi-value-title"><%:Download and install package%>:</label> <label class="cbi-value-title"><%:Download and install package%>:</label>
<div class="cbi-value-field"> <div class="cbi-value-field">
@ -71,7 +113,6 @@ end
<div class="cbi-value cbi-value-last"> <div class="cbi-value cbi-value-last">
<label class="cbi-value-title"><%:Filter%>:</label> <label class="cbi-value-title"><%:Filter%>:</label>
<div class="cbi-value-field"> <div class="cbi-value-field">
<input type="hidden" name="display" value="<%=pcdata(display)%>" />
<input type="text" name="query" size="20" value="<%=pcdata(query)%>" /> <input type="text" name="query" size="20" value="<%=pcdata(query)%>" />
<input type="submit" class="cbi-button cbi-input-find" name="search" value="<%:Find package%>" /> <input type="submit" class="cbi-button cbi-input-find" name="search" value="<%:Find package%>" />
</div> </div>
@ -81,25 +122,7 @@ end
<br /> <br />
<h3><%:Status%></h3> <h3><%:Status%></h3>
<fieldset class="cbi-section">
<%:Free space%>: <strong><%=(100-used_perc)%>%</strong> (<strong><%=wa.byte_format(free_byte)%></strong>)
<div style="margin:3px 0; width:300px; height:10px; border:1px solid #000000; background-color:#80C080">
<div style="background-color:#F08080; border-right:1px solid #000000; height:100%; width:<%=used_perc%>%">&#160;</div>
</div>
<% if querypat then %>
<br /><hr /><br />
<%:Displaying only packages containing%> <strong>"<%=pcdata(query)%>"</strong>
<input type="button" onclick="location.href='?display=<%=pcdata(display)%>'" href="#" class="cbi-button cbi-button-reset" style="margin-left:3em" value="Reset" />
<% end %>
<% if (install and next(install)) or (remove and next(remove)) or update or upgrade then %>
<br /><hr /><br />
<% if #stdout > 0 then %><pre><%=pcdata(stdout)%></pre><% end %>
<% if #stderr > 0 then %><pre class="error"><%=pcdata(stderr)%></pre><% end %>
<% end %>
</fieldset>
<br />
<ul class="cbi-tabmenu"> <ul class="cbi-tabmenu">
<li class="cbi-tab<% if display ~= "installed" then %>-disabled<% end %>"><a href="?display=installed&amp;query=<%=pcdata(query)%>"><%:Installed packages%><% if query then %> (<%=pcdata(query)%>)<% end %></a></li> <li class="cbi-tab<% if display ~= "installed" then %>-disabled<% end %>"><a href="?display=installed&amp;query=<%=pcdata(query)%>"><%:Installed packages%><% if query then %> (<%=pcdata(query)%>)<% end %></a></li>

View file

@ -15,96 +15,53 @@ $Id$
<%+header%> <%+header%>
<h2><a id="content" name="content"><%:System%></a></h2> <h2><a id="content" name="content"><%:System%> - <%:Flash Firmware%> - <%:Verify%></a></h2>
<h3><%:Flash Firmware%></h3>
<% if step == 1 then %>
<% if supported then %>
<form method="post" action="<%=REQUEST_URI%>" enctype="multipart/form-data">
<p>
<%:Upload an OpenWrt image file to reflash the device.%>
<% if bad_image then %>
<br /><br />
<div class="error"><%:The uploaded image file does not
contain a supported format. Make sure that you choose the generic
image format for your platform. %></div>
<% end %>
</p>
<div>
<%:Firmware image%>:<br />
<input type="hidden" name="step" value="2" />
<input type="file" size="30" name="image" />
<br />
<br />
<% if keepavail then -%>
<input type="checkbox" name="keepcfg" value="1" checked="checked" />
<span class="bold"><%:Keep configuration files%></span>
<% end -%>
<br />
<input class="cbi-button cbi-button-apply" type="submit" value="<%:Upload image%>" />
</div>
</form>
<% else %>
<div class="error"><%_ Sorry.
OpenWrt does not support a system upgrade on this platform.<br />
You need to manually flash your device. %></div>
<% end %>
<% elseif step == 2 then %>
<p> <p>
<%_ The flash image was uploaded. <%_ The flash image was uploaded.
Below is the checksum and file size listed, Below is the checksum and file size listed,
compare them with the original file to ensure data integrity.<br /> compare them with the original file to ensure data integrity.<br />
Click "Proceed" below to start the flash procedure. %> Click "Proceed" below to start the flash procedure. %>
<% if flashsize > 0 and filesize > flashsize then %> <% if storage > 0 and size > storage then %>
<br /><br /> <br /><br />
<div class="error"><%:It appears that you try to <div class="error"><%:It appears that you try to
flash an image that does not fit into the flash memory, please verify flash an image that does not fit into the flash memory, please verify
the image file! %></div> the image file! %></div>
<% end %> <% end %>
<br /> </p>
<fieldset class="cbi-section">
<ul> <ul>
<li><%:Checksum%>: <code><%=checksum%></code></li> <li><%:Checksum%>: <code><%=checksum%></code></li>
<li><%:Size%>: <% <li><%:Size%>: <%
local w = require "luci.tools.webadmin" local w = require "luci.tools.webadmin"
write(w.byte_format(filesize)) write(w.byte_format(size))
if flashsize > 0 then if storage > 0 then
write(luci.i18n.translatef( write(luci.i18n.translatef(
" (%s available)", " (%s available)",
w.byte_format(flashsize) w.byte_format(storage)
)) ))
end end
%></li> %></li>
<li><% if keepconfig then %> <li><% if keep then %>
<%:Configuration files will be kept.%> <%:Configuration files will be kept.%>
<% else %> <% else %>
<%:Note: Configuration files will be erased.%> <%:Note: Configuration files will be erased.%>
<% end %></li> <% end %></li>
</ul> </ul>
</p> </fieldset>
<div class="cbi-page-actions right"> <div class="cbi-page-actions right">
<form style="display:inline"> <form style="display:inline" action="<%=REQUEST_URI%>" method="post">
<input type="hidden" name="step" value="3" /> <input type="hidden" name="step" value="2" />
<input type="hidden" name="keepcfg" value="<%=keepconfig and "1" or "0"%>" /> <input type="hidden" name="keep" value="<%=keep and "1" or ""%>" />
<input class="cbi-button cbi-button-apply" type="submit" value="<%:Proceed%>" /> <input class="cbi-button cbi-button-apply" type="submit" value="<%:Proceed%>" />
</form> </form>
<form style="display:inline"> <form style="display:inline" action="<%=REQUEST_URI%>" method="post">
<input type="hidden" name="step" value="1" />
<input type="hidden" name="keepcfg" value="<%=keepconfig and "1" or "0"%>" />
<input class="cbi-button cbi-button-reset" type="submit" value="<%:Cancel%>" /> <input class="cbi-button cbi-button-reset" type="submit" value="<%:Cancel%>" />
</form> </form>
</div> </div>
<% elseif step == 3 then %>
<p><%_ The system is flashing now.<br />
DO NOT POWER OFF THE DEVICE!<br />
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. %></p>
<iframe src="<%=REQUEST_URI%>?step=4&#38;keepcfg=<%=keepconfig and "1" or "0"%>" style="border:1px solid black; width:100%; height:150px"></iframe>
<% end %>
<%+footer%> <%+footer%>