mirror of
https://github.com/openwrt/luci.git
synced 2026-04-15 19:01:56 +00:00
luci-app-advanced-reboot: bugfix: actual partition switch
At some point after r7, when I no longer had the dual boot device readily available for testing, a regression was introduced that the RPCD script would not actually perform the partition switch. Thanks to @bd0426 for report and @Jackie264 for fixing the issue. advanced-reboot.js * simplify partition number validation in handleAlternativeReboot * reformat text copy RPCD script * obtain OpenWrt version from "$OPENWRT_RELEASE" not "$PRETTY_NAME" for the snapshot compatibility * refactor parameter processing for boot_partition function * add logging/better output on error in boot_partition test.sh * introduce a test file for heartbeat check of the RPCD script Signed-off-by: Stan Grishin <stangri@melmac.ca>
This commit is contained in:
@@ -7,7 +7,7 @@ PKG_NAME:=luci-app-advanced-reboot
|
||||
PKG_LICENSE:=AGPL-3.0-or-later
|
||||
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
|
||||
PKG_VERSION:=1.1.1
|
||||
PKG_RELEASE:=9
|
||||
PKG_RELEASE:=15
|
||||
|
||||
PKG_BUILD_DEPENDS:=jq/host
|
||||
|
||||
|
||||
@@ -108,8 +108,8 @@ return view.extend({
|
||||
E(
|
||||
"p",
|
||||
_(
|
||||
'WARNING: Power off might result in a reboot on a device which doesn\'t support power off.<br /><br />\
|
||||
Click "Proceed" below to power off your device.'
|
||||
"WARNING: Power off might result in a reboot on a device which doesn't support power off.<br /><br />" +
|
||||
"Click \"Proceed\" below to power off your device."
|
||||
)
|
||||
),
|
||||
E("div", { class: "right" }, [
|
||||
@@ -192,7 +192,9 @@ return view.extend({
|
||||
"p",
|
||||
{ class: "spinning" },
|
||||
_(
|
||||
"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."
|
||||
"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."
|
||||
)
|
||||
),
|
||||
]);
|
||||
@@ -216,23 +218,10 @@ return view.extend({
|
||||
);
|
||||
},
|
||||
|
||||
handleAlternativeReboot: function () {
|
||||
// accept either (ev, number) or (number, ev)
|
||||
var pn = null;
|
||||
handleAlternativeReboot: function (number, ev) {
|
||||
var pn = Number(number);
|
||||
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var a = arguments[i];
|
||||
if (typeof a === "number" && !Number.isNaN(a)) {
|
||||
pn = a;
|
||||
break;
|
||||
}
|
||||
if (typeof a === "string" && a !== "" && !Number.isNaN(Number(a))) {
|
||||
pn = Number(a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pn == null) {
|
||||
if (Number.isNaN(pn)) {
|
||||
// fall back / safety
|
||||
ui.addNotification(null, E("p", _("Missing partition number")));
|
||||
return Promise.resolve();
|
||||
@@ -247,12 +236,12 @@ return view.extend({
|
||||
E(
|
||||
"p",
|
||||
_(
|
||||
'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,\
|
||||
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\
|
||||
and boot back to the currently active partition.<br /><br />\
|
||||
Click "Proceed" below to reboot device to the selected partition.'
|
||||
"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," +
|
||||
" 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" +
|
||||
" and boot back to the currently active partition.<br /><br />" +
|
||||
"Click \"Proceed\" below to reboot device to the selected partition."
|
||||
)
|
||||
),
|
||||
E("div", { class: "right" }, [
|
||||
@@ -283,8 +272,8 @@ Click "Proceed" below to reboot device to the selected partition.'
|
||||
typeof fn === "function"
|
||||
? fn(a)
|
||||
: _("Unexpected error: %s").format(
|
||||
String(res.error)
|
||||
);
|
||||
String(res.error)
|
||||
);
|
||||
|
||||
return ui.addNotification(null, E("p", msg));
|
||||
}
|
||||
@@ -395,18 +384,18 @@ Click "Proceed" below to reboot device to the selected partition.'
|
||||
{ class: "alert-message warning" },
|
||||
_(
|
||||
"Warning: Device (%s) is unknown or isn't a dual-firmware device!" +
|
||||
"%s" +
|
||||
"If you are seeing this on an OpenWrt dual-firmware supported device," +
|
||||
"%s" +
|
||||
"please refer to " +
|
||||
"%sHow to add a new device section of the README%s."
|
||||
"%s" +
|
||||
"If you are seeing this on an OpenWrt dual-firmware supported device," +
|
||||
"%s" +
|
||||
"please refer to " +
|
||||
"%sHow to add a new device section of the README%s."
|
||||
).format(
|
||||
warnBoard,
|
||||
"<br /><br />",
|
||||
"<br />",
|
||||
'<a href="' +
|
||||
pkg.URL +
|
||||
'#how-to-add-a-new-device" target="_blank">',
|
||||
pkg.URL +
|
||||
'#how-to-add-a-new-device" target="_blank">',
|
||||
"</a>"
|
||||
)
|
||||
)
|
||||
@@ -474,18 +463,18 @@ Click "Proceed" below to reboot device to the selected partition.'
|
||||
body.appendChild(
|
||||
poweroff_supported
|
||||
? E(
|
||||
"button",
|
||||
{
|
||||
class: "btn cbi-button cbi-button-apply important",
|
||||
click: ui.createHandlerFn(this, "handlePowerOff"),
|
||||
},
|
||||
_("Perform power off...")
|
||||
)
|
||||
"button",
|
||||
{
|
||||
class: "btn cbi-button cbi-button-apply important",
|
||||
click: ui.createHandlerFn(this, "handlePowerOff"),
|
||||
},
|
||||
_("Perform power off...")
|
||||
)
|
||||
: E(
|
||||
"p",
|
||||
{ class: "alert-message warning" },
|
||||
_("Warning: This system does not support powering off!")
|
||||
)
|
||||
"p",
|
||||
{ class: "alert-message warning" },
|
||||
_("Warning: This system does not support powering off!")
|
||||
)
|
||||
);
|
||||
|
||||
return body;
|
||||
|
||||
@@ -161,17 +161,9 @@ function get_volume_info(path) {
|
||||
let pretty = command(
|
||||
". " +
|
||||
shellquote(root + "etc/os-release") +
|
||||
' 2>/dev/null; echo "$PRETTY_NAME" 2>/dev/null'
|
||||
' 2>/dev/null; echo "$OPENWRT_RELEASE" 2>/dev/null'
|
||||
);
|
||||
if (pretty) label = trim(pretty);
|
||||
if (label && match(label, /SNAPSHOT/)) {
|
||||
let rel = command(
|
||||
'grep -m1 "^DISTRIB_RELEASE=" ' +
|
||||
shellquote(root + "etc/openwrt_release") +
|
||||
" 2>/dev/null | awk -F= '{gsub(/[\"'']/, \"\", $2); print $2}'"
|
||||
);
|
||||
if (rel) label = "OpenWrt " + trim(rel);
|
||||
}
|
||||
|
||||
let kver = null;
|
||||
if (root == "/") {
|
||||
@@ -496,18 +488,31 @@ function obtain_device_info() {
|
||||
* Accepts ubus args: { "number": "<partition-number>" }.
|
||||
* Uses the device schema to map partition numbers to env values or dual-flag bytes.
|
||||
*
|
||||
* @param {{args:{number:String|Number}}} req
|
||||
* @param {{number:String}} req
|
||||
* @returns {Object} {} on success; {error:..., ...} on failure.
|
||||
* @sideeffects Calls fw_setenv/fw_saveenv or writes to dual-flag MTD.
|
||||
*/
|
||||
function boot_partition(req) {
|
||||
log("boot_partition req=" + sprintf("%J", req?.args));
|
||||
/* extract target partition number from RPC args */
|
||||
let number;
|
||||
if (req && req.number != null) number = int(req.number);
|
||||
if (!number)
|
||||
let val;
|
||||
|
||||
if (type(req) == "array" && length(req) > 0)
|
||||
val = req[0]?.number;
|
||||
else if (type(req?.args) == "object")
|
||||
val = req.args.number;
|
||||
else if (type(req) == "object")
|
||||
val = req.number;
|
||||
|
||||
if (val != null) val = "" + val;
|
||||
if (val != null && match(val, /^[0-9]+$/))
|
||||
number = int(val);
|
||||
|
||||
if (number == null)
|
||||
return {
|
||||
error: "INVALID_ARG",
|
||||
detail: "number is required and must be numeric",
|
||||
detail: "number is required and must be numeric (got: " + sprintf("%J", req?.args) + ")",
|
||||
};
|
||||
|
||||
let board = get_board_name();
|
||||
@@ -540,23 +545,32 @@ function boot_partition(req) {
|
||||
for (let j = 0; j < length(params); j++) {
|
||||
let param = params[j];
|
||||
let value = target.param_values ? target.param_values[j] : null;
|
||||
let rc = "0";
|
||||
|
||||
if (param == null || param == "") continue;
|
||||
if (value == null) continue;
|
||||
let rc = command(
|
||||
setcmd +
|
||||
" " +
|
||||
shellquote(param) +
|
||||
" " +
|
||||
shellquote("" + value) +
|
||||
" 2>/dev/null; echo $?"
|
||||
);
|
||||
if (rc != "0")
|
||||
return {
|
||||
error: "ERR_SET_ENV",
|
||||
args: [param, "" + value],
|
||||
rom_board_name: board,
|
||||
};
|
||||
if (savecmd) rc = command(savecmd + " 2>/dev/null; echo $?");
|
||||
|
||||
if (setcmd) {
|
||||
let cmd = setcmd +
|
||||
" " +
|
||||
shellquote(param) +
|
||||
" " +
|
||||
shellquote("" + value) +
|
||||
" 2>/dev/null; echo $?";
|
||||
log("boot_partition running: " + cmd);
|
||||
rc = command(cmd);
|
||||
if (rc != "0")
|
||||
return {
|
||||
error: "ERR_SET_ENV",
|
||||
args: [param, "" + value],
|
||||
rom_board_name: board,
|
||||
};
|
||||
}
|
||||
if (savecmd) {
|
||||
let cmd = savecmd + " 2>/dev/null; echo $?";
|
||||
log("boot_partition running: " + cmd);
|
||||
rc = command(cmd);
|
||||
}
|
||||
if (rc != "0") return { error: "ERR_SAVE_ENV", rom_board_name: board };
|
||||
}
|
||||
} else {
|
||||
@@ -564,6 +578,9 @@ function boot_partition(req) {
|
||||
if (!df) return { error: "NO_DUAL_FLAG", rom_board_name: board };
|
||||
if (!file_exists(df))
|
||||
return { error: "NO_DUAL_FLAG_BLOCK", rom_board_name: board };
|
||||
|
||||
log("boot_partition setting dual flag: " + df + " to " + target.param_values[0]);
|
||||
|
||||
if (!write_dual_flag_value(df, target.param_values[0]))
|
||||
return { error: "ERR_SET_DUAL_FLAG", args: [df], rom_board_name: board };
|
||||
}
|
||||
|
||||
5
applications/luci-app-advanced-reboot/test.sh
Normal file
5
applications/luci-app-advanced-reboot/test.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
ubus -S call luci.advanced-reboot obtain_device_info | grep 'NO_BOARD_NAME_MATCH' && \
|
||||
ubus -S call luci.advanced-reboot boot_partition '{ "number": "1" }' | grep 'NO_BOARD_NAME_MATCH' && \
|
||||
ubus -S call luci.advanced-reboot boot_partition '{ "number": "2" }' | grep 'NO_BOARD_NAME_MATCH'
|
||||
Reference in New Issue
Block a user