diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Core/Api/FirmwareController.php b/src/opnsense/mvc/app/controllers/OPNsense/Core/Api/FirmwareController.php
index be92d697b..d1150d7c6 100644
--- a/src/opnsense/mvc/app/controllers/OPNsense/Core/Api/FirmwareController.php
+++ b/src/opnsense/mvc/app/controllers/OPNsense/Core/Api/FirmwareController.php
@@ -99,6 +99,7 @@ class FirmwareController extends ApiControllerBase
}
$packages_size = !empty($response['download_size']) ? $response['download_size'] : 0;
+ $upgrade_size = 0;
$sets_size = 0;
if (!empty($response['upgrade_packages'])) {
@@ -131,7 +132,7 @@ class FirmwareController extends ApiControllerBase
$download_size = $this->formatBytes($packages_size + $sets_size);
- $sorted = array();
+ $sorted = [];
foreach (
array('new_packages', 'reinstall_packages', 'upgrade_packages',
@@ -200,6 +201,32 @@ class FirmwareController extends ApiControllerBase
$response['all_packages'] = $sorted;
+ $sorted = [];
+
+ if (isset($response['upgrade_sets'])) {
+ foreach ($response['upgrade_sets'] as $value) {
+ if (!empty($value['size'])) {
+ $upgrade_size += $value['size'];
+ }
+ $sorted[$value['name']] = array(
+ 'reason' => gettext('upgrade'),
+ 'old' => empty($value['current_version']) ?
+ gettext('N/A') : $value['current_version'],
+ 'new' => $value['new_version'],
+ 'repository' => $value['repository'],
+ 'name' => $value['name'],
+ );
+ }
+ }
+
+ $upgrade_size = $this->formatBytes($upgrade_size);
+
+ uksort($sorted, function ($a, $b) {
+ return strnatcasecmp($a, $b);
+ });
+
+ $response['all_sets'] = $sorted;
+
if (array_key_exists('connection', $response) && $response['connection'] == 'unresolved') {
$response['status_msg'] = gettext('No address record found for the selected mirror.');
$response['status'] = 'error';
@@ -262,7 +289,24 @@ class FirmwareController extends ApiControllerBase
gettext('This update requires a reboot.')
);
}
- $response['status'] = 'ok';
+ $response['status'] = 'update';
+ } elseif (array_key_exists('upgrade_sets', $response) && count($response['upgrade_sets'])) {
+ if (count($response['upgrade_sets']) == 1) {
+ /* keep this dynamic for template translation even though %s is always '1' */
+ $response['status_msg'] = sprintf(
+ gettext('There is %s update available, total download size is %s.'),
+ count($response['upgrade_sets']),
+ $upgrade_size
+ );
+ } else {
+ $response['status_msg'] = sprintf(
+ gettext('There are %s updates available, total download size is %s.'),
+ count($response['upgrade_sets']),
+ $upgrade_size
+ );
+ }
+ $response['status_msg'] = sprintf( '%s %s', $response['status_msg'], gettext('This update requires multiple reboots.'));
+ $response['status'] = 'upgrade';
} elseif (array_key_exists('updates', $response) && $response['updates'] == 0) {
$response['status_msg'] = gettext('There are no updates available on the selected mirror.');
$response['status'] = 'none';
diff --git a/src/opnsense/mvc/app/views/OPNsense/Core/firmware.volt b/src/opnsense/mvc/app/views/OPNsense/Core/firmware.volt
index 166eecb5d..ac55ee145 100644
--- a/src/opnsense/mvc/app/views/OPNsense/Core/firmware.volt
+++ b/src/opnsense/mvc/app/views/OPNsense/Core/firmware.volt
@@ -61,19 +61,27 @@
* retrieve update status from backend
*/
function updateStatus() {
- // update UI
- $('#major-upgrade').hide();
- $('#upgrade_maj').prop('disabled', true);
- $.upgrade_major_message = '';
- $.upgrade_major_version = '';
+ $('#upgrade_maj').hide();
+ $('#upgrade').hide();
- // request status
ajaxGet('/api/core/firmware/status', {}, function (data, status){
- if (data['status'] == "ok") {
+ let upgrade_major_message = '';
+ let upgrade_major_version = '';
+
+ if ('upgrade_major_message' in data) {
+ upgrade_major_message = data['upgrade_major_message'];
+ }
+ if ('upgrade_major_version' in data) {
+ upgrade_major_version = data['upgrade_major_version'];
+ }
+
+ if (data['status'] == "update") {
+ let show_log = '';
+
$.upgrade_needs_reboot = data['upgrade_needs_reboot'];
- $.upgrade_show_log = '';
// show upgrade list
+ $('#upgrade').show();
$('#updatestatus').html(data['status_msg']);
$('#updatelist > tbody').empty();
$('#updatetab > a').tab('show');
@@ -83,23 +91,64 @@
row['reason']+'
'+row['repository'] + '
');
if (row['name'] == data['product_target'] && row['new'] != 'N/A') {
- $.upgrade_show_log = row['new'].replace(/[_-].*/, '');
+ show_log = row['new'].replace(/[_-].*/, '');
}
});
$('#update_status_container').hide();
$('#updatelist').show();
// display the current changelog if one was found
- if ($.upgrade_show_log != '') {
- changelog($.upgrade_show_log);
+ if (show_log != '') {
+ changelog(show_log);
}
// update list so plugins sync as well (no logs)
packagesInfo(false);
- } else {
- // ok or an error of some sort: make this official
+ } else if (data['status'] == "upgrade") {
+ if (upgrade_major_message == '') {
+ upgrade_major_message = '{{ lang._('This software release has reached its designated end of life.') }}';
+ upgrade_major_message += ' {{ lang._('The next major release is:') }} ' + upgrade_major_version;
+ }
+
BootstrapDialog.show({
- type: data['status'] != "error" ? BootstrapDialog.TYPE_SUCCESS : BootstrapDialog.TYPE_DANGER,
+ type: BootstrapDialog.TYPE_WARNING,
+ title: '{{ lang._('Upgrade instructions') }}',
+ /* we trust this data, it was signed by us and secured by csrf */
+ message: htmlDecode(upgrade_major_message),
+ buttons: [{
+ label: "{{ lang._('Unlock') }}",
+ cssClass: 'btn-warning',
+ action: function (dialogRef) {
+ dialogRef.close();
+
+ // show upgrade list
+ $('#upgrade_maj').show();
+ $('#updatestatus').html(data['status_msg']);
+ $('#updatelist > tbody').empty();
+ $('#updatetab > a').tab('show');
+ $.each(data['all_sets'], function (index, row) {
+ $('#updatelist > tbody').append('
'+row['name']+'
' +
+ '
'+row['old']+'
'+row['new']+'
' +
+ row['reason']+'
'+row['repository'] + '
');
+ });
+ $('#update_status_container').hide();
+ $('#updatelist').show();
+
+ changelog(upgrade_major_version);
+ }
+ },{
+ label: "{{ lang._('Cancel') }}",
+ action: function (dialogRef) {
+ dialogRef.close();
+ }
+ }]
+ });
+
+ // update list so plugins sync as well (all)
+ packagesInfo(true);
+ } else if (data['status'] == "error") {
+ BootstrapDialog.show({
+ type: BootstrapDialog.TYPE_DANGER,
title: "{{ lang._('Status') }}",
onshow:function(dialogRef){
dialogRef.getModalBody().html(data['status_msg']);
@@ -114,17 +163,27 @@
// update list so plugins sync as well (all)
packagesInfo(true);
- }
+ } else if (data['status'] == "none") {
+ BootstrapDialog.show({
+ type: BootstrapDialog.TYPE_SUCCESS,
+ title: "{{ lang._('Status') }}",
+ onshow:function(dialogRef){
+ dialogRef.getModalBody().html(data['status_msg']);
+ },
+ buttons: [{
+ label: "{{ lang._('Close') }}",
+ action: function(dialogRef){
+ dialogRef.close();
+ }
+ }]
+ });
- if ('upgrade_major_message' in data) {
- $.upgrade_major_message = data['upgrade_major_message'];
- }
- if ('upgrade_major_version' in data) {
- $.upgrade_major_version = data['upgrade_major_version'];
- }
- if ($.upgrade_major_version != '') {
- $('#upgrade-version').text($.upgrade_major_version);
- $('#major-upgrade').show();
+ // update list so plugins sync as well (all)
+ packagesInfo(true);
+ } else {
+ // in case new responses are added
+ console.log('Unknown check response');
+ console.log(data);
}
});
}
@@ -134,8 +193,7 @@
*/
function backend(type) {
if ($.upgrade_action == 'maj') {
- $("#upgrade_maj").attr("style","");
- $('#updatetab_progress').addClass("fa fa-spinner fa-pulse");
+ // leave upgrade action as is
} else if (type == 'check') {
$.upgrade_action = 'check';
} else {
@@ -308,8 +366,6 @@
}
if (data['status'] == 'done') {
$('#updatetab_progress').removeClass("fa fa-spinner fa-pulse");
- $('#major-upgrade').hide();
- $('#upgrade_maj').prop('disabled', true);
if ($.upgrade_action == 'check') {
updateStatus();
} else {
@@ -608,34 +664,6 @@
$.upgrade_action = 'maj';
upgrade_ui();
});
- $('#checkupdate_maj').click(function () {
- if ($.upgrade_major_message == "") {
- $('#upgrade_maj').prop('disabled', false);
- changelog($.upgrade_major_version);
- } else {
- BootstrapDialog.show({
- type:BootstrapDialog.TYPE_WARNING,
- title: "{{ lang._('Upgrade instructions') }}",
- /* we trust this data, it was signed by us and secured by csrf */
- message: htmlDecode($.upgrade_major_message),
- buttons: [{
- label: "{{ lang._('Unlock') }}",
- cssClass: 'btn-warning',
- action: function (dialogRef) {
- dialogRef.close();
- $('#upgrade_maj').prop('disabled', false);
- changelog($.upgrade_major_version);
- }
- },{
- label: "{{ lang._('Cancel') }}",
- action: function (dialogRef) {
- dialogRef.close();
- }
- }]
- });
- packagesInfo(true);
- }
- });
// populate package information
packagesInfo(true);
@@ -794,20 +822,6 @@
}
-
-
-
-
-
-
- {{ lang._('This software release has reached its designated end of life.') }}
- {{ lang._('The next major release is:') }}
-
-