From ab06bf517cc85865809d4a416a87f00927f9ec8a Mon Sep 17 00:00:00 2001 From: Mark Waite Date: Thu, 25 May 2023 11:25:39 -0600 Subject: [PATCH] Warn when operating system end of life is approaching (#7913) * Ubuntu 18.04 end of life admin monitor First prototype that includes a user interface and localized messages with parameters to support the specific operating system. * Use a base class for common features Admin monitors are disabled and enabled by a user interface action. There is not an obvious way to detect that a date has passed so that it should be enabled again. * Better comment * Make the logging clearer * Split pattern check to separate method * Add a message to show after end of life * Suppress most logging * Minor logging improvements * Use actual end of life date for Ubuntu 18.04 * Logger not needed * Add Alpine 3.14 end of life admin monitor * Add Alpine 3.15 end of life monitor * Add Alpine 3.16 end of life monitor * Add Alpine 3.17 end of life monitor * Spotless cleanup * Add Fedora 37, 38, and Red Hat 7 * More accurate regex to detect version * Add Debian 10 end of life admin monitor * Add a few tests * Add another test * Fix checkstyle violations * Fix spotbugs warning * Correct the copyright * Make test viable on non-Linux machines Do not depend on the existence of /etc/os-release * Name the setup function more accurately * Test a file with non-matching content * Test the Alpine end of life admin monitors * Add more tests * Test Fedora 37 admin monitor * Add RHEL 7 test * Announce RHEL 7 early end of support immediately * Use consistent logging calls * Add Red Hat 8 to RHEL 7 as a test * Use past date to report RHEL 7 end of life * Remove Red Hat 8 from RHEL 7 end of life * Log more information * Display end of support date Incorrect to declare end of support as the date when we begin warning the user about end of life. * Add descriptions of the admin monitors * Use a better redirect URL * Group admin monitors better by display name * Remove unnused message.properties files * Add description.jelly file * Better description of the admin monitors * Add endOfSupportDate getter Needed for UI * Fix minor indentation error * Each monitor must be independently disabled * Repurpose identifier for use in disabled property Don't need the idenitfier anywhere except in the initial constructor call that is later used to enable and disable the admin monitor. * Add Red Hat 8 to RHEL 7 as a test * Add os-release tests and data files * Remove unused URL arg to constructor * Reduce duplication in data Easier to test with symbolic constants that are consistently named across all the classes. Includes tests of os-release files from each of the end of life operating systems * Fix inaccurate comment * Use constant for documentation URL * Remove RHEL 8 from RHEL 8 Admin Monitor * Fedora 36 security support ends 18 May 2023 * Fedora 37 support ends 15 Dec 2023 * Fix spelling error in description * Read data file with UTF-8 character set * Do not use extension point name in symbol * Use single word 'Ignore' in button, not name of monitor * Use a smaller layout for monitor name * Include operating system version in RHEL 7 check Includes a TODO comment to remove the RHEL 8 entry that I use for testing and development * Fix regex syntax error * First prototype using a data file * Start the conversion to a single monitor * Latest experiments with end of life data as JSON * More exploring and evolving * Remove Alpine admin monitor * Remove Fedora admin monitor * Remove Debian admin monitor * Remove Ubuntu admin monitor * Throw IOException rather than check for null IOException should be uncommon and mistakes should be detected by automated tests * Stop inheriting from EndOfLifeAdminMonitor * Simplify initialization logic Else clauses not required due to break. * Add isActivated implementation * Add setDisabled test method * Minor formatting changes * Test some additional methods * Call super in constructor * Minor updates from study of upstream class * Format JSON data * Fix formatting errors * Fix assertion * Better variable naming * Explain the purpose of ignoreEndOfLife flag * Remove unused import * Store the pretty name, not the pattern * Test pretty name with sample os-release data files * Remove RedHat 7 specific monitor * Set RHEL 8 end of life early for test * Ongoing debugging * Describe the monitor * Honor start date * Add pretty name as monitor attribute * Add end of support date * Remove earlier implementations * Move end of life data * Rename end of support to end of life End of life is used throughout the monitor * Improve message with after end of life date status * Undo .gitignore change * Rename effective date to end of life date * Rename pretty name to operating system name * More rename of prettyName * Fix logging mistakes * Add RHEL 8 * Default start date is 6 months before end of life * Add operating system end of life patterns and dates * Fix JSON file formatting * Simplify logging code * Better logging * Add Alma and Rocky Linux tests and patterns * Add methods to help test automation * Remove unused methods * Start warning RHEL 7 users immediately * Suppress spotbugs traversal_in warning - false positive * Throw IOException on bad data file Fail tests quickly when a a bad data file is used * Better exception message * Correct RHEL 8 end of life date * Enable isActivated test * Increase test coverage * Fix spelling error Co-authored-by: Alexander Brandes * Remove non-breaking spaces from message Non-breaking spaces are not recommended. Co-authored-by: Tim Jacomb <21194782+timja@users.noreply.github.com> * Rename class to match symbol https://github.com/jenkinsci/jenkins/pull/7913/files#r1199814150 * Sort end of life data alphabetically * Included OS query parameter and fragment in docs URL The fragment may be useful in the future for analytics. Harmless to send the fragment to www.jenkins.io and www.jenkins.io may be able to make use of it to direct the reader to information that is specific to their operating system. * Scientific Linux 8 does not exist * Remove fragment, only need query parameter https://github.com/jenkinsci/jenkins/pull/7913#discussion_r1200991347 is the comment that prompted the improvement. --------- Co-authored-by: Alexander Brandes Co-authored-by: Tim Jacomb <21194782+timja@users.noreply.github.com> Co-authored-by: Alexander Brandes --- .../OperatingSystemEndOfLifeAdminMonitor.java | 278 +++++++++++++++ .../description.jelly | 4 + .../description.properties | 1 + .../end-of-life-data.json | 98 +++++ .../message.jelly | 45 +++ .../message.properties | 9 + ...ratingSystemEndOfLifeAdminMonitorTest.java | 334 ++++++++++++++++++ .../jenkins/monitor/os-release-alma-8 | 18 + .../jenkins/monitor/os-release-alpine-3.14 | 6 + .../jenkins/monitor/os-release-alpine-3.15 | 6 + .../jenkins/monitor/os-release-alpine-3.16 | 6 + .../jenkins/monitor/os-release-alpine-3.17 | 6 + .../jenkins/monitor/os-release-alpine-3.18 | 6 + .../jenkins/monitor/os-release-centos-7 | 16 + .../jenkins/monitor/os-release-debian-10 | 9 + .../jenkins/monitor/os-release-fedora-36 | 22 ++ .../jenkins/monitor/os-release-fedora-37 | 22 ++ .../jenkins/monitor/os-release-oracle-7 | 17 + .../jenkins/monitor/os-release-oracle-8 | 18 + .../jenkins/monitor/os-release-redhat-7 | 17 + .../jenkins/monitor/os-release-redhat-8 | 17 + .../jenkins/monitor/os-release-rocky-8 | 16 + .../jenkins/monitor/os-release-scientific-7 | 15 + .../jenkins/monitor/os-release-ubuntu-18.04 | 12 + 24 files changed, 998 insertions(+) create mode 100644 core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java create mode 100644 core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/description.jelly create mode 100644 core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/description.properties create mode 100644 core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/end-of-life-data.json create mode 100644 core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/message.jelly create mode 100644 core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/message.properties create mode 100644 core/src/test/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitorTest.java create mode 100644 core/src/test/resources/jenkins/monitor/os-release-alma-8 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-alpine-3.14 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-alpine-3.15 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-alpine-3.16 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-alpine-3.17 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-alpine-3.18 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-centos-7 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-debian-10 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-fedora-36 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-fedora-37 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-oracle-7 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-oracle-8 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-redhat-7 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-redhat-8 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-rocky-8 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-scientific-7 create mode 100644 core/src/test/resources/jenkins/monitor/os-release-ubuntu-18.04 diff --git a/core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java b/core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java new file mode 100644 index 0000000000..e0579b9090 --- /dev/null +++ b/core/src/main/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor.java @@ -0,0 +1,278 @@ +/* + * The MIT License + * + * Copyright 2023 Mark Waite. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.monitor; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Extension; +import hudson.model.AdministrativeMonitor; +import hudson.security.Permission; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.time.LocalDate; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import jenkins.model.Jenkins; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.apache.commons.io.IOUtils; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.HttpRedirect; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.interceptor.RequirePOST; + +@Extension +@Restricted(NoExternalUse.class) +@Symbol("operatingSystemEndOfLife") +public class OperatingSystemEndOfLifeAdminMonitor extends AdministrativeMonitor { + + static final Logger LOGGER = Logger.getLogger(OperatingSystemEndOfLifeAdminMonitor.class.getName()); + + /** + * Allow tests to disable the end of life monitor without a JenkinsRule. + */ + boolean ignoreEndOfLife = false; + + private LocalDate warningsStartDate = LocalDate.now().plusYears(10); + private boolean afterEndOfLifeDate = false; + private String operatingSystemName = System.getProperty("os.name", "Unknown"); + private String endOfLifeDate = "2099-12-31"; + private String documentationUrl = "https://www.jenkins.io/redirect/operating-system-end-of-life"; + + public OperatingSystemEndOfLifeAdminMonitor(String id) throws IOException { + super(id); + fillOperatingSystemList(); + } + + public OperatingSystemEndOfLifeAdminMonitor() throws IOException { + fillOperatingSystemList(); + } + + private void fillOperatingSystemList() throws IOException { + if (Jenkins.getInstanceOrNull() != null && !isEnabled()) { + /* If not enabled, do not read the data files or perform any checks */ + LOGGER.log(Level.FINEST, "Operating system end of life monitor is not enabled, reading no data"); + return; + } + ClassLoader cl = getClass().getClassLoader(); + URL localOperatingSystemData = cl.getResource("jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/end-of-life-data.json"); + String initialOperatingSystemJson = IOUtils.toString(localOperatingSystemData.openStream(), StandardCharsets.UTF_8); + readOperatingSystemList(initialOperatingSystemJson); + } + + /* Package protected for testing */ + void readOperatingSystemList(String initialOperatingSystemJson) throws IOException { + JSONArray systems = JSONArray.fromObject(initialOperatingSystemJson); + if (systems.isEmpty()) { + throw new IOException("Empty data set"); + } + for (Object systemObj : systems) { + if (!(systemObj instanceof JSONObject)) { + throw new IOException("Wrong object type in data file"); + } + JSONObject system = (JSONObject) systemObj; + + if (!system.has("pattern")) { + throw new IOException("Missing pattern in definition file"); + } + String pattern = system.getString("pattern"); + + if (!system.has("endOfLife")) { + throw new IOException("No end of life date for " + pattern); + } + LocalDate endOfLife = LocalDate.parse(system.getString("endOfLife")); + + /* Start date defaults to 6 months before end of life */ + LocalDate startDate = system.has("start") ? LocalDate.parse(system.getString("start")) : endOfLife.minusMonths(6); + + File dataFile = getDataFile(system); + + LOGGER.log(Level.FINEST, "Pattern {0} starts {1} and reaches end of life {2} from file {3}", + new Object[]{pattern, startDate, endOfLife, dataFile}); + + String name = readOperatingSystemName(dataFile, pattern); + if (name.isEmpty()) { + LOGGER.log(Level.FINE, "Pattern {0} did not match from file {1}", + new Object[]{pattern, dataFile}); + continue; + } + + if (startDate.isBefore(warningsStartDate)) { + warningsStartDate = startDate; + LOGGER.log(Level.FINE, "Warnings start date is now {0}", warningsStartDate); + } + + LOGGER.log(Level.FINE, "Matched operating system {0}", name); + if (startDate.isBefore(LocalDate.now())) { + this.operatingSystemName = name; + this.documentationUrl = buildDocumentationUrl(this.operatingSystemName); + this.endOfLifeDate = endOfLife.toString(); + if (endOfLife.isBefore(LocalDate.now())) { + LOGGER.log(Level.FINE, "Operating system {0} is after end of life {1}", + new Object[]{name, endOfLife}); + afterEndOfLifeDate = true; + } else { + LOGGER.log(Level.FINE, "Operating system {0} started warnings {1} and reaches end of life {2}", + new Object[]{name, startDate, endOfLife}); + } + } + } + } + + @SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", + justification = "File path defined in war file, not by user") + @CheckForNull + private File getDataFile(@NonNull JSONObject system) { + /* dataFile defaults to /etc/os-release */ + String fileName = "/etc/os-release"; + if (system.has("file")) { + fileName = system.getString("file"); + } + File dataFile = new File(fileName); + return dataFile; + } + + /* Package protected for testing */ + @NonNull + String readOperatingSystemName(File dataFile, @NonNull String patternStr) { + if (dataFile == null || !dataFile.exists()) { + return ""; + } + Pattern pattern = Pattern.compile("^PRETTY_NAME=[\"](" + patternStr + ".*)[\"]"); + String name = ""; + try { + List lines = Files.readAllLines(dataFile.toPath()); + for (String line : lines) { + Matcher matcher = pattern.matcher(line); + if (matcher.matches()) { + name = matcher.group(1); + } + } + } catch (IOException ioe) { + LOGGER.log(Level.SEVERE, "File read exception", ioe); + } + return name; + } + + @NonNull + public String getOperatingSystemName() { + return operatingSystemName; + } + + @NonNull + public String getEndOfLifeDate() { + return endOfLifeDate; + } + + public boolean getAfterEndOfLifeDate() { + return afterEndOfLifeDate; + } + + @NonNull + public String getDocumentationUrl() { + return documentationUrl; + } + + /* Package protected for tests */ + @NonNull + String readDocumentationUrl(File dataFile, @NonNull String patternStr) { + if (dataFile == null || !dataFile.exists()) { + return ""; + } + String operatingSystemName = readOperatingSystemName(dataFile, patternStr); + return buildDocumentationUrl(operatingSystemName); + } + + private String buildDocumentationUrl(String operatingSystemName) { + String scheme = "https"; + String hostName = "www.jenkins.io"; + String path = "/redirect/operating-system-end-of-life"; + String query = "q=" + operatingSystemName.replace(" ", "-").replace("/", "-").replace("(", "").replace(")", ""); + + String url = documentationUrl; + try { + URI documentationURI = new URI(scheme, hostName, path, query, null); + url = documentationURI.toString(); + } catch (URISyntaxException e) { + url = scheme + "://" + hostName + path; + } + return url; + } + + /* + * Send user to the right place depending on "yes" or "no". + */ + @Restricted(DoNotUse.class) // WebOnly + @RequirePOST + public HttpResponse doAct(@QueryParameter String no) throws IOException { + if (no != null) { // dismiss + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + disable(true); + LOGGER.log(Level.FINE, "Disabled operating system end of life monitor"); + return HttpResponses.forwardToPreviousPage(); + } else { + LOGGER.log(Level.FINE, "Enabled operating system end of life monitor"); + return new HttpRedirect(documentationUrl); + } + } + + @Override + public boolean isActivated() { + if (ignoreEndOfLife) { + LOGGER.log(Level.FINE, "Not activated because ignoring end of life monitor"); + return false; + } + if (LocalDate.now().isBefore(warningsStartDate)) { + LOGGER.log(Level.FINE, "Not activated because it is before the start date {0}", warningsStartDate); + return false; + } + LOGGER.log(Level.FINEST, "Activated because it is after the warnings start date {0}", warningsStartDate); + return true; + } + + @Override + public Permission getRequiredPermission() { + return Jenkins.SYSTEM_READ; + } + + @Override + public String getDisplayName() { + return "Operating system end of life monitor"; + } +} diff --git a/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/description.jelly b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/description.jelly new file mode 100644 index 0000000000..bb405e9319 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/description.jelly @@ -0,0 +1,4 @@ + + + ${%blurb} + diff --git a/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/description.properties b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/description.properties new file mode 100644 index 0000000000..0228718c65 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/description.properties @@ -0,0 +1 @@ +blurb=Warns administrators when the controller operating system is approaching end of life and will be unsupported diff --git a/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/end-of-life-data.json b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/end-of-life-data.json new file mode 100644 index 0000000000..d3136f94f1 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/end-of-life-data.json @@ -0,0 +1,98 @@ +[ + { + "pattern": "AlmaLinux.* 8", + "endOfLife": "2029-03-31" + }, + { + "pattern": "Alpine Linux v3.14", + "endOfLife": "2023-05-01" + }, + { + "pattern": "Alpine Linux v3.15", + "endOfLife": "2023-11-01" + }, + { + "pattern": "Alpine Linux v3.16", + "endOfLife": "2024-05-01" + }, + { + "pattern": "Alpine Linux v3.17", + "endOfLife": "2024-11-01" + }, + { + "pattern": "Alpine Linux v3.18", + "endOfLife": "2025-05-01" + }, + { + "pattern": "CentOS Linux.* 7", + "start": "2023-05-01", + "endOfLife": "2023-11-16" + }, + { + "pattern": "CentOS Linux.* 8", + "endOfLife": "2029-03-31" + }, + { + "pattern": "Debian.* 10", + "endOfLife": "2024-06-30" + }, + { + "pattern": "Debian.* 11", + "endOfLife": "2026-06-30" + }, + { + "pattern": "Debian.* 12", + "endOfLife": "2028-06-30" + }, + { + "pattern": "Fedora.* 36", + "endOfLife": "2023-05-18" + }, + { + "pattern": "Fedora.* 37", + "endOfLife": "2023-12-15" + }, + { + "pattern": "Fedora.* 38", + "endOfLife": "2023-05-18" + }, + { + "pattern": "Oracle Linux.* 7", + "start": "2023-05-01", + "endOfLife": "2023-11-16" + }, + { + "pattern": "Oracle Linux.* 8", + "endOfLife": "2029-03-31" + }, + { + "pattern": "Red Hat Enterprise Linux.* 7", + "start": "2023-05-01", + "endOfLife": "2023-11-16" + }, + { + "pattern": "Red Hat Enterprise Linux.* 8", + "endOfLife": "2029-03-31" + }, + { + "pattern": "Rocky Linux.* 8", + "endOfLife": "2029-03-31" + }, + { + "pattern": "Scientific Linux.* 7", + "start": "2023-05-01", + "endOfLife": "2023-11-16" + }, + { + "pattern": "Ubuntu.* 18.04", + "endOfLife": "2023-05-31" + }, + { + "pattern": "Ubuntu.* 20.04", + "endOfLife": "2025-04-02" + }, + { + "pattern": "Ubuntu.* 22.04", + "endOfLife": "2027-04-01" + } +] diff --git a/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/message.jelly b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/message.jelly new file mode 100644 index 0000000000..e61f7a4e88 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/message.jelly @@ -0,0 +1,45 @@ + + + + +
+
+ + + + + +

${it.displayName}

+ + + ${%Past_End_of_Life(it.operatingSystemName, it.endOfLifeDate, it.documentationUrl)} + + + ${%Upcoming_End_of_Life(it.operatingSystemName, it.endOfLifeDate, it.documentationUrl)} + + +
+
diff --git a/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/message.properties b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/message.properties new file mode 100644 index 0000000000..fcc27beff2 --- /dev/null +++ b/core/src/main/resources/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitor/message.properties @@ -0,0 +1,9 @@ +End_of_Life_Heading={0} in Jenkins +Upcoming_End_of_Life=

You are running Jenkins on {0}. \ + Jenkins will no longer support {0} after {1}.\ +

Please plan your upgrade to a supported operating system before {1}.

\ +

Refer to the documentation for details.

+Past_End_of_Life=

You are running Jenkins on {0}. \ + Jenkins stopped supporting {0} as of {1}.\ +

Please upgrade to a supported operating system.

\ +

Refer to the documentation for details.

diff --git a/core/src/test/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitorTest.java b/core/src/test/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitorTest.java new file mode 100644 index 0000000000..7125896597 --- /dev/null +++ b/core/src/test/java/jenkins/monitor/OperatingSystemEndOfLifeAdminMonitorTest.java @@ -0,0 +1,334 @@ +/* + * The MIT License + * + * Copyright 2023 Mark Waite. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.monitor; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; + +import java.io.File; +import java.io.IOException; +import java.util.Random; +import org.junit.Test; + +public class OperatingSystemEndOfLifeAdminMonitorTest { + + private final OperatingSystemEndOfLifeAdminMonitor monitor; + private final Random random = new Random(); + private final String PREFIX = "administrativeMonitor/"; + + public OperatingSystemEndOfLifeAdminMonitorTest() throws IOException { + this.monitor = random.nextBoolean() + ? new OperatingSystemEndOfLifeAdminMonitor() + : new OperatingSystemEndOfLifeAdminMonitor(OperatingSystemEndOfLifeAdminMonitor.class.getName()); + } + + @Test + public void testGetDisplayName() { + assertThat(monitor.getDisplayName(), is("Operating system end of life monitor")); + } + + @Test + public void testGetAfterEndOfLifeDate() { + assertFalse(monitor.getAfterEndOfLifeDate()); + } + + @Test + public void testGetDocumentationUrl() { + assertThat(monitor.getDocumentationUrl(), is(not(nullValue()))); + } + + @Test + public void testGetEndOfLifeDate() { + assertThat(monitor.getEndOfLifeDate(), is("2099-12-31")); + } + + @Test + public void testGetOperatingSystemName() { + /* Operating system name depends on the operating system running test */ + assertThat(monitor.getOperatingSystemName(), not(nullValue())); + } + + @Test + public void testGetSearchUrl() { + assertThat(monitor.getSearchUrl(), is(PREFIX + monitor.getClass().getName())); + } + + @Test + public void testGetUrl() { + assertThat(monitor.getUrl(), is(PREFIX + monitor.getClass().getName())); + } + + @Test + public void testIsActivated() throws IOException { + // Will fail if operating system running the test is reaching end of life soon + assertFalse(monitor.isActivated()); + } + + @Test + public void testIsSecurity() throws IOException { + assertFalse(monitor.isSecurity()); + } + + @Test + public void testNotIsActivatedWhenIgnoreEndOfLife() throws IOException { + monitor.ignoreEndOfLife = true; + assertFalse(monitor.isActivated()); + } + + private String docsUrl(String component) { + return "https://www.jenkins.io/redirect/operating-system-end-of-life?q=" + component; + } + + @Test + public void testReadDocumentationUrlAlma8() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alma-8").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "AlmaLinux.* 8"), is(docsUrl("AlmaLinux-8.7-Stone-Smilodon"))); + } + + @Test + public void testReadDocumentationUrlAlpine314() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.14").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Alpine Linux v3.14"), is(docsUrl("Alpine-Linux-v3.14"))); + } + + @Test + public void testReadDocumentationUrlAlpine315() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.15").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Alpine Linux v3.15"), is(docsUrl("Alpine-Linux-v3.15"))); + } + + @Test + public void testReadDocumentationUrlAlpine316() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.16").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Alpine Linux v3.16"), is(docsUrl("Alpine-Linux-v3.16"))); + } + + @Test + public void testReadDocumentationUrlAlpine317() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.17").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Alpine Linux v3.17"), is(docsUrl("Alpine-Linux-v3.17"))); + } + + @Test + public void testReadDocumentationUrlAlpine318() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.18").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Alpine Linux v3.18"), is(docsUrl("Alpine-Linux-v3.18"))); + } + + @Test + public void testReadDocumentationUrlCentOS7() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-centos-7").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "CentOS Linux.* 7"), is(docsUrl("CentOS-Linux-7-Core"))); + } + + @Test + public void testReadDocumentationUrlDebian10() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-debian-10").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Debian.* 10"), is(docsUrl("Debian-GNU-Linux-10-buster"))); + } + + @Test + public void testReadDocumentationUrlFedora36() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-fedora-36").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Fedora.* 36"), is(docsUrl("Fedora-Linux-36-Container-Image"))); + } + + @Test + public void testReadDocumentationUrlFedora37() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-fedora-37").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Fedora.* 37"), is(docsUrl("Fedora-Linux-37-Container-Image"))); + } + + @Test + public void testReadDocumentationUrlOracle7() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-oracle-7").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Oracle Linux.* 7"), is(docsUrl("Oracle-Linux-Server-7.9"))); + } + + @Test + public void testReadDocumentationUrlOracle8() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-oracle-8").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Oracle Linux.* 8"), is(docsUrl("Oracle-Linux-Server-8.7"))); + } + + @Test + public void testReadDocumentationUrlRedHat7() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-redhat-7").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Red Hat Enterprise Linux.* 7"), is(docsUrl("Red-Hat-Enterprise-Linux-Server-7.9-Maipo"))); + } + + @Test + public void testReadDocumentationUrlRedHat8() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-redhat-8").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Red Hat Enterprise Linux.* 8"), is(docsUrl("Red-Hat-Enterprise-Linux-8.8-Ootpa"))); + } + + @Test + public void testReadDocumentationUrlRocky8() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-rocky-8").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Rocky Linux.* 8"), is(docsUrl("Rocky-Linux-8.7-Green-Obsidian"))); + } + + @Test + public void testReadDocumentationUrlScientific7() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-scientific-7").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Scientific Linux.* 7"), is(docsUrl("Scientific-Linux-7.9-Nitrogen"))); + } + + @Test + public void testReadDocumentationUrlUbuntu18() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-ubuntu-18.04").toURI()); + assertThat(monitor.readDocumentationUrl(releaseFile, "Ubuntu.* 18"), is(docsUrl("Ubuntu-18.04.6-LTS"))); + } + + @Test + public void testReadOperatingSystemListEmptySet() { + IOException e = assertThrows(IOException.class, () -> monitor.readOperatingSystemList("[]")); + assertThat(e.getMessage(), is("Empty data set")); + } + + @Test + public void testReadOperatingSystemListNoEndOfLife() { + IOException e = assertThrows(IOException.class, () -> monitor.readOperatingSystemList("[{\"pattern\": \"Alpine\"}]")); + assertThat(e.getMessage(), is("No end of life date for Alpine")); + } + + @Test + public void testReadOperatingSystemListNoPattern() { + IOException e = assertThrows(IOException.class, () -> monitor.readOperatingSystemList("[{\"endOfLife\": \"2029-03-31\"}]")); + assertThat(e.getMessage(), is("Missing pattern in definition file")); + } + + @Test + public void testReadOperatingSystemNameAlma8() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alma-8").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "AlmaLinux.* 8"), is("AlmaLinux 8.7 (Stone Smilodon)")); + } + + @Test + public void testReadOperatingSystemNameAlpine314() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.14").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Alpine Linux v3.14"), is("Alpine Linux v3.14")); + } + + @Test + public void testReadOperatingSystemNameAlpine315() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.15").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Alpine Linux v3.15"), is("Alpine Linux v3.15")); + } + + @Test + public void testReadOperatingSystemNameAlpine316() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.16").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Alpine Linux v3.16"), is("Alpine Linux v3.16")); + } + + @Test + public void testReadOperatingSystemNameAlpine317() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.17").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Alpine Linux v3.17"), is("Alpine Linux v3.17")); + } + + @Test + public void testReadOperatingSystemNameAlpine318() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-alpine-3.18").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Alpine Linux v3.18"), is("Alpine Linux v3.18")); + } + + @Test + public void testReadOperatingSystemNameCentOS7() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-centos-7").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "CentOS Linux.* 7"), is("CentOS Linux 7 (Core)")); + } + + @Test + public void testReadOperatingSystemNameDebian10() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-debian-10").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Debian.* 10"), is("Debian GNU/Linux 10 (buster)")); + } + + @Test + public void testReadOperatingSystemNameFedora36() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-fedora-36").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Fedora.* 36"), is("Fedora Linux 36 (Container Image)")); + } + + @Test + public void testReadOperatingSystemNameFedora37() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-fedora-37").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Fedora.* 37"), is("Fedora Linux 37 (Container Image)")); + } + + @Test + public void testReadOperatingSystemNameMissingFile() { + assertThat(monitor.readOperatingSystemName(new File("/this/file/does/not/exist"), ".*"), is("")); + } + + @Test + public void testReadOperatingSystemNameOracle7() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-oracle-7").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Oracle Linux.* 7"), is("Oracle Linux Server 7.9")); + } + + @Test + public void testReadOperatingSystemNameOracle8() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-oracle-8").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Oracle Linux.* 8"), is("Oracle Linux Server 8.7")); + } + + @Test + public void testReadOperatingSystemNameRedHat7() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-redhat-7").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Red Hat Enterprise Linux.* 7"), is("Red Hat Enterprise Linux Server 7.9 (Maipo)")); + } + + @Test + public void testReadOperatingSystemNameRedHat8() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-redhat-8").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Red Hat Enterprise Linux.* 8"), is("Red Hat Enterprise Linux 8.8 (Ootpa)")); + } + + @Test + public void testReadOperatingSystemNameRocky8() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-rocky-8").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Rocky Linux.* 8"), is("Rocky Linux 8.7 (Green Obsidian)")); + } + + @Test + public void testReadOperatingSystemNameScientific7() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-scientific-7").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Scientific Linux.* 7"), is("Scientific Linux 7.9 (Nitrogen)")); + } + + @Test + public void testReadOperatingSystemNameUbuntu18() throws Exception { + File releaseFile = new File(this.getClass().getResource("os-release-ubuntu-18.04").toURI()); + assertThat(monitor.readOperatingSystemName(releaseFile, "Ubuntu.* 18"), is("Ubuntu 18.04.6 LTS")); + } +} diff --git a/core/src/test/resources/jenkins/monitor/os-release-alma-8 b/core/src/test/resources/jenkins/monitor/os-release-alma-8 new file mode 100644 index 0000000000..d483909db5 --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-alma-8 @@ -0,0 +1,18 @@ +NAME="AlmaLinux" +VERSION="8.7 (Stone Smilodon)" +ID="almalinux" +ID_LIKE="rhel centos fedora" +VERSION_ID="8.7" +PLATFORM_ID="platform:el8" +PRETTY_NAME="AlmaLinux 8.7 (Stone Smilodon)" +ANSI_COLOR="0;34" +LOGO="fedora-logo-icon" +CPE_NAME="cpe:/o:almalinux:almalinux:8::baseos" +HOME_URL="https://almalinux.org/" +DOCUMENTATION_URL="https://wiki.almalinux.org/" +BUG_REPORT_URL="https://bugs.almalinux.org/" + +ALMALINUX_MANTISBT_PROJECT="AlmaLinux-8" +ALMALINUX_MANTISBT_PROJECT_VERSION="8.7" +REDHAT_SUPPORT_PRODUCT="AlmaLinux" +REDHAT_SUPPORT_PRODUCT_VERSION="8.7" diff --git a/core/src/test/resources/jenkins/monitor/os-release-alpine-3.14 b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.14 new file mode 100644 index 0000000000..55adf73bc9 --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.14 @@ -0,0 +1,6 @@ +NAME="Alpine Linux" +ID=alpine +VERSION_ID=3.14.10 +PRETTY_NAME="Alpine Linux v3.14" +HOME_URL="https://alpinelinux.org/" +BUG_REPORT_URL="https://bugs.alpinelinux.org/" diff --git a/core/src/test/resources/jenkins/monitor/os-release-alpine-3.15 b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.15 new file mode 100644 index 0000000000..8857f30893 --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.15 @@ -0,0 +1,6 @@ +NAME="Alpine Linux" +ID=alpine +VERSION_ID=3.15.8 +PRETTY_NAME="Alpine Linux v3.15" +HOME_URL="https://alpinelinux.org/" +BUG_REPORT_URL="https://bugs.alpinelinux.org/" diff --git a/core/src/test/resources/jenkins/monitor/os-release-alpine-3.16 b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.16 new file mode 100644 index 0000000000..b523a229bf --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.16 @@ -0,0 +1,6 @@ +NAME="Alpine Linux" +ID=alpine +VERSION_ID=3.16.5 +PRETTY_NAME="Alpine Linux v3.16" +HOME_URL="https://alpinelinux.org/" +BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues" diff --git a/core/src/test/resources/jenkins/monitor/os-release-alpine-3.17 b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.17 new file mode 100644 index 0000000000..8478d8e8bf --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.17 @@ -0,0 +1,6 @@ +NAME="Alpine Linux" +ID=alpine +VERSION_ID=3.17.3 +PRETTY_NAME="Alpine Linux v3.17" +HOME_URL="https://alpinelinux.org/" +BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues" diff --git a/core/src/test/resources/jenkins/monitor/os-release-alpine-3.18 b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.18 new file mode 100644 index 0000000000..a9e1d0057d --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-alpine-3.18 @@ -0,0 +1,6 @@ +NAME="Alpine Linux" +ID=alpine +VERSION_ID=3.18.0 +PRETTY_NAME="Alpine Linux v3.18" +HOME_URL="https://alpinelinux.org/" +BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues" diff --git a/core/src/test/resources/jenkins/monitor/os-release-centos-7 b/core/src/test/resources/jenkins/monitor/os-release-centos-7 new file mode 100644 index 0000000000..7037a940fa --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-centos-7 @@ -0,0 +1,16 @@ +NAME="CentOS Linux" +VERSION="7 (Core)" +ID="centos" +ID_LIKE="rhel fedora" +VERSION_ID="7" +PRETTY_NAME="CentOS Linux 7 (Core)" +ANSI_COLOR="0;31" +CPE_NAME="cpe:/o:centos:centos:7" +HOME_URL="https://www.centos.org/" +BUG_REPORT_URL="https://bugs.centos.org/" + +CENTOS_MANTISBT_PROJECT="CentOS-7" +CENTOS_MANTISBT_PROJECT_VERSION="7" +REDHAT_SUPPORT_PRODUCT="centos" +REDHAT_SUPPORT_PRODUCT_VERSION="7" + diff --git a/core/src/test/resources/jenkins/monitor/os-release-debian-10 b/core/src/test/resources/jenkins/monitor/os-release-debian-10 new file mode 100644 index 0000000000..9b5419df8b --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-debian-10 @@ -0,0 +1,9 @@ +PRETTY_NAME="Debian GNU/Linux 10 (buster)" +NAME="Debian GNU/Linux" +VERSION_ID="10" +VERSION="10 (buster)" +VERSION_CODENAME=buster +ID=debian +HOME_URL="https://www.debian.org/" +SUPPORT_URL="https://www.debian.org/support" +BUG_REPORT_URL="https://bugs.debian.org/" diff --git a/core/src/test/resources/jenkins/monitor/os-release-fedora-36 b/core/src/test/resources/jenkins/monitor/os-release-fedora-36 new file mode 100644 index 0000000000..ae039188b2 --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-fedora-36 @@ -0,0 +1,22 @@ +NAME="Fedora Linux" +VERSION="36 (Container Image)" +ID=fedora +VERSION_ID=36 +VERSION_CODENAME="" +PLATFORM_ID="platform:f36" +PRETTY_NAME="Fedora Linux 36 (Container Image)" +ANSI_COLOR="0;38;2;60;110;180" +LOGO=fedora-logo-icon +CPE_NAME="cpe:/o:fedoraproject:fedora:36" +HOME_URL="https://fedoraproject.org/" +DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f36/system-administrators-guide/" +SUPPORT_URL="https://ask.fedoraproject.org/" +BUG_REPORT_URL="https://bugzilla.redhat.com/" +REDHAT_BUGZILLA_PRODUCT="Fedora" +REDHAT_BUGZILLA_PRODUCT_VERSION=36 +REDHAT_SUPPORT_PRODUCT="Fedora" +REDHAT_SUPPORT_PRODUCT_VERSION=36 +PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy" +SUPPORT_END=2023-05-16 +VARIANT="Container Image" +VARIANT_ID=container diff --git a/core/src/test/resources/jenkins/monitor/os-release-fedora-37 b/core/src/test/resources/jenkins/monitor/os-release-fedora-37 new file mode 100644 index 0000000000..a44f5bc6ef --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-fedora-37 @@ -0,0 +1,22 @@ +NAME="Fedora Linux" +VERSION="37 (Container Image)" +ID=fedora +VERSION_ID=37 +VERSION_CODENAME="" +PLATFORM_ID="platform:f37" +PRETTY_NAME="Fedora Linux 37 (Container Image)" +ANSI_COLOR="0;38;2;60;110;180" +LOGO=fedora-logo-icon +CPE_NAME="cpe:/o:fedoraproject:fedora:37" +DEFAULT_HOSTNAME="fedora" +HOME_URL="https://fedoraproject.org/" +DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f37/system-administrators-guide/" +SUPPORT_URL="https://ask.fedoraproject.org/" +BUG_REPORT_URL="https://bugzilla.redhat.com/" +REDHAT_BUGZILLA_PRODUCT="Fedora" +REDHAT_BUGZILLA_PRODUCT_VERSION=37 +REDHAT_SUPPORT_PRODUCT="Fedora" +REDHAT_SUPPORT_PRODUCT_VERSION=37 +SUPPORT_END=2023-11-14 +VARIANT="Container Image" +VARIANT_ID=container diff --git a/core/src/test/resources/jenkins/monitor/os-release-oracle-7 b/core/src/test/resources/jenkins/monitor/os-release-oracle-7 new file mode 100644 index 0000000000..f8823a8e1c --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-oracle-7 @@ -0,0 +1,17 @@ +NAME="Oracle Linux Server" +VERSION="7.9" +ID="ol" +ID_LIKE="fedora" +VARIANT="Server" +VARIANT_ID="server" +VERSION_ID="7.9" +PRETTY_NAME="Oracle Linux Server 7.9" +ANSI_COLOR="0;31" +CPE_NAME="cpe:/o:oracle:linux:7:9:server" +HOME_URL="https://linux.oracle.com/" +BUG_REPORT_URL="https://bugzilla.oracle.com/" + +ORACLE_BUGZILLA_PRODUCT="Oracle Linux 7" +ORACLE_BUGZILLA_PRODUCT_VERSION=7.9 +ORACLE_SUPPORT_PRODUCT="Oracle Linux" +ORACLE_SUPPORT_PRODUCT_VERSION=7.9 diff --git a/core/src/test/resources/jenkins/monitor/os-release-oracle-8 b/core/src/test/resources/jenkins/monitor/os-release-oracle-8 new file mode 100644 index 0000000000..b91c366e47 --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-oracle-8 @@ -0,0 +1,18 @@ +NAME="Oracle Linux Server" +VERSION="8.7" +ID="ol" +ID_LIKE="fedora" +VARIANT="Server" +VARIANT_ID="server" +VERSION_ID="8.7" +PLATFORM_ID="platform:el8" +PRETTY_NAME="Oracle Linux Server 8.7" +ANSI_COLOR="0;31" +CPE_NAME="cpe:/o:oracle:linux:8:7:server" +HOME_URL="https://linux.oracle.com/" +BUG_REPORT_URL="https://bugzilla.oracle.com/" + +ORACLE_BUGZILLA_PRODUCT="Oracle Linux 8" +ORACLE_BUGZILLA_PRODUCT_VERSION=8.7 +ORACLE_SUPPORT_PRODUCT="Oracle Linux" +ORACLE_SUPPORT_PRODUCT_VERSION=8.7 diff --git a/core/src/test/resources/jenkins/monitor/os-release-redhat-7 b/core/src/test/resources/jenkins/monitor/os-release-redhat-7 new file mode 100644 index 0000000000..ec038b12aa --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-redhat-7 @@ -0,0 +1,17 @@ +NAME="Red Hat Enterprise Linux Server" +VERSION="7.9 (Maipo)" +ID="rhel" +ID_LIKE="fedora" +VARIANT="Server" +VARIANT_ID="server" +VERSION_ID="7.9" +PRETTY_NAME="Red Hat Enterprise Linux Server 7.9 (Maipo)" +ANSI_COLOR="0;31" +CPE_NAME="cpe:/o:redhat:enterprise_linux:7.9:GA:server" +HOME_URL="https://www.redhat.com/" +BUG_REPORT_URL="https://bugzilla.redhat.com/" + +REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7" +REDHAT_BUGZILLA_PRODUCT_VERSION=7.9 +REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" +REDHAT_SUPPORT_PRODUCT_VERSION="7.9" diff --git a/core/src/test/resources/jenkins/monitor/os-release-redhat-8 b/core/src/test/resources/jenkins/monitor/os-release-redhat-8 new file mode 100644 index 0000000000..2fafad589d --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-redhat-8 @@ -0,0 +1,17 @@ +NAME="Red Hat Enterprise Linux" +VERSION="8.8 (Ootpa)" +ID="rhel" +ID_LIKE="fedora" +VERSION_ID="8.8" +PLATFORM_ID="platform:el8" +PRETTY_NAME="Red Hat Enterprise Linux 8.8 (Ootpa)" +ANSI_COLOR="0;31" +CPE_NAME="cpe:/o:redhat:enterprise_linux:8::baseos" +HOME_URL="https://www.redhat.com/" +DOCUMENTATION_URL="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8" +BUG_REPORT_URL="https://bugzilla.redhat.com/" + +REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8" +REDHAT_BUGZILLA_PRODUCT_VERSION=8.8 +REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" +REDHAT_SUPPORT_PRODUCT_VERSION="8.8" diff --git a/core/src/test/resources/jenkins/monitor/os-release-rocky-8 b/core/src/test/resources/jenkins/monitor/os-release-rocky-8 new file mode 100644 index 0000000000..2fd5d0f4bc --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-rocky-8 @@ -0,0 +1,16 @@ +NAME="Rocky Linux" +VERSION="8.7 (Green Obsidian)" +ID="rocky" +ID_LIKE="rhel centos fedora" +VERSION_ID="8.7" +PLATFORM_ID="platform:el8" +PRETTY_NAME="Rocky Linux 8.7 (Green Obsidian)" +ANSI_COLOR="0;32" +LOGO="fedora-logo-icon" +CPE_NAME="cpe:/o:rocky:rocky:8:GA" +HOME_URL="https://rockylinux.org/" +BUG_REPORT_URL="https://bugs.rockylinux.org/" +ROCKY_SUPPORT_PRODUCT="Rocky-Linux-8" +ROCKY_SUPPORT_PRODUCT_VERSION="8.7" +REDHAT_SUPPORT_PRODUCT="Rocky Linux" +REDHAT_SUPPORT_PRODUCT_VERSION="8.7" diff --git a/core/src/test/resources/jenkins/monitor/os-release-scientific-7 b/core/src/test/resources/jenkins/monitor/os-release-scientific-7 new file mode 100644 index 0000000000..e8ba770fd4 --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-scientific-7 @@ -0,0 +1,15 @@ +NAME="Scientific Linux" +VERSION="7.9 (Nitrogen)" +ID="scientific" +ID_LIKE="rhel centos fedora" +VERSION_ID="7.9" +PRETTY_NAME="Scientific Linux 7.9 (Nitrogen)" +ANSI_COLOR="0;31" +CPE_NAME="cpe:/o:scientificlinux:scientificlinux:7.9:GA" +HOME_URL="http://www.scientificlinux.org//" +BUG_REPORT_URL="mailto:scientific-linux-devel@listserv.fnal.gov" + +REDHAT_BUGZILLA_PRODUCT="Scientific Linux 7" +REDHAT_BUGZILLA_PRODUCT_VERSION=7.9 +REDHAT_SUPPORT_PRODUCT="Scientific Linux" +REDHAT_SUPPORT_PRODUCT_VERSION="7.9" diff --git a/core/src/test/resources/jenkins/monitor/os-release-ubuntu-18.04 b/core/src/test/resources/jenkins/monitor/os-release-ubuntu-18.04 new file mode 100644 index 0000000000..097c592002 --- /dev/null +++ b/core/src/test/resources/jenkins/monitor/os-release-ubuntu-18.04 @@ -0,0 +1,12 @@ +NAME="Ubuntu" +VERSION="18.04.6 LTS (Bionic Beaver)" +ID=ubuntu +ID_LIKE=debian +PRETTY_NAME="Ubuntu 18.04.6 LTS" +VERSION_ID="18.04" +HOME_URL="https://www.ubuntu.com/" +SUPPORT_URL="https://help.ubuntu.com/" +BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" +PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" +VERSION_CODENAME=bionic +UBUNTU_CODENAME=bionic