From d04a80b2d7a1a53e11637a2d9e89e82295cc14f9 Mon Sep 17 00:00:00 2001 From: EBIBO Date: Tue, 26 Sep 2023 05:10:11 +0800 Subject: [PATCH 1/5] [JENKINS-71890] Model links in build history views and administrative monitors no longer work (#8485) (cherry picked from commit 9f6bf542829ad1248af0b4dc6af08bdf65d4a1f6) --- war/src/main/js/components/dropdowns/jumplists.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/war/src/main/js/components/dropdowns/jumplists.js b/war/src/main/js/components/dropdowns/jumplists.js index 9158be7c3d64..baa54711190e 100644 --- a/war/src/main/js/components/dropdowns/jumplists.js +++ b/war/src/main/js/components/dropdowns/jumplists.js @@ -11,7 +11,7 @@ function init() { * Appends a ⌄ button at the end of links which support jump lists */ function generateJumplistAccessors() { - document.querySelectorAll("A.model-link").forEach((link) => { + behaviorShim.specify("A.model-link", "-jumplist-", 999, (link) => { const isFirefox = navigator.userAgent.indexOf("Firefox") !== -1; // Firefox adds unwanted lines when copying buttons in text, so use a span instead const dropdownChevron = document.createElement( From 4cb85704dcde04c61f7508d736fb404538e8f11e Mon Sep 17 00:00:00 2001 From: Daniel Beck <1831569+daniel-beck@users.noreply.github.com> Date: Thu, 31 Aug 2023 20:14:11 +0200 Subject: [PATCH 2/5] Add telemetry for security-related settings (#8440) * Add telemetry for security-related settings * Actually include component information * FindBugs, also TcpSlaveAgentListener can be null --------- Co-authored-by: Daniel Beck (cherry picked from commit 95373a96f710874d2b9d2f9bd40d28f1af7dc9e5) --- .../telemetry/impl/SecurityConfiguration.java | 79 +++++++++++++++++++ .../SecurityConfiguration/description.jelly | 17 ++++ 2 files changed, 96 insertions(+) create mode 100644 core/src/main/java/jenkins/telemetry/impl/SecurityConfiguration.java create mode 100644 core/src/main/resources/jenkins/telemetry/impl/SecurityConfiguration/description.jelly diff --git a/core/src/main/java/jenkins/telemetry/impl/SecurityConfiguration.java b/core/src/main/java/jenkins/telemetry/impl/SecurityConfiguration.java new file mode 100644 index 000000000000..a59a34bcbf4c --- /dev/null +++ b/core/src/main/java/jenkins/telemetry/impl/SecurityConfiguration.java @@ -0,0 +1,79 @@ +/* + * The MIT License + * + * Copyright (c) 2023, CloudBees, Inc. + * + * 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.telemetry.impl; + +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.Extension; +import hudson.ExtensionList; +import hudson.TcpSlaveAgentListener; +import hudson.security.csrf.CrumbIssuer; +import java.time.LocalDate; +import jenkins.model.Jenkins; +import jenkins.security.apitoken.ApiTokenPropertyConfiguration; +import jenkins.telemetry.Telemetry; +import net.sf.json.JSONObject; + +@Extension +public class SecurityConfiguration extends Telemetry { + @NonNull + @Override + public String getDisplayName() { + return "Basic information about security-related settings"; + } + + @NonNull + @Override + public LocalDate getStart() { + return LocalDate.of(2023, 8, 1); + } + + @NonNull + @Override + public LocalDate getEnd() { + return LocalDate.of(2023, 12, 1); + } + + @Override + public JSONObject createContent() { + final Jenkins j = Jenkins.get(); + final JSONObject o = new JSONObject(); + o.put("components", buildComponentInformation()); + + o.put("authorizationStrategy", j.getAuthorizationStrategy().getClass().getName()); + o.put("securityRealm", j.getSecurityRealm().getClass().getName()); + final CrumbIssuer crumbIssuer = j.getCrumbIssuer(); + o.put("crumbIssuer", crumbIssuer == null ? null : crumbIssuer.getClass().getName()); + o.put("markupFormatter", j.getMarkupFormatter().getClass().getName()); + final TcpSlaveAgentListener tcpSlaveAgentListener = j.getTcpSlaveAgentListener(); + o.put("inboundAgentListener", tcpSlaveAgentListener == null ? null : tcpSlaveAgentListener.configuredPort != -1); + + final ApiTokenPropertyConfiguration apiTokenPropertyConfiguration = ExtensionList.lookupSingleton(ApiTokenPropertyConfiguration.class); + o.put("apiTokenCreationOfLegacyTokenEnabled", apiTokenPropertyConfiguration.isCreationOfLegacyTokenEnabled()); + o.put("apiTokenTokenGenerationOnCreationEnabled", apiTokenPropertyConfiguration.isTokenGenerationOnCreationEnabled()); + o.put("apiTokenUsageStatisticsEnabled", apiTokenPropertyConfiguration.isUsageStatisticsEnabled()); + + return o; + } +} diff --git a/core/src/main/resources/jenkins/telemetry/impl/SecurityConfiguration/description.jelly b/core/src/main/resources/jenkins/telemetry/impl/SecurityConfiguration/description.jelly new file mode 100644 index 000000000000..85dd418c67e6 --- /dev/null +++ b/core/src/main/resources/jenkins/telemetry/impl/SecurityConfiguration/description.jelly @@ -0,0 +1,17 @@ + + + This trial collects basic information about security settings: +
    +
  • The type of the currently configured security realm, e.g., hudson.security.HudsonPrivateSecurityRealm
  • +
  • The type of the currently configured authorization strategy, e.g., hudson.security.ProjectMatrixAuthorizationStrategy
  • +
  • The type of the currently configured crumb issuer, e.g., hudson.security.csrf.DefaultCrumbIssuer
  • +
  • The type of the currently configured markup formatter, e.g., hudson.markup.RawHtmlMarkupFormatter
  • +
  • Whether the TCP port for inbound agents is enabled (fixed or random) or disabled
  • +
  • Whether the API token option labeled Generate a legacy API token for each newly created user (Not recommended) is enabled or disabled
  • +
  • Whether the API token option labeled Allow users to manually create a legacy API token (Not recommended) is enabled or disabled
  • +
  • Whether the API token option labeled Enable API Token usage statistics is enabled or disabled
  • +
+ + Additionally this trial collects the list of installed plugins, their version, and the version of Jenkins. + This data will be used to understand the popularity of the various implementations for each of these features. +
From 2cc2c05b2c9a2ff4e3018ed874c00a5ba2e14539 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Wed, 20 Sep 2023 14:45:14 -0400 Subject: [PATCH 3/5] =?UTF-8?q?[JENKINS-72016]=20Define=20a=20thread=20poo?= =?UTF-8?q?l=20for=20`ProxyConfiguration`=E2=80=99s=20`HttpClient`=20(#849?= =?UTF-8?q?0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Define a thread pool for `ProxyConfiguration`’s `HttpClient` * Skip test on Windows https://github.com/jenkinsci/jenkins/pull/8490#issuecomment-1720108881 (cherry picked from commit 3e1747eca666b4a4ff495e83966065ca9480a386) --- .../main/java/hudson/ProxyConfiguration.java | 7 ++ .../java/hudson/ProxyConfigurationTest.java | 71 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 test/src/test/java/hudson/ProxyConfigurationTest.java diff --git a/core/src/main/java/hudson/ProxyConfiguration.java b/core/src/main/java/hudson/ProxyConfiguration.java index a165fa6e3151..08f7131289b2 100644 --- a/core/src/main/java/hudson/ProxyConfiguration.java +++ b/core/src/main/java/hudson/ProxyConfiguration.java @@ -31,7 +31,9 @@ import hudson.model.Descriptor; import hudson.model.Saveable; import hudson.model.listeners.SaveableListener; +import hudson.util.DaemonThreadFactory; import hudson.util.FormValidation; +import hudson.util.NamingThreadFactory; import hudson.util.Scrambler; import hudson.util.Secret; import hudson.util.XStream2; @@ -58,6 +60,8 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; import jenkins.UserAgentURLConnectionDecorator; @@ -370,6 +374,8 @@ public static HttpClient newHttpClient() { return newHttpClientBuilder().followRedirects(HttpClient.Redirect.NORMAL).build(); } + private static final Executor httpClientExecutor = Executors.newCachedThreadPool(new NamingThreadFactory(new DaemonThreadFactory(), "Jenkins HttpClient")); + /** * Create a new {@link HttpClient.Builder} preconfigured with Jenkins-specific default settings. * @@ -397,6 +403,7 @@ public static HttpClient.Builder newHttpClientBuilder() { if (DEFAULT_CONNECT_TIMEOUT_MILLIS > 0) { httpClientBuilder.connectTimeout(Duration.ofMillis(DEFAULT_CONNECT_TIMEOUT_MILLIS)); } + httpClientBuilder.executor(httpClientExecutor); return httpClientBuilder; } diff --git a/test/src/test/java/hudson/ProxyConfigurationTest.java b/test/src/test/java/hudson/ProxyConfigurationTest.java new file mode 100644 index 000000000000..f1f796968525 --- /dev/null +++ b/test/src/test/java/hudson/ProxyConfigurationTest.java @@ -0,0 +1,71 @@ +/* + * The MIT License + * + * Copyright 2023 CloudBees, Inc. + * + * 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 hudson; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import hudson.model.InvisibleAction; +import hudson.model.UnprotectedRootAction; +import java.net.URI; +import org.junit.Assume; +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.TestExtension; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.HttpResponses; + +public final class ProxyConfigurationTest { + + @Rule + public JenkinsRule r = new JenkinsRule(); + + @Test + public void httpClientExecutor() throws Exception { + Assume.assumeFalse("Too slow on Windows", Functions.isWindows()); + for (int i = 0; i < 50_000; i++) { + if (i % 1_000 == 0) { + System.err.println("#" + i); + } + assertThat(ProxyConfiguration.newHttpClient().send(ProxyConfiguration.newHttpRequestBuilder(URI.create(r.getURL() + "ping/")).build(), + java.net.http.HttpResponse.BodyHandlers.discarding()).statusCode(), + is(200)); + } + } + + @TestExtension("httpClientExecutor") + public static final class Ping extends InvisibleAction implements UnprotectedRootAction { + @Override + public String getUrlName() { + return "ping"; + } + + public HttpResponse doIndex() { + return HttpResponses.ok(); + } + } + +} From f0673ee2e91db530f24177c5bed921bde166c02c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 14:27:13 -0700 Subject: [PATCH 4/5] Bump org.apache.commons:commons-compress from 1.23.0 to 1.24.0 (#8478) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (cherry picked from commit fa02412b8323490356dec49fac6c2277bf1d6c01) --- bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/pom.xml b/bom/pom.xml index 514a3ddd5511..dfc0cb222d4c 100644 --- a/bom/pom.xml +++ b/bom/pom.xml @@ -194,7 +194,7 @@ THE SOFTWARE. org.apache.commons commons-compress - 1.23.0 + 1.24.0 org.codehaus.groovy From 1baa6838d275307c5285df67a0b1fdd62fc96dff Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Fri, 29 Sep 2023 09:26:14 -0700 Subject: [PATCH 5/5] [JENKINS-72067] High memory usage from `XStream2.AssociatedConverterImpl` (#8529) (cherry picked from commit 91527dce3a80f352fd62c9bb9ed46d495d5624bf) --- core/src/main/java/hudson/util/XStream2.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/hudson/util/XStream2.java b/core/src/main/java/hudson/util/XStream2.java index 5c6ebc566731..cf1b5e9bcaab 100644 --- a/core/src/main/java/hudson/util/XStream2.java +++ b/core/src/main/java/hudson/util/XStream2.java @@ -475,12 +475,8 @@ protected Class computeValue(Class type) { return computeConverterClass(type); } }; - private final ClassValue cache = new ClassValue() { - @Override - protected Converter computeValue(Class type) { - return computeConverter(type); - } - }; + private final ConcurrentHashMap, Converter> cache = + new ConcurrentHashMap<>(); private AssociatedConverterImpl(XStream xstream) { this.xstream = xstream; @@ -491,7 +487,9 @@ private Converter findConverter(@CheckForNull Class t) { if (t == null) { return null; } - return cache.get(t); + Converter result = cache.computeIfAbsent(t, unused -> computeConverter(t)); + // ConcurrentHashMap does not allow null, so use this object to represent null + return result == this ? null : result; } @CheckForNull @@ -515,7 +513,8 @@ private static Class computeConverterClass(@NonNull private Converter computeConverter(@NonNull Class t) { Class cl = classCache.get(t); if (cl == null) { - return null; + // See above.. this object in cache represents null + return this; } try { Constructor c = cl.getConstructors()[0];