Skip to content

Commit

Permalink
Merge branch 'master' into improve-project-settings
Browse files Browse the repository at this point in the history
  • Loading branch information
janfaracik authored Oct 19, 2024
2 parents 56cb9df + 091953f commit 42d3e01
Show file tree
Hide file tree
Showing 79 changed files with 893 additions and 1,096 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,8 @@ jobs:
GIT_COMMITTER_EMAIL: <86592549+jenkins-infra-changelog-generator[bot]@users.noreply.github.com>
run: |
wget --quiet https://raw.githubusercontent.com/jenkinsci/core-changelog-generator/master/generate-weekly-changelog.sh
# Create a Python virtual environment for pip install
# See https://github.com/jenkinsci/core-changelog-generator/issues/37
python3 -m venv venv
source venv/bin/activate
bash generate-weekly-changelog.sh
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=6038.v190f938efc87
export ATH_VERSION=6040.v72ed2f5b_59f6

if [[ $# -eq 0 ]]; then
export JDK=17
Expand Down
2 changes: 1 addition & 1 deletion bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ THE SOFTWARE.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>6.1.13</version>
<version>6.1.14</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
3 changes: 2 additions & 1 deletion core/src/main/java/hudson/logging/LogRecorder.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import hudson.remoting.VirtualChannel;
import hudson.slaves.ComputerListener;
import hudson.util.CopyOnWriteList;
import hudson.util.FormApply;
import hudson.util.FormValidation;
import hudson.util.HttpResponses;
import hudson.util.RingBufferLogHandler;
Expand Down Expand Up @@ -463,7 +464,7 @@ public synchronized void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rs

save();
if (oldFile != null) oldFile.delete();
rsp.sendRedirect2(redirect);
FormApply.success(redirect).generateResponse(req, rsp, null);
}

@RequirePOST
Expand Down
112 changes: 64 additions & 48 deletions core/src/main/java/hudson/model/Computer.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import hudson.util.DaemonThreadFactory;
import hudson.util.EditDistance;
import hudson.util.ExceptionCatchingThreadFactory;
import hudson.util.FormApply;
import hudson.util.Futures;
import hudson.util.IOUtils;
import hudson.util.NamingThreadFactory;
Expand Down Expand Up @@ -179,11 +180,6 @@

private long connectTime = 0;

/**
* True if Jenkins shouldn't start new builds on this node.
*/
private boolean temporarilyOffline;

/**
* {@link Node} object may be created and deleted independently
* from this object.
Expand Down Expand Up @@ -360,6 +356,13 @@ public AnnotatedLargeText<Computer> getLogText() {
*/
@Exported
public OfflineCause getOfflineCause() {
var node = getNode();
if (node != null) {
var temporaryOfflineCause = node.getTemporaryOfflineCause();
if (temporaryOfflineCause != null) {
return temporaryOfflineCause;
}
}
return offlineCause;
}

Expand All @@ -371,6 +374,7 @@ public boolean hasOfflineCause() {
@Exported
@Override
public String getOfflineCauseReason() {
var offlineCause = getOfflineCause();
if (offlineCause == null) {
return "";
}
Expand Down Expand Up @@ -549,7 +553,7 @@ public void cliDisconnect(String cause) throws ExecutionException, InterruptedEx
@Deprecated
public void cliOffline(String cause) throws ExecutionException, InterruptedException {
checkPermission(DISCONNECT);
setTemporarilyOffline(true, new ByCLI(cause));
setTemporaryOfflineCause(new ByCLI(cause));
}

/**
Expand All @@ -558,7 +562,7 @@ public void cliOffline(String cause) throws ExecutionException, InterruptedExcep
@Deprecated
public void cliOnline() throws ExecutionException, InterruptedException {
checkPermission(CONNECT);
setTemporarilyOffline(false, null);
setTemporaryOfflineCause(null);
}

/**
Expand Down Expand Up @@ -620,7 +624,7 @@ public BuildTimelineWidget getTimeline() {
@Exported
@Override
public boolean isOffline() {
return temporarilyOffline || getChannel() == null;
return isTemporarilyOffline() || getChannel() == null;
}

public final boolean isOnline() {
Expand Down Expand Up @@ -669,41 +673,64 @@ public boolean isLaunchSupported() {
@Exported
@Deprecated
public boolean isTemporarilyOffline() {
return temporarilyOffline;
var node = getNode();
return node != null && node.isTemporarilyOffline();
}

/**
* @deprecated as of 1.320.
* Use {@link #setTemporarilyOffline(boolean, OfflineCause)}
* Use {@link #setTemporaryOfflineCause(OfflineCause)}
*/
@Deprecated
public void setTemporarilyOffline(boolean temporarilyOffline) {
setTemporarilyOffline(temporarilyOffline, null);
setTemporaryOfflineCause(temporarilyOffline ? new OfflineCause.LegacyOfflineCause() : null);
}

/**
* @deprecated
* Use {@link #setTemporaryOfflineCause(OfflineCause)} instead.
*/
@Deprecated(since = "TODO")
public void setTemporarilyOffline(boolean temporarilyOffline, OfflineCause cause) {
if (cause == null) {
setTemporarilyOffline(temporarilyOffline);
} else {
setTemporaryOfflineCause(temporarilyOffline ? cause : null);
}
}

/**
* Marks the computer as temporarily offline. This retains the underlying
* {@link Channel} connection, but prevent builds from executing.
*
* @param cause
* If the first argument is true, specify the reason why the node is being put
* offline.
* @param temporaryOfflineCause The reason why the node is being put offline.
* If null, this cancels the status
* @since TODO
*/
public void setTemporarilyOffline(boolean temporarilyOffline, OfflineCause cause) {
offlineCause = temporarilyOffline ? cause : null;
this.temporarilyOffline = temporarilyOffline;
Node node = getNode();
if (node != null) {
node.setTemporaryOfflineCause(offlineCause);
public void setTemporaryOfflineCause(@CheckForNull OfflineCause temporaryOfflineCause) {
var node = getNode();
if (node == null) {
throw new IllegalStateException("Can't set a temporary offline cause if the node has been removed");
}
synchronized (statusChangeLock) {
statusChangeLock.notifyAll();
node.setTemporaryOfflineCause(temporaryOfflineCause);
}

/**
* @since TODO
* @return If the node is temporarily offline, the reason why.
*/
@SuppressWarnings("unused") // used by setOfflineCause.jelly
public String getTemporaryOfflineCauseReason() {
var node = getNode();
if (node == null) {
// Node was deleted; computer still exists
return null;
}
if (temporarilyOffline) {
Listeners.notify(ComputerListener.class, false, l -> l.onTemporarilyOffline(this, cause));
} else {
Listeners.notify(ComputerListener.class, false, l -> l.onTemporarilyOnline(this));
var cause = node.getTemporaryOfflineCause();
if (cause instanceof OfflineCause.UserCause userCause) {
return userCause.getMessage();
}
return cause != null ? cause.toString() : "";
}

@Exported
Expand Down Expand Up @@ -785,16 +812,6 @@ protected void setNode(Node node) {
this.nodeName = null;

setNumExecutors(node.getNumExecutors());
if (this.temporarilyOffline) {
// When we get a new node, push our current temp offline
// status to it (as the status is not carried across
// configuration changes that recreate the node).
// Since this is also called the very first time this
// Computer is created, avoid pushing an empty status
// as that could overwrite any status that the Node
// brought along from its persisted config data.
node.setTemporaryOfflineCause(this.offlineCause);
}
}

/**
Expand Down Expand Up @@ -1396,24 +1413,23 @@ public void doRssLatest(StaplerRequest2 req, StaplerResponse2 rsp) throws IOExce

@RequirePOST
public HttpResponse doToggleOffline(@QueryParameter String offlineMessage) throws IOException, ServletException {
if (!temporarilyOffline) {
checkPermission(DISCONNECT);
offlineMessage = Util.fixEmptyAndTrim(offlineMessage);
setTemporarilyOffline(!temporarilyOffline,
new OfflineCause.UserCause(User.current(), offlineMessage));
} else {
var node = getNode();
if (node == null) {
return HttpResponses.notFound();
}
if (node.isTemporarilyOffline()) {
checkPermission(CONNECT);
setTemporarilyOffline(!temporarilyOffline, null);
setTemporaryOfflineCause(null);
return HttpResponses.redirectToDot();
} else {
return doChangeOfflineCause(offlineMessage);
}
return HttpResponses.redirectToDot();
}

@RequirePOST
public HttpResponse doChangeOfflineCause(@QueryParameter String offlineMessage) throws IOException, ServletException {
checkPermission(DISCONNECT);
offlineMessage = Util.fixEmptyAndTrim(offlineMessage);
setTemporarilyOffline(true,
new OfflineCause.UserCause(User.current(), offlineMessage));
setTemporaryOfflineCause(new OfflineCause.UserCause(User.current(), Util.fixEmptyAndTrim(offlineMessage)));
return HttpResponses.redirectToDot();
}

Expand Down Expand Up @@ -1512,7 +1528,7 @@ public void doConfigSubmit(StaplerRequest2 req, StaplerResponse2 rsp) throws IOE
}

// take the user back to the agent top page.
rsp.sendRedirect2("../" + result.getNodeName() + '/');
FormApply.success("../" + result.getNodeName() + '/').generateResponse(req, rsp, null);
}

/**
Expand Down
26 changes: 10 additions & 16 deletions core/src/main/java/hudson/model/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.BulkChange;
import hudson.Extension;
import hudson.ExtensionPoint;
import hudson.FilePath;
import hudson.FileSystemProvisioner;
Expand Down Expand Up @@ -69,6 +68,7 @@
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import jenkins.model.Nodes;
import jenkins.util.Listeners;
import jenkins.util.SystemProperties;
import jenkins.util.io.OnMaster;
import net.sf.json.JSONObject;
Expand Down Expand Up @@ -265,24 +265,13 @@ public void onLoad(Nodes parent, String name) {
}

/**
* Let Nodes be aware of the lifecycle of their own {@link Computer}.
* @return true if this node has a temporary offline cause set.
*/
@Extension
public static class InternalComputerListener extends ComputerListener {
@Override
public void onOnline(Computer c, TaskListener listener) {
Node node = c.getNode();

// At startup, we need to restore any previously in-effect temp offline cause.
// We wait until the computer is started rather than getting the data to it sooner
// so that the normal computer start up processing works as expected.
if (node != null && node.temporaryOfflineCause != null && node.temporaryOfflineCause != c.getOfflineCause()) {
c.setTemporarilyOffline(true, node.temporaryOfflineCause);
}
}
boolean isTemporarilyOffline() {
return temporaryOfflineCause != null;
}

private OfflineCause temporaryOfflineCause;
private volatile OfflineCause temporaryOfflineCause;

/**
* Enable a {@link Computer} to inform its node when it is taken
Expand All @@ -294,6 +283,11 @@ void setTemporaryOfflineCause(OfflineCause cause) {
temporaryOfflineCause = cause;
save();
}
if (temporaryOfflineCause != null) {
Listeners.notify(ComputerListener.class, false, l -> l.onTemporarilyOffline(toComputer(), temporaryOfflineCause));
} else {
Listeners.notify(ComputerListener.class, false, l -> l.onTemporarilyOnline(toComputer()));
}
} catch (java.io.IOException e) {
LOGGER.warning("Unable to complete save, temporary offline status will not be persisted: " + e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ public boolean isIgnored() {
*/
protected boolean markOnline(Computer c) {
if (isIgnored() || c.isOnline()) return false; // noop
c.setTemporarilyOffline(false, null);
c.setTemporaryOfflineCause(null);
return true;
}

Expand All @@ -247,7 +247,7 @@ protected boolean markOnline(Computer c) {
protected boolean markOffline(Computer c, OfflineCause oc) {
if (isIgnored() || c.isTemporarilyOffline()) return false; // noop

c.setTemporarilyOffline(true, oc);
c.setTemporaryOfflineCause(oc);

// notify the admin
MonitorMarkedNodeOffline no = AdministrativeMonitor.all().get(MonitorMarkedNodeOffline.class);
Expand Down
32 changes: 27 additions & 5 deletions core/src/main/java/hudson/slaves/OfflineCause.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import java.util.Date;
import jenkins.model.Jenkins;
import org.jvnet.localizer.Localizable;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;

Expand Down Expand Up @@ -71,6 +73,19 @@ public long getTimestamp() {
return new Date(timestamp);
}

/**
* @deprecated Only exists for backward compatibility.
* @see Computer#setTemporarilyOffline(boolean)
*/
@Deprecated
@Restricted(NoExternalUse.class)
public static class LegacyOfflineCause extends OfflineCause {
@Exported(name = "description") @Override
public String toString() {
return "";
}
}

/**
* {@link OfflineCause} that renders a static text,
* but without any further UI.
Expand Down Expand Up @@ -136,15 +151,15 @@ public static class UserCause extends SimpleOfflineCause {
// null when unknown
private /*final*/ @CheckForNull String userId;

private final String message;

public UserCause(@CheckForNull User user, @CheckForNull String message) {
this(
user != null ? user.getId() : null,
message != null ? " : " + message : ""
);
this(user != null ? user.getId() : null, message);
}

private UserCause(String userId, String message) {
super(hudson.slaves.Messages._SlaveComputer_DisconnectedBy(userId != null ? userId : Jenkins.ANONYMOUS2.getName(), message));
super(hudson.slaves.Messages._SlaveComputer_DisconnectedBy(userId != null ? userId : Jenkins.ANONYMOUS2.getName(), message != null ? " : " + message : ""));
this.message = message;
this.userId = userId;
}

Expand All @@ -155,6 +170,13 @@ public User getUser() {
;
}

/**
* @return the message that was provided when the computer was taken offline
*/
public String getMessage() {
return message;
}

// Storing the User in a filed was a mistake, switch to userId
private Object readResolve() throws ObjectStreamException {
if (user != null) {
Expand Down
Loading

0 comments on commit 42d3e01

Please sign in to comment.