Skip to content

Commit

Permalink
Merge branch 'master' into new-item-cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
janfaracik committed Jan 4, 2024
2 parents 06c3756 + 444f2de commit 383b12e
Show file tree
Hide file tree
Showing 95 changed files with 1,224 additions and 585 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/publish-release-artifact.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ jobs:
is-rc: ${{ steps.set-version.outputs.is-rc }}
steps:
- uses: actions/checkout@v4
- name: Set up JDK 11
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: 11
java-version: 17
cache: "maven"
- name: Set version
id: set-version
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This page provides information about contributing code to the Jenkins core codeb
1. Fork the repository on GitHub
2. Clone the forked repository to your machine
3. Install the necessary development tools. In order to develop Jenkins, you need the following:
- Java Development Kit (JDK) 11 or 17.
- Java Development Kit (JDK) 11, 17 or 21.
In the Jenkins project we usually use [Eclipse Temurin](https://adoptium.net/) or [OpenJDK](https://openjdk.java.net/), but you can use other JDKs as well.
- Apache Maven 3.8.1 or above. You can [download Maven here](https://maven.apache.org/download.cgi).
In the Jenkins project we usually use the most recent Maven release.
Expand Down
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=5740.vd30f30408987
export ATH_VERSION=5770.v81b_784f28b_d7

if [[ $# -eq 0 ]]; then
export JDK=17
Expand Down
12 changes: 6 additions & 6 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand All @@ -39,7 +39,7 @@ THE SOFTWARE.

<properties>
<asm.version>9.6</asm.version>
<slf4jVersion>2.0.9</slf4jVersion>
<slf4jVersion>2.0.10</slf4jVersion>
<stapler.version>1822.v120278426e1c</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.8</version>
<version>5.8.9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand All @@ -82,7 +82,7 @@ THE SOFTWARE.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
<version>33.0.0-jre</version>
</dependency>
<dependency>
<!-- Overriding Stapler’s 1.1.3 version to diagnose JENKINS-20618: -->
Expand Down Expand Up @@ -196,9 +196,9 @@ THE SOFTWARE.
<version>${groovy.version}</version>
</dependency>
<dependency>
<groupId>org.connectbot.jbcrypt</groupId>
<groupId>org.connectbot</groupId>
<artifactId>jbcrypt</artifactId>
<version>1.0.0</version>
<version>1.0.2</version>
</dependency>
<dependency>
<!-- Groovy shell uses this, but it doesn't declare the dependency -->
Expand Down
2 changes: 1 addition & 1 deletion cli/pom.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand Down
4 changes: 2 additions & 2 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand Down Expand Up @@ -282,7 +282,7 @@ THE SOFTWARE.
<artifactId>groovy-all</artifactId>
</dependency>
<dependency>
<groupId>org.connectbot.jbcrypt</groupId>
<groupId>org.connectbot</groupId>
<artifactId>jbcrypt</artifactId>
</dependency>
<dependency>
Expand Down
42 changes: 40 additions & 2 deletions core/src/main/java/hudson/FilePath.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import static hudson.Util.fileToPath;
import static hudson.Util.fixEmpty;
import static hudson.Util.fixEmptyAndTrim;

import com.google.common.annotations.VisibleForTesting;
import com.jcraft.jzlib.GZIPInputStream;
Expand Down Expand Up @@ -962,7 +963,7 @@ public Void invoke(File dir, VirtualChannel channel) throws IOException {
* </ul>
*
* @param archive
* The resource that represents the tgz/zip file. This URL must support the {@code Last-Modified} header.
* The resource that represents the tgz/zip file. This URL must support the {@code Last-Modified} header or the {@code ETag} header.
* (For example, you could use {@link ClassLoader#getResource}.)
* @param listener
* If non-null, a message will be printed to this listener once this method decides to
Expand All @@ -984,12 +985,18 @@ private boolean installIfNecessaryFrom(@NonNull URL archive, @NonNull TaskListen
try {
FilePath timestamp = this.child(".timestamp");
long lastModified = timestamp.lastModified();
// https://httpwg.org/specs/rfc9110.html#field.etag is the ETag specification
// Read previously stored ETag if timestamp is available
String etag = timestamp.exists() ? fixEmptyAndTrim(timestamp.readToString()) : null;
URLConnection con;
try {
con = ProxyConfiguration.open(archive);
if (lastModified != 0) {
con.setIfModifiedSince(lastModified);
}
if (etag != null) {
con.setRequestProperty("If-None-Match", etag);
}
con.connect();
} catch (IOException x) {
if (this.exists()) {
Expand All @@ -1016,7 +1023,7 @@ private boolean installIfNecessaryFrom(@NonNull URL archive, @NonNull TaskListen
return false;
}
}
if (lastModified != 0) {
if (lastModified != 0 || etag != null) {
if (responseCode == HttpURLConnection.HTTP_NOT_MODIFIED) {
return false;
} else if (responseCode != HttpURLConnection.HTTP_OK) {
Expand All @@ -1027,8 +1034,12 @@ private boolean installIfNecessaryFrom(@NonNull URL archive, @NonNull TaskListen
}

long sourceTimestamp = con.getLastModified();
String resultEtag = fixEmptyAndTrim(con.getHeaderField("ETag"));

if (this.exists()) {
if (equalETags(etag, resultEtag)) {
return false; // already up to date
}
if (lastModified != 0 && sourceTimestamp == lastModified)
return false; // already up to date
this.deleteContents();
Expand All @@ -1042,6 +1053,10 @@ private boolean installIfNecessaryFrom(@NonNull URL archive, @NonNull TaskListen
// First try to download from the agent machine.
try {
act(new Unpack(archive));
if (resultEtag != null && !equalETags(etag, resultEtag)) {
/* Store the ETag value in the timestamp file for later use */
timestamp.write(resultEtag, "UTF-8");
}
timestamp.touch(sourceTimestamp);
return true;
} catch (IOException x) {
Expand All @@ -1061,13 +1076,36 @@ private boolean installIfNecessaryFrom(@NonNull URL archive, @NonNull TaskListen
throw new IOException(String.format("Failed to unpack %s (%d bytes read of total %d)",
archive, cis.getByteCount(), con.getContentLength()), e);
}
if (resultEtag != null && !equalETags(etag, resultEtag)) {
/* Store the ETag value in the timestamp file for later use */
timestamp.write(resultEtag, "UTF-8");
}
timestamp.touch(sourceTimestamp);
return true;
} catch (IOException e) {
throw new IOException("Failed to install " + archive + " to " + remote, e);
}
}

/* Return true if etag1 equals etag2 as defined by the etag specification
https://httpwg.org/specs/rfc9110.html#field.etag
*/
private boolean equalETags(String etag1, String etag2) {
if (etag1 == null || etag2 == null) {
return false;
}
if (etag1.equals(etag2)) {
return true;
}
/* Weak tags are identified by leading characters "W/" as a marker */
/* Weak tag marker must not be considered in tag comparison.
This implements the weak comparison in the specification at
https://httpwg.org/specs/rfc9110.html#field.etag */
String opaqueTag1 = etag1.startsWith("W/") ? etag1.substring(2) : etag1;
String opaqueTag2 = etag2.startsWith("W/") ? etag2.substring(2) : etag2;
return opaqueTag1.equals(opaqueTag2);
}

// this reads from arbitrary URL
private static final class Unpack extends MasterToSlaveFileCallable<Void> {
private final URL archive;
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/hudson/Functions.java
Original file line number Diff line number Diff line change
Expand Up @@ -692,13 +692,13 @@ public static String getUserTimeZone() {
}

@Restricted(NoExternalUse.class)
public static String getUserTimeZonePostfix() {
public static String getUserTimeZonePostfix(Date date) {
if (!isUserTimeZoneOverride()) {
return "";
}

TimeZone tz = TimeZone.getTimeZone(getUserTimeZone());
return tz.getDisplayName(tz.observesDaylightTime(), TimeZone.SHORT);
return tz.getDisplayName(tz.inDaylightTime(date), TimeZone.SHORT, getCurrentLocale());
}

@Restricted(NoExternalUse.class)
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/hudson/cli/declarative/CLIMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import hudson.cli.CLICommand;
import hudson.util.ListBoxModel.Option;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.jvnet.hudson.annotation_indexer.Indexed;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

/**
* Annotates methods on model objects to expose them as CLI commands.
Expand Down
24 changes: 21 additions & 3 deletions core/src/main/java/hudson/model/ComputerSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -352,15 +352,33 @@ public synchronized HttpResponse doConfigSubmit(StaplerRequest req) throws IOExc
BulkChange bc = new BulkChange(MONITORS_OWNER);
try {
Jenkins.get().checkPermission(Jenkins.MANAGE);
monitors.rebuild(req, req.getSubmittedForm(), getNodeMonitorDescriptors());
JSONObject json = req.getSubmittedForm();
monitors.rebuild(req, json, getNodeMonitorDescriptors());

// add in the rest of instances are ignored instances
for (Descriptor<NodeMonitor> d : NodeMonitor.all())
if (monitors.get(d) == null) {
for (Descriptor<NodeMonitor> d : NodeMonitor.all()) {
NodeMonitor monitor = monitors.get(d);
if (monitor == null) {
NodeMonitor i = createDefaultInstance(d, true);
if (i != null)
monitors.add(i);
} else {
/*
* Some monitors in plugins do not have a DataBoundConstructor
* but a Descriptor that overrides newInstance. For those the ignored
* field is not set, so we have to explicitly set it.
*/
String name = d.getJsonSafeClassName();
JSONObject o = json.optJSONObject(name);
boolean ignored = true;
if (o != null) {
if (o.containsKey("ignored")) {
ignored = o.getBoolean("ignored");
}
}
monitor.setIgnored(ignored);
}
}

// recompute the data
for (NodeMonitor nm : monitors) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,25 @@ protected AbstractNodeMonitorDescriptor() {
this(PERIOD);
}

/**
* Indicates if this monitor is capable to take agents offline in case it detects a problem.
* If true, this will enable the configuration option to ignore the monitor.
* Defaults to {@code true} so plugins that do not override this method behave as before.
* Plugins that do implement a monitor that will not take agents offline should override this
* method and return false.
*
* @return true if this monitor might take agents offline
* @since TODO
*/
public boolean canTakeOffline() {
return true;
}

@Override
public String getConfigPage() {
return getViewPage(clazz, "configure.jelly");
}

/**
* @deprecated as of 1.522
* Extend from {@link AbstractAsyncNodeMonitorDescriptor}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@
import hudson.remoting.Callable;
import java.io.IOException;
import jenkins.security.MasterToSlaveCallable;
import net.sf.json.JSONObject;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

/**
* Discovers the architecture of the system to display in the agent list page.
Expand All @@ -60,8 +58,8 @@ public String getDisplayName() {
}

@Override
public NodeMonitor newInstance(StaplerRequest req, JSONObject formData) throws FormException {
return new ArchitectureMonitor();
public boolean canTakeOffline() {
return false;
}
}

Expand Down
12 changes: 5 additions & 7 deletions core/src/main/java/hudson/node_monitors/ClockMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@
import hudson.remoting.Callable;
import hudson.util.ClockDifference;
import java.io.IOException;
import net.sf.json.JSONObject;
import org.jenkinsci.Symbol;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

/**
* {@link NodeMonitor} that checks clock of {@link Node} to
Expand Down Expand Up @@ -72,6 +70,11 @@ public DescriptorImpl() {
DESCRIPTOR = this;
}

@Override
public boolean canTakeOffline() {
return false;
}

@Override
protected Callable<ClockDifference, IOException> createCallable(Computer c) {
Node n = c.getNode();
Expand All @@ -84,10 +87,5 @@ protected Callable<ClockDifference, IOException> createCallable(Computer c) {
public String getDisplayName() {
return Messages.ClockMonitor_DisplayName();
}

@Override
public NodeMonitor newInstance(StaplerRequest req, JSONObject formData) throws FormException {
return new ClockMonitor();
}
}
}
2 changes: 2 additions & 0 deletions core/src/main/java/hudson/node_monitors/NodeMonitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import hudson.util.DescriptorList;
import java.util.List;
import jenkins.model.Jenkins;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;

Expand Down Expand Up @@ -133,6 +134,7 @@ public boolean isIgnored() {
return ignored;
}

@DataBoundSetter
public void setIgnored(boolean ignored) {
this.ignored = ignored;
}
Expand Down
Loading

0 comments on commit 383b12e

Please sign in to comment.