Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ public function statusAction()
$response['status_msg'] = sprintf(
'%s %s',
$response['status_msg'],
gettext('This update requires a reboot.')
gettext('This update requires a reboot/ power off.')
);
}
$response['status_reboot'] = $active_reboot;
Expand Down Expand Up @@ -466,12 +466,15 @@ public function updateAction()
if ($this->request->isPost()) {
$this->getLogger('audit')->notice(sprintf("[Firmware] User %s executed a firmware update", $this->getUserName()));
$backend->configdRun('firmware flush');
$response['msg_uuid'] = trim($backend->configdRun('firmware update', true));

$cmd = 'firmware update';
if ($this->request->getPost('shutdown') === '1') {
$cmd .= ' shutdown';
}

$response['msg_uuid'] = trim($backend->configdRun($cmd, true));
$response['status'] = 'ok';
} else {
$response['status'] = 'failure';
}

return $response;
}

Expand All @@ -487,12 +490,15 @@ public function upgradeAction()
if ($this->request->isPost()) {
$this->getLogger('audit')->notice(sprintf("[Firmware] User %s executed a firmware upgrade", $this->getUserName()));
$backend->configdRun('firmware flush');
$response['msg_uuid'] = trim($backend->configdRun('firmware upgrade', true));

$cmd = 'firmware upgrade';
if ($this->request->getPost('shutdown') === '1') {
$cmd .= ' shutdown';
}

$response['msg_uuid'] = trim($backend->configdRun($cmd, true));
$response['status'] = 'ok';
} else {
$response['status'] = 'failure';
}

return $response;
}

Expand Down Expand Up @@ -769,6 +775,8 @@ public function upgradestatusAction()
$result['status'] = 'done';
} elseif (strpos($cmd_result, '***REBOOT***') !== false) {
$result['status'] = 'reboot';
} elseif (strpos($cmd_result, '***POWER OFF***') !== false) {
$result['status'] = 'shutdown';
}

return $result;
Expand Down
45 changes: 39 additions & 6 deletions src/opnsense/mvc/app/views/OPNsense/Core/firmware.volt
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,19 @@
/**
* perform backend action and install poller to update status
*/
function backend(type) {
function backend(type, data) {
$.upgrade_check = type == 'check';
if (data === undefined) {
data = {};
}

$('#update_status').html('');
$('#updatelist').hide();
$('#update_status_container').show();
$('#updatetab > a').tab('show');
$('#updatetab_progress').addClass("fa fa-spinner fa-pulse");

ajaxCall('/api/core/firmware/' + type, {}, function () {
ajaxCall('/api/core/firmware/' + type, data, function () {
setTimeout(trackStatus, 500);
});
}
Expand Down Expand Up @@ -247,21 +250,43 @@
if (major === true) {
reboot_msg = "{{ lang._('The firewall will download all firmware sets and reboot multiple times for this upgrade. All operating system files and packages will be reinstalled as a consequence. This may take several minutes to complete.') }}";
}
reboot_msg += '<br><br><label><input type="checkbox" id="upgrade_shutdown_cb"> ' +
'{{ lang._("Power off instead of reboot") }}</label>';
// reboot required, inform the user.
let countdownSeconds = 30;
let countdownTimer = null;
BootstrapDialog.show({
type:BootstrapDialog.TYPE_WARNING,
title: "{{ lang._('Reboot required') }}",
title: "{{ lang._('Reboot/ Power off required') }}",
message: reboot_msg,
onshown: function(dialogRef) {
let $btn = dialogRef.getButton('btn-reboot');
countdownTimer = setInterval(function () {
countdownSeconds--;
$btn.text('{{ lang._("Confirm") }} (' + countdownSeconds + ')');
if (countdownSeconds <= 0) {
clearInterval(countdownTimer);
$btn.trigger('click');
}
}, 1000);
},
onhidden: function() {
if (countdownTimer) clearInterval(countdownTimer);
},
buttons: [{
label: "{{ lang._('OK') }}",
id: 'btn-reboot',
label: '{{ lang._("Confirm") }} (' + countdownSeconds + ')',
cssClass: 'btn-warning',
action: function(dialogRef){
if (countdownTimer) clearInterval(countdownTimer);
let doShutdown = $('#upgrade_shutdown_cb').is(':checked') ? '1' : '0';
dialogRef.close();
backend(major === true ? 'upgrade' : 'update');
backend(major === true ? 'upgrade' : 'update', {'shutdown': doShutdown});
}
},{
label: "{{ lang._('Cancel') }}",
action: function(dialogRef){
if (countdownTimer) clearInterval(countdownTimer);
dialogRef.close();
}
}]
Expand Down Expand Up @@ -314,6 +339,14 @@
setTimeout(rebootWait, 45000);
},
});
} else if (data['status'] == 'shutdown') {
BootstrapDialog.show({
type:BootstrapDialog.TYPE_INFO,
title: "{{ lang._('Shutting down after update') }}",
closable: false,
message: "{{ lang._('The system is shutting down. You chose to power off instead of reboot. The system will need to be started manually.') }}" +
' <i class="fa fa-power-off"></i>',
});
} else {
// schedule next poll
setTimeout(trackStatus, 500);
Expand Down Expand Up @@ -848,7 +881,7 @@
<button class='btn btn-warning' id="upgrade_maj"><i class="fa fa-check"></i> {{ lang._('Upgrade') }}</button>
<button class="btn btn-default" id="upgrade_cancel"><i class="fa fa-times"></i> {{ lang._('Cancel') }}</button>
</td>
<td colspan="2" style="vertical-align:middle">
<td colspan="3" style="vertical-align:middle">
<strong><div id="updatestatus"></div></strong>
</td>
<td></td>
Expand Down
26 changes: 26 additions & 0 deletions src/opnsense/scripts/firmware/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,18 @@ output_done()
exit 0
}

output_restart_action()
{
KEEP_LOG=${1}
PREFER_SHUTDOWN=${2:-0}

if [ "${PREFER_SHUTDOWN}" = "1" ]; then
output_shutdown "${KEEP_LOG}"
else
output_reboot "${KEEP_LOG}"
fi
}

output_reboot()
{
KEEP_LOG=${1}
Expand All @@ -163,6 +175,20 @@ output_reboot()
/usr/local/etc/rc.reboot
}

output_shutdown()
{
KEEP_LOG=${1}

echo '***POWER OFF***' >> ${LOCKFILE}

if [ -n "${KEEP_LOG}" ]; then
cp ${LOCKFILE} ${LOGFILE}
fi

sleep 5
/usr/local/etc/rc.halt
}

# if output is requested clear file and set new request right away
if [ -n "${REQUEST}" ]; then
output_request "${REQUEST}"
Expand Down
12 changes: 10 additions & 2 deletions src/opnsense/scripts/firmware/update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ REQUEST="UPDATE"

. /usr/local/opnsense/scripts/firmware/config.sh

PREFER_SHUTDOWN=0
for arg in "$@"; do
if [ "$arg" = "shutdown" ]; then
PREFER_SHUTDOWN=1
break
fi
done

CMD=${1}
FORCE=

Expand Down Expand Up @@ -71,13 +79,13 @@ fi
# if we can update base, we'll do that as well
if opnsense-update ${FORCE} -bk -c; then
if output_cmd opnsense-update ${FORCE} -bk; then
output_reboot keep-log
output_restart_action keep-log ${PREFER_SHUTDOWN}
fi
fi

if [ "${ALWAYS_REBOOT}" = "1" ]; then
if [ "${PKGS_HASH}" != "$(${PKG} query %n-%v 2> /dev/null | sha256)" ]; then
output_reboot keep-log
output_restart_action keep-log ${PREFER_SHUTDOWN}
fi
fi

Expand Down
10 changes: 9 additions & 1 deletion src/opnsense/scripts/firmware/upgrade.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,21 @@ REQUEST="UPGRADE"

. /usr/local/opnsense/scripts/firmware/config.sh

PREFER_SHUTDOWN=0
for arg in "$@"; do
if [ "$arg" = "shutdown" ]; then
PREFER_SHUTDOWN=1
break
fi
done

if output_cmd opnsense-update -u; then
if output_cmd /usr/local/etc/rc.syshook upgrade; then
# pending kernel applies before reboot
if output_cmd opnsense-update -K -c; then
output_cmd opnsense-update -K
fi
output_reboot keep-log
output_restart_action keep-log ${PREFER_SHUTDOWN}
fi

output_txt "The upgrade was aborted due to an error."
Expand Down
2 changes: 1 addition & 1 deletion src/opnsense/scripts/shell/firmware.sh
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ if [ -n "${RELEASE}" ]; then

PROMPT="${RELEASE}/${PROMPT}"
elif CHANGELOG=$(${LAUNCHER} -u reboot); then
echo "This update requires a reboot."
echo "This update requires a reboot/ power off."
echo
fi

Expand Down