Skip to content

Commit

Permalink
Merge branch 'master' into un-inline-build-now
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-beck authored Sep 18, 2023
2 parents 3fc78c5 + c5fbbbe commit 557443f
Show file tree
Hide file tree
Showing 164 changed files with 2,260 additions and 914 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
private_key: ${{ secrets.JENKINS_CHANGELOG_UPDATER_PRIVATE_KEY }}
repository: jenkins-infra/jenkins.io
- name: Check out
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Publish jenkins.io changelog draft
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-release-artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
project-version: ${{ steps.set-version.outputs.project-version }}
is-lts: ${{ steps.set-version.outputs.is-lts }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
Expand Down
8 changes: 4 additions & 4 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ THE SOFTWARE.

<properties>
<asm.version>9.5</asm.version>
<slf4jVersion>2.0.7</slf4jVersion>
<slf4jVersion>2.0.9</slf4jVersion>
<stapler.version>1802.v9e2750160d01</stapler.version>
<groovy.version>2.4.21</groovy.version>
</properties>
Expand All @@ -64,7 +64,7 @@ THE SOFTWARE.
<!-- https://docs.spring.io/spring-security/site/docs/5.5.4/reference/html5/#getting-maven-no-boot -->
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>5.8.5</version>
<version>5.8.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down Expand Up @@ -189,12 +189,12 @@ THE SOFTWARE.
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.13</version>
<version>1.10.14</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.23.0</version>
<version>1.24.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
Expand Down
14 changes: 11 additions & 3 deletions core/src/main/java/hudson/init/InitStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
Expand Down Expand Up @@ -64,7 +65,11 @@ private void listPluginFiles(PluginManager pm, String extension, Collection<File
if (files == null)
throw new IOException("Jenkins is unable to create " + pm.rootDir + "\nPerhaps its security privilege is insufficient");

all.addAll(Arrays.asList(files));
List<File> pluginFiles = new ArrayList<>();
pluginFiles.addAll(List.of(files));
pluginFiles.sort(Comparator.comparing(File::getName));

all.addAll(pluginFiles);
}

/**
Expand All @@ -76,15 +81,16 @@ private void listPluginFiles(PluginManager pm, String extension, Collection<File
protected void getBundledPluginsFromProperty(final List<File> r) {
String hplProperty = SystemProperties.getString("hudson.bundled.plugins");
if (hplProperty != null) {
List<File> pluginFiles = new ArrayList<>();
for (String hplLocation : hplProperty.split(",")) {
File hpl = new File(hplLocation.trim());
if (hpl.exists()) {
r.add(hpl);
pluginFiles.add(hpl);
} else if (hpl.getName().contains("*")) {
try {
new DirScanner.Glob(hpl.getName(), null).scan(hpl.getParentFile(), new FileVisitor() {
@Override public void visit(File f, String relativePath) throws IOException {
r.add(f);
pluginFiles.add(f);
}
});
} catch (IOException x) {
Expand All @@ -94,6 +100,8 @@ protected void getBundledPluginsFromProperty(final List<File> r) {
LOGGER.warning("bundled plugin " + hplLocation + " does not exist");
}
}
pluginFiles.sort(Comparator.comparing(File::getName));
r.addAll(pluginFiles);
}
}

Expand Down
12 changes: 9 additions & 3 deletions core/src/main/java/hudson/model/Label.java
Original file line number Diff line number Diff line change
Expand Up @@ -592,10 +592,16 @@ public static Set<LabelAtom> parse(@CheckForNull String labels) {
final Set<LabelAtom> r = new TreeSet<>();
labels = fixNull(labels);
if (labels.length() > 0) {
final QuotedStringTokenizer tokenizer = new QuotedStringTokenizer(labels);
while (tokenizer.hasMoreTokens())
r.add(Jenkins.get().getLabelAtom(tokenizer.nextToken()));
Jenkins j = Jenkins.get();
LabelAtom labelAtom = j.tryGetLabelAtom(labels);
if (labelAtom == null) {
final QuotedStringTokenizer tokenizer = new QuotedStringTokenizer(labels);
while (tokenizer.hasMoreTokens())
r.add(j.getLabelAtom(tokenizer.nextToken()));
} else {
r.add(labelAtom);
}
}
return r;
}

Expand Down
16 changes: 14 additions & 2 deletions core/src/main/java/hudson/model/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import net.sf.json.JSONObject;
import org.jvnet.localizer.Localizable;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.accmod.restrictions.ProtectedExternally;
import org.kohsuke.stapler.BindInterceptor;
import org.kohsuke.stapler.Stapler;
Expand Down Expand Up @@ -298,20 +299,31 @@ public OfflineCause getTemporaryOfflineCause() {
public TagCloud<LabelAtom> getLabelCloud() {
return new TagCloud<>(getAssignedLabels(), Label::getTiedJobCount);
}

/**
* @return An immutable set of LabelAtom associated with the current node label.
*/
@NonNull
@Restricted(NoExternalUse.class)
protected Set<LabelAtom> getLabelAtomSet() {
// Default implementation doesn't cache, since we can't hook on label updates.
return Collections.unmodifiableSet(Label.parse(getLabelString()));
}

/**
* Returns the possibly empty set of labels that are assigned to this node,
* including the automatic {@link #getSelfLabel() self label}, manually
* assigned labels and dynamically assigned labels via the
* {@link LabelFinder} extension point.
*
* This method has a side effect of updating the hudson-wide set of labels
* and should be called after events that will change that - e.g. a agent
* and should be called after events that will change that - e.g. an agent
* connecting.
*/

@Exported
public Set<LabelAtom> getAssignedLabels() {
Set<LabelAtom> r = Label.parse(getLabelString());
Set<LabelAtom> r = new HashSet<>(getLabelAtomSet());
r.add(getSelfLabel());
r.addAll(getDynamicLabels());
return Collections.unmodifiableSet(r);
Expand Down
34 changes: 32 additions & 2 deletions core/src/main/java/hudson/model/Slave.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import hudson.Util;
import hudson.cli.CLI;
import hudson.model.Descriptor.FormException;
import hudson.model.labels.LabelAtom;
import hudson.remoting.Callable;
import hudson.remoting.Channel;
import hudson.remoting.Which;
Expand All @@ -60,6 +61,7 @@
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.jar.JarFile;
Expand Down Expand Up @@ -179,6 +181,7 @@ protected Slave(@NonNull String name, String remoteFS, ComputerLauncher launcher
this.name = name;
this.remoteFS = remoteFS;
this.launcher = launcher;
this.labelAtomSet = Collections.unmodifiableSet(Label.parse(label));
}

/**
Expand All @@ -193,7 +196,7 @@ protected Slave(@NonNull String name, String nodeDescription, String remoteFS, i
this.numExecutors = numExecutors;
this.mode = mode;
this.remoteFS = Util.fixNull(remoteFS).trim();
this.label = Util.fixNull(labelString).trim();
this.labelAtomSet = Collections.unmodifiableSet(Label.parse(labelString));
this.launcher = launcher;
this.retentionStrategy = retentionStrategy;
getAssignedLabels(); // compute labels now
Expand Down Expand Up @@ -308,6 +311,10 @@ public DescribableList<NodeProperty<?>, NodePropertyDescriptor> getNodePropertie

@DataBoundSetter
public void setNodeProperties(List<? extends NodeProperty<?>> properties) throws IOException {
if (nodeProperties == null) {
warnPlugin();
nodeProperties = new DescribableList<>(this);
}
nodeProperties.replaceBy(properties);
}

Expand All @@ -328,11 +335,33 @@ public String getLabelString() {
@Override
@DataBoundSetter
public void setLabelString(String labelString) throws IOException {
this.label = Util.fixNull(labelString).trim();
_setLabelString(labelString);
// Compute labels now.
getAssignedLabels();
}

private void _setLabelString(String labelString) {
this.label = Util.fixNull(labelString).trim();
this.labelAtomSet = Collections.unmodifiableSet(Label.parse(label));
}

@CheckForNull // should be @NonNull, but we've seen plugins overriding readResolve() without calling super.
private transient Set<LabelAtom> labelAtomSet;

@Override
protected Set<LabelAtom> getLabelAtomSet() {
if (labelAtomSet == null) {
warnPlugin();
this.labelAtomSet = Collections.unmodifiableSet(Label.parse(label));
}
return labelAtomSet;
}

private void warnPlugin() {
LOGGER.log(Level.WARNING, () -> getClass().getName() + " or one of its superclass overrides readResolve() without calling super implementation." +
"Please file an issue against the plugin implementing it: " + Jenkins.get().getPluginManager().whichPlugin(getClass()));
}

@Override
public Callable<ClockDifference, IOException> getClockDifferenceCallable() {
return new GetClockDifference1();
Expand Down Expand Up @@ -574,6 +603,7 @@ public int hashCode() {
protected Object readResolve() {
if (nodeProperties == null)
nodeProperties = new DescribableList<>(this);
_setLabelString(label);
return this;
}

Expand Down
22 changes: 17 additions & 5 deletions core/src/main/java/hudson/security/SecurityRealm.java
Original file line number Diff line number Diff line change
Expand Up @@ -647,15 +647,27 @@ public static String getFrom() {
from = request.getParameter("from");
}

// On the 404 error page, use the session attribute it sets
if (request != null && request.getRequestURI().equals(request.getContextPath() + "/404")) {
final HttpSession session = request.getSession(false);
if (session != null) {
final Object attribute = session.getAttribute("from");
if (attribute != null) {
from = attribute.toString();
}
}
}

// If entry point was not found, try to deduce it from the request URI
// except pages related to login process
// except pages related to login process and the 404 error page
if (from == null
&& request != null
&& request.getRequestURI() != null
&& !request.getRequestURI().equals("/loginError")
&& !request.getRequestURI().equals("/login")) {

from = request.getRequestURI();
// The custom login page makes the next two lines obsolete, but safer to have them.
&& !request.getRequestURI().equals(request.getContextPath() + "/loginError")
&& !request.getRequestURI().equals(request.getContextPath() + "/login")
&& !request.getRequestURI().equals(request.getContextPath() + "/404")) {
from = request.getRequestURI();
}

// If deduced entry point isn't deduced yet or the content is a blank value
Expand Down
3 changes: 1 addition & 2 deletions core/src/main/java/hudson/util/ProcessTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import static java.util.logging.Level.FINER;
import static java.util.logging.Level.FINEST;

import com.google.common.primitives.Ints;
import com.sun.jna.LastErrorException;
import com.sun.jna.Memory;
import com.sun.jna.Native;
Expand Down Expand Up @@ -750,7 +749,7 @@ abstract static class Unix extends Local {
@CheckForNull
@Override
public OSProcess get(@NonNull Process proc) {
return get(Ints.checkedCast(proc.pid()));
return get(Math.toIntExact(proc.pid()));
}

@Override
Expand Down
41 changes: 41 additions & 0 deletions core/src/main/java/jenkins/ErrorAttributeFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package jenkins;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import jenkins.model.Jenkins;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.springframework.security.core.Authentication;

/**
* Record the current user authentication for later impersonation if the response is 404 Not Found.
*
* @see Jenkins#generateNotFoundResponse(org.kohsuke.stapler.StaplerRequest, org.kohsuke.stapler.StaplerResponse)
*/
@Restricted(NoExternalUse.class)
public class ErrorAttributeFilter implements Filter {

public static final String USER_ATTRIBUTE = "jenkins.ErrorAttributeFilter.user";

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
final Authentication authentication = Jenkins.getAuthentication2();
servletRequest.setAttribute(USER_ATTRIBUTE, authentication);
filterChain.doFilter(servletRequest, servletResponse);
}

@Override
public void destroy() {
// Otherwise the PCT fails
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Otherwise the PCT fails
}
}
53 changes: 53 additions & 0 deletions core/src/main/java/jenkins/appearance/AppearanceCategory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* The MIT License
*
* Copyright (c) 2023, Tim Jacomb
*
* 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.appearance;

import hudson.Extension;
import jenkins.model.GlobalConfigurationCategory;

/**
* <p>Global configuration of appearance configuration.</p>
*
* <p>This should be used for Plugins that contribute to the look and feel of Jenkins.
* Theming, header and footer changes, information density are all good examples.
* API plugins for UI components that are used by other plugins also fit into that, e.g. source code display.</p>
*
* <p>Configuration specific to a single plugin that is not related to the overall look and feel of Jenkins may not belong here.</p>
*
* <p>If a plugin has a single global configuration it should separate appearance and general configuration to different classes.</p>
*
*/
@Extension
public class AppearanceCategory extends GlobalConfigurationCategory {
@Override
public String getShortDescription() {
return Messages.AppearanceCategory_DisplayName();
}

@Override
public String getDisplayName() {
return Messages.AppearanceCategory_Description();
}
}
Loading

0 comments on commit 557443f

Please sign in to comment.