From 0fae78ec21aa8e734f68ee576dd8de328b37f2ce Mon Sep 17 00:00:00 2001 From: Marius Vollmer Date: Fri, 18 Oct 2024 14:52:10 +0300 Subject: [PATCH] create: Show all operating systems This will show all operating systems, regardless of EOL or release dates, but the recommended ones will be at the top. Operating systems with an expired EOL date will be annotated accordingly in the list. The tests have been brought up-to-date with regard to what OSes are actually in the list and are downloadable. Fixes #509 --- .../create-vm-dialog/createVmDialog.jsx | 36 +++++++++-- .../create-vm-dialog/createVmDialogUtils.js | 14 +++++ src/machines.scss | 5 ++ test/check-machines-create | 59 ++++++++++--------- test/reference | 2 +- 5 files changed, 81 insertions(+), 35 deletions(-) diff --git a/src/components/create-vm-dialog/createVmDialog.jsx b/src/components/create-vm-dialog/createVmDialog.jsx index 08e56cf9f..dffef00b4 100644 --- a/src/components/create-vm-dialog/createVmDialog.jsx +++ b/src/components/create-vm-dialog/createVmDialog.jsx @@ -76,6 +76,7 @@ import { correctSpecialCases, filterReleaseEolDates, getOSStringRepresentation, + getOSDescription, needsRHToken, isDownloadableOs, loadOfflineToken, @@ -405,10 +406,8 @@ const SourceRow = ({ connectionName, source, sourceType, networks, nodeDevices, class OSRow extends React.Component { constructor(props) { super(props); - const IGNORE_VENDORS = ['ALTLinux', 'Mandriva', 'GNOME Project']; const osInfoListExt = this.props.osInfoList .map(os => correctSpecialCases(os)) - .filter(os => filterReleaseEolDates(os) && !IGNORE_VENDORS.find(vendor => vendor == os.vendor)) .sort((a, b) => { if (a.vendor == b.vendor) { // Sort OS with numbered version by version @@ -426,9 +425,20 @@ class OSRow extends React.Component { return getOSStringRepresentation(a).toLowerCase() > getOSStringRepresentation(b).toLowerCase() ? 1 : -1; }); + const IGNORE_VENDORS = ['ALTLinux', 'Mandriva', 'GNOME Project']; + const newOsEntries = []; + const oldOsEntries = []; + for (const os of osInfoListExt) { + if (filterReleaseEolDates(os) && !IGNORE_VENDORS.find(vendor => vendor == os.vendor)) + newOsEntries.push(os); + else + oldOsEntries.push(os); + } + this.state = { typeAheadKey: Math.random(), - osEntries: osInfoListExt, + newOsEntries, + oldOsEntries, }; this.createValue = os => { return ({ @@ -474,9 +484,23 @@ class OSRow extends React.Component { }} onToggle={(_event, isOpen) => this.setState({ isOpen })} isOpen={this.state.isOpen} - menuAppendTo="parent"> - {this.state.osEntries.map(os => ())} + menuAppendTo="parent" + isGrouped + > + + {this.state.newOsEntries + .map(os => ()) + } + + + {this.state.oldOsEntries + .map(os => ()) + } + diff --git a/src/components/create-vm-dialog/createVmDialogUtils.js b/src/components/create-vm-dialog/createVmDialogUtils.js index 64be4c745..401f66c6f 100644 --- a/src/components/create-vm-dialog/createVmDialogUtils.js +++ b/src/components/create-vm-dialog/createVmDialogUtils.js @@ -17,6 +17,10 @@ * along with Cockpit; If not, see . */ +import cockpit from 'cockpit'; +import React from 'react'; +import { ExclamationTriangleIcon } from "@patternfly/react-icons"; + import { getTodayYearShifted, } from "../../helpers.js"; @@ -24,6 +28,8 @@ import { import * as python from "python.js"; import autoDetectOSScript from './autoDetectOS.py'; +const _ = cockpit.gettext; + const ACCEPT_RELEASE_DATES_AFTER = getTodayYearShifted(-3); const ACCEPT_EOL_DATES_AFTER = getTodayYearShifted(-1); const RHSM_TOKEN = "rhsm-offline-token"; @@ -76,6 +82,14 @@ export function filterReleaseEolDates(os) { ); } +export function getOSDescription(os) { + if (os.eolDate && compareDates(ACCEPT_EOL_DATES_AFTER, os.eolDate) < 0) + return {cockpit.format(_("Vendor support ended $0"), os.eolDate)}; + if (!os.eolDate && os.releaseDate && compareDates(ACCEPT_RELEASE_DATES_AFTER, os.releaseDate) < 0) + return cockpit.format(_("Released $0"), os.releaseDate); + return null; +} + export function compareDates(a, b, emptyFirst = false) { if (!a) { if (!b) { diff --git a/src/machines.scss b/src/machines.scss index a4f6b4c7c..361af3948 100644 --- a/src/machines.scss +++ b/src/machines.scss @@ -102,3 +102,8 @@ #storage-pool-delete-modal span.pf-v5-c-check__body { margin-block-start: 0; } + +#os-select .pf-v5-c-select__menu-item.pf-m-description { + display: flex; + align-items: baseline; +} diff --git a/test/check-machines-create b/test/check-machines-create index 67d9b0d64..3f26609f6 100755 --- a/test/check-machines-create +++ b/test/check-machines-create @@ -91,16 +91,16 @@ class TestMachinesCreate(machineslib.VirtualMachinesCase): pixel_test_tag="auto")) # check if older os are filtered - runner.checkFilteredOsTest(TestMachinesCreate.VmDialog(self, os_name=config.REDHAT_RHEL_4_7_FILTERED_OS, - pixel_test_tag="filter")) - - runner.checkFilteredOsTest(TestMachinesCreate.VmDialog(self, os_name=config.MANDRIVA_2011_FILTERED_OS)) + runner.checkFilteredOsTest(TestMachinesCreate.VmDialog(self, os_name=config.OLD_FILTERED_OS, + os_is_old=True)) - runner.checkFilteredOsTest(TestMachinesCreate.VmDialog(self, os_name=config.MAGEIA_3_FILTERED_OS)) + runner.checkFilteredOsTest(TestMachinesCreate.VmDialog(self, os_name=config.UNSUPPORTED_FILTERED_OS, + os_is_unsupported=True, + pixel_test_tag="filter-unsupported")) - # check that newer oses are present and searchable with substring match - runner.checkFilteredOsTest(TestMachinesCreate.VmDialog(self, os_name=config.WINDOWS_SERVER_10, - os_search_name=config.WINDOWS_SERVER_10_SHORT)) + runner.checkFilteredOsTest(TestMachinesCreate.VmDialog(self, os_name=config.NOT_FOUND_FILTERED_OS, + os_is_not_found=True, + pixel_test_tag="filter")) # check OS versions are sorted in alphabetical order runner.checkSortedOsTest(TestMachinesCreate.VmDialog(self), [config.FEDORA_29, config.FEDORA_28]) @@ -935,7 +935,9 @@ vnc_password= "{vnc_passwd}" TREE_URL = 'https://archive.fedoraproject.org/pub/archive/fedora/linux/releases/28/Server/x86_64/os' # LINUX can be filtered if 3 years old - REDHAT_RHEL_4_7_FILTERED_OS = 'Red Hat Enterprise Linux 4.9' + OLD_FILTERED_OS = 'Red Hat Enterprise Linux 8.3' + UNSUPPORTED_FILTERED_OS = 'Fedora 34' + NOT_FOUND_FILTERED_OS = 'Red Hat Enterprise Linux 4.9' FEDORA_28 = 'Fedora 28' FEDORA_28_SHORTID = 'fedora28' @@ -950,13 +952,6 @@ vnc_password= "{vnc_passwd}" CENTOS_7 = 'CentOS 7' - MANDRIVA_2011_FILTERED_OS = 'Mandriva Linux 2011' - - MAGEIA_3_FILTERED_OS = 'Mageia 3' - - WINDOWS_SERVER_10 = 'Microsoft Windows 10' - WINDOWS_SERVER_10_SHORT = 'win' - class VmDialog: vmId = 0 @@ -969,6 +964,9 @@ vnc_password= "{vnc_passwd}" os_name="Fedora 28", os_search_name=None, os_short_id="fedora28", + os_is_unsupported=False, + os_is_old=False, + os_is_not_found=False, expected_os_name=None, is_unattended=None, profile=None, @@ -1017,6 +1015,9 @@ vnc_password= "{vnc_passwd}" self.os_name = os_name self.os_search_name = os_search_name self.os_short_id = os_short_id + self.os_is_unsupported = os_is_unsupported + self.os_is_old = os_is_old + self.os_is_not_found = os_is_not_found self.expected_os_name = expected_os_name self.is_unattended = is_unattended self.profile = profile @@ -1078,7 +1079,7 @@ vnc_password= "{vnc_passwd}" # https://bugzilla.redhat.com/show_bug.cgi?id=1987120 b.select_from_dropdown("#source-type", "url") fake_fedora = "Fedora 28" # 128 MiB minimum storage - suse = "SUSE CaaS Platform Unknown (unknown)" # 20 GiB minimum storage + suse = "SUSE CaaS Platform Unknown" # 20 GiB minimum storage b.set_input_text("#os-select-group input", fake_fedora) b.click(f"#os-select li button:contains('{fake_fedora}')") b.wait_val("#storage-limit", "128") @@ -1176,23 +1177,25 @@ vnc_password= "{vnc_passwd}" return self - def checkOsFiltered(self, present=False): + def checkOsFiltered(self): b = self.browser b.focus("#os-select-group input") - # os_search_name is meant to be used to test substring much + # os_search_name is meant to be used to test substring match b.input_text(self.os_search_name or self.os_name) - if not present: - try: - with b.wait_timeout(5): - b.wait_in_text("#os-select li button", "No results found") - return self - except AssertionError: - # os found which is not ok - self.fail(f"{self.os_name} was not filtered") + if not self.os_is_not_found: + # There should be exactly one entry + b.wait_in_text("#os-select li button", self.os_name) + # It might have a description + if self.os_is_unsupported: + b.wait_in_text("#os-select li button", "Vendor support ended") + elif self.os_is_old: + b.wait_in_text("#os-select li button", "Released ") else: - b.wait_visible(f"#os-select li button:contains({self.os_search_name})") + b.wait_in_text("#os-select li button", "No results found") + + return self def checkRhelIsDownloadable(self): b = self.browser diff --git a/test/reference b/test/reference index d610bd77d..ac55d3424 160000 --- a/test/reference +++ b/test/reference @@ -1 +1 @@ -Subproject commit d610bd77d2a9b589812e924494df7b6d0f7dcf9d +Subproject commit ac55d34246451844a62e899e93ffa2ba579e8a5e