luci-app-advanced-reboot: show OpenWrt info on compatible NAND routers

Signed-off-by: Stan Grishin <stangri@melmac.net>
This commit is contained in:
Stan Grishin 2019-11-15 16:41:58 -07:00
parent 7fd017d83d
commit 5589dba07a
6 changed files with 339 additions and 255 deletions

View file

@ -3,7 +3,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_LICENSE:=GPL-3.0+ PKG_LICENSE:=GPL-3.0-or-later
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net> PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net>
LUCI_TITLE:=Advanced Linksys Reboot Web UI LUCI_TITLE:=Advanced Linksys Reboot Web UI
@ -11,9 +11,9 @@ LUCI_DESCRIPTION:=Provides Web UI (found under System/Advanced Reboot) to reboot
an alternative partition. Also provides Web UI to shut down (power off) your device. Supported dual-partition\ an alternative partition. Also provides Web UI to shut down (power off) your device. Supported dual-partition\
routers are listed at https://github.com/openwrt/luci/blob/master/applications/luci-app-advanced-reboot/README.md routers are listed at https://github.com/openwrt/luci/blob/master/applications/luci-app-advanced-reboot/README.md
LUCI_DEPENDS:=+luci-mod-admin-full LUCI_DEPENDS:=+luci-compat +luci-mod-admin-full
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
PKG_RELEASE:=42 PKG_RELEASE:=43
include ../../luci.mk include ../../luci.mk

View file

@ -22,11 +22,11 @@ Currently supported dual-partition devices include:
- Linksys WRT32X - Linksys WRT32X
- ZyXEL NBG6817 - ZyXEL NBG6817
If you're interested in having your device supported, please post in [OpenWrt Forum Support Thread](https://forum.openwrt.org/t/web-ui-to-reboot-to-another-partition-dual-partition-routers/3423). If your device is not in the list above, however it is a [dual-firmware device](https://openwrt.org/tag/dual_firmware?do=showtag&tag=dual_firmware) and you're interested in having your device supported, please post in [OpenWrt Forum Support Thread](https://forum.openwrt.org/t/web-ui-to-reboot-to-another-partition-dual-partition-routers/3423).
## Screenshot (luci-app-advanced-reboot) ## Screenshot (luci-app-advanced-reboot)
![screenshot](https://raw.githubusercontent.com/stangri/openwrt_packages/master/screenshots/luci-app-advanced-reboot/screenshot01.png "screenshot") ![screenshot](https://raw.githubusercontent.com/stangri/openwrt_packages/master/screenshots/luci-app-advanced-reboot/screenshot02.png "screenshot")
## How to install ## How to install

View file

@ -3,203 +3,282 @@
module("luci.controller.advanced_reboot", package.seeall) module("luci.controller.advanced_reboot", package.seeall)
local util = require "luci.util"
local fs = require "nixio.fs"
local sys = require "luci.sys"
local http = require "luci.http"
local dispatcher = require "luci.dispatcher"
local i18n = require "luci.i18n"
local ltemplate = require "luci.template"
local ip = require "luci.ip"
local http = require "luci.http"
local sys = require "luci.sys"
local dispatcher = require "luci.dispatcher"
local uci = require "luci.model.uci".cursor()
function is_alt_mountable(p1_mtd, p2_mtd)
if p1_mtd:sub(1,3) == "mtd" and
p2_mtd:sub(1,3) == "mtd" and
fs.access("/usr/sbin/ubiattach") and
fs.access("/usr/sbin/ubiblock") and
fs.access("/bin/mount") then
return true
else
return false
end
end
function get_partition_os_info(op_ubi)
local cp_info, ap_info
if fs.access("/etc/os-release") then
cp_info = util.trim(util.exec('. /etc/os-release && echo "$PRETTY_NAME"'))
end
alt_partition_unmount(op_ubi)
alt_partition_mount(op_ubi)
if fs.access("/alt/rom/etc/os-release") then
ap_info = util.trim(util.exec('. /alt/rom/etc/os-release && echo "$PRETTY_NAME"'))
end
alt_partition_unmount(op_ubi)
return cp_info, ap_info
end
function alt_partition_mount(op_ubi)
local ubi_dev
util.exec('for i in rom overlay firmware; do [ ! -d "$i" ] && mkdir -p "/alt/${i}"; done')
util.exec("ubidetach -m " .. tostring(op_ubi))
ubi_dev = tostring(util.exec("ubiattach -m " .. tostring(op_ubi)))
_, _, ubi_dev = ubi_dev:find("UBI device number (%d+)")
if not ubi_dev then
util.exec("ubidetach -m " .. tostring(op_ubi))
return
end
util.exec("ubiblock --create /dev/ubi" .. ubi_dev .. "_0")
util.exec("mount -t squashfs -o ro /dev/ubiblock" .. ubi_dev .. "_0 /alt/rom")
util.exec("mount -t ubifs /dev/ubi1_" .. ubi_dev .. " /alt/overlay")
util.exec("mount -t overlay overlay -o noatime,lowerdir=/alt/rom,upperdir=/alt/overlay/upper,workdir=/alt/overlay/work /alt/firmware")
end
function alt_partition_unmount(op_ubi)
util.exec("umount /alt/firmware")
util.exec("umount /alt/overlay")
util.exec("umount /alt/rom")
util.exec("ubiblock --remove /dev/ubi1_0")
util.exec("ubidetach -m " .. tostring(op_ubi))
util.exec('rm -rf /alt')
end
devices = { devices = {
-- deviceName, boardName, partition1, partition2, offset, envVar1, envVar1Value1, envVar1Value2, envVar2, envVar2Value1, envVar2Value2 -- deviceName, boardName, part1MTD, part2MTD, offset, envVar1, envVar1Value1, envVar1Value2, envVar2, envVar2Value1, envVar2Value2
{"Linksys EA3500", "linksys-audi", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, {"Linksys EA3500", "linksys-audi", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys E4200v2/EA4500", "linksys-viper", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, {"Linksys E4200v2/EA4500", "linksys-viper", "mtd3", "mtd5", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys EA6350v3", "linksys-ea6350v3", "mtd10", "mtd12", 192, "boot_part", 1, 2}, {"Linksys EA6350v3", "linksys-ea6350v3", "mtd10", "mtd12", 192, "boot_part", 1, 2},
{"Linksys EA8300", "linksys-ea8300", "mtd10", "mtd12", 192, "boot_part", 1, 2}, {"Linksys EA8300", "linksys-ea8300", "mtd10", "mtd12", 192, "boot_part", 1, 2},
{"Linksys EA8500", "ea8500", "mtd13", "mtd15", 32, "boot_part", 1, 2}, {"Linksys EA8500", "ea8500", "mtd13", "mtd15", 32, "boot_part", 1, 2},
-- {"Linksys EA9500", "linksys-panamera", "mtd3", "mtd6", 28, "boot_part", 1, 2}, -- {"Linksys EA9500", "linksys-panamera", "mtd3", "mtd6", 28, "boot_part", 1, 2},
{"Linksys WRT1200AC", "linksys-caiman", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, {"Linksys WRT1200AC", "linksys-caiman", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys WRT1900AC", "linksys-mamba", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, {"Linksys WRT1900AC", "linksys-mamba", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys WRT1900ACv2", "linksys-cobra", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, {"Linksys WRT1900ACv2", "linksys-cobra", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys WRT1900ACS", "linksys-shelby", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, {"Linksys WRT1900ACS", "linksys-shelby", "mtd4", "mtd6", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys WRT3200ACM", "linksys-rango", "mtd5", "mtd7", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, {"Linksys WRT3200ACM", "linksys-rango", "mtd5", "mtd7", 32, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"Linksys WRT32X", "linksys-venom", "mtd5", "mtd7", nil, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"}, {"Linksys WRT32X", "linksys-venom", "mtd5", "mtd7", nil, "boot_part", 1, 2, "bootcmd", "run nandboot", "run altnandboot"},
{"ZyXEL NBG6817","nbg6817","mmcblk0p4","mmcblk0p7", 32, nil, 255, 1} {"ZyXEL NBG6817", "nbg6817", "mmcblk0p4", "mmcblk0p7", 32, nil, 255, 1}
} }
errorMessage = nil -- local errorMessage, d
rom_board_name = luci.util.trim(luci.sys.exec("cat /tmp/sysinfo/board_name")) -- local device_name, p1_mtd, p2_mtd, offset, bev1, bev1p1, bev1p2, bev2, bev2p1, bev2p2
for i=1, #devices do romBoardName = util.trim(util.exec("cat /tmp/sysinfo/board_name"))
device_board_name = devices[i][2]:gsub('%p','')
if rom_board_name and rom_board_name:gsub('%p',''):match(device_board_name) then
device_name = devices[i][1]
partition_one_mtd = devices[i][3] or nil
partition_two_mtd = devices[i][4] or nil
partition_skip = devices[i][5] or nil
boot_envvar1 = devices[i][6] or nil
boot_envvar1_partition_one = tonumber(devices[i][7]) or nil
boot_envvar1_partition_two = tonumber(devices[i][8]) or nil
boot_envvar2 = devices[i][9] or nil
boot_envvar2_partition_one = devices[i][10] or nil
boot_envvar2_partition_two = devices[i][11] or nil
if partition_one_mtd and partition_skip then
partition_one_label = luci.util.trim(luci.sys.exec("dd if=/dev/" .. partition_one_mtd .. " bs=1 skip=" .. partition_skip .. " count=128" .. " 2>/dev/null"))
n, partition_one_version = string.match(partition_one_label, '(Linux)-([%d|.]+)')
end
if partition_two_mtd and partition_skip then
partition_two_label = luci.util.trim(luci.sys.exec("dd if=/dev/" .. partition_two_mtd .. " bs=1 skip=" .. partition_skip .. " count=128" .. " 2>/dev/null"))
n, partition_two_version = string.match(partition_two_label, '(Linux)-([%d|.]+)')
end
if partition_one_label and string.find(partition_one_label, "LEDE") then partition_one_os = "LEDE" end
if partition_one_label and string.find(partition_one_label, "OpenWrt") then partition_one_os = "OpenWrt" end
if partition_one_label and string.find(partition_one_label, "Linksys") then partition_one_os = "Linksys" end
if partition_two_label and string.find(partition_two_label, "LEDE") then partition_two_os = "LEDE" end
if partition_two_label and string.find(partition_two_label, "OpenWrt") then partition_two_os = "OpenWrt" end
if partition_two_label and string.find(partition_two_label, "Linksys") then partition_two_os = "Linksys" end
if device_name and device_name == "ZyXEL NBG6817" then
if not partition_one_os then partition_one_os = "ZyXEL" end
if not partition_two_os then partition_two_os = "ZyXEL" end
end
if device_name and device_name == "Linksys WRT32X" then
if not partition_one_os then partition_one_os = "Unknown/Compressed" end
if not partition_two_os then partition_two_os = "Unknown/Compressed" end
end
if not partition_one_os then partition_one_os = "Unknown" end
if not partition_two_os then partition_two_os = "Unknown" end
if partition_one_os and partition_one_version then partition_one_os = partition_one_os .. " (Linux " .. partition_one_version .. ")" end
if partition_two_os and partition_two_version then partition_two_os = partition_two_os .. " (Linux " .. partition_two_version .. ")" end
if device_name and device_name == "ZyXEL NBG6817" then for i=1, #devices do
if not zyxelFlagPartition then zyxelFlagPartition = luci.util.trim(luci.sys.exec("source /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end d = devices[i][2]:gsub('%p','')
if not zyxelFlagPartition then if romBoardName and romBoardName:gsub('%p',''):match(d) then
errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to find Dual Boot Flag Partition." .. " ") device_name = devices[i][1]
luci.util.perror(luci.i18n.translate("Unable to find Dual Boot Flag Partition.")) p1_mtd = devices[i][3] or nil
else p2_mtd = devices[i][4] or nil
current_partition = tonumber(luci.sys.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'")) offset = devices[i][5] or nil
end bev1 = devices[i][6] or nil
else bev1p1 = tonumber(devices[i][7]) or nil
if nixio.fs.access("/usr/sbin/fw_printenv") and nixio.fs.access("/usr/sbin/fw_setenv") then bev1p2 = tonumber(devices[i][8]) or nil
current_partition = tonumber(luci.util.trim(luci.sys.exec("/usr/sbin/fw_printenv -n " .. boot_envvar1))) bev2 = devices[i][9] or nil
end bev2p1 = devices[i][10] or nil
end bev2p2 = devices[i][11] or nil
other_partition = current_partition == boot_envvar1_partition_two and boot_envvar1_partition_one or boot_envvar1_partition_two if p1_mtd and offset then
end p1_label = util.trim(util.exec("dd if=/dev/" .. p1_mtd .. " bs=1 skip=" .. offset .. " count=128" .. " 2>/dev/null"))
n, p1_version = p1_label:match('(Linux)-([%d|.]+)')
end
if p2_mtd and offset then
p2_label = util.trim(util.exec("dd if=/dev/" .. p2_mtd .. " bs=1 skip=" .. offset .. " count=128" .. " 2>/dev/null"))
n, p2_version = p2_label:match('(Linux)-([%d|.]+)')
end
if p1_label and p1_label:find("LEDE") then p1_os = "LEDE" end
if p1_label and p1_label:find("OpenWrt") then p1_os = "OpenWrt" end
if p1_label and p1_label:find("Linksys") then p1_os = "Linksys" end
if p2_label and p2_label:find("LEDE") then p2_os = "LEDE" end
if p2_label and p2_label:find("OpenWrt") then p2_os = "OpenWrt" end
if p2_label and p2_label:find("Linksys") then p2_os = "Linksys" end
if device_name == "ZyXEL NBG6817" then
if not p1_os then p1_os = "ZyXEL" end
if not p2_os then p2_os = "ZyXEL" end
end
if device_name == "Linksys WRT32X" then
if not p1_os then p1_os = "Unknown/Compressed" end
if not p2_os then p2_os = "Unknown/Compressed" end
end
if not p1_os then p1_os = "Unknown" end
if not p2_os then p2_os = "Unknown" end
if p1_os and p1_version then p1_os = p1_os .. " (Linux " .. p1_version .. ")" end
if p2_os and p2_version then p2_os = p2_os .. " (Linux " .. p2_version .. ")" end
if device_name == "ZyXEL NBG6817" then
if not zyxelFlagPartition then zyxelFlagPartition = util.trim(util.exec(". /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end
if not zyxelFlagPartition then
errorMessage = errorMessage or "" .. i18n.translate("Unable to find Dual Boot Flag Partition." .. " ")
util.perror(i18n.translate("Unable to find Dual Boot Flag Partition."))
else
current_partition = tonumber(util.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'"))
end
else
if fs.access("/usr/sbin/fw_printenv") and fs.access("/usr/sbin/fw_setenv") then
current_partition = tonumber(util.trim(util.exec("fw_printenv -n " .. bev1)))
end
end
other_partition = current_partition == bev1p2 and bev1p1 or bev1p2
if is_alt_mountable(p1_mtd, p2_mtd) then
if current_partition == bev1p1 then
op_ubi = tonumber(p2_mtd:sub(4)) + 1
else
op_ubi = tonumber(p1_mtd:sub(4)) + 1
end
local cp_info, ap_info = get_partition_os_info(op_ubi)
if current_partition == bev1p1 then
p1_os = cp_info or p1_os
p2_os = ap_info or p2_os
else
p1_os = ap_info or p1_os
p2_os = cp_info or p2_os
end
end
end
end end
function index() function index()
entry({"admin", "system", "advanced_reboot"}, template("advanced_reboot/advanced_reboot"), _("Advanced Reboot"), 90) entry({"admin", "system", "advanced_reboot"}, template("advanced_reboot/advanced_reboot"), _("Advanced Reboot"), 90)
entry({"admin", "system", "advanced_reboot", "reboot"}, post("action_reboot")) entry({"admin", "system", "advanced_reboot", "reboot"}, post("action_reboot"))
entry({"admin", "system", "advanced_reboot", "alternative_reboot"}, post("action_altreboot")) entry({"admin", "system", "advanced_reboot", "alternative_reboot"}, post("action_altreboot"))
entry({"admin", "system", "advanced_reboot", "power_off"}, post("action_poweroff")) entry({"admin", "system", "advanced_reboot", "power_off"}, post("action_poweroff"))
end end
function action_reboot() function action_reboot()
local uci = require "luci.model.uci".cursor() ltemplate.render("admin_system/applyreboot", {
local ip = uci:get("network", "lan", "ipaddr") title = i18n.translate("Rebooting..."),
luci.template.render("advanced_reboot/applyreboot", { msg = i18n.translate("The system is rebooting now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings."),
title = luci.i18n.translate("Rebooting..."), addr = ip.new(type(ip) == "string" and ip or "192.168.1.1") or "192.168.1.1"
msg = luci.i18n.translate("The system is rebooting now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a few minutes before 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 = luci.ip.new(type(ip) == "string" and ip or "192.168.1.1") or "192.168.1.1" sys.reboot()
})
luci.sys.reboot()
end end
function action_altreboot() function action_altreboot()
local uci = require "luci.model.uci".cursor() local zyxelFlagPartition, zyxelBootFlag, zyxelNewBootFlag, errorCode, curEnvSetting, newEnvSetting
local zyxelFlagPartition, zyxelBootFlag, zyxelNewBootFlag, errorCode, curEnvSetting, newEnvSetting errorMessage = nil
errorMessage = nil errorCode = 0
errorCode = 0 if http.formvalue("cancel") then
if luci.http.formvalue("cancel") then http.redirect(dispatcher.build_url('admin/system/advanced_reboot'))
luci.http.redirect(luci.dispatcher.build_url('admin/system/advanced_reboot')) return
return end
end local step = tonumber(http.formvalue("step") or 1)
local step = tonumber(luci.http.formvalue("step") or 1) if step == 1 then
if step == 1 then if fs.access("/usr/sbin/fw_printenv") and fs.access("/usr/sbin/fw_setenv") then
if device_name and nixio.fs.access("/usr/sbin/fw_printenv") and nixio.fs.access("/usr/sbin/fw_setenv") then ltemplate.render("advanced_reboot/alternative_reboot",{})
luci.template.render("advanced_reboot/alternative_reboot",{}) else
else ltemplate.render("advanced_reboot/advanced_reboot",{errorMessage = i18n.translate("No access to fw_printenv or fw_printenv!")})
luci.template.render("advanced_reboot/advanced_reboot",{errorMessage = luci.i18n.translate("No access to fw_printenv or fw_printenv!")}) end
end elseif step == 2 then
elseif step == 2 then if bev1 or bev2 then -- Linksys devices
if boot_envvar1 or boot_envvar2 then -- Linksys devices if bev1 then
if boot_envvar1 then curEnvSetting = tonumber(util.trim(util.exec("fw_printenv -n " .. bev1)))
curEnvSetting = tonumber(luci.util.trim(luci.sys.exec("/usr/sbin/fw_printenv -n " .. boot_envvar1))) if not curEnvSetting then
if not curEnvSetting then errorMessage = errorMessage .. i18n.translate("Unable to obtain firmware environment variable") .. ": " .. bev1 .. ". "
errorMessage = errorMessage .. luci.i18n.translate("Unable to obtain firmware environment variable") .. ": " .. boot_envvar1 .. ". " util.perror(i18n.translate("Unable to obtain firmware environment variable") .. ": " .. bev1 .. ".")
luci.util.perror(luci.i18n.translate("Unable to obtain firmware environment variable") .. ": " .. boot_envvar1 .. ".") else
else newEnvSetting = curEnvSetting == bev1p1 and bev1p2 or bev1p1
newEnvSetting = curEnvSetting == boot_envvar1_partition_one and boot_envvar1_partition_two or boot_envvar1_partition_one errorCode = sys.call("fw_setenv " .. bev1 .. " " .. newEnvSetting)
errorCode = luci.sys.call("/usr/sbin/fw_setenv " .. boot_envvar1 .. " " .. newEnvSetting) if errorCode ~= 0 then
if errorCode ~= 0 then errorMessage = errorMessage or "" .. i18n.translate("Unable to set firmware environment variable") .. ": " .. bev1 .. " " .. i18n.translate("to") .. " " .. newEnvSetting .. ". "
errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to set firmware environment variable") .. ": " .. boot_envvar1 .. " " .. luci.i18n.translate("to") .. " " .. newEnvSetting .. ". " util.perror(i18n.translate("Unable to set firmware environment variable") .. ": " .. bev1 .. " " .. i18n.translate("to") .. " " .. newEnvSetting .. ".")
luci.util.perror(luci.i18n.translate("Unable to set firmware environment variable") .. ": " .. boot_envvar1 .. " " .. luci.i18n.translate("to") .. " " .. newEnvSetting .. ".") end
end end
end end
end if bev2 then
if boot_envvar2 then curEnvSetting = util.trim(util.exec("fw_printenv -n " .. bev2))
curEnvSetting = luci.util.trim(luci.sys.exec("/usr/sbin/fw_printenv -n " .. boot_envvar2)) if not curEnvSetting then
if not curEnvSetting then errorMessage = errorMessage or "" .. i18n.translate("Unable to obtain firmware environment variable") .. ": " .. bev2 .. ". "
errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to obtain firmware environment variable") .. ": " .. boot_envvar2 .. ". " util.perror(i18n.translate("Unable to obtain firmware environment variable") .. ": " .. bev2 .. ".")
luci.util.perror(luci.i18n.translate("Unable to obtain firmware environment variable") .. ": " .. boot_envvar2 .. ".") else
else newEnvSetting = curEnvSetting == bev2p1 and bev2p2 or bev2p1
newEnvSetting = curEnvSetting == boot_envvar2_partition_one and boot_envvar2_partition_two or boot_envvar2_partition_one errorCode = sys.call("fw_setenv " .. bev2 .. " '" .. newEnvSetting .. "'")
errorCode = luci.sys.call("/usr/sbin/fw_setenv " .. boot_envvar2 .. " '" .. newEnvSetting .. "'") if errorCode ~= 0 then
if errorCode ~= 0 then errorMessage = errorMessage or "" .. i18n.translate("Unable to set firmware environment variable") .. ": " .. bev2 .. " " .. i18n.translate("to") .. " " .. newEnvSetting .. ". "
errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to set firmware environment variable") .. ": " .. boot_envvar2 .. " " .. luci.i18n.translate("to") .. " " .. newEnvSetting .. ". " util.perror(i18n.translate("Unable to set firmware environment variable") .. ": " .. bev2 .. " " .. i18n.translate("to") .. " " .. newEnvSetting .. ".")
luci.util.perror(luci.i18n.translate("Unable to set firmware environment variable") .. ": " .. boot_envvar2 .. " " .. luci.i18n.translate("to") .. " " .. newEnvSetting .. ".") end
end end
end end
end else -- NetGear device
else -- NetGear device if not zyxelFlagPartition then zyxelFlagPartition = util.trim(util.exec(". /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end
if not zyxelFlagPartition then zyxelFlagPartition = luci.util.trim(luci.sys.exec("source /lib/functions.sh; find_mtd_part 0:DUAL_FLAG")) end if not zyxelFlagPartition then
if not zyxelFlagPartition then errorMessage = errorMessage .. i18n.translate("Unable to find Dual Boot Flag Partition." .. " ")
errorMessage = errorMessage .. luci.i18n.translate("Unable to find Dual Boot Flag Partition." .. " ") util.perror(i18n.translate("Unable to find Dual Boot Flag Partition."))
luci.util.perror(luci.i18n.translate("Unable to find Dual Boot Flag Partition.")) else
else zyxelBootFlag = tonumber(util.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'"))
zyxelBootFlag = tonumber(luci.sys.exec("dd if=" .. zyxelFlagPartition .. " bs=1 count=1 2>/dev/null | hexdump -n 1 -e '1/1 \"%d\"'")) zyxelNewBootFlag = zyxelBootFlag and zyxelBootFlag == 1 and "\\xff" or "\\x01"
zyxelNewBootFlag = zyxelBootFlag and zyxelBootFlag == 1 and "\\xff" or "\\x01" if zyxelNewBootFlag then
if zyxelNewBootFlag then errorCode = sys.call("printf \"" .. zyxelNewBootFlag .. "\" >" .. zyxelFlagPartition )
errorCode = luci.sys.call("printf \"" .. zyxelNewBootFlag .. "\" >" .. zyxelFlagPartition ) if errorCode ~= 0 then
if errorCode ~= 0 then errorMessage = errorMessage or "" .. i18n.translate("Unable to set Dual Boot Flag Partition entry for partition") .. ": " .. zyxelFlagPartition .. ". "
errorMessage = errorMessage or "" .. luci.i18n.translate("Unable to set Dual Boot Flag Partition entry for partition") .. ": " .. zyxelFlagPartition .. ". " util.perror(i18n.translate("Unable to set Dual Boot Flag Partition entry for partition") .. ": " .. zyxelFlagPartition .. ".")
luci.util.perror(luci.i18n.translate("Unable to set Dual Boot Flag Partition entry for partition") .. ": " .. zyxelFlagPartition .. ".") end
end end
end end
end end
end if not errorMessage then
if not errorMessage then ltemplate.render("admin_system/applyreboot", {
luci.template.render("advanced_reboot/applyreboot", { title = i18n.translate("Rebooting..."),
title = luci.i18n.translate("Rebooting..."), msg = i18n.translate("The system is rebooting to an alternative partition now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a few minutes before you try to reconnect. It might be necessary to renew the address of your computer to reach the device again, depending on your settings."),
msg = luci.i18n.translate("The system is rebooting to an alternative partition now.<br /> DO NOT POWER OFF THE DEVICE!<br /> Wait a few minutes before 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 = ip.new(uci:get("network", "lan", "ipaddr")) or "192.168.1.1"
addr = luci.ip.new(uci:get("network", "lan", "ipaddr")) or "192.168.1.1" })
}) sys.reboot()
luci.sys.reboot() else
else ltemplate.render("advanced_reboot/advanced_reboot",{
luci.template.render("advanced_reboot/advanced_reboot",{ romBoardName=romBoardName,
rom_board_name=rom_board_name, device_name=device_name,
device_name=device_name, bev1p1=bev1p1,
boot_envvar1_partition_one=boot_envvar1_partition_one, p1_os=p1_os,
partition_one_os=partition_one_os, bev1p2=bev1p2,
boot_envvar1_partition_two=boot_envvar1_partition_two, p2_os=p2_os,
partition_two_os=partition_two_os, current_partition=current_partition,
current_partition=current_partition, errorMessage = errorMessage})
errorMessage = errorMessage}) end
end end
end
end end
function action_poweroff() function action_poweroff()
local uci = require "luci.model.uci".cursor() local uci = require "luci.model.uci".cursor()
if luci.http.formvalue("cancel") then if http.formvalue("cancel") then
luci.http.redirect(luci.dispatcher.build_url('admin/system/advanced_reboot')) http.redirect(dispatcher.build_url('admin/system/advanced_reboot'))
return return
end end
local step = tonumber(luci.http.formvalue("step") or 1) local step = tonumber(http.formvalue("step") or 1)
if step == 1 then if step == 1 then
if nixio.fs.access("/sbin/poweroff") then if fs.access("/sbin/poweroff") then
luci.template.render("advanced_reboot/power_off",{}) ltemplate.render("advanced_reboot/power_off",{})
else else
luci.template.render("advanced_reboot/advanced_reboot",{}) ltemplate.render("advanced_reboot/advanced_reboot",{})
end end
elseif step == 2 then elseif step == 2 then
luci.template.render("advanced_reboot/applyreboot", { ltemplate.render("admin_system/applyreboot", {
title = luci.i18n.translate("Shutting down..."), title = i18n.translate("Shutting down..."),
msg = luci.i18n.translate("The system is shutting down now.<br /> DO NOT POWER OFF THE DEVICE!<br /> It might be necessary to renew the address of your computer to reach the device again, depending on your settings."), msg = i18n.translate("The system is shutting down now.<br /> DO NOT POWER OFF THE DEVICE!<br /> It might be necessary to renew the address of your computer to reach the device again, depending on your settings."),
addr = luci.ip.new(uci:get("network", "lan", "ipaddr")) or "192.168.1.1" addr = ip.new(uci:get("network", "lan", "ipaddr")) or "192.168.1.1"
}) })
luci.sys.call("/sbin/poweroff") sys.call("/sbin/poweroff")
end end
end end

View file

@ -20,70 +20,70 @@
<%- if device_name then -%> <%- if device_name then -%>
<fieldset class="cbi-section"> <fieldset class="cbi-section">
<legend><%=device_name%><%: Partitions%></legend> <legend><%=device_name%><%: Partitions%></legend>
<div class="table cbi-section-table" id="partitions"> <div class="table cbi-section-table" id="partitions">
<div class="tr cbi-section-table-titles"> <div class="tr cbi-section-table-titles">
<div class="th cbi-section-table-cell"><%:Partition%></div> <div class="th cbi-section-table-cell"><%:Partition%></div>
<div class="th cbi-section-table-cell"><%:Status%></div> <div class="th cbi-section-table-cell"><%:Status%></div>
<div class="th cbi-section-table-cell"><%:Firmware/OS (Kernel)%></div> <div class="th cbi-section-table-cell"><%:Firmware%></div>
<div class="th cbi-section-table-cell"><%:Action%></div> <div class="th cbi-section-table-cell"><%:Reboot%></div>
</div> </div>
<div class="tr cbi-section-table-row"> <div class="tr cbi-section-table-row cbi-rowstyle-1">
<div class="td"> <div class="td">
<%=string.format("%X", boot_envvar1_partition_one)%> <%=string.format("%X", bev1p1)%>
</div> </div>
<div class="td"> <div class="td">
<%- if boot_envvar1_partition_one == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%> <%- if bev1p1 == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%>
</div> </div>
<div class="td"> <div class="td">
<%=partition_one_os%> <%=p1_os%>
</div> </div>
<div class="td"> <div class="td">
<%- if boot_envvar1_partition_one == current_partition then -%> <%- if bev1p1 == current_partition then -%>
<form method="post" action="<%=url('admin/system/advanced_reboot/reboot')%>"> <form method="post" action="<%=url('admin/system/advanced_reboot/reboot')%>">
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<input id="reboot-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Reboot to current partition%>" /> <input id="reboot-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Reboot to current partition%>" />
</form> </form>
<%- else -%> <%- else -%>
<form method="post" action="<%=url('admin/system/advanced_reboot/alternative_reboot')%>"> <form method="post" action="<%=url('admin/system/advanced_reboot/alternative_reboot')%>">
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<input id="altreboot-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Reboot to alternative partition...%>" /> <input id="altreboot-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Reboot to alternative partition...%>" />
</form> </form>
<%- end -%> <%- end -%>
</div> </div>
</div> </div>
<div class="tr cbi-section-table-row"> <div class="tr cbi-section-table-row cbi-rowstyle-2">
<div class="td"> <div class="td">
<%=string.format("%X", boot_envvar1_partition_two)%> <%=string.format("%X", bev1p2)%>
</div> </div>
<div class="td"> <div class="td">
<%- if boot_envvar1_partition_two == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%> <%- if bev1p2 == current_partition then -%><%:Current%><%- else -%><%:Alternative%><%- end -%>
</div> </div>
<div class="td"> <div class="td">
<%=partition_two_os%> <%=p2_os%>
</div> </div>
<div class="td"> <div class="td">
<%- if boot_envvar1_partition_two == current_partition then -%> <%- if bev1p2 == current_partition then -%>
<form method="post" action="<%=url('admin/system/advanced_reboot/reboot')%>"> <form method="post" action="<%=url('admin/system/advanced_reboot/reboot')%>">
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<input id="reboot-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Reboot to current partition%>" /> <input id="reboot-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Reboot to current partition%>" />
</form> </form>
<%- else -%> <%- else -%>
<form method="post" action="<%=url('admin/system/advanced_reboot/alternative_reboot')%>"> <form method="post" action="<%=url('admin/system/advanced_reboot/alternative_reboot')%>">
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<input id="altreboot-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Reboot to alternative partition...%>" /> <input id="altreboot-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Reboot to alternative partition...%>" />
</form> </form>
<%- end -%> <%- end -%>
</div> </div>
</div> </div>
</div> </div>
</fieldset> </fieldset>
<%- else -%> <%- else -%>
<%- if rom_board_name then -%> <%- if rom_board_name then -%>
<p class="alert-message warning"><%=pcdata(translatef("Warning: Device (%s) is unknown or isn't a dual-partition device!", rom_board_name))%></p> <p class="alert-message warning"><%=pcdata(translatef("Warning: Device (%s) is unknown or isn't a dual-partition device!", rom_board_name))%></p>
<%- else -%> <%- else -%>
<p class="alert-message warning"><%=pcdata(translatef("Warning: Unable to obtain device information!"))%></p> <p class="alert-message warning"><%=pcdata(translatef("Warning: Unable to obtain device information!"))%></p>
<%- end -%> <%- end -%>
<%- end -%> <%- end -%>
<hr /> <hr />
@ -91,10 +91,10 @@
<%- if nixio.fs.access("/sbin/poweroff") then -%> <%- if nixio.fs.access("/sbin/poweroff") then -%>
<form method="post" action="<%=url('admin/system/advanced_reboot/power_off')%>"> <form method="post" action="<%=url('admin/system/advanced_reboot/power_off')%>">
<input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="token" value="<%=token%>" />
<input id="poweroff-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Perform power off...%>" /> <input id="poweroff-button" type="submit" class="cbi-button cbi-button-apply important" value="<%:Perform power off...%>" />
</form> </form>
<%- else -%> <%- else -%>
<p class="alert-message warning"><%:Warning: This system does not support powering off!%></p> <p class="alert-message warning"><%:Warning: This system does not support powering off!%></p>
<%- end -%> <%- end -%>
<%+footer%> <%+footer%>

View file

@ -10,10 +10,10 @@
<h2 name="content"><%:Reboot Device to an Alternative Partition%> - <%:Confirm%></h2> <h2 name="content"><%:Reboot Device to an Alternative Partition%> - <%:Confirm%></h2>
<p> <p>
<%_ WARNING: An alternative partition might have its own settings and completely different firmware.<br /><br /> <%_ WARNING: An alternative partition might have its own settings and completely different firmware.<br /><br />
As your network configuration and WiFi SSID/password on alternative partition might be different, As your network configuration and WiFi SSID/password on alternative partition might be different,
you might have to adjust your computer settings to be able to access your device once it reboots.<br /><br /> you might have to adjust your computer settings to be able to access your device once it reboots.<br /><br />
Please also be aware that alternative partition firmware might not provide an easy way to switch active partition Please also be aware that alternative partition firmware might not provide an easy way to switch active partition
and boot back to the currently active partition.<br /><br /> and boot back to the currently active partition.<br /><br />
Click "Proceed" below to reboot device to an alternative partition. %> Click "Proceed" below to reboot device to an alternative partition. %>
</p> </p>

View file

@ -0,0 +1,5 @@
#!/bin/sh
rm -rf /var/luci-modulecache/; rm -f /var/luci-indexcache;
exit 0