();
+ for (Computer c : jenkins.getComputers()) {
+ if (!c.getName().isEmpty()) {
+ names.add(c.getName());
+ }
+ }
+ }
+ String adv = EditDistance.findNearest(node_s, names);
+ throw new IllegalArgumentException(adv == null ?
+ hudson.model.Messages.Computer_NoSuchSlaveExistsWithoutAdvice(node_s) :
+ hudson.model.Messages.Computer_NoSuchSlaveExists(node_s, adv));
+ }
+
+ computer.cliDisconnect(cause);
+ } catch (Exception e) {
+ if (hs.size() == 1) {
+ throw e;
+ }
+
+ stderr.println(String.format(node_s + ": " + e.getMessage()));
+ errorOccurred = true;
+ continue;
+ }
+ }
+
+ if (errorOccurred) {
+ throw new AbortException("Error occured while performing this command, see previous stderr output.");
+ }
+ return 0;
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java b/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java
new file mode 100644
index 0000000000..35cdad086c
--- /dev/null
+++ b/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java
@@ -0,0 +1,50 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2016 Red Hat, Inc.
+ *
+ * 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 hudson.cli;
+
+import hudson.Extension;
+import jenkins.model.Jenkins;
+
+/**
+ * Reload everything from file system
+ *
+ * @author pjanouse
+ * @since TODO
+ */
+@Extension
+public class ReloadConfigurationCommand extends CLICommand {
+
+ @Override
+ public String getShortDescription() {
+ return Messages.ReloadConfigurationCommand_ShortDescription();
+ }
+
+ @Override
+ protected int run() throws Exception {
+ Jenkins.getActiveInstance().doReload();
+ return 0;
+ }
+
+}
diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java
index 582f883945..071872fab3 100644
--- a/core/src/main/java/hudson/model/AbstractBuild.java
+++ b/core/src/main/java/hudson/model/AbstractBuild.java
@@ -127,7 +127,6 @@ public abstract class AbstractBuild,R extends Abs
/**
* SCM used for this build.
- * Maybe null, for historical reason, in which case CVS is assumed.
*/
private ChangeLogParser scm;
@@ -597,9 +596,6 @@ public abstract class AbstractBuild
,R extends Abs
AbstractProject, ?> project = build.getProject();
for (int retryCount=project.getScmCheckoutRetryCount(); ; retryCount--) {
- // for historical reasons, null in the scm field means CVS, so we need to explicitly set this to something
- // in case check out fails and leaves a broken changelog.xml behind.
- // see http://www.nabble.com/CVSChangeLogSet.parse-yields-SAXParseExceptions-when-parsing-bad-*AccuRev*-changelog.xml-files-td22213663.html
build.scm = NullChangeLogParser.INSTANCE;
try {
@@ -870,20 +866,7 @@ public abstract class AbstractBuild
,R extends Abs
public ChangeLogSet extends Entry> getChangeSet() {
synchronized (changeSetLock) {
if (scm==null) {
- // for historical reason, null means CVS.
- try {
- Class> c = Jenkins.getInstance().getPluginManager().uberClassLoader.loadClass("hudson.scm.CVSChangeLogParser");
- scm = (ChangeLogParser)c.newInstance();
- } catch (ClassNotFoundException e) {
- // if CVS isn't available, fall back to something non-null.
- scm = NullChangeLogParser.INSTANCE;
- } catch (InstantiationException e) {
- scm = NullChangeLogParser.INSTANCE;
- throw (Error)new InstantiationError().initCause(e);
- } catch (IllegalAccessException e) {
- scm = NullChangeLogParser.INSTANCE;
- throw (Error)new IllegalAccessError().initCause(e);
- }
+ scm = NullChangeLogParser.INSTANCE;
}
}
diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java
index 12c3824561..ae0d6f3cfc 100644
--- a/core/src/main/java/hudson/model/Computer.java
+++ b/core/src/main/java/hudson/model/Computer.java
@@ -506,10 +506,13 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
}
/**
- * CLI command to disconnects this node.
+ * @deprecated Implementation of CLI command "disconnect-node" moved to {@link hudson.cli.DisconnectNodeCommand}.
+ *
+ * @param cause
+ * Record the note about why you are disconnecting this node
*/
- @CLIMethod(name="disconnect-node")
- public void cliDisconnect(@Option(name="-m",usage="Record the note about why you are disconnecting this node") String cause) throws ExecutionException, InterruptedException {
+ @Deprecated
+ public void cliDisconnect(String cause) throws ExecutionException, InterruptedException {
checkPermission(DISCONNECT);
disconnect(new ByCLI(cause)).get();
}
diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java
index e78b90caa1..b1a308ab80 100644
--- a/core/src/main/java/hudson/model/UpdateCenter.java
+++ b/core/src/main/java/hudson/model/UpdateCenter.java
@@ -52,6 +52,7 @@ import hudson.util.IOException2;
import hudson.util.IOUtils;
import hudson.util.PersistedList;
import hudson.util.XStream2;
+import jenkins.MissingDependencyException;
import jenkins.RestartRequiredException;
import jenkins.install.InstallUtil;
import jenkins.model.Jenkins;
@@ -143,9 +144,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
/**
* {@linkplain UpdateSite#getId() ID} of the default update site.
- * @since 1.483
+ * @since 1.483 - public property
+ * @since TODO - configurable via system property
*/
- public static final String ID_DEFAULT = "default";
+ public static final String ID_DEFAULT = System.getProperty(UpdateCenter.class.getName()+".defaultUpdateSiteId", "default");
@Restricted(NoExternalUse.class)
public static final String ID_UPLOAD = "_upload";
@@ -290,7 +292,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
/**
* Get the current connection status.
*
- * Supports a "siteId" request parameter, defaulting to "default" for the default
+ * Supports a "siteId" request parameter, defaulting to {@link #ID_DEFAULT} for the default
* update site.
*
* @return The current connection status.
@@ -302,6 +304,9 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
String siteId = request.getParameter("siteId");
if (siteId == null) {
siteId = ID_DEFAULT;
+ } else if (siteId.equals("default")) {
+ // If the request explicitly requires the default ID, ship it
+ siteId = ID_DEFAULT;
}
ConnectionCheckJob checkJob = getConnectionCheckJob(siteId);
if (checkJob == null) {
@@ -334,7 +339,8 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
}
return HttpResponses.okJSON(checkJob.connectionStates);
} else {
- return HttpResponses.errorJSON(String.format("Unknown site '%s'.", siteId));
+ return HttpResponses.errorJSON(String.format("Cannot check connection status of the update site with ID='%s'"
+ + ". This update center cannot be resolved", siteId));
}
} catch (Exception e) {
return HttpResponses.errorJSON(String.format("ERROR: %s", e.getMessage()));
@@ -463,7 +469,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
/**
* Alias for {@link #getById}.
+ * @param id ID of the update site to be retrieved
+ * @return Discovered {@link UpdateSite}. {@code null} if it cannot be found
*/
+ @CheckForNull
public UpdateSite getSite(String id) {
return getById(id);
}
@@ -488,7 +497,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
/**
* Gets {@link UpdateSite} by its ID.
* Used to bind them to URL.
+ * @param id ID of the update site to be retrieved
+ * @return Discovered {@link UpdateSite}. {@code null} if it cannot be found
*/
+ @CheckForNull
public UpdateSite getById(String id) {
for (UpdateSite s : sites) {
if (s.getId().equals(id)) {
@@ -502,8 +514,9 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
* Gets the {@link UpdateSite} from which we receive updates for jenkins.war.
*
* @return
- * null if no such update center is provided.
+ * {@code null} if no such update center is provided.
*/
+ @CheckForNull
public UpdateSite getCoreSource() {
for (UpdateSite s : sites) {
Data data = s.getData();
@@ -527,6 +540,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
/**
* Gets the plugin with the given name from the first {@link UpdateSite} to contain it.
+ * @return Discovered {@link Plugin}. {@code null} if it cannot be found
*/
public @CheckForNull Plugin getPlugin(String artifactId) {
for (UpdateSite s : sites) {
@@ -1519,6 +1533,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
status = e;
if (status.isSuccess()) onSuccess();
requiresRestart |= status.requiresRestart();
+ } catch (MissingDependencyException e) {
+ LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { getName(), e.getMessage() });
+ status = new Failure(e);
+ error = e;
} catch (Throwable e) {
LOGGER.log(Level.SEVERE, "Failed to install "+getName(),e);
status = new Failure(e);
@@ -2038,12 +2056,19 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
@Restricted(NoExternalUse.class)
public static void updateDefaultSite() {
+ final UpdateSite site = Jenkins.getInstance().getUpdateCenter().getSite(UpdateCenter.ID_DEFAULT);
+ if (site == null) {
+ LOGGER.log(Level.SEVERE, "Upgrading Jenkins. Cannot retrieve the default Update Site ''{0}''. "
+ + "Plugin installation may fail.", UpdateCenter.ID_DEFAULT);
+ return;
+ }
try {
// Need to do the following because the plugin manager will attempt to access
- // $JENKINS_HOME/updates/default.json. Needs to be up to date.
- Jenkins.getInstance().getUpdateCenter().getSite(UpdateCenter.ID_DEFAULT).updateDirectlyNow(true);
+ // $JENKINS_HOME/updates/$ID_DEFAULT.json. Needs to be up to date.
+ site.updateDirectlyNow(true);
} catch (Exception e) {
- LOGGER.log(WARNING, "Upgrading Jenkins. Failed to update default UpdateSite. Plugin upgrades may fail.", e);
+ LOGGER.log(WARNING, "Upgrading Jenkins. Failed to update the default Update Site '" + UpdateCenter.ID_DEFAULT +
+ "'. Plugin upgrades may fail.", e);
}
}
diff --git a/core/src/main/java/jenkins/MissingDependencyException.java b/core/src/main/java/jenkins/MissingDependencyException.java
new file mode 100644
index 0000000000..c1b25673ef
--- /dev/null
+++ b/core/src/main/java/jenkins/MissingDependencyException.java
@@ -0,0 +1,60 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2016, CloudBees, Inc.
+ *
+ * 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;
+
+import java.io.IOException;
+import java.util.List;
+
+import hudson.PluginWrapper.Dependency;
+import hudson.Util;
+
+/**
+ * Exception thrown if plugin resolution fails due to missing dependencies
+ *
+ * @author Carlos Sanchez
+ * @since TODO
+ *
+ */
+public class MissingDependencyException extends IOException {
+
+ private String pluginShortName;
+ private List missingDependencies;
+
+ public MissingDependencyException(String pluginShortName, List missingDependencies) {
+ super("One or more dependencies could not be resolved for " + pluginShortName + " : "
+ + Util.join(missingDependencies, ", "));
+ this.pluginShortName = pluginShortName;
+ this.missingDependencies = missingDependencies;
+ }
+
+ public List getMissingDependencies() {
+ return missingDependencies;
+ }
+
+ public String getPluginShortName() {
+ return pluginShortName;
+ }
+
+}
diff --git a/core/src/main/java/jenkins/PluginSubtypeMarker.java b/core/src/main/java/jenkins/PluginSubtypeMarker.java
index 6dba87f5cb..d8e127f3ce 100644
--- a/core/src/main/java/jenkins/PluginSubtypeMarker.java
+++ b/core/src/main/java/jenkins/PluginSubtypeMarker.java
@@ -30,7 +30,6 @@ import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
@@ -54,7 +53,6 @@ import java.util.Set;
* @author Kohsuke Kawaguchi
* @since 1.420
*/
-@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("*")
@MetaInfServices(Processor.class)
@SuppressWarnings({"Since15"})
@@ -80,6 +78,11 @@ public class PluginSubtypeMarker extends AbstractProcessor {
return super.visitType(e, aVoid);
}
+
+ @Override
+ public Void visitUnknown(Element e, Void aVoid) {
+ return DEFAULT_VALUE;
+ }
};
for (Element e : roundEnv.getRootElements()) {
@@ -100,6 +103,11 @@ public class PluginSubtypeMarker extends AbstractProcessor {
}
}
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
private void write(TypeElement c) throws IOException {
FileObject f = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT,
"", "META-INF/services/hudson.Plugin");
diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java
index 3ee4f9aeaa..da5d2ac61e 100644
--- a/core/src/main/java/jenkins/model/Jenkins.java
+++ b/core/src/main/java/jenkins/model/Jenkins.java
@@ -755,10 +755,17 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
* @throws IllegalStateException {@link Jenkins} has not been started, or was already shut down
*/
@CLIResolver
- @Nullable // TODO replace with non-null once Jenkins 2.0+
+ @Nonnull
public static Jenkins getInstance() {
- // TODO throw an IllegalStateException in Jenkins 2.0+
- return HOLDER.getInstance();
+ Jenkins instance = HOLDER.getInstance();
+ if (instance == null) {
+ if(!Boolean.getBoolean(Jenkins.class.getName()+".disableExceptionOnNullInstance")) {
+ // TODO: remove that second block around 2.20 (that is: ~20 versions to battle test it)
+ // See https://github.com/jenkinsci/jenkins/pull/2297#issuecomment-216710150
+ throw new IllegalStateException("Jenkins has not been started, or was already shut down");
+ }
+ }
+ return instance;
}
/**
@@ -3686,7 +3693,6 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
/**
* Reloads the configuration.
*/
- @CLIMethod(name="reload-configuration")
@RequirePOST
public synchronized HttpResponse doReload() throws IOException {
checkPermission(ADMINISTER);
diff --git a/core/src/main/resources/hudson/cli/Messages.properties b/core/src/main/resources/hudson/cli/Messages.properties
index a7a7f656a5..985f6f78c2 100644
--- a/core/src/main/resources/hudson/cli/Messages.properties
+++ b/core/src/main/resources/hudson/cli/Messages.properties
@@ -88,4 +88,6 @@ ReloadJobCommand.ShortDescription=Reload job(s)
OnlineNodeCommand.ShortDescription=Resume using a node for performing builds, to cancel out the earlier "offline-node" command.
ClearQueueCommand.ShortDescription=Clears the build queue.
+ReloadConfigurationCommand.ShortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk.
+DisconnectNodeCommand.ShortDescription=Disconnects from a node.
diff --git a/core/src/main/resources/hudson/cli/Messages_bg.properties b/core/src/main/resources/hudson/cli/Messages_bg.properties
index 9a44c3b966..e85eb64dcd 100644
--- a/core/src/main/resources/hudson/cli/Messages_bg.properties
+++ b/core/src/main/resources/hudson/cli/Messages_bg.properties
@@ -125,3 +125,8 @@ BuildCommand.CLICause.CannotBuildUnknownReasons=\
ClearQueueCommand.ShortDescription=\
\u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 \u0441\u044a\u0441 \u0437\u0430\u0434\u0430\u0447\u0438.
+DisconnectNodeCommand.ShortDescription=\
+ \u041f\u0440\u0435\u043a\u044a\u0441\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430 \u0441 \u043c\u0430\u0448\u0438\u043d\u0430.
+ReloadConfigurationCommand.ShortDescription=\
+ \u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u043c\u0435\u0442\u0442\u0430 \u0438 \u043f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u043e \u043e\u0442 \u0444\u0430\u0439\u043b\u043e\u0432\u0430\u0442\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430.\
+ \u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0438 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e \u0434\u0438\u0441\u043a\u0430.
diff --git a/core/src/main/resources/hudson/cli/Messages_da.properties b/core/src/main/resources/hudson/cli/Messages_da.properties
index 66ed157450..24c7ecb750 100644
--- a/core/src/main/resources/hudson/cli/Messages_da.properties
+++ b/core/src/main/resources/hudson/cli/Messages_da.properties
@@ -4,4 +4,8 @@ DeleteJobCommand.ShortDescription=Sletter et job
OnlineNodeCommand.ShortDescription=Genoptag brugen af en byggenode, for at annullere en tidligere udstedt "offline-node" kommando.
ClearQueueCommand.ShortDescription=Ryd byggek\u00f8en
+ReloadConfigurationCommand.ShortDescription=Genindl\u00e6s alle data fra filsystemet. \
+Nyttigt hvis du har modificeret konfigurationsfiler direkte, udenom Jenkins.
+
+DisconnectNodeCommand.ShortDescription=Afbryder forbindelsen til en node
diff --git a/core/src/main/resources/hudson/cli/Messages_de.properties b/core/src/main/resources/hudson/cli/Messages_de.properties
index 366dcfb5e5..2d54e32d1d 100644
--- a/core/src/main/resources/hudson/cli/Messages_de.properties
+++ b/core/src/main/resources/hudson/cli/Messages_de.properties
@@ -4,4 +4,6 @@ DeleteJobCommand.ShortDescription=Job l\u00f6schen.
OnlineNodeCommand.ShortDescription=Knoten wird wieder f\u00fcr neue Builds verwendet. Hebt ein vorausgegangenes "offline-node"-Kommando auf.
ClearQueueCommand.ShortDescription=Build-Warteschlange l\u00f6schen.
+ReloadConfigurationCommand.ShortDescription=Alle Daten im Speicher verwerfen und Konfiguration neu von Festplatte laden. Dies ist n\u00fctzlich, wenn Sie \u00c4nderungen direkt im Dateisystem vorgenommen haben.
+DisconnectNodeCommand.ShortDescription=Knoten trennen.
diff --git a/core/src/main/resources/hudson/cli/Messages_es.properties b/core/src/main/resources/hudson/cli/Messages_es.properties
index bb3e82e01a..74544043bd 100644
--- a/core/src/main/resources/hudson/cli/Messages_es.properties
+++ b/core/src/main/resources/hudson/cli/Messages_es.properties
@@ -54,4 +54,6 @@ DeleteNodeCommand.ShortDescription=Borrar un nodo
OnlineNodeCommand.ShortDescription=Continuar usando un nodo y candelar el comando "offline-node" mas reciente.
ClearQueueCommand.ShortDescription=Limpiar la cola de trabajos
+ReloadConfigurationCommand.ShortDescription=Descartar todos los datos presentes en memoria y recargar todo desde el disco duro. \u00datil cuando se han hecho modificaciones a mano en el disco duro.
+DisconnectNodeCommand.ShortDescription=Desconectarse de un nodo
diff --git a/core/src/main/resources/hudson/cli/Messages_it.properties b/core/src/main/resources/hudson/cli/Messages_it.properties
index 20b07b0c7a..e7c801919a 100644
--- a/core/src/main/resources/hudson/cli/Messages_it.properties
+++ b/core/src/main/resources/hudson/cli/Messages_it.properties
@@ -4,4 +4,5 @@ DeleteJobCommand.ShortDescription=Cancella un job
OnlineNodeCommand.ShortDescription=Resume using a node for performing builds, to cancel out the earlier "offline-node" command.
ClearQueueCommand.ShortDescription=Pulisce la coda di lavoro
+ReloadConfigurationCommand.ShortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk.
diff --git a/core/src/main/resources/hudson/cli/Messages_ja.properties b/core/src/main/resources/hudson/cli/Messages_ja.properties
index 83944936c1..b51f1edfd7 100644
--- a/core/src/main/resources/hudson/cli/Messages_ja.properties
+++ b/core/src/main/resources/hudson/cli/Messages_ja.properties
@@ -76,4 +76,6 @@ DeleteJobCommand.ShortDescription=\u30b8\u30e7\u30d6\u3092\u524a\u9664\u3057\u30
OnlineNodeCommand.ShortDescription=\u76f4\u524d\u306b\u5b9f\u884c\u3057\u305f"online-node"\u30b3\u30de\u30f3\u30c9\u3092\u53d6\u308a\u6d88\u3057\u3001\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3059\u308b\u30ce\u30fc\u30c9\u306e\u4f7f\u7528\u3092\u518d\u958b\u3057\u307e\u3059\u3002
ClearQueueCommand.ShortDescription=\u30d3\u30eb\u30c9\u30ad\u30e5\u30fc\u3092\u30af\u30ea\u30a2\u3057\u307e\u3059\u3002
+ReloadConfigurationCommand.ShortDescription=\u30e1\u30e2\u30ea\u306b\u3042\u308b\u3059\u3079\u3066\u306e\u30c7\u30fc\u30bf\u3092\u7834\u68c4\u3057\u3066\u3001\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u518d\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u76f4\u63a5\u4fee\u6b63\u3057\u305f\u5834\u5408\u306b\u5f79\u306b\u7acb\u3061\u307e\u3059\u3002
+DisconnectNodeCommand.ShortDescription=\u30ce\u30fc\u30c9\u3068\u306e\u63a5\u7d9a\u3092\u5207\u65ad\u3057\u307e\u3059\u3002
diff --git a/core/src/main/resources/hudson/cli/Messages_pt_BR.properties b/core/src/main/resources/hudson/cli/Messages_pt_BR.properties
index 5ba26b1c5f..9d878637a0 100644
--- a/core/src/main/resources/hudson/cli/Messages_pt_BR.properties
+++ b/core/src/main/resources/hudson/cli/Messages_pt_BR.properties
@@ -122,4 +122,7 @@ ReloadJobCommand.ShortDescription=\
OnlineNodeCommand.ShortDescription=Continuar usando um n\u00f3 para realizar os builds
ClearQueueCommand.ShortDescription=Limpa a fila de builds
+ReloadConfigurationCommand.ShortDescription=Descarta todo o conte\u00fado de mem\u00f3ria e recarrega novamente a partir do arquivo. \
+Indicado quando voc\u00ea modificou os arquivos diretamente no disco.
+DisconnectNodeCommand.ShortDescription=Desconectar do n\u00f3
diff --git a/core/src/main/resources/hudson/cli/Messages_zh_CN.properties b/core/src/main/resources/hudson/cli/Messages_zh_CN.properties
index 111ff92e1a..a36bb8e9a6 100644
--- a/core/src/main/resources/hudson/cli/Messages_zh_CN.properties
+++ b/core/src/main/resources/hudson/cli/Messages_zh_CN.properties
@@ -2,3 +2,4 @@ DeleteNodeCommand.ShortDescription=Deletes a node
DeleteJobCommand.ShortDescription=Deletes a job
ClearQueueCommand.ShortDescription=Clears the build queue
+ReloadConfigurationCommand.ShortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk.
diff --git a/core/src/main/resources/hudson/cli/Messages_zh_TW.properties b/core/src/main/resources/hudson/cli/Messages_zh_TW.properties
index 5bc2801193..d422030cf3 100644
--- a/core/src/main/resources/hudson/cli/Messages_zh_TW.properties
+++ b/core/src/main/resources/hudson/cli/Messages_zh_TW.properties
@@ -77,3 +77,5 @@ DeleteNodeCommand.ShortDescription=\u522a\u9664\u6307\u5b9a\u7bc0\u9ede\u3002
DeleteJobCommand.ShortDescription=\u522a\u9664\u4f5c\u696d\u3002
ClearQueueCommand.ShortDescription=\u6e05\u9664\u5efa\u7f6e\u4f47\u5217\u3002
+DisconnectNodeCommand.ShortDescription=\u4e2d\u65b7\u8207\u6307\u5b9a\u7bc0\u9ede\u7684\u9023\u7dda\u3002
+ReloadConfigurationCommand.ShortDescription=\u653e\u68c4\u6240\u6709\u8a18\u61b6\u9ad4\u88e1\u7684\u8cc7\u6599\uff0c\u7531\u6a94\u6848\u7cfb\u7d71\u4e2d\u91cd\u65b0\u8f09\u5165\u3002\u9069\u5408\u5728\u76f4\u63a5\u4fee\u6539\u8a2d\u5b9a\u6a94\u5f8c\u4f7f\u7528\u3002
diff --git a/core/src/main/resources/hudson/model/Messages.properties b/core/src/main/resources/hudson/model/Messages.properties
index 8d0b6a509f..062e96e5d2 100644
--- a/core/src/main/resources/hudson/model/Messages.properties
+++ b/core/src/main/resources/hudson/model/Messages.properties
@@ -93,7 +93,6 @@ Build.post_build_steps_failed=Post-build steps failed
CLI.clear-queue.shortDescription=Clears the build queue.
CLI.disable-job.shortDescription=Disables a job.
CLI.enable-job.shortDescription=Enables a job.
-CLI.disconnect-node.shortDescription=Disconnects from a node.
CLI.connect-node.shortDescription=Reconnect to a node.
CLI.offline-node.shortDescription=Stop using a node for performing builds temporarily, until the next "online-node" command.
CLI.wait-node-online.shortDescription=Wait for a node to become online.
@@ -101,6 +100,7 @@ CLI.wait-node-offline.shortDescription=Wait for a node to become offline.
Computer.Caption=Agent {0}
Computer.NoSuchSlaveExists=No such agent "{0}" exists. Did you mean "{1}"?
+Computer.NoSuchSlaveExistsWithoutAdvice=No such agent "{0}" exists.
Computer.Permissions.Title=Agent
Computer.ExtendedReadPermission.Description=This permission allows users to read agent configuration.
Computer.ConfigurePermission.Description=This permission allows users to configure agents.
@@ -373,7 +373,6 @@ CLI.safe-restart.shortDescription=Safely restart Jenkins
CLI.keep-build.shortDescription=Mark the build to keep the build forever.
CLI.quiet-down.shortDescription=Quiet down Jenkins, in preparation for a restart. Don\u2019t start any builds.
CLI.cancel-quiet-down.shortDescription=Cancel the effect of the "quiet-down" command.
-CLI.reload-configuration.shortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk.
BuildAuthorizationToken.InvalidTokenProvided=Invalid token provided.
diff --git a/core/src/main/resources/hudson/model/Messages_bg.properties b/core/src/main/resources/hudson/model/Messages_bg.properties
index 7bfa610ffd..1a7096f590 100644
--- a/core/src/main/resources/hudson/model/Messages_bg.properties
+++ b/core/src/main/resources/hudson/model/Messages_bg.properties
@@ -145,8 +145,6 @@ CLI.enable-job.shortDescription=\
\u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430.
CLI.delete-node.shortDescription=\
\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430.
-CLI.disconnect-node.shortDescription=\
- \u041f\u0440\u0435\u043a\u044a\u0441\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430 \u0441 \u043c\u0430\u0448\u0438\u043d\u0430.
CLI.connect-node.shortDescription=\
\u0421\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435 \u043a\u044a\u043c \u043c\u0430\u0448\u0438\u043d\u0430.
CLI.online-node.shortDescription=\
@@ -602,9 +600,6 @@ CLI.quiet-down.shortDescription=\
\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043d\u0430 Jenkins \u0437\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435. \u0414\u0430 \u043d\u0435 \u0441\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0442 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f.
CLI.cancel-quiet-down.shortDescription=\
\u041e\u0442\u043c\u044f\u043d\u0430 \u043d\u0430 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430\u0442\u0430 \u0437\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u2014 \u0449\u0435 \u0441\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0442 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f.
-CLI.reload-configuration.shortDescription=\
- \u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u043c\u0435\u0442\u0442\u0430 \u0438 \u043f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u043e \u043d\u0430\u043d\u043e\u0432\u043e \u043e\u0442 \u0444\u0430\u0439\u043b\u043e\u0432\u0430\u0442\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430.\
- \u0422\u043e\u0432\u0430 \u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043f\u0440\u0438 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043d\u043e \u043f\u043e \u0434\u0438\u0441\u043a\u0430.
BuildAuthorizationToken.InvalidTokenProvided=\
\u0417\u0430\u0434\u0430\u0434\u0435\u043d \u0435 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u0436\u0435\u0442\u043e\u043d \u0437\u0430 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442.
diff --git a/core/src/main/resources/hudson/model/Messages_da.properties b/core/src/main/resources/hudson/model/Messages_da.properties
index 427ba244f1..630e3ed9c6 100644
--- a/core/src/main/resources/hudson/model/Messages_da.properties
+++ b/core/src/main/resources/hudson/model/Messages_da.properties
@@ -83,6 +83,8 @@ FileParameterDefinition.DisplayName=Filparametre
Run.Summary.Unstable=Ustabil
CLI.reload-configuration.shortDescription=Genindl\u00e6s alle data fra filsystemet. \
Nyttigt hvis du har modificeret konfigurationsfiler direkte, udenom Jenkins.
+ComputerSet.NoSuchSlave=Ingen slave ved navn: {0}
+ComputerSet.SlaveAlreadyExists=En slave ved navn ''{0}'' eksisterer allerede
Executor.NotAvailable=N/A
Item.Permissions.Title=Job
AbstractProject.NoWorkspace=Intet arbejdsomr\u00e5de tilg\u00e6ngeligt, kan ikke checke for opdateringer.
@@ -186,7 +188,6 @@ LoadStatistics.Legends.QueueLength=K\u00f8 l\u00e6ngde
Hudson.ViewName=Alle
Job.BuildStability=Bygge stabilitet: {0}
Job.Pronoun=Projekt
-CLI.disconnect-node.shortDescription=Afbryder forbindelsen til en node
CLI.restart.shortDescription=Genstart Jenkins
Permalink.LastStableBuild=Sidste stabile byg
Hudson.NoJavaInPath=Java er ikke i din sti. M\u00e5ske mangler du at konfigurere JDK?
diff --git a/core/src/main/resources/hudson/model/Messages_de.properties b/core/src/main/resources/hudson/model/Messages_de.properties
index 21e7988d2c..d57981c328 100644
--- a/core/src/main/resources/hudson/model/Messages_de.properties
+++ b/core/src/main/resources/hudson/model/Messages_de.properties
@@ -77,10 +77,10 @@ CLI.keep-build.shortDescription=Build f\u00fcr immer aufbewahren.
CLI.quiet-down.shortDescription=Jenkins' Aktivit\u00e4t reduzieren, z.B. zur Vorbereitung eines Neustarts. Es werden keine neuen Builds mehr gestartet.
CLI.cancel-quiet-down.shortDescription=Wirkung des Befehls "quiet-down" wieder aufheben.
CLI.reload-configuration.shortDescription=Alle Daten im Speicher verwerfen und Konfiguration neu von Festplatte laden. Dies ist n\u00fctzlich, wenn Sie \u00c4nderungen direkt im Dateisystem vorgenommen haben.
+CLI.clear-queue.shortDescription=Build-Warteschlange l\u00f6schen.
CLI.disable-job.shortDescription=Job deaktivieren.
CLI.enable-job.shortDescription=Job aktivieren.
CLI.connect-node.shortDescription=Erneut mit Knoten verbinden.
-CLI.disconnect-node.shortDescription=Knoten trennen.
CLI.offline-node.shortDescription=Knoten wird bis zum n\u00e4chsten "online-node"-Kommando f\u00fcr keine neuen Builds verwendet.
CLI.safe-restart.shortDescription=Startet Jenkins neu.
Queue.init=Build-Warteschlange neu initialisieren
diff --git a/core/src/main/resources/hudson/model/Messages_es.properties b/core/src/main/resources/hudson/model/Messages_es.properties
index 29feb6dbeb..5fdcb09530 100644
--- a/core/src/main/resources/hudson/model/Messages_es.properties
+++ b/core/src/main/resources/hudson/model/Messages_es.properties
@@ -58,7 +58,6 @@ BallColor.Unstable=Inestable
CLI.disable-job.shortDescription=Desactivar una tarea
CLI.enable-job.shortDescription=Activar una tarea
-CLI.disconnect-node.shortDescription=Desconectarse de un nodo
CLI.connect-node.shortDescription=Reconectarse con un nodo
CLI.offline-node.shortDescription=Dejar de utilizar un nodo temporalmente hasta que se ejecute el comando "online-node".
@@ -249,7 +248,6 @@ CLI.safe-restart.shortDescription=Reiniciar Jenkins de manera segura
CLI.keep-build.shortDescription=Marcar la ejecuci\u00f3n para ser guardada para siempre.
CLI.quiet-down.shortDescription=Poner Jenkins en modo quieto y estar preparado para un reinicio. No comenzar ninguna ejecuci\u00f3n.
CLI.cancel-quiet-down.shortDescription=Cancelar el efecto del comando "quiet-down".
-CLI.reload-configuration.shortDescription=Descartar todos los datos presentes en memoria y recargar todo desde el disco duro. \u00datil cuando se han hecho modificaciones a mano en el disco duro.
View.MissingMode=No se ha especificado el tipo para la vista
AbstractProject.NoBuilds=No existen ejecuciones. Lanzando una nueva.
diff --git a/core/src/main/resources/hudson/model/Messages_it.properties b/core/src/main/resources/hudson/model/Messages_it.properties
index 6beced04f0..ce28f41835 100644
--- a/core/src/main/resources/hudson/model/Messages_it.properties
+++ b/core/src/main/resources/hudson/model/Messages_it.properties
@@ -72,7 +72,6 @@ BallColor.Unstable=Instabile
CLI.disable-job.shortDescription=Disabilita un job
CLI.enable-job.shortDescription=Abilita un job
-CLI.disconnect-node.shortDescription=Disconnects from a node
CLI.connect-node.shortDescription=Riconnettersi ad un nodo
CLI.offline-node.shortDescription=Stop using a node for performing builds temporarily, until the next "online-node" command.
CLI.wait-node-online.shortDescription=Attende che il nodo sia attivo
@@ -281,7 +280,6 @@ CLI.safe-restart.shortDescription=Riavvio sicuro Jenkins
CLI.keep-build.shortDescription=Mark the build to keep the build forever.
CLI.quiet-down.shortDescription=Quiet down Jenkins, in preparation for a restart. Don''t start any builds.
CLI.cancel-quiet-down.shortDescription=Cancel the effect of the "quiet-down" command.
-CLI.reload-configuration.shortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk.
BuildAuthorizationToken.InvalidTokenProvided=Invalid token provided.
ParametersDefinitionProperty.DisplayName=Questa build \u00E8 parametrizzata
diff --git a/core/src/main/resources/hudson/model/Messages_ja.properties b/core/src/main/resources/hudson/model/Messages_ja.properties
index f36f34306a..c14d955dae 100644
--- a/core/src/main/resources/hudson/model/Messages_ja.properties
+++ b/core/src/main/resources/hudson/model/Messages_ja.properties
@@ -293,9 +293,9 @@ CLI.keep-build.shortDescription=\u30d3\u30eb\u30c9\u3092\u4fdd\u5b58\u3059\u308b
CLI.quiet-down.shortDescription=Jenkins\u306f\u518d\u8d77\u52d5\u306b\u5411\u3051\u3066\u7d42\u4e86\u51e6\u7406\u3092\u5b9f\u65bd\u4e2d\u3067\u3059\u3002\u30d3\u30eb\u30c9\u3092\u958b\u59cb\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002
CLI.cancel-quiet-down.shortDescription="quite-down"\u30b3\u30de\u30f3\u30c9\u306e\u51e6\u7406\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3059\u3002
CLI.reload-configuration.shortDescription=\u30e1\u30e2\u30ea\u306b\u3042\u308b\u3059\u3079\u3066\u306e\u30c7\u30fc\u30bf\u3092\u7834\u68c4\u3057\u3066\u3001\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u518d\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u76f4\u63a5\u4fee\u6b63\u3057\u305f\u5834\u5408\u306b\u5f79\u306b\u7acb\u3061\u307e\u3059\u3002
+CLI.clear-queue.shortDescription=\u30d3\u30eb\u30c9\u30ad\u30e5\u30fc\u3092\u30af\u30ea\u30a2\u3057\u307e\u3059\u3002
CLI.disable-job.shortDescription=\u30b8\u30e7\u30d6\u3092\u7121\u52b9\u5316\u3057\u307e\u3059\u3002
CLI.enable-job.shortDescription=\u30b8\u30e7\u30d6\u3092\u6709\u52b9\u5316\u3057\u307e\u3059\u3002
-CLI.disconnect-node.shortDescription=\u30ce\u30fc\u30c9\u3068\u306e\u63a5\u7d9a\u3092\u5207\u65ad\u3057\u307e\u3059\u3002
CLI.connect-node.shortDescription=\u30ce\u30fc\u30c9\u3068\u518d\u63a5\u7d9a\u3057\u307e\u3059\u3002
CLI.offline-node.shortDescription="online-node"\u30b3\u30de\u30f3\u30c9\u304c\u5b9f\u884c\u3055\u308c\u308b\u307e\u3067\u3001\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3059\u308b\u30ce\u30fc\u30c9\u306e\u4f7f\u7528\u3092\u4e00\u6642\u7684\u306b\u505c\u6b62\u3057\u307e\u3059\u3002
CLI.wait-node-online.shortDescription=\u30ce\u30fc\u30c9\u304c\u30aa\u30f3\u30e9\u30a4\u30f3\u306b\u306a\u308b\u306e\u3092\u5f85\u3061\u307e\u3059\u3002
diff --git a/core/src/main/resources/hudson/model/Messages_pt_BR.properties b/core/src/main/resources/hudson/model/Messages_pt_BR.properties
index 0a3f406e25..b108d0f52f 100644
--- a/core/src/main/resources/hudson/model/Messages_pt_BR.properties
+++ b/core/src/main/resources/hudson/model/Messages_pt_BR.properties
@@ -176,8 +176,12 @@ FileParameterDefinition.DisplayName=Par\u00e2metros de arquivo
# unstable
Run.Summary.Unstable=Inst\u00e1vel
# Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk.
-CLI.reload-configuration.shortDescription=Descarta todo o conte\u00fado de mem\u00f3ria e recarrega novamente a partir do arquivo. /
+CLI.reload-configuration.shortDescription=Descarta todo o conte\u00fado de mem\u00f3ria e recarrega novamente a partir do arquivo. \
Indicado quando voc\u00ea modificou os arquivos diretamente no disco.
+# Slave called ''{0}'' already exists
+ComputerSet.SlaveAlreadyExists=Slave ''{0}'' j\u00e1 existe
+# No such slave: {0}
+ComputerSet.NoSuchSlave=Nenhum slave: {0}
# Disables a job
CLI.disable-job.shortDescription=Desabilitar uma job
# Build Triggers
@@ -302,8 +306,6 @@ Hudson.NotANumber=n\u00e3o \u00e9 um n\u00famero
View.CreatePermission.Description=Permite aos usu\u00e1rios criarem novas views
# Queue length
LoadStatistics.Legends.QueueLength=Comprimento da fila
-# Disconnects from a node
-CLI.disconnect-node.shortDescription=Desconectar do n\u00f3
# Restart Jenkins
CLI.restart.shortDescription=Reiniciar o Jenkins
# {0} is offline
diff --git a/core/src/main/resources/hudson/model/Messages_zh_CN.properties b/core/src/main/resources/hudson/model/Messages_zh_CN.properties
index 15d419d1f9..83f27e4383 100644
--- a/core/src/main/resources/hudson/model/Messages_zh_CN.properties
+++ b/core/src/main/resources/hudson/model/Messages_zh_CN.properties
@@ -62,7 +62,6 @@ BallColor.Unstable=Unstable
CLI.disable-job.shortDescription=Disables a job
CLI.enable-job.shortDescription=Enables a job
-CLI.disconnect-node.shortDescription=Disconnects from a node
CLI.connect-node.shortDescription=Reconnect to a node
CLI.online-node.shortDescription=Resume using a node for performing builds, to cancel out the earlier "offline-node" command.
CLI.offline-node.shortDescription=Stop using a node for performing builds temporarily, until the next "online-node" command.
@@ -249,6 +248,5 @@ CLI.safe-restart.shortDescription=Safely restart Jenkins
CLI.keep-build.shortDescription=Mark the build to keep the build forever.
CLI.quiet-down.shortDescription=Quiet down Jenkins, in preparation for a restart. Don''t start any builds.
CLI.cancel-quiet-down.shortDescription=Cancel the effect of the "quiet-down" command.
-CLI.reload-configuration.shortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk.
ManageJenkinsAction.DisplayName=\u7cfb\u7edf\u7ba1\u7406
ParametersDefinitionProperty.DisplayName=\u53C2\u6570\u5316\u6784\u5EFA\u8FC7\u7A0B
diff --git a/core/src/main/resources/hudson/model/Messages_zh_TW.properties b/core/src/main/resources/hudson/model/Messages_zh_TW.properties
index 9109aa1f54..bde8bb7bc1 100644
--- a/core/src/main/resources/hudson/model/Messages_zh_TW.properties
+++ b/core/src/main/resources/hudson/model/Messages_zh_TW.properties
@@ -78,7 +78,6 @@ BallColor.Unstable=\u4e0d\u7a69\u5b9a
CLI.disable-job.shortDescription=\u505c\u7528\u4f5c\u696d\u3002
CLI.enable-job.shortDescription=\u555f\u7528\u4f5c\u696d\u3002
-CLI.disconnect-node.shortDescription=\u4e2d\u65b7\u8207\u6307\u5b9a\u7bc0\u9ede\u7684\u9023\u7dda\u3002
CLI.connect-node.shortDescription=\u9023\u7dda\u5230\u6307\u5b9a\u7bc0\u9ede\u3002
CLI.online-node.shortDescription=\u7e7c\u7e8c\u4f7f\u7528\u6307\u5b9a\u7bc0\u9ede\u4f86\u5efa\u7f6e\uff0c\u53d6\u6d88\u5148\u524d\u7684 "offline-node" \u6307\u4ee4\u3002
CLI.offline-node.shortDescription=\u66ab\u6642\u4e0d\u4f7f\u7528\u6307\u5b9a\u7bc0\u9ede\u4f86\u5efa\u7f6e\uff0c\u76f4\u5230\u57f7\u884c "online-node" \u6307\u4ee4\u70ba\u6b62\u3002
@@ -297,7 +296,6 @@ CLI.safe-restart.shortDescription=\u5b89\u5168\u7684\u91cd\u65b0\u555f\u52d5 Jen
CLI.keep-build.shortDescription=\u6c38\u4e45\u4fdd\u5b58\u9019\u6b21\u5efa\u7f6e\u3002
CLI.quiet-down.shortDescription=\u8b93 Jenkins \u6c89\u6fb1\u4e00\u4e0b\uff0c\u6e96\u5099\u91cd\u65b0\u555f\u52d5\u3002\u5148\u4e0d\u8981\u518d\u5efa\u7f6e\u4efb\u4f55\u4f5c\u696d\u3002
CLI.cancel-quiet-down.shortDescription=\u53d6\u6d88 "quiet-down" \u6307\u4ee4\u3002
-CLI.reload-configuration.shortDescription=\u653e\u68c4\u6240\u6709\u8a18\u61b6\u9ad4\u88e1\u7684\u8cc7\u6599\uff0c\u7531\u6a94\u6848\u7cfb\u7d71\u4e2d\u91cd\u65b0\u8f09\u5165\u3002\u9069\u5408\u5728\u76f4\u63a5\u4fee\u6539\u8a2d\u5b9a\u6a94\u5f8c\u4f7f\u7528\u3002
BuildAuthorizationToken.InvalidTokenProvided=\u63d0\u4f9b\u7684 Token \u7121\u6548\u3002
diff --git a/core/src/main/resources/jenkins/model/Messages.properties b/core/src/main/resources/jenkins/model/Messages.properties
index 297812254b..e0dcf95e89 100644
--- a/core/src/main/resources/jenkins/model/Messages.properties
+++ b/core/src/main/resources/jenkins/model/Messages.properties
@@ -49,7 +49,6 @@ CLI.safe-restart.shortDescription=Safely restart Jenkins.
CLI.keep-build.shortDescription=Mark the build to keep the build forever.
CLI.quiet-down.shortDescription=Quiet down Jenkins, in preparation for a restart. Don\u2019t start any builds.
CLI.cancel-quiet-down.shortDescription=Cancel the effect of the "quiet-down" command.
-CLI.reload-configuration.shortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk.
CauseOfInterruption.ShortDescription=Aborted by {0}
CLI.shutdown.shortDescription=Immediately shuts down Jenkins server.
CLI.safe-shutdown.shortDescription=Puts Jenkins into the quiet mode, wait for existing builds to be completed, and then shut down Jenkins.
diff --git a/core/src/main/resources/jenkins/model/Messages_bg.properties b/core/src/main/resources/jenkins/model/Messages_bg.properties
index 21bcd85721..3edebe8d04 100644
--- a/core/src/main/resources/jenkins/model/Messages_bg.properties
+++ b/core/src/main/resources/jenkins/model/Messages_bg.properties
@@ -72,9 +72,6 @@ CLI.quiet-down.shortDescription=\
\u0437\u0430\u043f\u043e\u0447\u0432\u0430\u0442 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f.
CLI.cancel-quiet-down.shortDescription=\
\u041e\u0442\u043c\u044f\u043d\u0430 \u043d\u0430 \u0435\u0444\u0435\u043a\u0442\u0430 \u043d\u0430 \u043f\u0440\u0438\u0432\u044a\u0440\u0448\u0432\u0430\u043d\u0435\u0442\u043e.
-CLI.reload-configuration.shortDescription=\
- \u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u043c\u0435\u0442\u0442\u0430 \u0438 \u043f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u043e \u043e\u0442 \u0444\u0430\u0439\u043b\u043e\u0432\u0430\u0442\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430.\
- \u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0438 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e \u0434\u0438\u0441\u043a\u0430.
CauseOfInterruption.ShortDescription=\
\u041f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0435\u043d\u043e \u043e\u0442 \u201e{0}\u201c
CLI.shutdown.shortDescription=\
diff --git a/core/src/main/resources/jenkins/model/Messages_da.properties b/core/src/main/resources/jenkins/model/Messages_da.properties
index 5aff31f66b..dcaf66120f 100644
--- a/core/src/main/resources/jenkins/model/Messages_da.properties
+++ b/core/src/main/resources/jenkins/model/Messages_da.properties
@@ -47,8 +47,6 @@ CLI.quiet-down.shortDescription=Forbereder nedlukning, starter ingen nye byg.
CLI.keep-build.shortDescription=Marker bygget for at gemme det for evig tid
CLI.restart.shortDescription=Genstart Jenkins
CLI.cancel-quiet-down.shortDescription=Sl\u00e5 effekten af "quite-down" kommandoen fra.
-CLI.reload-configuration.shortDescription=Genindl\u00e6s alle data fra filsystemet. \
-Nyttigt hvis du har modificeret konfigurationsfiler direkte, udenom Jenkins.
Mailer.Address.Not.Configured=Adresse ikke konfigureret
Mailer.Localhost.Error=Venligst inds\u00e6t et gyldigt v\u00e6rtsnavn, istedet for localhost
diff --git a/core/src/main/resources/jenkins/model/Messages_de.properties b/core/src/main/resources/jenkins/model/Messages_de.properties
index 44f27164ab..d2030e2d22 100644
--- a/core/src/main/resources/jenkins/model/Messages_de.properties
+++ b/core/src/main/resources/jenkins/model/Messages_de.properties
@@ -50,7 +50,6 @@ CLI.restart.shortDescription=Jenkins neu starten.
CLI.keep-build.shortDescription=Build f\u00fcr immer aufbewahren.
CLI.quiet-down.shortDescription=Jenkins' Aktivit\u00e4t reduzieren, z.B. zur Vorbereitung eines Neustarts. Es werden keine neuen Builds mehr gestartet.
CLI.cancel-quiet-down.shortDescription=Wirkung des Befehls "quiet-down" wieder aufheben.
-CLI.reload-configuration.shortDescription=Alle Daten im Speicher verwerfen und Konfiguration neu von Festplatte laden. Dies ist n\u00fctzlich, wenn Sie \u00c4nderungen direkt im Dateisystem vorgenommen haben.
CLI.safe-restart.shortDescription=Startet Jenkins neu.
DefaultProjectNamingStrategy.DisplayName=keine Einschr\u00e4nkung
diff --git a/core/src/main/resources/jenkins/model/Messages_es.properties b/core/src/main/resources/jenkins/model/Messages_es.properties
index dbcea9d5d4..344aebeee1 100644
--- a/core/src/main/resources/jenkins/model/Messages_es.properties
+++ b/core/src/main/resources/jenkins/model/Messages_es.properties
@@ -49,7 +49,6 @@ CLI.safe-restart.shortDescription=Reiniciar Jenkins de manera segura
CLI.keep-build.shortDescription=Marcar la ejecuci\u00f3n para ser guardada para siempre.
CLI.quiet-down.shortDescription=Poner Jenkins en modo quieto y estar preparado para un reinicio. No comenzar ninguna ejecuci\u00f3n.
CLI.cancel-quiet-down.shortDescription=Cancelar el efecto del comando "quiet-down".
-CLI.reload-configuration.shortDescription=Descartar todos los datos presentes en memoria y recargar todo desde el disco duro. \u00datil cuando se han hecho modificaciones a mano en el disco duro.
PatternProjectNamingStrategy.DisplayName=Patrón
DefaultProjectNamingStrategy.DisplayName=Por defecto
diff --git a/core/src/main/resources/jenkins/model/Messages_ja.properties b/core/src/main/resources/jenkins/model/Messages_ja.properties
index a881b1699e..294ad5dbc3 100644
--- a/core/src/main/resources/jenkins/model/Messages_ja.properties
+++ b/core/src/main/resources/jenkins/model/Messages_ja.properties
@@ -48,7 +48,6 @@ CLI.safe-restart.shortDescription=Jenkins\u3092\u5b89\u5168\u306b\u518d\u8d77\u5
CLI.keep-build.shortDescription=\u30d3\u30eb\u30c9\u3092\u4fdd\u5b58\u3059\u308b\u3088\u3046\u306b\u30de\u30fc\u30af\u3057\u307e\u3059\u3002
CLI.quiet-down.shortDescription=Jenkins\u306f\u518d\u8d77\u52d5\u306b\u5411\u3051\u3066\u7d42\u4e86\u51e6\u7406\u3092\u5b9f\u65bd\u4e2d\u3067\u3059\u3002\u30d3\u30eb\u30c9\u3092\u958b\u59cb\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002
CLI.cancel-quiet-down.shortDescription="quite-down"\u30b3\u30de\u30f3\u30c9\u306e\u51e6\u7406\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3059\u3002
-CLI.reload-configuration.shortDescription=\u30e1\u30e2\u30ea\u306b\u3042\u308b\u3059\u3079\u3066\u306e\u30c7\u30fc\u30bf\u3092\u7834\u68c4\u3057\u3066\u3001\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u518d\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u76f4\u63a5\u4fee\u6b63\u3057\u305f\u5834\u5408\u306b\u5f79\u306b\u7acb\u3061\u307e\u3059\u3002
CauseOfInterruption.ShortDescription={0}\u306b\u3088\u308b\u4e2d\u65ad
CLI.shutdown.shortDescription=Jenkins\u30b5\u30fc\u30d0\u30fc\u3092\u76f4\u3061\u306b\u30b7\u30e3\u30c3\u30c8\u30c0\u30a6\u30f3\u3057\u307e\u3059\u3002
CLI.safe-shutdown.shortDescription=\
diff --git a/core/src/main/resources/jenkins/model/Messages_pt_BR.properties b/core/src/main/resources/jenkins/model/Messages_pt_BR.properties
index 75a636be07..bae1f43df6 100644
--- a/core/src/main/resources/jenkins/model/Messages_pt_BR.properties
+++ b/core/src/main/resources/jenkins/model/Messages_pt_BR.properties
@@ -38,8 +38,6 @@ Hudson.NodeDescription=N\u00f3 master do Jenkins
CLI.safe-restart.shortDescription=Seguro reiniciar o Jenkins
CLI.quiet-down.shortDescription=Desativar em modo silencioso, em prepara\u00e7\u00e3o para o rein\u00edcio. N\u00e3o comece nenhum build.
CLI.cancel-quiet-down.shortDescription=Cancela o comando "quiet-down"
-CLI.reload-configuration.shortDescription=Descarta todo o conte\u00fado de mem\u00f3ria e recarrega novamente a partir do arquivo. \
-Indicado quando voc\u00ea modificou os arquivos diretamente no disco.
CLI.restart.shortDescription=Reiniciar o Jenkins
CLI.keep-build.shortDescription=Marcar o build como permanente
diff --git a/core/src/main/resources/jenkins/model/Messages_zh_TW.properties b/core/src/main/resources/jenkins/model/Messages_zh_TW.properties
index c7bf681af0..f58819e794 100644
--- a/core/src/main/resources/jenkins/model/Messages_zh_TW.properties
+++ b/core/src/main/resources/jenkins/model/Messages_zh_TW.properties
@@ -49,7 +49,6 @@ CLI.safe-restart.shortDescription=\u5b89\u5168\u7684\u91cd\u65b0\u555f\u52d5 Jen
CLI.keep-build.shortDescription=\u6c38\u4e45\u4fdd\u5b58\u9019\u6b21\u5efa\u7f6e\u3002
CLI.quiet-down.shortDescription=\u8b93 Jenkins \u6c88\u6fb1\u4e00\u4e0b\uff0c\u6e96\u5099\u91cd\u65b0\u555f\u52d5\u3002\u5148\u4e0d\u8981\u518d\u5efa\u7f6e\u4efb\u4f55\u4f5c\u696d\u3002
CLI.cancel-quiet-down.shortDescription=\u53d6\u6d88 "quiet-down" \u6307\u4ee4\u3002
-CLI.reload-configuration.shortDescription=\u653e\u68c4\u6240\u6709\u8a18\u61b6\u9ad4\u88e1\u7684\u8cc7\u6599\uff0c\u7531\u6a94\u6848\u7cfb\u7d71\u4e2d\u91cd\u65b0\u8f09\u5165\u3002\u9069\u5408\u5728\u76f4\u63a5\u4fee\u6539\u8a2d\u5b9a\u6a94\u5f8c\u4f7f\u7528\u3002
CauseOfInterruption.ShortDescription=\u7531 {0} \u4e2d\u6b62
CLI.shutdown.shortDescription=\u7acb\u5373\u5c07 Jenkins \u4f3a\u670d\u5668\u505c\u6a5f
CLI.safe-shutdown.shortDescription=\u8b93 Jenkins \u9032\u5165\u975c\u5019\u6a21\u5f0f\uff0c\u7b49\u5230\u73fe\u6709\u4f5c\u696d\u90fd\u5b8c\u6210\u5f8c\u5c31\u5c07 Jenkins \u505c\u6a5f\u3002
diff --git a/test/src/test/java/hudson/cli/DisconnectNodeCommandTest.java b/test/src/test/java/hudson/cli/DisconnectNodeCommandTest.java
new file mode 100644
index 0000000000..858a3c9ec0
--- /dev/null
+++ b/test/src/test/java/hudson/cli/DisconnectNodeCommandTest.java
@@ -0,0 +1,302 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2016 Red Hat, Inc.
+ *
+ * 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.
+ */
+
+/**
+ * @author pjanouse
+ */
+
+package hudson.cli;
+
+import hudson.model.Computer;
+import hudson.slaves.DumbSlave;
+import hudson.slaves.OfflineCause;
+import jenkins.model.Jenkins;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsRule;
+
+import static hudson.cli.CLICommandInvoker.Matcher.failedWith;
+import static hudson.cli.CLICommandInvoker.Matcher.hasNoStandardOutput;
+import static hudson.cli.CLICommandInvoker.Matcher.succeededSilently;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.not;
+
+public class DisconnectNodeCommandTest {
+
+ private CLICommandInvoker command;
+
+ @Rule
+ public final JenkinsRule j = new JenkinsRule();
+
+ @Before
+ public void setUp() {
+ command = new CLICommandInvoker(j, "disconnect-node");
+ }
+
+ @Test
+ public void disconnectNodeShouldFailWithoutComputerDisconnectPermission() throws Exception {
+ j.createSlave("aNode", "", null);
+
+ final CLICommandInvoker.Result result = command
+ .authorizedTo(Jenkins.READ)
+ .invokeWithArgs("aNode");
+ assertThat(result, failedWith(6));
+ assertThat(result, hasNoStandardOutput());
+ assertThat(result.stderr(), containsString("ERROR: user is missing the Agent/Disconnect permission"));
+ assertThat(result.stderr(), not(containsString("ERROR: Error occured while performing this command, see previous stderr output.")));
+ }
+
+ @Test
+ public void disconnectNodeShouldFailIfNodeDoesNotExist() throws Exception {
+ final CLICommandInvoker.Result result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("never_created");
+ assertThat(result, failedWith(3));
+ assertThat(result, hasNoStandardOutput());
+ assertThat(result.stderr(), containsString("ERROR: No such agent \"never_created\" exists."));
+ assertThat(result.stderr(), not(containsString("ERROR: Error occured while performing this command, see previous stderr output.")));
+ }
+
+ @Test
+ public void disconnectNodeShouldSucceed() throws Exception {
+ DumbSlave slave = j.createSlave("aNode", "", null);
+ slave.toComputer().waitUntilOnline();
+ assertThat(slave.toComputer().isOnline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), equalTo(null));
+
+ CLICommandInvoker.Result result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode");
+ assertThat(result, succeededSilently());
+ assertThat(slave.toComputer().isOffline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave.toComputer().getOfflineCause()).message, equalTo(null));
+
+ slave.toComputer().connect(true);
+ slave.toComputer().waitUntilOnline();
+ assertThat(slave.toComputer().isOnline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), equalTo(null));
+
+ result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode");
+ assertThat(result, succeededSilently());
+ assertThat(slave.toComputer().isOffline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave.toComputer().getOfflineCause()).message, equalTo(null));
+
+ result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode");
+ assertThat(result, succeededSilently());
+ assertThat(slave.toComputer().isOffline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave.toComputer().getOfflineCause()).message, equalTo(null));
+ }
+
+ @Test
+ public void disconnectNodeShouldSucceedWithCause() throws Exception {
+ DumbSlave slave = j.createSlave("aNode", "", null);
+ slave.toComputer().waitUntilOnline();
+ assertThat(slave.toComputer().isOnline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), equalTo(null));
+
+ CLICommandInvoker.Result result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode", "-m", "aCause");
+ assertThat(result, succeededSilently());
+ assertThat(slave.toComputer().isOffline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave.toComputer().getOfflineCause()).message, equalTo("aCause"));
+
+ slave.toComputer().connect(true);
+ slave.toComputer().waitUntilOnline();
+ assertThat(slave.toComputer().isOnline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), equalTo(null));
+
+ result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode", "-m", "anotherCause");
+ assertThat(result, succeededSilently());
+ assertThat(slave.toComputer().isOffline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave.toComputer().getOfflineCause()).message, equalTo("anotherCause"));
+
+ result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode", "-m", "yetAnotherCause");
+ assertThat(result, succeededSilently());
+ assertThat(slave.toComputer().isOffline(), equalTo(true));
+ assertThat(slave.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave.toComputer().getOfflineCause()).message, equalTo("yetAnotherCause"));
+ }
+
+ @Test
+ public void disconnectNodeManyShouldSucceed() throws Exception {
+ DumbSlave slave1 = j.createSlave("aNode1", "", null);
+ DumbSlave slave2 = j.createSlave("aNode2", "", null);
+ DumbSlave slave3 = j.createSlave("aNode3", "", null);
+ slave1.toComputer().waitUntilOnline();
+ assertThat(slave1.toComputer().isOnline(), equalTo(true));
+ assertThat(slave1.toComputer().getOfflineCause(), equalTo(null));
+ slave2.toComputer().waitUntilOnline();
+ assertThat(slave2.toComputer().isOnline(), equalTo(true));
+ assertThat(slave2.toComputer().getOfflineCause(), equalTo(null));
+ slave3.toComputer().waitUntilOnline();
+ assertThat(slave3.toComputer().isOnline(), equalTo(true));
+ assertThat(slave3.toComputer().getOfflineCause(), equalTo(null));
+
+ final CLICommandInvoker.Result result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode1", "aNode2", "aNode3");
+ assertThat(result, succeededSilently());
+ assertThat(slave1.toComputer().isOffline(), equalTo(true));
+ assertThat(slave1.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave1.toComputer().getOfflineCause()).message, equalTo(null));
+ assertThat(slave2.toComputer().isOffline(), equalTo(true));
+ assertThat(slave2.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave2.toComputer().getOfflineCause()).message, equalTo(null));
+ assertThat(slave3.toComputer().isOffline(), equalTo(true));
+ assertThat(slave3.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave3.toComputer().getOfflineCause()).message, equalTo(null));
+ }
+
+ @Test
+ public void disconnectNodeManyShouldSucceedWithCause() throws Exception {
+ DumbSlave slave1 = j.createSlave("aNode1", "", null);
+ DumbSlave slave2 = j.createSlave("aNode2", "", null);
+ DumbSlave slave3 = j.createSlave("aNode3", "", null);
+ slave1.toComputer().waitUntilOnline();
+ assertThat(slave1.toComputer().isOnline(), equalTo(true));
+ assertThat(slave1.toComputer().getOfflineCause(), equalTo(null));
+ slave2.toComputer().waitUntilOnline();
+ assertThat(slave2.toComputer().isOnline(), equalTo(true));
+ assertThat(slave2.toComputer().getOfflineCause(), equalTo(null));
+ slave3.toComputer().waitUntilOnline();
+ assertThat(slave3.toComputer().isOnline(), equalTo(true));
+ assertThat(slave3.toComputer().getOfflineCause(), equalTo(null));
+
+ final CLICommandInvoker.Result result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode1", "aNode2", "aNode3", "-m", "aCause");
+ assertThat(result, succeededSilently());
+ assertThat(slave1.toComputer().isOffline(), equalTo(true));
+ assertThat(slave1.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave1.toComputer().getOfflineCause()).message, equalTo("aCause"));
+ assertThat(slave2.toComputer().isOffline(), equalTo(true));
+ assertThat(slave2.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave2.toComputer().getOfflineCause()).message, equalTo("aCause"));
+ assertThat(slave3.toComputer().isOffline(), equalTo(true));
+ assertThat(slave3.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave3.toComputer().getOfflineCause()).message, equalTo("aCause"));
+ }
+
+ @Test
+ public void disconnectNodeManyShouldFailIfANodeDoesNotExist() throws Exception {
+ DumbSlave slave1 = j.createSlave("aNode1", "", null);
+ DumbSlave slave2 = j.createSlave("aNode2", "", null);
+ slave1.toComputer().waitUntilOnline();
+ assertThat(slave1.toComputer().isOnline(), equalTo(true));
+ assertThat(slave1.toComputer().getOfflineCause(), equalTo(null));
+ slave2.toComputer().waitUntilOnline();
+ assertThat(slave2.toComputer().isOnline(), equalTo(true));
+ assertThat(slave2.toComputer().getOfflineCause(), equalTo(null));
+
+ final CLICommandInvoker.Result result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode1", "aNode2", "never_created", "-m", "aCause");
+ assertThat(result, failedWith(5));
+ assertThat(result, hasNoStandardOutput());
+ assertThat(result.stderr(), containsString("never_created: No such agent \"never_created\" exists. Did you mean \"aNode1\"?"));
+ assertThat(result.stderr(), containsString("ERROR: Error occured while performing this command, see previous stderr output."));
+ assertThat(slave1.toComputer().isOffline(), equalTo(true));
+ assertThat(slave1.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave1.toComputer().getOfflineCause()).message, equalTo("aCause"));
+ assertThat(slave2.toComputer().isOffline(), equalTo(true));
+ assertThat(slave2.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave2.toComputer().getOfflineCause()).message, equalTo("aCause"));
+ }
+
+ @Test
+ public void disconnectNodeManyShouldSucceedEvenANodeIsSpecifiedTwice() throws Exception {
+ DumbSlave slave1 = j.createSlave("aNode1", "", null);
+ DumbSlave slave2 = j.createSlave("aNode2", "", null);
+ slave1.toComputer().waitUntilOnline();
+ assertThat(slave1.toComputer().isOnline(), equalTo(true));
+ assertThat(slave1.toComputer().getOfflineCause(), equalTo(null));
+ slave2.toComputer().waitUntilOnline();
+ assertThat(slave2.toComputer().isOnline(), equalTo(true));
+ assertThat(slave2.toComputer().getOfflineCause(), equalTo(null));
+
+ final CLICommandInvoker.Result result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("aNode1", "aNode2", "aNode1", "-m", "aCause");
+ assertThat(result, succeededSilently());
+ assertThat(slave1.toComputer().isOffline(), equalTo(true));
+ assertThat(slave1.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave1.toComputer().getOfflineCause()).message, equalTo("aCause"));
+ assertThat(slave2.toComputer().isOffline(), equalTo(true));
+ assertThat(slave2.toComputer().getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) slave2.toComputer().getOfflineCause()).message, equalTo("aCause"));
+ }
+
+ public void disconnectNodeShouldSucceedOnMaster() throws Exception {
+ final Computer masterComputer = j.jenkins.getActiveInstance().getComputer("");
+ assertThat(masterComputer.isOnline(), equalTo(true));
+ assertThat(masterComputer.getOfflineCause(), equalTo(null));
+
+ CLICommandInvoker.Result result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("");
+ assertThat(result, succeededSilently());
+ assertThat(masterComputer.isOffline(), equalTo(true));
+ assertThat(masterComputer.getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) masterComputer.getOfflineCause()).message, equalTo(null));
+
+ masterComputer.connect(true);
+ masterComputer.waitUntilOnline();
+ assertThat(masterComputer.isOnline(), equalTo(true));
+ assertThat(masterComputer.getOfflineCause(), equalTo(null));
+
+ result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("");
+ assertThat(result, succeededSilently());
+ assertThat(masterComputer.isOffline(), equalTo(true));
+ assertThat(masterComputer.getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) masterComputer.getOfflineCause()).message, equalTo(null));
+
+ result = command
+ .authorizedTo(Computer.DISCONNECT, Jenkins.READ)
+ .invokeWithArgs("");
+ assertThat(result, succeededSilently());
+ assertThat(masterComputer.isOffline(), equalTo(true));
+ assertThat(masterComputer.getOfflineCause(), instanceOf(OfflineCause.ByCLI.class));
+ assertThat(((OfflineCause.ByCLI) masterComputer.getOfflineCause()).message, equalTo(null));
+ }
+}
diff --git a/test/src/test/java/hudson/cli/ReloadConfigurationCommandTest.java b/test/src/test/java/hudson/cli/ReloadConfigurationCommandTest.java
new file mode 100644
index 0000000000..6be46f174a
--- /dev/null
+++ b/test/src/test/java/hudson/cli/ReloadConfigurationCommandTest.java
@@ -0,0 +1,197 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2016 Red Hat, Inc.
+ *
+ * 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 hudson.cli;
+
+import hudson.Util;
+import hudson.model.FreeStyleProject;
+import hudson.model.ListView;
+import hudson.model.Node;
+import hudson.model.User;
+import hudson.tasks.Mailer;
+import jenkins.model.Jenkins;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.jvnet.hudson.test.JenkinsRule;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import static hudson.cli.CLICommandInvoker.Matcher.failedWith;
+import static hudson.cli.CLICommandInvoker.Matcher.hasNoStandardOutput;
+
+import static hudson.cli.CLICommandInvoker.Matcher.succeededSilently;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+
+/**
+ * @author pjanouse
+ */
+public class ReloadConfigurationCommandTest {
+
+ private CLICommandInvoker command;
+
+ @Rule public final JenkinsRule j = new JenkinsRule();
+
+ @Before public void setUp() {
+ command = new CLICommandInvoker(j, "reload-configuration");
+ }
+
+ @Test
+ public void reloadConfigurationShouldFailWithoutAdministerPermission() throws Exception {
+ final CLICommandInvoker.Result result = command
+ .authorizedTo(Jenkins.READ).invoke();
+
+ assertThat(result, failedWith(6));
+ assertThat(result, hasNoStandardOutput());
+ assertThat(result.stderr(), containsString("user is missing the Overall/Administer permission"));
+ }
+
+ @Test
+ public void reloadMasterConfig() throws Exception {
+ Node node = j.jenkins;
+ node.setLabelString("oldLabel");
+
+ modifyNode(node);
+
+ assertThat(node.getLabelString(), equalTo("newLabel"));
+ }
+
+ @Test
+ public void reloadSlaveConfig() throws Exception {
+ Node node = j.createSlave("a_slave", "oldLabel", null);
+
+ modifyNode(node);
+
+ node = j.jenkins.getNode("a_slave");
+ assertThat(node.getLabelString(), equalTo("newLabel"));
+ }
+
+ private void modifyNode(Node node) throws Exception {
+ replace(node.getNodeName().equals("") ? "config.xml" : String.format("nodes/%s/config.xml",node.getNodeName()), "oldLabel", "newLabel");
+
+ assertThat(node.getLabelString(), equalTo("oldLabel"));
+
+ reloadJenkinsConfigurationViaCliAndWait();
+ }
+
+ @Test
+ public void reloadUserConfig() throws Exception {
+ User user = User.get("some_user", true, null);
+ user.setFullName("oldName");
+ user.save();
+
+ replace("users/some_user/config.xml", "oldName", "newName");
+
+ assertThat(user.getFullName(), equalTo("oldName"));
+
+ reloadJenkinsConfigurationViaCliAndWait();
+
+ assertThat(user.getFullName(), equalTo("newName"));
+ }
+
+ @Test
+ public void reloadJobConfig() throws Exception {
+ FreeStyleProject project = j.createFreeStyleProject("a_project");
+ project.setDescription("oldDescription");
+
+ replace("jobs/a_project/config.xml", "oldDescription", "newDescription");
+
+ assertThat( project.getDescription(), equalTo("oldDescription"));
+
+ reloadJenkinsConfigurationViaCliAndWait();
+
+ project = j.jenkins.getItem("a_project", j.jenkins, FreeStyleProject.class);
+ assertThat(project.getDescription(), equalTo("newDescription"));
+ }
+
+ @Test
+ public void reloadViewConfig() throws Exception {
+ ListView view = new ListView("a_view");
+ j.jenkins.addView(view);
+
+ view.setIncludeRegex("oldIncludeRegex");
+ view.save();
+
+ replace("config.xml", "oldIncludeRegex", "newIncludeRegex");
+
+ assertThat(view.getIncludeRegex(), equalTo("oldIncludeRegex"));
+
+ reloadJenkinsConfigurationViaCliAndWait();
+
+ view = (ListView) j.jenkins.getView("a_view");
+ assertThat(view.getIncludeRegex(), equalTo("newIncludeRegex"));
+ }
+
+ @Ignore // Until fixed JENKINS-8217
+ @Test
+ public void reloadDescriptorConfig() throws Exception {
+ Mailer.DescriptorImpl desc = j.jenkins.getExtensionList(Mailer.DescriptorImpl.class).get(0);;
+ desc.setDefaultSuffix("@oldSuffix");
+ desc.save();
+
+ replace("hudson.tasks.Mailer.xml", "@oldSuffix", "@newSuffix");
+
+ assertThat(desc.getDefaultSuffix(), equalTo("@oldSuffix"));
+
+ reloadJenkinsConfigurationViaCliAndWait();
+
+ assertThat(desc.getDefaultSuffix(), equalTo("@newSuffix"));
+ }
+
+ private void reloadJenkinsConfigurationViaCliAndWait() throws Exception {
+ final CLICommandInvoker.Result result = command
+ .authorizedTo(Jenkins.READ, Jenkins.ADMINISTER).invoke();
+
+ assertThat(result, succeededSilently());
+
+ // reload-configuration is performed in a separate thread
+ // we have to wait until it finishes
+ while (!(j.jenkins.servletContext.getAttribute("app") instanceof Jenkins)) {
+ System.out.println("Jenkins reload operation is performing, sleeping 1s...");
+ Thread.sleep(1000);
+ }
+ }
+
+ private void replace(String path, String search, String replace) {
+ File configFile = new File(j.jenkins.getRootDir(), path);
+
+ try {
+ String oldConfig = Util.loadFile(configFile);
+
+ String newConfig = oldConfig.replaceAll(search, replace);
+
+ FileWriter fw = new FileWriter(configFile);
+ fw.write(newConfig);
+ fw.close();
+ } catch (IOException ex) {
+ throw new AssertionError(ex);
+ }
+ }
+
+}
diff --git a/test/src/test/java/hudson/model/UpdateCenterConnectionStatusTest.java b/test/src/test/java/hudson/model/UpdateCenterConnectionStatusTest.java
index 0a1113e9d9..b06ee59627 100644
--- a/test/src/test/java/hudson/model/UpdateCenterConnectionStatusTest.java
+++ b/test/src/test/java/hudson/model/UpdateCenterConnectionStatusTest.java
@@ -67,7 +67,7 @@ public class UpdateCenterConnectionStatusTest {
JSONObject response = jenkinsRule.getJSON("updateCenter/connectionStatus?siteId=blahblah").getJSONObject();
Assert.assertEquals("error", response.getString("status"));
- Assert.assertEquals("Unknown site 'blahblah'.", response.getString("message"));
+ Assert.assertEquals("Cannot check connection status of the update site with ID='blahblah'. This update center cannot be resolved", response.getString("message"));
}
private UpdateSite updateSite = new UpdateSite(UpdateCenter.ID_DEFAULT, "http://xyz") {
diff --git a/war/package.json b/war/package.json
index a16adbac94..9b714a89ad 100644
--- a/war/package.json
+++ b/war/package.json
@@ -3,6 +3,12 @@
"version": "1.0.0",
"description": "Jenkins User Interface",
"license": "MIT",
+ "author": {
+ "name": "Tom Fennelly",
+ "email": "tom.fennelly@gmail.com",
+ "url": "https://github.com/tfennelly"
+ },
+ "private": true,
"devDependencies": {
"gulp": "^3.9.0",
"handlebars": "^3.0.3",
diff --git a/war/src/main/js/pluginSetupWizardGui.js b/war/src/main/js/pluginSetupWizardGui.js
index f62406862a..8d3468dcf9 100644
--- a/war/src/main/js/pluginSetupWizardGui.js
+++ b/war/src/main/js/pluginSetupWizardGui.js
@@ -889,9 +889,15 @@ var createPluginSetupWizard = function(appendTarget) {
translations = localizations;
// check for connectivity
- jenkins.testConnectivity(handleGenericError(function(isConnected) {
+ //TODO: make the Update Center ID configurable
+ var siteId = 'default';
+ jenkins.testConnectivity(siteId, handleGenericError(function(isConnected, isFatal, errorMessage) {
if(!isConnected) {
- setPanel(offlinePanel);
+ if (isFatal) { // We cannot continue, show error
+ setPanel(errorPanel, { errorMessage: 'Default update site connectivity check failed with fatal error: ' + errorMessage + '. If you see this issue for the custom Jenkins WAR bundle, consider setting the correct value of the hudson.model.UpdateCenter.defaultUpdateSiteId system property (requires Jenkins restart). Otherwise please create a bug in Jenkins JIRA.' });
+ } else { // The update center is offline, no problem
+ setPanel(offlinePanel);
+ }
return;
}
diff --git a/war/src/main/js/util/jenkins.js b/war/src/main/js/util/jenkins.js
index 0423f1d6a4..e0681dc7a5 100644
--- a/war/src/main/js/util/jenkins.js
+++ b/war/src/main/js/util/jenkins.js
@@ -192,18 +192,22 @@ exports.loadTranslations = function(bundleName, handler, onError) {
/**
* Runs a connectivity test, calls handler with a boolean whether there is sufficient connectivity to the internet
*/
-exports.testConnectivity = function(handler) {
+exports.testConnectivity = function(siteId, handler) {
// check the connectivity api
var testConnectivity = function() {
- exports.get('/updateCenter/connectionStatus?siteId=default', function(response) {
+ exports.get('/updateCenter/connectionStatus?siteId=' + siteId, function(response) {
+ if(response.status !== 'ok') {
+ handler(false, true, response.message);
+ }
+
var uncheckedStatuses = ['PRECHECK', 'CHECKING', 'UNCHECKED'];
if(uncheckedStatuses.indexOf(response.data.updatesite) >= 0 || uncheckedStatuses.indexOf(response.data.internet) >= 0) {
setTimeout(testConnectivity, 100);
}
else {
if(response.status !== 'ok' || response.data.updatesite !== 'OK' || response.data.internet !== 'OK') {
- // no connectivity
- handler(false);
+ // no connectivity, but not fatal
+ handler(false, false);
}
else {
handler(true);
diff --git a/war/src/main/webapp/WEB-INF/jboss-web.xml b/war/src/main/webapp/WEB-INF/jboss-web.xml
new file mode 100644
index 0000000000..a659be9d18
--- /dev/null
+++ b/war/src/main/webapp/WEB-INF/jboss-web.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ COOKIE
+
+
+
+
diff --git a/war/src/main/webapp/scripts/sortable.js b/war/src/main/webapp/scripts/sortable.js
index 809c817a69..6f5f1bd777 100644
--- a/war/src/main/webapp/scripts/sortable.js
+++ b/war/src/main/webapp/scripts/sortable.js
@@ -31,12 +31,12 @@ Usage
=====
Add the "sortable" CSS class to a table to make it sortable.
-The first column must be always table header, and the rest must be table data.
+The first row must be always table header, and the rest must be table data.
(the script seems to support rows to be fixed at the bottom, but haven't figured out how to use it.)
If the table data is sorted to begin with, you can add 'initialSortDir="up|down"' to the
-corresponding column in the header row to display the direction icon from the beginning.
-This is recommended to provide a visual cue that the table can be sorted.
+corresponding cell in the header row to display the direction icon from the beginning.
+This is recommended to provide a visual clue that the table can be sorted.
The script guesses the table data, and try to use the right sorting algorithm.
But you can override this behavior by having 'data="..."' attribute on each row,