0
0
mirror of https://github.com/openwrt/luci.git synced 2025-10-31 13:18:04 +00:00
Files
Stan Grishin a353d15b55 luci-app-advanced-reboot: update to 1.1.0-1
Makefile:
- update SPDX license identified and copyright
- update documentation link

README:
- add short README with the link to full documentation

System View javascript:
- switch from single to double quotes
- update documentation link
- more readable translateTable
- better code readability for
  - callPowerOff
  - handlePowerOff
  - handleReboot
  - handleTogglePartition
  - handleAlternativeReboot
  - parsePartitions
  - some visual elements

RPCD Script:
- more resilient to unexpected CLI output
- add debugger function to ease development/debugging
- better check if `/var/alt_rom` is mounted before calling umount
- better handling of MTD indices

Device Support:
- add Linksys MR7350 which slipped thru the cracks

Signed-off-by: Stan Grishin <stangri@melmac.ca>
2025-08-12 08:38:34 +00:00

387 lines
9.1 KiB
JavaScript

"use strict";
"require view";
"require rpc";
"require ui";
"require uci";
"require fs";
var pkg = {
get Name() {
return "luci-app-advanced-reboot";
},
get URL() {
return "https://docs.openwrt.melmac.ca/" + pkg.Name + "/";
},
};
return view.extend({
translateTable: {
NO_BOARD_NAME: function (args) {
return _("Unable to find Device Board Name.");
},
NO_DUAL_FLAG: function (args) {
return _("Unable to find Dual Boot Flag Partition.");
},
NO_DUAL_FLAG_BLOCK: function (args) {
return _(
"The Dual Boot Flag Partition: %s is not a block device."
).format(args[0]);
},
ERR_SET_DUAL_FLAG: function (args) {
return _(
"Unable to set Dual Boot Flag Partition entry for partition: %s."
).format(args[0]);
},
NO_FIRM_ENV: function (args) {
return _("Unable to obtain firmware environment variable: %s.").format(
args[0]
);
},
ERR_SET_ENV: function (args) {
return _("Unable to set firmware environment variable: %s to %s.").format(
args[0],
args[1]
);
},
},
callReboot: rpc.declare({
object: "system",
method: "reboot",
expect: { result: 0 },
}),
callObtainDeviceInfo: rpc.declare({
object: "luci.advanced_reboot",
method: "obtain_device_info",
expect: {},
}),
callTogglePartition: rpc.declare({
object: "luci.advanced_reboot",
method: "toggle_boot_partition",
expect: {},
}),
callPowerOff: function () {
return fs.exec("/sbin/poweroff").then(function () {
ui.showModal(_("Shutting down..."), [
E(
"p",
{ class: "spinning" },
_(
"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."
)
),
]);
});
},
handlePowerOff: function () {
ui.showModal(_("Power Off Device"), [
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.'
)
),
E("div", { class: "right" }, [
E(
"button",
{
class: "btn",
click: ui.hideModal,
},
_("Cancel")
),
" ",
E(
"button",
{
class: "btn cbi-button cbi-button-positive important",
click: L.bind(this.callPowerOff, this),
},
_("Proceed")
),
]),
]);
},
handleReboot: function (ev) {
return this.callReboot()
.then(function (res) {
if (res != 0) {
ui.addNotification(
null,
E("p", _("The reboot command failed with code %d").format(res))
);
L.raise("Error", "Reboot failed");
}
ui.showModal(_("Rebooting…"), [
E("p", { class: "spinning" }, _("Waiting for device...")),
]);
window.setTimeout(function () {
ui.showModal(_("Rebooting…"), [
E(
"p",
{ class: "spinning alert-message warning" },
_("Device unreachable! Still waiting for device...")
),
]);
}, 150000);
ui.awaitReconnect();
})
.catch(function (e) {
ui.addNotification(null, E("p", e.message));
});
},
handleTogglePartition: function (ev) {
return this.callTogglePartition().then(
L.bind(function (res) {
if (res.error) {
ui.hideModal();
return ui.addNotification(
null,
E("p", this.translateTable[res.error](res.args))
);
}
return this.callReboot()
.then(function (res) {
if (res != 0) {
ui.addNotification(
null,
E("p", _("The reboot command failed with code %d").format(res))
);
L.raise("Error", "Reboot failed");
}
ui.showModal(_("Rebooting…"), [
E(
"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."
)
),
]);
window.setTimeout(function () {
ui.showModal(_("Rebooting…"), [
E(
"p",
{ class: "spinning alert-message warning" },
_("Device unreachable! Still waiting for device...")
),
]);
}, 150000);
ui.awaitReconnect();
})
.catch(function (e) {
ui.addNotification(null, E("p", e.message));
});
}, this)
);
},
handleAlternativeReboot: function (ev) {
return Promise.all([
L.resolveDefault(fs.stat("/usr/sbin/fw_printenv"), null),
L.resolveDefault(fs.stat("/usr/sbin/fw_setenv"), null),
]).then(
L.bind(function (data) {
if (!data[0] || !data[1]) {
return ui.addNotification(
null,
E("p", _("No access to fw_printenv or fw_printenv!"))
);
}
ui.showModal(
_("Reboot Device to an Alternative Partition") + " - " + _("Confirm"),
[
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 an alternative partition.'
)
),
E("div", { class: "right" }, [
E(
"button",
{
class: "btn",
click: ui.hideModal,
},
_("Cancel")
),
" ",
E(
"button",
{
class: "btn cbi-button cbi-button-positive important",
click: L.bind(this.handleTogglePartition, this),
},
_("Proceed")
),
]),
]
);
}, this)
);
},
parsePartitions: function (partitions) {
var res = [];
partitions.forEach(
L.bind(function (partition) {
var func, text;
if (partition.state == "Current") {
func = "handleReboot";
text = _("Reboot to current partition");
} else {
func = "handleAlternativeReboot";
text = _("Reboot to alternative partition...");
}
res.push([
(partition.number + 0x100).toString(16).substr(-2).toUpperCase(),
_(partition.state),
partition.os
.replace("Unknown", _("Unknown"))
.replace("Compressed", _("Compressed")),
E(
"button",
{
class: "btn cbi-button cbi-button-apply important",
click: ui.createHandlerFn(this, func),
},
text
),
]);
}, this)
);
return res;
},
load: function () {
return Promise.all([
uci.changes(),
L.resolveDefault(fs.stat("/sbin/poweroff"), null),
this.callObtainDeviceInfo(),
]);
},
render: function (data) {
var changes = data[0],
poweroff_supported = data[1] != null ? true : false,
device_info = data[2];
var body = E([E("h2", _("Advanced Reboot"))]);
for (var config in changes || {}) {
body.appendChild(
E(
"p",
{ class: "alert-message warning" },
_("Warning: There are unsaved changes that will get lost on reboot!")
)
);
break;
}
if (device_info.error)
body.appendChild(
E(
"p",
{ class: "alert-message warning" },
_("ERROR: ") + this.translateTable[device_info.error]()
)
);
body.appendChild(
E("h3", (device_info.device_name || "") + _(" Partitions"))
);
if (device_info.device_name) {
var partitions_table = E("table", { class: "table" }, [
E("tr", { class: "tr table-titles" }, [
E("th", { class: "th" }, [_("Partition")]),
E("th", { class: "th" }, [_("Status")]),
E("th", { class: "th" }, [_("Firmware")]),
E("th", { class: "th" }, [_("Reboot")]),
]),
]);
cbi_update_table(
partitions_table,
this.parsePartitions(device_info.partitions)
);
body.appendChild(partitions_table);
} else {
body.appendChild(
E(
"p",
{ class: "alert-message warning" },
device_info.rom_board_name
? _(
"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."
).format(
device_info.rom_board_name,
"<br /><br />",
"<br />",
'<a href="' +
pkg.URL +
'#how-to-add-a-new-device" target="_blank">',
"</a>"
)
: _("Warning: Unable to obtain device information!")
)
);
}
body.appendChild(E("hr"));
body.appendChild(
poweroff_supported
? E(
"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!")
)
);
return body;
},
handleSaveApply: null,
handleSave: null,
handleReset: null,
});