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 @@ }
-
- -