mirror of https://github.com/jenkinsci/jenkins.git
Merge branch 'master' into describable
This commit is contained in:
commit
8ac576e5f8
|
@ -41,7 +41,7 @@ THE SOFTWARE.
|
|||
<commons-fileupload2.version>2.0.0-M2</commons-fileupload2.version>
|
||||
<groovy.version>2.4.21</groovy.version>
|
||||
<jelly.version>1.1-jenkins-20250108</jelly.version>
|
||||
<stapler.version>1961.vd0a_a_60970a_a_2</stapler.version>
|
||||
<stapler.version>1962.v928389828d33</stapler.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
|
|
|
@ -895,37 +895,6 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
|
|||
@Override
|
||||
public Object getDynamic(String token, StaplerRequest2 req,
|
||||
StaplerResponse2 rsp) {
|
||||
if (Util.isOverridden(Job.class, getClass(), "getDynamic", String.class, StaplerRequest.class, StaplerResponse.class)) {
|
||||
return getDynamic(token, StaplerRequest.fromStaplerRequest2(req), StaplerResponse.fromStaplerResponse2(rsp));
|
||||
}
|
||||
try {
|
||||
// try to interpret the token as build number
|
||||
return getBuildByNumber(Integer.parseInt(token));
|
||||
} catch (NumberFormatException e) {
|
||||
// try to map that to widgets
|
||||
for (Widget w : getWidgets()) {
|
||||
if (w.getUrlName().equals(token))
|
||||
return w;
|
||||
}
|
||||
|
||||
// is this a permalink?
|
||||
for (Permalink p : getPermalinks()) {
|
||||
if (p.getId().equals(token))
|
||||
return p.resolve(this);
|
||||
}
|
||||
|
||||
return super.getDynamic(token, req, rsp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #getDynamic(String, StaplerRequest2, StaplerResponse2)}
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public Object getDynamic(String token, StaplerRequest req,
|
||||
StaplerResponse rsp) {
|
||||
// Intentionally not factoring this out into a common implementation method because it contains a call to super.
|
||||
try {
|
||||
// try to interpret the token as build number
|
||||
return getBuildByNumber(Integer.parseInt(token));
|
||||
|
|
|
@ -138,6 +138,7 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable
|
|||
}
|
||||
|
||||
/**
|
||||
* In most cases, you should not call this method directly, but {@link Jenkins#updateNode(Node)} instead.
|
||||
* @since 1.635.
|
||||
*/
|
||||
@Override
|
||||
|
@ -281,7 +282,7 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable
|
|||
try {
|
||||
if (temporaryOfflineCause != cause) {
|
||||
temporaryOfflineCause = cause;
|
||||
save();
|
||||
Jenkins.get().updateNode(this);
|
||||
}
|
||||
if (temporaryOfflineCause != null) {
|
||||
Listeners.notify(ComputerListener.class, false, l -> l.onTemporarilyOffline(toComputer(), temporaryOfflineCause));
|
||||
|
|
|
@ -248,6 +248,15 @@ public abstract class Slave extends Node implements Serializable {
|
|||
return launcher == null ? new JNLPLauncher() : launcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated In most cases, you should not call this method directly, but {@link Jenkins#updateNode(Node)} instead.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public void save() throws IOException {
|
||||
super.save();
|
||||
}
|
||||
|
||||
public void setLauncher(ComputerLauncher launcher) {
|
||||
this.launcher = launcher;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
@ -203,17 +202,18 @@ public class Nodes implements PersistenceRoot {
|
|||
* @since 1.634
|
||||
*/
|
||||
public boolean updateNode(final @NonNull Node node) throws IOException {
|
||||
return updateNode(node, true);
|
||||
}
|
||||
|
||||
private boolean updateNode(final @NonNull Node node, boolean fireListener) throws IOException {
|
||||
boolean exists;
|
||||
try {
|
||||
exists = Queue.withLock(new Callable<>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
if (node == nodes.get(node.getNodeName())) {
|
||||
jenkins.trimLabels(node);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
exists = Queue.withLock(() -> {
|
||||
if (node == nodes.get(node.getNodeName())) {
|
||||
jenkins.trimLabels(node);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
// should never happen, but if it does let's do the right thing
|
||||
|
@ -225,7 +225,9 @@ public class Nodes implements PersistenceRoot {
|
|||
if (exists) {
|
||||
// TODO there is a theoretical race whereby the node instance is updated/removed after lock release
|
||||
node.save();
|
||||
// TODO should this fireOnUpdated?
|
||||
if (fireListener) {
|
||||
NodeListener.fireOnUpdated(node, node);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -252,7 +254,7 @@ public class Nodes implements PersistenceRoot {
|
|||
newOne.onLoad(Nodes.this, newOne.getNodeName());
|
||||
}
|
||||
});
|
||||
updateNode(newOne);
|
||||
updateNode(newOne, false);
|
||||
if (!newOne.getNodeName().equals(oldOne.getNodeName())) {
|
||||
LOGGER.fine(() -> "deleting " + new File(getRootDir(), oldOne.getNodeName()));
|
||||
Util.deleteRecursive(new File(getRootDir(), oldOne.getNodeName()));
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
"postcss-preset-env": "10.1.5",
|
||||
"postcss-scss": "4.0.9",
|
||||
"prettier": "3.5.3",
|
||||
"sass": "1.85.1",
|
||||
"sass": "1.86.0",
|
||||
"sass-loader": "16.0.5",
|
||||
"style-loader": "4.0.0",
|
||||
"stylelint": "16.16.0",
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -73,9 +73,9 @@ THE SOFTWARE.
|
|||
</issueManagement>
|
||||
|
||||
<properties>
|
||||
<revision>2.502</revision>
|
||||
<revision>2.503</revision>
|
||||
<changelist>-SNAPSHOT</changelist>
|
||||
<project.build.outputTimestamp>2025-03-11T13:49:05Z</project.build.outputTimestamp>
|
||||
<project.build.outputTimestamp>2025-03-18T13:51:20Z</project.build.outputTimestamp>
|
||||
|
||||
<!-- configuration for patch tracker plugin -->
|
||||
<project.patchManagement.system>github</project.patchManagement.system>
|
||||
|
|
|
@ -178,7 +178,7 @@ THE SOFTWARE.
|
|||
<dependency>
|
||||
<groupId>org.jenkins-ci.main</groupId>
|
||||
<artifactId>jenkins-test-harness</artifactId>
|
||||
<version>2414.v185474555e66</version>
|
||||
<version>2418.ve283b_a_b_79e37</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
|
|
|
@ -39,6 +39,7 @@ import static org.junit.Assert.fail;
|
|||
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import hudson.EnvVars;
|
||||
import hudson.ExtensionList;
|
||||
import hudson.FilePath;
|
||||
import hudson.model.Node.Mode;
|
||||
import hudson.model.Queue.WaitingItem;
|
||||
|
@ -61,6 +62,7 @@ import java.util.Collection;
|
|||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import jenkins.model.Jenkins;
|
||||
import jenkins.model.NodeListener;
|
||||
import jenkins.security.QueueItemAuthenticatorConfiguration;
|
||||
import org.htmlunit.HttpMethod;
|
||||
import org.htmlunit.Page;
|
||||
|
@ -91,6 +93,20 @@ public class NodeTest {
|
|||
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
|
||||
}
|
||||
|
||||
@TestExtension("testSetTemporaryOfflineCause")
|
||||
public static class NodeListenerImpl extends NodeListener {
|
||||
private int count;
|
||||
|
||||
public static int getCount() {
|
||||
return ExtensionList.lookupSingleton(NodeListenerImpl.class).count;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUpdated(@NonNull Node oldOne, @NonNull Node newOne) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetTemporaryOfflineCause() throws Exception {
|
||||
Node node = j.createOnlineSlave();
|
||||
|
@ -98,16 +114,19 @@ public class NodeTest {
|
|||
project.setAssignedLabel(j.jenkins.getLabel(node.getDisplayName()));
|
||||
OfflineCause cause = new OfflineCause.ByCLI("message");
|
||||
node.setTemporaryOfflineCause(cause);
|
||||
assertThat(NodeListenerImpl.getCount(), is(1));
|
||||
for (ComputerListener l : ComputerListener.all()) {
|
||||
l.onOnline(node.toComputer(), TaskListener.NULL);
|
||||
}
|
||||
assertEquals("Node should have offline cause which was set.", cause, node.toComputer().getOfflineCause());
|
||||
OfflineCause cause2 = new OfflineCause.ByCLI("another message");
|
||||
node.setTemporaryOfflineCause(cause2);
|
||||
assertThat(NodeListenerImpl.getCount(), is(2));
|
||||
assertEquals("Node should have the new offline cause.", cause2, node.toComputer().getOfflineCause());
|
||||
// Exists in some plugins
|
||||
node.toComputer().setTemporarilyOffline(false, new OfflineCause.ByCLI("A third message"));
|
||||
assertThat(node.getTemporaryOfflineCause(), nullValue());
|
||||
assertThat(NodeListenerImpl.getCount(), is(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -49,6 +49,14 @@ public class NodeListenerTest {
|
|||
verifyNoMoreInteractions(mock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateNode() throws Exception {
|
||||
Node agent = j.createSlave();
|
||||
agent.setLabelString("some label");
|
||||
Jenkins.get().updateNode(agent);
|
||||
verify(mock, times(1)).onUpdated(any(Node.class), any(Node.class));
|
||||
}
|
||||
|
||||
private CLICommandInvoker cli(CLICommand cmd) {
|
||||
return new CLICommandInvoker(j, cmd);
|
||||
}
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -4372,7 +4372,7 @@ __metadata:
|
|||
postcss-preset-env: "npm:10.1.5"
|
||||
postcss-scss: "npm:4.0.9"
|
||||
prettier: "npm:3.5.3"
|
||||
sass: "npm:1.85.1"
|
||||
sass: "npm:1.86.0"
|
||||
sass-loader: "npm:16.0.5"
|
||||
sortablejs: "npm:1.15.6"
|
||||
style-loader: "npm:4.0.0"
|
||||
|
@ -6351,9 +6351,9 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sass@npm:1.85.1":
|
||||
version: 1.85.1
|
||||
resolution: "sass@npm:1.85.1"
|
||||
"sass@npm:1.86.0":
|
||||
version: 1.86.0
|
||||
resolution: "sass@npm:1.86.0"
|
||||
dependencies:
|
||||
"@parcel/watcher": "npm:^2.4.1"
|
||||
chokidar: "npm:^4.0.0"
|
||||
|
@ -6364,7 +6364,7 @@ __metadata:
|
|||
optional: true
|
||||
bin:
|
||||
sass: sass.js
|
||||
checksum: 10c0/f843aa1df1dca2f0e9cb2fb247e4939fd514ae4c182cdd1900a0622c0d71b40dfb1c4225f78b78e165a318287ca137ec597695db3e496408bd16a921a2bc2b3f
|
||||
checksum: 10c0/921caea1fd8a450d4a986e5570ce13c4ca7b2a57da390811add3d2087ad8f46f53b34652ddcb237d8bdaad49c560b8d6eee130c733c787d058bc5a71a914c139
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
Loading…
Reference in New Issue