Skip to content

Commit

Permalink
Merge branch 'master' into winstone-with-jetty-12
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkEWaite authored Sep 2, 2023
2 parents 8a42280 + c98e76b commit eba230e
Show file tree
Hide file tree
Showing 154 changed files with 1,832 additions and 984 deletions.
2 changes: 1 addition & 1 deletion ath.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set -o xtrace
cd "$(dirname "$0")"

# https://github.com/jenkinsci/acceptance-test-harness/releases
export ATH_VERSION=5695.ve1f0439c5a_51
export ATH_VERSION=5699.v27deb_ef5796c

if [[ $# -eq 0 ]]; then
export JDK=17
Expand Down
4 changes: 2 additions & 2 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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,7 +189,7 @@ 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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.StringEscapeUtils;

/**
* Filters out console notes.
Expand All @@ -36,6 +40,8 @@
*/
public class PlainTextConsoleOutputStream extends LineTransformationOutputStream.Delegating {

private static final Logger LOGGER = Logger.getLogger(PlainTextConsoleOutputStream.class.getName());

/**
*
*/
Expand Down Expand Up @@ -64,7 +70,11 @@ protected void eol(byte[] in, int sz) throws IOException {
int rest = sz - next;
ByteArrayInputStream b = new ByteArrayInputStream(in, next, rest);

ConsoleNote.skip(new DataInputStream(b));
try {
ConsoleNote.skip(new DataInputStream(b));
} catch (IOException x) {
LOGGER.log(Level.FINE, "Failed to skip annotation from \"" + StringEscapeUtils.escapeJava(new String(in, next, rest, Charset.defaultCharset())) + "\"", x);
}

int bytesUsed = rest - b.available(); // bytes consumed by annotations
written += bytesUsed;
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<>();

Check warning on line 84 in core/src/main/java/hudson/init/InitStrategy.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 84 is not covered by tests
for (String hplLocation : hplProperty.split(",")) {
File hpl = new File(hplLocation.trim());
if (hpl.exists()) {
r.add(hpl);
pluginFiles.add(hpl);

Check warning on line 88 in core/src/main/java/hudson/init/InitStrategy.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 88 is not covered by tests
} 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);

Check warning on line 93 in core/src/main/java/hudson/init/InitStrategy.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 93 is not covered by tests
}
});
} 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));

Check warning on line 103 in core/src/main/java/hudson/init/InitStrategy.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 103 is not covered by tests
r.addAll(pluginFiles);

Check warning on line 104 in core/src/main/java/hudson/init/InitStrategy.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 104 is not covered by tests
}
}

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
21 changes: 19 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 @@ -328,11 +331,24 @@ 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));
}

@NonNull
private transient Set<LabelAtom> labelAtomSet;

@Override
protected Set<LabelAtom> getLabelAtomSet() {
return labelAtomSet;
}

@Override
public Callable<ClockDifference, IOException> getClockDifferenceCallable() {
return new GetClockDifference1();
Expand Down Expand Up @@ -574,6 +590,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
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 eba230e

Please sign in to comment.