org.kohsuke
diff --git a/core/src/main/java/hudson/ExtensionListListener.java b/core/src/main/java/hudson/ExtensionListListener.java
index 26950b985a..f5c8528add 100644
--- a/core/src/main/java/hudson/ExtensionListListener.java
+++ b/core/src/main/java/hudson/ExtensionListListener.java
@@ -27,7 +27,7 @@ package hudson;
* {@link ExtensionList} listener.
*
* @author tom.fennelly@gmail.com
- * @since TODO
+ * @since 1.614
*/
public abstract class ExtensionListListener {
diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java
index d2778ba37e..07fdc9d17c 100644
--- a/core/src/main/java/hudson/FilePath.java
+++ b/core/src/main/java/hudson/FilePath.java
@@ -33,7 +33,6 @@ import hudson.model.AbstractProject;
import hudson.model.Computer;
import hudson.model.Item;
import hudson.model.TaskListener;
-import hudson.org.apache.tools.tar.TarInputStream;
import hudson.os.PosixAPI;
import hudson.os.PosixException;
import hudson.remoting.Callable;
@@ -70,7 +69,6 @@ import org.apache.commons.io.input.CountingInputStream;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.tar.TarEntry;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.kohsuke.stapler.Stapler;
@@ -120,6 +118,8 @@ import static hudson.Util.*;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import jenkins.security.MasterToSlaveCallable;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.jenkinsci.remoting.RoleChecker;
import org.jenkinsci.remoting.RoleSensitive;
@@ -175,7 +175,7 @@ import org.jenkinsci.remoting.RoleSensitive;
*
*
*
- * When {@link FileCallable} is transfered to a remote node, it will be done so
+ * When {@link FileCallable} is transferred to a remote node, it will be done so
* by using the same Java serialization scheme that the remoting module uses.
* See {@link Channel} for more about this.
*
@@ -2268,12 +2268,15 @@ public final class FilePath implements Serializable {
/**
* Reads from a tar stream and stores obtained files to the base dir.
+ * @since TODO supports large files > 10 GB, migration to commons-compress
*/
private void readFromTar(String name, File baseDir, InputStream in) throws IOException {
- TarInputStream t = new TarInputStream(in);
+ TarArchiveInputStream t = new TarArchiveInputStream(in);
+
+ // TarInputStream t = new TarInputStream(in);
try {
- TarEntry te;
- while ((te = t.getNextEntry()) != null) {
+ TarArchiveEntry te;
+ while ((te = t.getNextTarEntry()) != null) {
File f = new File(baseDir,te.getName());
if(te.isDirectory()) {
mkdirs(f);
@@ -2282,8 +2285,7 @@ public final class FilePath implements Serializable {
if (parent != null) mkdirs(parent);
writing(f);
- byte linkFlag = (Byte) LINKFLAG_FIELD.get(te);
- if (linkFlag==TarEntry.LF_SYMLINK) {
+ if (te.isSymbolicLink()) {
new FilePath(f).symlinkTo(te.getLinkName(), TaskListener.NULL);
} else {
IOUtils.copy(t,f);
@@ -2300,8 +2302,6 @@ public final class FilePath implements Serializable {
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // process this later
throw new IOException("Failed to extract "+name,e);
- } catch (IllegalAccessException e) {
- throw new IOException("Failed to extract "+name,e);
} finally {
t.close();
}
@@ -2725,20 +2725,6 @@ public final class FilePath implements Serializable {
}
};
- private static final Field LINKFLAG_FIELD = getTarEntryLinkFlagField();
-
- private static Field getTarEntryLinkFlagField() {
- try {
- Field f = TarEntry.class.getDeclaredField("linkFlag");
- f.setAccessible(true);
- return f;
- } catch (SecurityException e) {
- throw new AssertionError(e);
- } catch (NoSuchFieldException e) {
- throw new AssertionError(e);
- }
- }
-
/**
* Gets the {@link FilePath} representation of the "~" directory
* (User's home directory in the Unix sense) of the given channel.
diff --git a/core/src/main/java/hudson/FileSystemProvisioner.java b/core/src/main/java/hudson/FileSystemProvisioner.java
index 15932a1dca..bbb98f5e9d 100644
--- a/core/src/main/java/hudson/FileSystemProvisioner.java
+++ b/core/src/main/java/hudson/FileSystemProvisioner.java
@@ -238,7 +238,7 @@ public abstract class FileSystemProvisioner implements ExtensionPoint, Describab
@Extension
public static final class DescriptorImpl extends FileSystemProvisionerDescriptor {
public boolean discard(FilePath ws, TaskListener listener) throws IOException, InterruptedException {
- // the default provisioner doens't do anything special,
+ // the default provisioner does not do anything special,
// so allow other types to manage it
return false;
}
diff --git a/core/src/main/java/hudson/FileSystemProvisionerDescriptor.java b/core/src/main/java/hudson/FileSystemProvisionerDescriptor.java
index 2cb0506fa9..4827366d36 100644
--- a/core/src/main/java/hudson/FileSystemProvisionerDescriptor.java
+++ b/core/src/main/java/hudson/FileSystemProvisionerDescriptor.java
@@ -39,7 +39,7 @@ public abstract class FileSystemProvisionerDescriptor extends Descriptor
* Because users may modify the file system behind Hudson, and slaves may come and go when
- * configuration changes hapen, in general case Hudson is unable to keep track of which jobs
+ * configuration changes happen, in general case Hudson is unable to keep track of which jobs
* have workspaces in which slaves.
*
*
diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java
index bcdc69f7f3..4ecd7721d8 100644
--- a/core/src/main/java/hudson/Functions.java
+++ b/core/src/main/java/hudson/Functions.java
@@ -1385,7 +1385,7 @@ public class Functions {
/**
* If the value exists, return that value. Otherwise return the default value.
*
- * Starting 1.294, JEXL supports the elvis operator "x?:y" that supercedes this.
+ * Starting 1.294, JEXL supports the elvis operator "x?:y" that supersedes this.
*
* @since 1.150
*/
diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java
index 443716eed5..623de0f137 100644
--- a/core/src/main/java/hudson/PluginManager.java
+++ b/core/src/main/java/hudson/PluginManager.java
@@ -71,6 +71,7 @@ import org.kohsuke.stapler.HttpRedirect;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.HttpResponses;
import org.kohsuke.stapler.QueryParameter;
+import org.kohsuke.stapler.StaplerOverridable;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;
@@ -128,7 +129,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse;
* @author Kohsuke Kawaguchi
*/
@ExportedBean
-public abstract class PluginManager extends AbstractModelObject implements OnMaster {
+public abstract class PluginManager extends AbstractModelObject implements OnMaster, StaplerOverridable {
/**
* All discovered plugins.
*/
@@ -215,6 +216,16 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
return new Api(this);
}
+ /**
+ * Find all registered overrides (intended to allow overriding/adding views)
+ * @return List of extensions
+ * @since 1.627
+ */
+ @Override
+ public Collection getOverrides() {
+ return PluginManagerStaplerOverride.all();
+ }
+
/**
* Called immediately after the construction.
* This is a separate method so that code executed from here will see a valid value in
diff --git a/core/src/main/java/hudson/PluginManagerStaplerOverride.java b/core/src/main/java/hudson/PluginManagerStaplerOverride.java
new file mode 100644
index 0000000000..2de4ef90ed
--- /dev/null
+++ b/core/src/main/java/hudson/PluginManagerStaplerOverride.java
@@ -0,0 +1,28 @@
+package hudson;
+
+import jenkins.model.Jenkins;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+/**
+ * Extension point for selectively overriding parts of the {@link PluginManager} views
+ * Anything extending this and registered with an @Extension can replace existing views and define new views.
+ *
+ * It is also possible to add/modify API calls coming via Stapler, but this requires caution.
+ *
+ * In both cases, this is simply done by defining a resource or method that matches the existing one
+ *
+ * @author Sam Van Oort
+ * @since 1.627
+ */
+public abstract class PluginManagerStaplerOverride implements ExtensionPoint {
+
+ /**
+ * Return all implementations of this extension point
+ * @return All implementations of this extension point
+ */
+ public static @Nonnull ExtensionList all() {
+ return ExtensionList.lookup(PluginManagerStaplerOverride.class);
+ }
+}
diff --git a/core/src/main/java/hudson/PluginWrapper.java b/core/src/main/java/hudson/PluginWrapper.java
index aa683e630f..50fad48550 100644
--- a/core/src/main/java/hudson/PluginWrapper.java
+++ b/core/src/main/java/hudson/PluginWrapper.java
@@ -63,7 +63,7 @@ import javax.annotation.CheckForNull;
* for Jenkins to control {@link Plugin}.
*
*
- * A plug-in is packaged into a jar file whose extension is ".jpi" (or ".hpi" for backward compatability),
+ * A plug-in is packaged into a jar file whose extension is ".jpi" (or ".hpi" for backward compatibility),
* A plugin needs to have a special manifest entry to identify what it is.
*
*
diff --git a/core/src/main/java/hudson/cli/CloneableCLICommand.java b/core/src/main/java/hudson/cli/CloneableCLICommand.java
index 7fb3b96dd3..f6a4c60b02 100644
--- a/core/src/main/java/hudson/cli/CloneableCLICommand.java
+++ b/core/src/main/java/hudson/cli/CloneableCLICommand.java
@@ -26,7 +26,7 @@ package hudson.cli;
/**
* {@link Cloneable} {@link CLICommand}.
*
- * Uses {@link #clone()} instead of "new" to create a copy for exection.
+ * Uses {@link #clone()} instead of "new" to create a copy for execution.
*
* @author Kohsuke Kawaguchi
*/
diff --git a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java
index 29a2187b93..b955cd2178 100644
--- a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java
+++ b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java
@@ -36,6 +36,7 @@ import hudson.model.Saveable;
import hudson.model.listeners.ItemListener;
import hudson.model.listeners.RunListener;
import hudson.model.listeners.SaveableListener;
+import hudson.security.ACL;
import hudson.util.RobustReflectionConverter;
import hudson.util.VersionNumber;
import java.io.IOException;
@@ -46,10 +47,16 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.CheckForNull;
import jenkins.model.Jenkins;
+import org.acegisecurity.context.SecurityContext;
+import org.acegisecurity.context.SecurityContextHolder;
+import org.kohsuke.accmod.Restricted;
+import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.HttpRedirect;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.HttpResponses;
@@ -67,7 +74,7 @@ import org.kohsuke.stapler.interceptor.RequirePOST;
public class OldDataMonitor extends AdministrativeMonitor {
private static final Logger LOGGER = Logger.getLogger(OldDataMonitor.class.getName());
- private HashMap data = new HashMap();
+ private ConcurrentMap data = new ConcurrentHashMap();
static OldDataMonitor get(Jenkins j) {
return (OldDataMonitor) j.getAdministrativeMonitor("OldData");
@@ -87,12 +94,8 @@ public class OldDataMonitor extends AdministrativeMonitor {
}
public Map getData() {
- Map _data;
- synchronized (this) {
- _data = new HashMap(this.data);
- }
Map r = new HashMap();
- for (Map.Entry entry : _data.entrySet()) {
+ for (Map.Entry entry : this.data.entrySet()) {
Saveable s = entry.getKey().get();
if (s != null) {
r.put(s, entry.getValue());
@@ -102,12 +105,20 @@ public class OldDataMonitor extends AdministrativeMonitor {
}
private static void remove(Saveable obj, boolean isDelete) {
- OldDataMonitor odm = get(Jenkins.getInstance());
- synchronized (odm) {
- odm.data.remove(referTo(obj));
- if (isDelete && obj instanceof Job,?>)
- for (Run r : ((Job,?>)obj).getBuilds())
- odm.data.remove(referTo(r));
+ Jenkins j = Jenkins.getInstance();
+ if (j != null) {
+ OldDataMonitor odm = get(j);
+ SecurityContext oldContext = ACL.impersonate(ACL.SYSTEM);
+ try {
+ odm.data.remove(referTo(obj));
+ if (isDelete && obj instanceof Job, ?>) {
+ for (Run r : ((Job, ?>) obj).getBuilds()) {
+ odm.data.remove(referTo(r));
+ }
+ }
+ } finally {
+ SecurityContextHolder.setContext(oldContext);
+ }
}
}
@@ -146,15 +157,18 @@ public class OldDataMonitor extends AdministrativeMonitor {
*/
public static void report(Saveable obj, String version) {
OldDataMonitor odm = get(Jenkins.getInstance());
- synchronized (odm) {
- try {
- SaveableReference ref = referTo(obj);
+ try {
+ SaveableReference ref = referTo(obj);
+ while (true) {
VersionRange vr = odm.data.get(ref);
- if (vr != null) vr.add(version);
- else odm.data.put(ref, new VersionRange(version, null));
- } catch (IllegalArgumentException ex) {
- LOGGER.log(Level.WARNING, "Bad parameter given to OldDataMonitor", ex);
+ if (vr != null && odm.data.replace(ref, vr, new VersionRange(vr, version, null))) {
+ break;
+ } else if (odm.data.putIfAbsent(ref, new VersionRange(null, version, null)) == null) {
+ break;
+ }
}
+ } catch (IllegalArgumentException ex) {
+ LOGGER.log(Level.WARNING, "Bad parameter given to OldDataMonitor", ex);
}
}
@@ -201,32 +215,49 @@ public class OldDataMonitor extends AdministrativeMonitor {
return;
}
OldDataMonitor odm = get(j);
- synchronized (odm) {
- SaveableReference ref = referTo(obj);
+ SaveableReference ref = referTo(obj);
+ while (true) {
VersionRange vr = odm.data.get(ref);
- if (vr != null) vr.extra = buf.toString();
- else odm.data.put(ref, new VersionRange(null, buf.toString()));
+ if (vr != null && odm.data.replace(ref, vr, new VersionRange(vr, null, buf.toString()))) {
+ break;
+ } else if (odm.data.putIfAbsent(ref, new VersionRange(null, null, buf.toString())) == null) {
+ break;
+ }
}
}
public static class VersionRange {
private static VersionNumber currentVersion = Jenkins.getVersion();
- VersionNumber min, max;
- boolean single = true;
- public String extra;
+ final VersionNumber min;
+ final VersionNumber max;
+ final boolean single;
+ final public String extra;
- public VersionRange(String version, String extra) {
- min = max = version != null ? new VersionNumber(version) : null;
- this.extra = extra;
- }
-
- public void add(String version) {
- VersionNumber ver = new VersionNumber(version);
- if (min==null) { min = max = ver; }
- else {
- if (ver.isOlderThan(min)) { min = ver; single = false; }
- if (ver.isNewerThan(max)) { max = ver; single = false; }
+ public VersionRange(VersionRange previous, String version, String extra) {
+ if (previous == null) {
+ min = max = version != null ? new VersionNumber(version) : null;
+ this.single = true;
+ this.extra = extra;
+ } else if (version == null) {
+ min = previous.min;
+ max = previous.max;
+ single = previous.single;
+ this.extra = extra;
+ } else {
+ VersionNumber ver = new VersionNumber(version);
+ if (previous.min == null || ver.isOlderThan(previous.min)) {
+ this.min = ver;
+ } else {
+ this.min = previous.min;
+ }
+ if (previous.max == null || ver.isNewerThan(previous.max)) {
+ this.max = ver;
+ } else {
+ this.max = previous.max;
+ }
+ this.single = this.max.isNewerThan(this.min);
+ this.extra = extra;
}
}
@@ -245,15 +276,20 @@ public class OldDataMonitor extends AdministrativeMonitor {
|| (currentVersion.digit(0) == min.digit(0)
&& currentVersion.digit(1) - min.digit(1) >= threshold));
}
+
}
/**
* Sorted list of unique max-versions in the data set. For select list in jelly.
*/
- public synchronized Iterator getVersionList() {
+ @Restricted(NoExternalUse.class)
+ public Iterator getVersionList() {
TreeSet set = new TreeSet();
- for (VersionRange vr : data.values())
- if (vr.max!=null) set.add(vr.max);
+ for (VersionRange vr : data.values()) {
+ if (vr.max != null) {
+ set.add(vr.max);
+ }
+ }
return set.iterator();
}
@@ -279,7 +315,7 @@ public class OldDataMonitor extends AdministrativeMonitor {
final String thruVerParam = req.getParameter("thruVer");
final VersionNumber thruVer = thruVerParam.equals("all") ? null : new VersionNumber(thruVerParam);
- saveAndRemoveEntries( new Predicate>() {
+ saveAndRemoveEntries(new Predicate>() {
@Override
public boolean apply(Map.Entry entry) {
VersionNumber version = entry.getValue().max;
@@ -318,13 +354,8 @@ public class OldDataMonitor extends AdministrativeMonitor {
* does occur: just means the user will be prompted to discard less than they should have been (and
* would see the warning again after next restart).
*/
- Map localCopy = null;
- synchronized (this) {
- localCopy = new HashMap(data);
- }
-
List removed = new ArrayList();
- for (Map.Entry entry : localCopy.entrySet()) {
+ for (Map.Entry entry : data.entrySet()) {
if (matchingPredicate.apply(entry)) {
Saveable s = entry.getKey().get();
if (s != null) {
@@ -338,9 +369,7 @@ public class OldDataMonitor extends AdministrativeMonitor {
}
}
- synchronized (this) {
- data.keySet().removeAll(removed);
- }
+ data.keySet().removeAll(removed);
}
public HttpResponse doIndex(StaplerResponse rsp) throws IOException {
diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java
index 3f477f83e5..22fc55ecb8 100644
--- a/core/src/main/java/hudson/model/AbstractProject.java
+++ b/core/src/main/java/hudson/model/AbstractProject.java
@@ -106,6 +106,7 @@ import java.util.logging.Logger;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.servlet.ServletException;
+import jenkins.model.BlockedBecauseOfBuildInProgress;
import jenkins.model.Jenkins;
import jenkins.model.JenkinsLocationConfiguration;
import jenkins.model.ParameterizedJobMixIn;
@@ -324,11 +325,13 @@ public abstract class AbstractProject,R extends A
buildMixIn.onLoad(parent, name);
builds = buildMixIn.getRunMap();
triggers().setOwner(this);
- for (Trigger t : triggers()) {
- try {
- t.start(this, Items.currentlyUpdatingByXml());
- } catch (Throwable e) {
- LOGGER.log(Level.WARNING, "could not start trigger while loading project '" + getFullName() + "'", e);
+ if (isBuildable()) {
+ for (Trigger t : triggers()) {
+ try {
+ t.start(this, Items.currentlyUpdatingByXml());
+ } catch (Throwable e) {
+ LOGGER.log(Level.WARNING, "could not start trigger while loading project '" + getFullName() + "'", e);
+ }
}
}
if(scm==null)
@@ -471,6 +474,7 @@ public abstract class AbstractProject
,R extends A
* @since 1.401
*/
public String getBuildNowText() {
+ // For compatibility, still use the deprecated replacer if specified.
return AlternativeUiTextProvider.get(BUILD_NOW_TEXT, this, getParameterizedJobMixIn().getBuildNowText());
}
@@ -1098,23 +1102,12 @@ public abstract class AbstractProject
,R extends A
}
/**
- * Blocked because the previous build is already in progress.
+ * @deprecated use {@link BlockedBecauseOfBuildInProgress} instead.
*/
- public static class BecauseOfBuildInProgress extends CauseOfBlockage {
- private final AbstractBuild,?> build;
-
+ @Deprecated
+ public static class BecauseOfBuildInProgress extends BlockedBecauseOfBuildInProgress {
public BecauseOfBuildInProgress(AbstractBuild, ?> build) {
- this.build = build;
- }
-
- @Override
- public String getShortDescription() {
- Executor e = build.getExecutor();
- String eta = "";
- if (e != null)
- eta = Messages.AbstractProject_ETA(e.getEstimatedRemainingTime());
- int lbn = build.getNumber();
- return Messages.AbstractProject_BuildInProgress(lbn, eta);
+ super(build);
}
}
@@ -1150,10 +1143,12 @@ public abstract class AbstractProject
,R extends A
}
}
+ @Override
public CauseOfBlockage getCauseOfBlockage() {
// Block builds until they are done with post-production
- if (isLogUpdated() && !isConcurrentBuild())
- return new BecauseOfBuildInProgress(getLastBuild());
+ if (isLogUpdated() && !isConcurrentBuild()) {
+ return new BlockedBecauseOfBuildInProgress(getLastBuild());
+ }
if (blockBuildWhenDownstreamBuilding()) {
AbstractProject,?> bup = getBuildingDownstream();
if (bup!=null)
@@ -1879,8 +1874,10 @@ public abstract class AbstractProject
,R extends A
for (Trigger t : triggers())
t.stop();
triggers.replaceBy(buildDescribable(req, Trigger.for_(this)));
- for (Trigger t : triggers())
- t.start(this,true);
+ if (isBuildable()) {
+ for (Trigger t : triggers())
+ t.start(this, true);
+ }
}
/**
@@ -2113,8 +2110,8 @@ public abstract class AbstractProject
,R extends A
}
}
return FormValidation.okWithMarkup(Messages.AbstractProject_LabelLink(
- j.getRootUrl(), l.getUrl(), l.getNodes().size() + l.getClouds().size()
- ));
+ j.getRootUrl(), l.getUrl(), l.getNodes().size(), l.getClouds().size())
+ );
}
public FormValidation doCheckCustomWorkspace(@QueryParameter String customWorkspace){
@@ -2239,8 +2236,9 @@ public abstract class AbstractProject
,R extends A
public static final Permission ABORT = CANCEL;
/**
- * Replaceable "Build Now" text.
+ * @deprecated Use {@link ParameterizedJobMixIn#BUILD_NOW_TEXT}.
*/
+ @Deprecated
public static final Message BUILD_NOW_TEXT = new Message();
/**
diff --git a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java
index c13137d62a..0bd4b60ab3 100644
--- a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java
+++ b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java
@@ -17,20 +17,24 @@ import java.util.Arrays;
* @author huybrechts
*/
public class ChoiceParameterDefinition extends SimpleParameterDefinition {
- public static final String CHOICES_DELIMETER = "\\r?\\n";
+ public static final String CHOICES_DELIMITER = "\\r?\\n";
+
+ @Deprecated
+ public static final String CHOICES_DELIMETER = CHOICES_DELIMITER;
+
private final List choices;
private final String defaultValue;
public static boolean areValidChoices(String choices) {
String strippedChoices = choices.trim();
- return !StringUtils.isEmpty(strippedChoices) && strippedChoices.split(CHOICES_DELIMETER).length > 0;
+ return !StringUtils.isEmpty(strippedChoices) && strippedChoices.split(CHOICES_DELIMITER).length > 0;
}
@DataBoundConstructor
public ChoiceParameterDefinition(String name, String choices, String description) {
super(name, description);
- this.choices = Arrays.asList(choices.split(CHOICES_DELIMETER));
+ this.choices = Arrays.asList(choices.split(CHOICES_DELIMITER));
defaultValue = null;
}
diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java
index d0c049c2e5..003162eafe 100644
--- a/core/src/main/java/hudson/model/Computer.java
+++ b/core/src/main/java/hudson/model/Computer.java
@@ -63,9 +63,10 @@ import hudson.util.RunList;
import hudson.util.Futures;
import hudson.util.NamingThreadFactory;
import jenkins.model.Jenkins;
-import jenkins.model.queue.AsynchronousExecution;
import jenkins.util.ContextResettingExecutorService;
import jenkins.security.MasterToSlaveCallable;
+import jenkins.security.NotReallyRoleSensitiveCallable;
+
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.DoNotUse;
import org.kohsuke.accmod.restrictions.NoExternalUse;
@@ -86,6 +87,7 @@ import org.kohsuke.stapler.interceptor.RequirePOST;
import javax.annotation.concurrent.GuardedBy;
import javax.servlet.ServletException;
+
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
@@ -107,6 +109,7 @@ import java.net.NetworkInterface;
import java.net.Inet4Address;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -522,7 +525,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
@CLIMethod(name="online-node")
public void cliOnline() throws ExecutionException, InterruptedException {
checkPermission(CONNECT);
- setTemporarilyOffline(false,null);
+ setTemporarilyOffline(false, null);
}
/**
@@ -545,6 +548,15 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
return nodeName != null ? nodeName : "";
}
+ /**
+ * True if this computer is a Unix machine (as opposed to Windows machine).
+ *
+ * @since 1.624
+ * @return
+ * null if the computer is disconnected and therefore we don't know whether it is Unix or not.
+ */
+ public abstract @CheckForNull Boolean isUnix();
+
/**
* Returns the {@link Node} that this computer represents.
*
@@ -1416,21 +1428,23 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
/**
* Replaces the current {@link Node} by another one.
*/
- private void replaceBy(Node newNode) throws ServletException, IOException {
+ private void replaceBy(final Node newNode) throws ServletException, IOException {
final Jenkins app = Jenkins.getInstance();
- // replace the old Node object by the new one
- synchronized (app) {
- List nodes = new ArrayList(app.getNodes());
- Node node = getNode();
- int i = (node != null) ? nodes.indexOf(node) : -1;
- if(i<0) {
- throw new IOException("This slave appears to be removed while you were editing the configuration");
+ // use the queue lock until Nodes has a way of directly modifying a single node.
+ Queue.withLock(new NotReallyRoleSensitiveCallable() {
+ public Void call() throws IOException {
+ List nodes = new ArrayList(app.getNodes());
+ Node node = getNode();
+ int i = (node != null) ? nodes.indexOf(node) : -1;
+ if(i<0) {
+ throw new IOException("This slave appears to be removed while you were editing the configuration");
+ }
+ nodes.set(i, newNode);
+ app.setNodes(nodes);
+ return null;
}
-
- nodes.set(i, newNode);
- app.setNodes(nodes);
- }
+ });
}
/**
@@ -1556,8 +1570,8 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
if (m.matches()) {
File newLocation = new File(dir, "logs/slaves/" + m.group(1) + "/slave.log" + Util.fixNull(m.group(2)));
newLocation.getParentFile().mkdirs();
- boolean relocationSuccessfull=f.renameTo(newLocation);
- if (relocationSuccessfull) { // The operation will fail if mkdir fails
+ boolean relocationSuccessful=f.renameTo(newLocation);
+ if (relocationSuccessful) { // The operation will fail if mkdir fails
LOGGER.log(Level.INFO, "Relocated log file {0} to {1}",new Object[] {f.getPath(),newLocation.getPath()});
} else {
LOGGER.log(Level.WARNING, "Cannot relocate log file {0} to {1}",new Object[] {f.getPath(),newLocation.getPath()});
diff --git a/core/src/main/java/hudson/model/DownloadService.java b/core/src/main/java/hudson/model/DownloadService.java
index ff5e3811c9..905199581c 100644
--- a/core/src/main/java/hudson/model/DownloadService.java
+++ b/core/src/main/java/hudson/model/DownloadService.java
@@ -25,8 +25,11 @@ package hudson.model;
import hudson.Extension;
import hudson.ExtensionList;
+import hudson.ExtensionListListener;
import hudson.ExtensionPoint;
import hudson.ProxyConfiguration;
+import hudson.init.InitMilestone;
+import hudson.init.Initializer;
import hudson.util.FormValidation;
import hudson.util.FormValidation.Kind;
import hudson.util.QuotedStringTokenizer;
@@ -37,6 +40,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
+import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.DownloadSettings;
import jenkins.model.Jenkins;
@@ -194,6 +198,45 @@ public class DownloadService extends PageDecorator {
}
}
+ /**
+ * This installs itself as a listener to changes to the Downloadable extension list and will download the metadata
+ * for any newly added Downloadables.
+ */
+ @Restricted(NoExternalUse.class)
+ public static class DownloadableListener extends ExtensionListListener {
+
+ /**
+ * Install this listener to the Downloadable extension list after all extensions have been loaded; we only
+ * care about those that are added after initialization
+ */
+ @Initializer(after = InitMilestone.EXTENSIONS_AUGMENTED)
+ public static void installListener() {
+ ExtensionList.lookup(Downloadable.class).addListener(new DownloadableListener());
+ }
+
+ /**
+ * Look for Downloadables that have no data, and update them.
+ */
+ @Override
+ public void onChange() {
+ for (Downloadable d : Downloadable.all()) {
+ TextFile f = d.getDataFile();
+ if (f == null || !f.exists()) {
+ LOGGER.log(Level.FINE, "Updating metadata for " + d.getId());
+ try {
+ d.updateNow();
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, "Failed to update metadata for " + d.getId(), e);
+ }
+ } else {
+ LOGGER.log(Level.FINER, "Skipping update of metadata for " + d.getId());
+ }
+ }
+ }
+
+ private static final Logger LOGGER = Logger.getLogger(DownloadableListener.class.getName());
+ }
+
/**
* Represents a periodically updated JSON data file obtained from a remote URL.
*
diff --git a/core/src/main/java/hudson/model/Executor.java b/core/src/main/java/hudson/model/Executor.java
index f4c85460ac..5f021cfe80 100644
--- a/core/src/main/java/hudson/model/Executor.java
+++ b/core/src/main/java/hudson/model/Executor.java
@@ -142,7 +142,34 @@ public class Executor extends Thread implements ModelObject {
@Override
public void interrupt() {
- interrupt(Result.ABORTED);
+ if (Thread.currentThread() == this) {
+ // If you catch an InterruptedException the "correct" options are limited to one of two choices:
+ // 1. Propagate the exception;
+ // 2. Restore the Thread.currentThread().interrupted() flag
+ // The JVM locking support assumes such behaviour.
+ // Evil Jenkins overrides the interrupt() method so that when a different thread interrupts this thread
+ // we abort the build.
+ // but that causes JENKINS-28690 style deadlocks when the correctly written code does
+ //
+ // try {
+ // ... some long running thing ...
+ // } catch (InterruptedException e) {
+ // ... some tidy up
+ // // restore interrupted flag
+ // Thread.currentThread().interrupted();
+ // }
+ //
+ // What about why we do not set the Result.ABORTED on this branch?
+ // That is a good question to ask, the answer is that the only time a thread should be restoring
+ // its own interrupted flag is when that thread has already been interrupted by another thread
+ // as such we should assume that the result has already been applied. If that assumption were
+ // incorrect, then the Run.execute's catch (InterruptedException) block will either set the result
+ // or have been escaped - in which case the result of the run has been sealed anyway so it does not
+ // matter.
+ super.interrupt();
+ } else {
+ interrupt(Result.ABORTED);
+ }
}
void interruptForShutdown() {
diff --git a/core/src/main/java/hudson/model/Items.java b/core/src/main/java/hudson/model/Items.java
index 26efd209b5..8700c0554f 100644
--- a/core/src/main/java/hudson/model/Items.java
+++ b/core/src/main/java/hudson/model/Items.java
@@ -204,7 +204,7 @@ public class Items {
String[] c = context.getFullName().split("/");
String[] p = path.split("/");
- Stack name = new Stack();
+ Stack name = new Stack();
for (int i=0; i, RunT extends Run> properties = new CopyOnWriteList>();
diff --git a/core/src/main/java/hudson/model/Result.java b/core/src/main/java/hudson/model/Result.java
index b17a98a4cf..02e71f3ff3 100644
--- a/core/src/main/java/hudson/model/Result.java
+++ b/core/src/main/java/hudson/model/Result.java
@@ -25,9 +25,11 @@ package hudson.model;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
+
import hudson.cli.declarative.OptionHandlerExtension;
import hudson.init.Initializer;
import hudson.util.EditDistance;
+
import org.apache.commons.beanutils.Converter;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
@@ -40,6 +42,9 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+
/**
* The build outcome.
*
@@ -49,42 +54,42 @@ public final class Result implements Serializable, CustomExportedBean {
/**
* The build had no errors.
*/
- public static final Result SUCCESS = new Result("SUCCESS",BallColor.BLUE,0,true);
+ public static final @Nonnull Result SUCCESS = new Result("SUCCESS",BallColor.BLUE,0,true);
/**
* The build had some errors but they were not fatal.
* For example, some tests failed.
*/
- public static final Result UNSTABLE = new Result("UNSTABLE",BallColor.YELLOW,1,true);
+ public static final @Nonnull Result UNSTABLE = new Result("UNSTABLE",BallColor.YELLOW,1,true);
/**
* The build had a fatal error.
*/
- public static final Result FAILURE = new Result("FAILURE",BallColor.RED,2,true);
+ public static final @Nonnull Result FAILURE = new Result("FAILURE",BallColor.RED,2,true);
/**
* The module was not built.
*
* This status code is used in a multi-stage build (like maven2)
* where a problem in earlier stage prevented later stages from building.
*/
- public static final Result NOT_BUILT = new Result("NOT_BUILT",BallColor.NOTBUILT,3,false);
+ public static final @Nonnull Result NOT_BUILT = new Result("NOT_BUILT",BallColor.NOTBUILT,3,false);
/**
* The build was manually aborted.
*
* If you are catching {@link InterruptedException} and interpreting it as {@link #ABORTED},
* you should check {@link Executor#abortResult()} instead (starting 1.417.)
*/
- public static final Result ABORTED = new Result("ABORTED",BallColor.ABORTED,4,false);
+ public static final @Nonnull Result ABORTED = new Result("ABORTED",BallColor.ABORTED,4,false);
- private final String name;
+ private final @Nonnull String name;
/**
* Bigger numbers are worse.
*/
- public final int ordinal;
+ public final @Nonnegative int ordinal;
/**
* Default ball color for this status.
*/
- public final BallColor color;
+ public final @Nonnull BallColor color;
/**
* Is this a complete build - i.e. did it run to the end (not aborted)?
@@ -92,7 +97,7 @@ public final class Result implements Serializable, CustomExportedBean {
*/
public final boolean completeBuild;
- private Result(String name, BallColor color, int ordinal, boolean complete) {
+ private Result(@Nonnull String name, @Nonnull BallColor color, @Nonnegative int ordinal, boolean complete) {
this.name = name;
this.color = color;
this.ordinal = ordinal;
@@ -102,26 +107,26 @@ public final class Result implements Serializable, CustomExportedBean {
/**
* Combines two {@link Result}s and returns the worse one.
*/
- public Result combine(Result that) {
+ public @Nonnull Result combine(@Nonnull Result that) {
if(this.ordinal < that.ordinal)
return that;
else
return this;
}
- public boolean isWorseThan(Result that) {
+ public boolean isWorseThan(@Nonnull Result that) {
return this.ordinal > that.ordinal;
}
- public boolean isWorseOrEqualTo(Result that) {
+ public boolean isWorseOrEqualTo(@Nonnull Result that) {
return this.ordinal >= that.ordinal;
}
- public boolean isBetterThan(Result that) {
+ public boolean isBetterThan(@Nonnull Result that) {
return this.ordinal < that.ordinal;
}
- public boolean isBetterOrEqualTo(Result that) {
+ public boolean isBetterOrEqualTo(@Nonnull Result that) {
return this.ordinal <= that.ordinal;
}
@@ -133,24 +138,23 @@ public final class Result implements Serializable, CustomExportedBean {
return this.completeBuild;
}
-
@Override
- public String toString() {
+ public @Nonnull String toString() {
return name;
}
- public String toExportedObject() {
+ public @Nonnull String toExportedObject() {
return name;
}
- public static Result fromString(String s) {
+ public static @Nonnull Result fromString(@Nonnull String s) {
for (Result r : all)
if (s.equalsIgnoreCase(r.name))
return r;
return FAILURE;
}
- private static List getNames() {
+ private static @Nonnull List getNames() {
List l = new ArrayList();
for (Result r : all)
l.add(r.name);
@@ -170,10 +174,12 @@ public final class Result implements Serializable, CustomExportedBean {
private static final Result[] all = new Result[] {SUCCESS,UNSTABLE,FAILURE,NOT_BUILT,ABORTED};
public static final SingleValueConverter conv = new AbstractSingleValueConverter () {
+ @Override
public boolean canConvert(Class clazz) {
return clazz==Result.class;
}
+ @Override
public Object fromString(String s) {
return Result.fromString(s);
}
diff --git a/core/src/main/java/hudson/model/RunMap.java b/core/src/main/java/hudson/model/RunMap.java
index 2eb65a2fb3..1f923e0910 100644
--- a/core/src/main/java/hudson/model/RunMap.java
+++ b/core/src/main/java/hudson/model/RunMap.java
@@ -186,7 +186,7 @@ public final class RunMap> extends AbstractLazyLoadRunMap
// Defense against JENKINS-23152 and its ilk.
File rootDir = r.getRootDir();
if (rootDir.isDirectory()) {
- throw new IllegalStateException(rootDir + " already existed; will not overwite with " + r);
+ throw new IllegalStateException(rootDir + " already existed; will not overwrite with " + r);
}
if (!r.getClass().getName().equals("hudson.matrix.MatrixRun")) { // JENKINS-26739: grandfathered in
proposeNewNumber(r.getNumber());
diff --git a/core/src/main/java/hudson/model/Slave.java b/core/src/main/java/hudson/model/Slave.java
index 30bc6bf217..0b21fa89ae 100644
--- a/core/src/main/java/hudson/model/Slave.java
+++ b/core/src/main/java/hudson/model/Slave.java
@@ -127,7 +127,8 @@ public abstract class Slave extends Node implements Serializable {
*/
private String label="";
- private /*almost final*/ DescribableList,NodePropertyDescriptor> nodeProperties = new DescribableList,NodePropertyDescriptor>(Jenkins.getInstance());
+ private /*almost final*/ DescribableList,NodePropertyDescriptor> nodeProperties =
+ new DescribableList,NodePropertyDescriptor>(Jenkins.getInstance().getNodesObject());
/**
* Lazily computed set of labels from {@link #label}.
@@ -408,7 +409,7 @@ public abstract class Slave extends Node implements Serializable {
: new CommandLauncher(agentCommand);
}
if(nodeProperties==null)
- nodeProperties = new DescribableList,NodePropertyDescriptor>(Jenkins.getInstance());
+ nodeProperties = new DescribableList,NodePropertyDescriptor>(Jenkins.getInstance().getNodesObject());
return this;
}
diff --git a/core/src/main/java/hudson/model/UsageStatistics.java b/core/src/main/java/hudson/model/UsageStatistics.java
index 805403216b..4d2cde5411 100644
--- a/core/src/main/java/hudson/model/UsageStatistics.java
+++ b/core/src/main/java/hudson/model/UsageStatistics.java
@@ -197,10 +197,10 @@ public class UsageStatistics extends PageDecorator {
}
/**
- * Assymetric cipher is slow and in case of Sun RSA implementation it can only encyrypt the first block.
+ * Asymmetric cipher is slow and in case of Sun RSA implementation it can only encyrypt the first block.
*
* So first create a symmetric key, then place this key in the beginning of the stream by encrypting it
- * with the assymetric cipher. The rest of the stream will be encrypted by a symmetric cipher.
+ * with the asymmetric cipher. The rest of the stream will be encrypted by a symmetric cipher.
*/
public static final class CombinedCipherOutputStream extends FilterOutputStream {
public CombinedCipherOutputStream(OutputStream out, Cipher asym, String algorithm) throws IOException, GeneralSecurityException {
diff --git a/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java b/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java
index ff457ffed0..3875eb12a8 100644
--- a/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java
+++ b/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java
@@ -170,12 +170,7 @@ public abstract class AbstractNodeMonitorDescriptor extends Descriptor extends Descriptor inProgressStarted + getMonitoringTimeOut() + 1000) {
+ if (!inProgress.isAlive()) {
+ LOGGER.log(Level.WARNING, "Previous {0} monitoring activity died without cleaning up after itself",
+ getDisplayName());
+ inProgress = null;
+ } else if (System.currentTimeMillis() > inProgressStarted + getMonitoringTimeOut() + 1000) {
// maybe it got stuck?
LOGGER.log(Level.WARNING, "Previous {0} monitoring activity still in progress. Interrupting",
getDisplayName());
diff --git a/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java b/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java
index 4bd1c939c6..67d33c7227 100644
--- a/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java
+++ b/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java
@@ -37,6 +37,8 @@ import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Locale;
+import org.kohsuke.accmod.Restricted;
+import org.kohsuke.accmod.restrictions.DoNotUse;
import org.kohsuke.stapler.export.ExportedBean;
import org.kohsuke.stapler.export.Exported;
@@ -81,6 +83,14 @@ public abstract class DiskSpaceMonitorDescriptor extends AbstractAsyncNodeMonito
return path;
}
+ // Needed for jelly that does not seem to be able to access properties
+ // named 'size' as it confuses it with built-in size method and fails
+ // to parse the expression expecting '()'.
+ @Restricted(DoNotUse.class)
+ public long getFreeSize() {
+ return size;
+ }
+
/**
* Gets GB left.
*/
diff --git a/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java b/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java
index f2d10c1c39..d7d8a5b54d 100644
--- a/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java
+++ b/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java
@@ -37,8 +37,9 @@ import java.io.ByteArrayOutputStream;
* methods are provided to position at each successive entry in
* the archive, and the read each entry as a normal input stream
* using read().
- *
+ * @deprecated Use {@link org.apache.commons.compress.archivers.tar.TarArchiveInputStream} instead
*/
+@Deprecated
public class TarInputStream extends FilterInputStream {
// CheckStyle:VisibilityModifier OFF - bc
diff --git a/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java b/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java
index f23e442628..48f4876bd4 100644
--- a/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java
+++ b/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java
@@ -35,8 +35,11 @@ import java.io.IOException;
* The TarOutputStream writes a UNIX tar archive as an OutputStream.
* Methods are provided to put entries, and then write their contents
* by writing to this stream using write().
+ *
+ * @deprecated Use {@link org.apache.commons.compress.archivers.tar.TarArchiveOutputStream} instead
*
*/
+@Deprecated
public class TarOutputStream extends FilterOutputStream {
/** Fail if a long file name is required in the archive. */
public static final int LONGFILE_ERROR = 0;
diff --git a/core/src/main/java/hudson/os/SU.java b/core/src/main/java/hudson/os/SU.java
index 6a2b8abfa2..5998d366c0 100644
--- a/core/src/main/java/hudson/os/SU.java
+++ b/core/src/main/java/hudson/os/SU.java
@@ -62,7 +62,7 @@ public abstract class SU {
}
/**
- * Returns a {@link VirtualChannel} that's connected to the priviledge-escalated environment.
+ * Returns a {@link VirtualChannel} that's connected to the privilege-escalated environment.
*
* @param listener
* What this method is doing (such as what process it's invoking) will be sent here.
@@ -122,7 +122,7 @@ public abstract class SU {
}
/**
- * Starts a new priviledge-escalated environment, execute a closure, and shut it down.
+ * Starts a new privilege-escalated environment, execute a closure, and shut it down.
*/
public static V execute(TaskListener listener, String rootUsername, String rootPassword, final Callable closure) throws T, IOException, InterruptedException {
VirtualChannel ch = start(listener, rootUsername, rootPassword);
diff --git a/core/src/main/java/hudson/scheduler/CronTab.java b/core/src/main/java/hudson/scheduler/CronTab.java
index dd8e0efa9d..d289dc32ef 100644
--- a/core/src/main/java/hudson/scheduler/CronTab.java
+++ b/core/src/main/java/hudson/scheduler/CronTab.java
@@ -92,7 +92,7 @@ public final class CronTab {
/**
* @param timezone
- * Used to schedule cron in a differnt timezone. Null to use the default system
+ * Used to schedule cron in a different timezone. Null to use the default system
* timezone
* @since 1.615
*/
diff --git a/core/src/main/java/hudson/scheduler/CronTabList.java b/core/src/main/java/hudson/scheduler/CronTabList.java
index 34a3c6df1e..3243dda38e 100644
--- a/core/src/main/java/hudson/scheduler/CronTabList.java
+++ b/core/src/main/java/hudson/scheduler/CronTabList.java
@@ -29,6 +29,8 @@ import java.util.TimeZone;
import java.util.Collection;
import java.util.Vector;
import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
@@ -44,7 +46,7 @@ public final class CronTabList {
private final Vector tabs;
public CronTabList(Collection tabs) {
- this.tabs = new Vector(tabs);
+ this.tabs = new Vector<>(tabs);
}
/**
@@ -90,12 +92,12 @@ public final class CronTabList {
return null;
}
- public static CronTabList create(String format) throws ANTLRException {
+ public static CronTabList create(@Nonnull String format) throws ANTLRException {
return create(format,null);
}
- public static CronTabList create(String format, Hash hash) throws ANTLRException {
- Vector r = new Vector();
+ public static CronTabList create(@Nonnull String format, Hash hash) throws ANTLRException {
+ Vector r = new Vector<>();
int lineNumber = 0;
String timezone = null;
diff --git a/core/src/main/java/hudson/security/ACL.java b/core/src/main/java/hudson/security/ACL.java
index b0ed675d8b..e4736cbe9e 100644
--- a/core/src/main/java/hudson/security/ACL.java
+++ b/core/src/main/java/hudson/security/ACL.java
@@ -127,7 +127,7 @@ public abstract class ACL {
*
*
* This doesn't need to be included in {@link Authentication#getAuthorities()},
- * but {@link ACL} is responsible for checking it nontheless, as if it was the
+ * but {@link ACL} is responsible for checking it nonetheless, as if it was the
* last entry in the granted authority.
*/
public static final Sid EVERYONE = new Sid() {
diff --git a/core/src/main/java/hudson/security/SecurityRealm.java b/core/src/main/java/hudson/security/SecurityRealm.java
index 3c598632ab..0621d4a440 100644
--- a/core/src/main/java/hudson/security/SecurityRealm.java
+++ b/core/src/main/java/hudson/security/SecurityRealm.java
@@ -357,7 +357,7 @@ public abstract class SecurityRealm extends AbstractDescribableImpl pendingLaunches = new ArrayList();
+ private final AtomicReference> pendingLaunches
+ = new AtomicReference>(new ArrayList());
private final Lock provisioningLock = new ReentrantLock();
@@ -155,12 +156,7 @@ public class NodeProvisioner {
* @since 1.401
*/
public List getPendingLaunches() {
- provisioningLock.lock();
- try {
- return new ArrayList(pendingLaunches);
- } finally {
- provisioningLock.unlock();
- }
+ return new ArrayList(pendingLaunches.get());
}
/**
@@ -213,48 +209,73 @@ public class NodeProvisioner {
// bring up.
int plannedCapacitySnapshot = 0;
- List completedLaunches = new ArrayList();
- for (Iterator itr = pendingLaunches.iterator(); itr.hasNext(); ) {
+ List snapPendingLaunches = new ArrayList(pendingLaunches.get());
+ for (Iterator itr = snapPendingLaunches.iterator(); itr.hasNext(); ) {
PlannedNode f = itr.next();
if (f.future.isDone()) {
- completedLaunches.add(f);
- itr.remove();
+ try {
+ Node node = f.future.get();
+ for (CloudProvisioningListener cl : CloudProvisioningListener.all()) {
+ cl.onComplete(f, node);
+ }
+
+ jenkins.addNode(node);
+ LOGGER.log(Level.INFO,
+ "{0} provisioning successfully completed. "
+ + "We have now {1,number,integer} computer(s)",
+ new Object[]{f.displayName, jenkins.getComputers().length});
+ } catch (InterruptedException e) {
+ throw new AssertionError(e); // since we confirmed that the future is already done
+ } catch (ExecutionException e) {
+ LOGGER.log(Level.WARNING, "Provisioned slave " + f.displayName + " failed to launch",
+ e.getCause());
+ for (CloudProvisioningListener cl : CloudProvisioningListener.all()) {
+ cl.onFailure(f, e.getCause());
+ }
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, "Provisioned slave " + f.displayName + " failed to launch",
+ e);
+ for (CloudProvisioningListener cl : CloudProvisioningListener.all()) {
+ cl.onFailure(f, e);
+ }
+ } catch (Error e) {
+ // we are not supposed to try and recover from Errors
+ throw e;
+ } catch (Throwable e) {
+ LOGGER.log(Level.SEVERE, "Unexpected uncaught exception encountered while "
+ + "processing provisioned slave " + f.displayName, e);
+ } finally {
+ while (true) {
+ List orig = pendingLaunches.get();
+ List repl = new ArrayList(orig);
+ // the contract for List.remove(o) is that the first element i where
+ // (o==null ? get(i)==null : o.equals(get(i)))
+ // is true will be removed from the list
+ // since PlannedNode.equals(o) is not final and we cannot assume
+ // that subclasses do not override with an equals which does not
+ // assure object identity comparison, we need to manually
+ // do the removal based on instance identity not equality
+ boolean changed = false;
+ for (Iterator iterator = repl.iterator(); iterator.hasNext(); ) {
+ PlannedNode p = iterator.next();
+ if (p == f) {
+ iterator.remove();
+ changed = true;
+ break;
+ }
+ }
+ if (!changed || pendingLaunches.compareAndSet(orig, repl)) {
+ break;
+ }
+ }
+ f.spent();
+ }
} else {
plannedCapacitySnapshot += f.numExecutors;
}
}
- for (PlannedNode f : completedLaunches) {
- try {
- Node node = f.future.get();
- for (CloudProvisioningListener cl : CloudProvisioningListener.all()) {
- cl.onComplete(f, node);
- }
-
- jenkins.addNode(node);
- LOGGER.log(Level.INFO,
- "{0} provisioning successfully completed. We have now {1,number,integer} computer"
- + "(s)",
- new Object[]{f.displayName, jenkins.getComputers().length});
- } catch (InterruptedException e) {
- throw new AssertionError(e); // since we confirmed that the future is already done
- } catch (ExecutionException e) {
- LOGGER.log(Level.WARNING, "Provisioned slave " + f.displayName + " failed to launch",
- e.getCause());
- for (CloudProvisioningListener cl : CloudProvisioningListener.all()) {
- cl.onFailure(f, e.getCause());
- }
- } catch (IOException e) {
- LOGGER.log(Level.WARNING, "Provisioned slave " + f.displayName + " failed to launch", e);
- for (CloudProvisioningListener cl : CloudProvisioningListener.all()) {
- cl.onFailure(f, e);
- }
- }
-
- f.spent();
- }
-
float plannedCapacity = plannedCapacitySnapshot;
plannedCapacitiesEMA.update(plannedCapacity);
@@ -264,7 +285,7 @@ public class NodeProvisioner {
int queueLengthSnapshot = snapshot.getQueueLength();
if (queueLengthSnapshot <= availableSnapshot) {
- LOGGER.log(Level.FINE,
+ LOGGER.log(Level.FINER,
"Queue length {0} is less than the available capacity {1}. No provisioning strategy required",
new Object[]{queueLengthSnapshot, availableSnapshot});
provisioningState = null;
@@ -353,7 +374,6 @@ public class NodeProvisioner {
* The current statistics snapshot for this {@link #label}.
*/
private final LoadStatistics.LoadStatisticsSnapshot snapshot;
- private final List pendingLaunches;
/**
* The additional planned capacity for this {@link #label} and provisioned by previous strategies during the
* current updating of the {@link NodeProvisioner}.
@@ -370,7 +390,6 @@ public class NodeProvisioner {
this.snapshot = snapshot;
this.label = label;
this.plannedCapacitySnapshot = plannedCapacitySnapshot;
- pendingLaunches = NodeProvisioner.this.pendingLaunches;
}
/**
@@ -426,13 +445,8 @@ public class NodeProvisioner {
* The additional planned capacity for this {@link #getLabel()} and provisioned by previous strategies during
* the current updating of the {@link NodeProvisioner}.
*/
- public int getAdditionalPlannedCapacity() {
- provisioningLock.lock();
- try {
- return additionalPlannedCapacity;
- } finally {
- provisioningLock.unlock();
- }
+ public synchronized int getAdditionalPlannedCapacity() {
+ return additionalPlannedCapacity;
}
/**
@@ -542,7 +556,7 @@ public class NodeProvisioner {
additionalPlannedCapacity += node.getNumExecutors();
}
} catch (InterruptedException e) {
- // ignore, this will be caught by others later
+ // should never happen as we were told the future was done
} catch (ExecutionException e) {
// ignore, this will be caught by others later
}
@@ -550,14 +564,18 @@ public class NodeProvisioner {
additionalPlannedCapacity += f.numExecutors;
}
}
- provisioningLock.lock();
- try {
- pendingLaunches.addAll(plannedNodes);
- if (additionalPlannedCapacity > 0) {
- this.additionalPlannedCapacity += additionalPlannedCapacity;
+ while (!plannedNodes.isEmpty()) {
+ List orig = pendingLaunches.get();
+ List repl = new ArrayList(orig);
+ repl.addAll(plannedNodes);
+ if (pendingLaunches.compareAndSet(orig, repl)) {
+ if (additionalPlannedCapacity > 0) {
+ synchronized (this) {
+ this.additionalPlannedCapacity += additionalPlannedCapacity;
+ }
+ }
+ break;
}
- } finally {
- provisioningLock.unlock();
}
}
diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java
index c62401dc76..85f2c6def3 100644
--- a/core/src/main/java/hudson/slaves/SlaveComputer.java
+++ b/core/src/main/java/hudson/slaves/SlaveComputer.java
@@ -172,12 +172,7 @@ public class SlaveComputer extends Computer {
this.acceptingTasks = acceptingTasks;
}
- /**
- * True if this computer is a Unix machine (as opposed to Windows machine).
- *
- * @return
- * null if the computer is disconnected and therefore we don't know whether it is Unix or not.
- */
+ @Override
public Boolean isUnix() {
return isUnix;
}
diff --git a/core/src/main/java/hudson/tasks/Maven.java b/core/src/main/java/hudson/tasks/Maven.java
index c61255afca..51f41aa220 100644
--- a/core/src/main/java/hudson/tasks/Maven.java
+++ b/core/src/main/java/hudson/tasks/Maven.java
@@ -460,7 +460,7 @@ public class Maven extends Builder {
/**
* @deprecated since 2009-02-25.
*/
- @Deprecated // kept for backward compatiblity - use getHome()
+ @Deprecated // kept for backward compatibility - use getHome()
private transient String mavenHome;
/**
diff --git a/core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java b/core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java
index 938325f668..6433718c75 100644
--- a/core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java
+++ b/core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java
@@ -4,6 +4,7 @@ import hudson.FilePath;
import hudson.model.DownloadService.Downloadable;
import hudson.model.Node;
import hudson.model.TaskListener;
+import hudson.slaves.NodeSpecific;
import net.sf.json.JSONObject;
import java.io.IOException;
@@ -64,6 +65,10 @@ public abstract class DownloadFromUrlInstaller extends ToolInstaller {
return expected;
}
+ if (inst instanceof NodeSpecific) {
+ inst = (Installable) ((NodeSpecific) inst).forNode(node, log);
+ }
+
if(isUpToDate(expected,inst))
return expected;
@@ -175,4 +180,17 @@ public abstract class DownloadFromUrlInstaller extends ToolInstaller {
*/
public String url;
}
+
+ /**
+ * Convenient abstract class to implement a NodeSpecificInstallable based on an existing Installable
+ * @since 1.626
+ */
+ public abstract class NodeSpecificInstallable extends Installable implements NodeSpecific {
+
+ public NodeSpecificInstallable(Installable inst) {
+ this.id = inst.id;
+ this.name = inst.name;
+ this.url = inst.url;
+ }
+ }
}
diff --git a/core/src/main/java/hudson/triggers/SCMTrigger.java b/core/src/main/java/hudson/triggers/SCMTrigger.java
index c1b2dde483..6f772064a5 100644
--- a/core/src/main/java/hudson/triggers/SCMTrigger.java
+++ b/core/src/main/java/hudson/triggers/SCMTrigger.java
@@ -2,6 +2,7 @@
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Brian Westrich, Jean-Baptiste Quenot, id:cactusman
+ * 2015 Kanstantsin Shautsou
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,6 +25,7 @@
package hudson.triggers;
import antlr.ANTLRException;
+import com.google.common.base.Preconditions;
import hudson.Extension;
import hudson.Util;
import hudson.console.AnnotatedLargeText;
@@ -117,6 +119,10 @@ public class SCMTrigger extends Trigger- {
@Override
public void run() {
+ if (job == null) {
+ return;
+ }
+
run(null);
}
@@ -128,6 +134,10 @@ public class SCMTrigger extends Trigger
- {
* @since 1.375
*/
public void run(Action[] additionalActions) {
+ if (job == null) {
+ return;
+ }
+
DescriptorImpl d = getDescriptor();
LOGGER.fine("Scheduling a polling for "+job);
@@ -152,6 +162,10 @@ public class SCMTrigger extends Trigger
- {
@Override
public Collection extends Action> getProjectActions() {
+ if (job == null) {
+ return Collections.emptyList();
+ }
+
return Collections.singleton(new SCMAction());
}
@@ -457,10 +471,12 @@ public class SCMTrigger extends Trigger
- {
private Action[] additionalActions;
public Runner() {
- additionalActions = new Action[0];
+ this(null);
}
public Runner(Action[] actions) {
+ Preconditions.checkNotNull(job, "Runner can't be instantiated when job is null");
+
if (actions == null) {
additionalActions = new Action[0];
} else {
@@ -514,11 +530,7 @@ public class SCMTrigger extends Trigger
- {
else
logger.println("No changes");
return result;
- } catch (Error e) {
- e.printStackTrace(listener.error("Failed to record SCM polling for "+job));
- LOGGER.log(Level.SEVERE,"Failed to record SCM polling for "+job,e);
- throw e;
- } catch (RuntimeException e) {
+ } catch (Error | RuntimeException e) {
e.printStackTrace(listener.error("Failed to record SCM polling for "+job));
LOGGER.log(Level.SEVERE,"Failed to record SCM polling for "+job,e);
throw e;
@@ -532,6 +544,10 @@ public class SCMTrigger extends Trigger
- {
}
public void run() {
+ if (job == null) {
+ return;
+ }
+
String threadName = Thread.currentThread().getName();
Thread.currentThread().setName("SCM polling for "+job);
try {
diff --git a/core/src/main/java/hudson/triggers/TimerTrigger.java b/core/src/main/java/hudson/triggers/TimerTrigger.java
index 0466c8a4c3..1925f00b90 100644
--- a/core/src/main/java/hudson/triggers/TimerTrigger.java
+++ b/core/src/main/java/hudson/triggers/TimerTrigger.java
@@ -2,6 +2,7 @@
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jean-Baptiste Quenot, Martin Eigenbrodt
+ * 2015 Kanstantsin Shautsou
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -38,6 +39,8 @@ import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
+import javax.annotation.Nonnull;
+
/**
* {@link Trigger} that runs a job periodically.
*
@@ -46,12 +49,16 @@ import org.kohsuke.stapler.QueryParameter;
public class TimerTrigger extends Trigger {
@DataBoundConstructor
- public TimerTrigger(String spec) throws ANTLRException {
+ public TimerTrigger(@Nonnull String spec) throws ANTLRException {
super(spec);
}
@Override
public void run() {
+ if (job == null) {
+ return;
+ }
+
job.scheduleBuild(0, new TimerTriggerCause());
}
diff --git a/core/src/main/java/hudson/triggers/Trigger.java b/core/src/main/java/hudson/triggers/Trigger.java
index 6f5c922d26..dade0854c3 100644
--- a/core/src/main/java/hudson/triggers/Trigger.java
+++ b/core/src/main/java/hudson/triggers/Trigger.java
@@ -2,7 +2,8 @@
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Brian Westrich, Jean-Baptiste Quenot, Stephen Connolly, Tom Huybrechts
- *
+ * 2015 Kanstantsin Shautsou
+ *
* 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
@@ -57,6 +58,8 @@ import java.util.logging.Logger;
import antlr.ANTLRException;
import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import hudson.model.Items;
import jenkins.model.ParameterizedJobMixIn;
@@ -99,6 +102,8 @@ public abstract class Trigger implements Describable>
*
* This method is invoked when {@link #Trigger(String)} is used
* to create an instance, and the crontab matches the current time.
+ *
+ * Maybe run even before {@link #start(hudson.model.Item, boolean)}, prepare for it.
*/
public void run() {}
@@ -147,6 +152,7 @@ public abstract class Trigger implements Describable>
protected final String spec;
protected transient CronTabList tabs;
+ @CheckForNull
protected transient J job;
/**
@@ -154,7 +160,7 @@ public abstract class Trigger implements Describable>
* periodically. This is useful when your trigger does
* some polling work.
*/
- protected Trigger(String cronTabSpec) throws ANTLRException {
+ protected Trigger(@Nonnull String cronTabSpec) throws ANTLRException {
this.spec = cronTabSpec;
this.tabs = CronTabList.create(cronTabSpec);
}
@@ -241,6 +247,10 @@ public abstract class Trigger implements Describable>
// FIXME allow to set a global crontab spec
previousSynchronousPolling = scmd.getExecutor().submit(new DependencyRunner(new ProjectRunnable() {
public void run(AbstractProject p) {
+ if (!p.isBuildable()) {
+ return; //skip disabled/copied project
+ }
+
for (Trigger t : (Collection) p.getTriggers().values()) {
if (t instanceof SCMTrigger) {
LOGGER.fine("synchronously triggering SCMTrigger for project " + t.job.getName());
@@ -256,6 +266,12 @@ public abstract class Trigger implements Describable>
// Process all triggers, except SCMTriggers when synchronousPolling is set
for (ParameterizedJobMixIn.ParameterizedJob p : inst.getAllItems(ParameterizedJobMixIn.ParameterizedJob.class)) {
+ if (p instanceof AbstractProject, ?>) {
+ if (!((AbstractProject) p).isBuildable()) {
+ continue; // skip disabled/copied project
+ }
+ }
+
for (Trigger t : p.getTriggers().values()) {
if (! (t instanceof SCMTrigger && scmd.synchronousPolling)) {
LOGGER.log(Level.FINE, "cron checking {0} with spec ‘{1}’", new Object[] {p, t.spec.trim()});
@@ -304,7 +320,7 @@ public abstract class Trigger implements Describable>
* Returns a subset of {@link TriggerDescriptor}s that applys to the given item.
*/
public static List for_(Item i) {
- List r = new ArrayList();
+ List r = new ArrayList<>();
for (TriggerDescriptor t : all()) {
if(!t.isApplicable(i)) continue;
diff --git a/core/src/main/java/hudson/util/ChartUtil.java b/core/src/main/java/hudson/util/ChartUtil.java
index e6a14cc8d8..1fcd8d7215 100644
--- a/core/src/main/java/hudson/util/ChartUtil.java
+++ b/core/src/main/java/hudson/util/ChartUtil.java
@@ -113,7 +113,7 @@ public class ChartUtil {
*
* @param defaultSize
* The size of the picture to be generated. These values can be overridden
- * by the query paramter 'width' and 'height' in the request.
+ * by the query parameter 'width' and 'height' in the request.
* @deprecated as of 1.320
* Bind {@link Graph} to the URL space. See {@code hudson.tasks.junit.History} as an example (note that doing so involves
* a bit of URL structure change.)
@@ -129,7 +129,7 @@ public class ChartUtil {
* @param defaultW
* @param defaultH
* The size of the picture to be generated. These values can be overridden
- * by the query paramter 'width' and 'height' in the request.
+ * by the query parameter 'width' and 'height' in the request.
* @deprecated as of 1.320
* Bind {@link Graph} to the URL space. See {@code hudson.tasks.junit.History} as an example (note that doing so involves
* a bit of URL structure change.)
diff --git a/core/src/main/java/hudson/util/CopyOnWriteList.java b/core/src/main/java/hudson/util/CopyOnWriteList.java
index 179d2d0825..43e189ba19 100644
--- a/core/src/main/java/hudson/util/CopyOnWriteList.java
+++ b/core/src/main/java/hudson/util/CopyOnWriteList.java
@@ -39,6 +39,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Arrays;
+import jenkins.util.xstream.CriticalXStreamException;
+
/**
* {@link List}-like implementation that has copy-on-write semantics.
@@ -194,6 +196,8 @@ public class CopyOnWriteList implements Iterable {
try {
Object item = readItem(reader, context, items);
items.add(item);
+ } catch (CriticalXStreamException e) {
+ throw e;
} catch (XStreamException e) {
RobustReflectionConverter.addErrorInContext(context, e);
} catch (LinkageError e) {
diff --git a/core/src/main/java/hudson/util/DoubleLaunchChecker.java b/core/src/main/java/hudson/util/DoubleLaunchChecker.java
index 3404650233..6642022abf 100644
--- a/core/src/main/java/hudson/util/DoubleLaunchChecker.java
+++ b/core/src/main/java/hudson/util/DoubleLaunchChecker.java
@@ -51,7 +51,7 @@ import java.lang.reflect.Method;
* to forestall the problem of running multiple instances of Hudson that point to the same data directory.
*
*
- * This set up error occasionally happens especialy when the user is trying to reassign the context path of the app,
+ * This set up error occasionally happens especially when the user is trying to reassign the context path of the app,
* and it results in a hard-to-diagnose error, so we actively check this.
*
*
diff --git a/core/src/main/java/hudson/util/MultipartFormDataParser.java b/core/src/main/java/hudson/util/MultipartFormDataParser.java
index ee579b8390..5c1184cd2e 100644
--- a/core/src/main/java/hudson/util/MultipartFormDataParser.java
+++ b/core/src/main/java/hudson/util/MultipartFormDataParser.java
@@ -28,6 +28,7 @@ import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
+import javax.annotation.CheckForNull;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.ServletException;
import java.util.List;
@@ -71,4 +72,30 @@ public class MultipartFormDataParser {
for (FileItem item : byName.values())
item.delete();
}
+
+ /**
+ * Checks a Content-Type string to assert if it is "multipart/form-data".
+ *
+ * @param contentType Content-Type string.
+ * @return {@code true} if the content type is "multipart/form-data", otherwise {@code false}.
+ * @since TODO
+ */
+ public static boolean isMultiPartForm(@CheckForNull String contentType) {
+ if (contentType == null) {
+ return false;
+ }
+
+ String[] parts = contentType.split(";");
+ if (parts.length == 0) {
+ return false;
+ }
+
+ for (int i = 0; i < parts.length; i++) {
+ if ("multipart/form-data".equals(parts[i])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/core/src/main/java/hudson/util/PluginServletFilter.java b/core/src/main/java/hudson/util/PluginServletFilter.java
index dfc8bdf03e..41d83899a5 100644
--- a/core/src/main/java/hudson/util/PluginServletFilter.java
+++ b/core/src/main/java/hudson/util/PluginServletFilter.java
@@ -27,6 +27,7 @@ import hudson.ExtensionPoint;
import hudson.security.SecurityRealm;
import jenkins.model.Jenkins;
+import javax.annotation.CheckForNull;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -71,8 +72,11 @@ public class PluginServletFilter implements Filter, ExtensionPoint {
/**
* Lookup the instance from servlet context.
+ *
+ * @param c the ServletContext most of the time taken from a Jenkins instance
+ * @return get the current PluginServletFilter if it is already available
*/
- private static PluginServletFilter getInstance(ServletContext c) {
+ private static @CheckForNull PluginServletFilter getInstance(ServletContext c) {
return (PluginServletFilter)c.getAttribute(KEY);
}
@@ -90,12 +94,17 @@ public class PluginServletFilter implements Filter, ExtensionPoint {
public static void addFilter(Filter filter) throws ServletException {
Jenkins j = Jenkins.getInstance();
- if (j==null) {
+
+ PluginServletFilter container = null;
+ if(j != null) {
+ container = getInstance(j.servletContext);
+ }
+ // https://marvelution.atlassian.net/browse/JJI-188
+ if (j==null || container == null) {
// report who is doing legacy registration
LOGGER.log(Level.WARNING, "Filter instance is registered too early: "+filter, new Exception());
LEGACY.add(filter);
} else {
- PluginServletFilter container = getInstance(j.servletContext);
filter.init(container.config);
container.list.add(filter);
}
@@ -103,7 +112,7 @@ public class PluginServletFilter implements Filter, ExtensionPoint {
public static void removeFilter(Filter filter) throws ServletException {
Jenkins j = Jenkins.getInstance();
- if (j==null) {
+ if (j==null || getInstance(j.servletContext) == null) {
LEGACY.remove(filter);
} else {
getInstance(j.servletContext).list.remove(filter);
diff --git a/core/src/main/java/hudson/util/ProcessKillingVeto.java b/core/src/main/java/hudson/util/ProcessKillingVeto.java
new file mode 100644
index 0000000000..a410a610fd
--- /dev/null
+++ b/core/src/main/java/hudson/util/ProcessKillingVeto.java
@@ -0,0 +1,92 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2015, Daniel Weber
+ *
+ * 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.util;
+
+import hudson.ExtensionPoint;
+import hudson.util.ProcessTreeRemoting.IOSProcess;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+
+import jenkins.model.Jenkins;
+
+/**
+ * Allows extensions to veto killing processes. If at least one extension vetoes
+ * the killing of a process, it will not be killed. This can be useful to keep
+ * daemon processes alive. An example is mspdbsrv.exe used by Microsoft
+ * compilers.
+ *
+ * See JENKINS-9104
+ *
+ * @since TODO
+ *
+ * @author Daniel Weber
+ */
+public abstract class ProcessKillingVeto implements ExtensionPoint {
+
+ /**
+ * Describes the cause for a process killing veto.
+ */
+ public static class VetoCause {
+ private final String message;
+
+ /**
+ * @param message A string describing the reason for the veto
+ */
+ public VetoCause(@Nonnull String message) {
+ this.message = message;
+ }
+
+ /**
+ * @return A string describing the reason for the veto.
+ */
+ public @Nonnull String getMessage() {
+ return message;
+ }
+ }
+
+ /**
+ * @return All ProcessKillingVeto extensions currently registered. An empty
+ * list if Jenkins is not available, never null.
+ */
+ public static List all() {
+ Jenkins jenkins = Jenkins.getInstance();
+ if (jenkins == null)
+ return Collections.emptyList();
+ return jenkins.getExtensionList(ProcessKillingVeto.class);
+ }
+
+ /**
+ * Ask the extension whether it vetoes killing of the given process
+ *
+ * @param p The process that is about to be killed
+ * @return a {@link VetoCause} if the process should not be killed,
+ * null else.
+ */
+ @CheckForNull
+ public abstract VetoCause vetoProcessKilling(@Nonnull IOSProcess p);
+}
diff --git a/core/src/main/java/hudson/util/ProcessTree.java b/core/src/main/java/hudson/util/ProcessTree.java
index 00d64f5d75..dd5a3d756b 100644
--- a/core/src/main/java/hudson/util/ProcessTree.java
+++ b/core/src/main/java/hudson/util/ProcessTree.java
@@ -32,6 +32,7 @@ import hudson.Util;
import hudson.remoting.Channel;
import hudson.remoting.VirtualChannel;
import hudson.slaves.SlaveComputer;
+import hudson.util.ProcessKillingVeto.VetoCause;
import hudson.util.ProcessTree.OSProcess;
import hudson.util.ProcessTreeRemoting.IOSProcess;
import hudson.util.ProcessTreeRemoting.IProcessTree;
@@ -56,6 +57,7 @@ import java.util.SortedMap;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.annotation.CheckForNull;
import static com.sun.jna.Pointer.NULL;
import static hudson.util.jna.GNUCLibrary.LIBC;
import static java.util.logging.Level.FINE;
@@ -227,6 +229,22 @@ public abstract class ProcessTree implements Iterable, IProcessTree,
*/
public abstract void killRecursively() throws InterruptedException;
+ /**
+ * @return The first non-null {@link VetoCause} provided by a process killing veto extension for this OSProcess.
+ * null if no one objects killing the process.
+ */
+ protected @CheckForNull VetoCause getVeto() {
+ for (ProcessKillingVeto vetoExtension : ProcessKillingVeto.all()) {
+ VetoCause cause = vetoExtension.vetoProcessKilling(this);
+ if (cause != null) {
+ if (LOGGER.isLoggable(FINEST))
+ LOGGER.finest("Killing of pid " + getPid() + " vetoed by " + vetoExtension.getClass().getName() + ": " + cause.getMessage());
+ return cause;
+ }
+ }
+ return null;
+ }
+
/**
* Gets the command-line arguments of this process.
*
@@ -363,6 +381,8 @@ public abstract class ProcessTree implements Iterable, IProcessTree,
}
public void kill() throws InterruptedException {
+ if (getVeto() != null)
+ return;
proc.destroy();
killByKiller();
}
@@ -398,12 +418,18 @@ public abstract class ProcessTree implements Iterable, IProcessTree,
}
public void killRecursively() throws InterruptedException {
+ if (getVeto() != null)
+ return;
+
LOGGER.finer("Killing recursively "+getPid());
p.killRecursively();
killByKiller();
}
public void kill() throws InterruptedException {
+ if (getVeto() != null)
+ return;
+
LOGGER.finer("Killing "+getPid());
p.kill();
killByKiller();
@@ -537,6 +563,8 @@ public abstract class ProcessTree implements Iterable, IProcessTree,
* Tries to kill this process.
*/
public void kill() throws InterruptedException {
+ if (getVeto() != null)
+ return;
try {
int pid = getPid();
LOGGER.fine("Killing pid="+pid);
@@ -557,6 +585,7 @@ public abstract class ProcessTree implements Iterable, IProcessTree,
}
public void killRecursively() throws InterruptedException {
+ // We kill individual processes of a tree, so handling vetoes inside #kill() is enough for UnixProcess es
LOGGER.fine("Recursively killing pid="+getPid());
for (OSProcess p : getChildren())
p.killRecursively();
diff --git a/core/src/main/java/hudson/util/QuotedStringTokenizer.java b/core/src/main/java/hudson/util/QuotedStringTokenizer.java
index 248f1ac954..e33b15ccab 100644
--- a/core/src/main/java/hudson/util/QuotedStringTokenizer.java
+++ b/core/src/main/java/hudson/util/QuotedStringTokenizer.java
@@ -44,7 +44,7 @@ import java.util.ArrayList;
/** StringTokenizer with Quoting support.
*
* This class is a copy of the java.util.StringTokenizer API and
- * the behaviour is the same, except that single and doulbe quoted
+ * the behaviour is the same, except that single and double quoted
* string values are recognized.
* Delimiters within quotes are not considered delimiters.
* Quotes can be escaped with '\'.
@@ -328,7 +328,7 @@ public class QuotedStringTokenizer
/* ------------------------------------------------------------ */
/** Quote a string.
* The string is quoted only if quoting is required due to
- * embeded delimiters, quote characters or the
+ * embedded delimiters, quote characters or the
* empty string.
* @param s The string to quote.
* @return quoted string
@@ -358,7 +358,7 @@ public class QuotedStringTokenizer
/* ------------------------------------------------------------ */
/** Quote a string.
* The string is quoted only if quoting is required due to
- * embeded delimiters, quote characters or the
+ * embedded delimiters, quote characters or the
* empty string.
* @param s The string to quote.
* @return quoted string
diff --git a/core/src/main/java/hudson/util/RobustCollectionConverter.java b/core/src/main/java/hudson/util/RobustCollectionConverter.java
index 78dc2b2f2f..d0903ff82b 100644
--- a/core/src/main/java/hudson/util/RobustCollectionConverter.java
+++ b/core/src/main/java/hudson/util/RobustCollectionConverter.java
@@ -36,6 +36,8 @@ import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
+import jenkins.util.xstream.CriticalXStreamException;
+
/**
* {@link CollectionConverter} that ignores {@link XStreamException}.
@@ -82,6 +84,8 @@ public class RobustCollectionConverter extends CollectionConverter {
try {
Object item = readItem(reader, context, collection);
collection.add(item);
+ } catch (CriticalXStreamException e) {
+ throw e;
} catch (XStreamException e) {
RobustReflectionConverter.addErrorInContext(context, e);
} catch (LinkageError e) {
diff --git a/core/src/main/java/hudson/util/RobustMapConverter.java b/core/src/main/java/hudson/util/RobustMapConverter.java
index 6a52bfb016..48bdf94c79 100644
--- a/core/src/main/java/hudson/util/RobustMapConverter.java
+++ b/core/src/main/java/hudson/util/RobustMapConverter.java
@@ -30,6 +30,7 @@ import com.thoughtworks.xstream.converters.collections.MapConverter;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.mapper.Mapper;
import java.util.Map;
+import jenkins.util.xstream.CriticalXStreamException;
/**
* Loads a {@link Map} while tolerating read errors on its keys and values.
@@ -55,6 +56,8 @@ final class RobustMapConverter extends MapConverter {
reader.moveDown();
try {
return readItem(reader, context, map);
+ } catch (CriticalXStreamException x) {
+ throw x;
} catch (XStreamException x) {
RobustReflectionConverter.addErrorInContext(context, x);
return ERROR;
diff --git a/core/src/main/java/hudson/util/RobustReflectionConverter.java b/core/src/main/java/hudson/util/RobustReflectionConverter.java
index 18909ba74f..7270ee4e10 100644
--- a/core/src/main/java/hudson/util/RobustReflectionConverter.java
+++ b/core/src/main/java/hudson/util/RobustReflectionConverter.java
@@ -54,6 +54,7 @@ import java.util.Set;
import static java.util.logging.Level.FINE;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
+import jenkins.util.xstream.CriticalXStreamException;
/**
* Custom {@link ReflectionConverter} that handle errors more gracefully.
@@ -307,9 +308,11 @@ public class RobustReflectionConverter implements Converter {
implicitCollectionsForCurrentObject = writeValueToImplicitCollection(context, value, implicitCollectionsForCurrentObject, result, fieldName);
}
}
+ } catch (CriticalXStreamException e) {
+ throw e;
} catch (XStreamException e) {
if (critical) {
- throw e;
+ throw new CriticalXStreamException(e);
}
addErrorInContext(context, e);
} catch (LinkageError e) {
diff --git a/core/src/main/java/hudson/util/SequentialExecutionQueue.java b/core/src/main/java/hudson/util/SequentialExecutionQueue.java
index 31f10e049d..a1cfa3ccba 100644
--- a/core/src/main/java/hudson/util/SequentialExecutionQueue.java
+++ b/core/src/main/java/hudson/util/SequentialExecutionQueue.java
@@ -1,5 +1,6 @@
package hudson.util;
+import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -58,7 +59,7 @@ public class SequentialExecutionQueue implements Executor {
}
- public synchronized void execute(Runnable item) {
+ public synchronized void execute(@Nonnull Runnable item) {
QueueEntry e = entries.get(item);
if(e==null) {
e = new QueueEntry(item);
diff --git a/core/src/main/java/hudson/util/io/TarArchiver.java b/core/src/main/java/hudson/util/io/TarArchiver.java
index 7e7a3dd4f0..600a16cba6 100644
--- a/core/src/main/java/hudson/util/io/TarArchiver.java
+++ b/core/src/main/java/hudson/util/io/TarArchiver.java
@@ -37,6 +37,8 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import static org.apache.tools.tar.TarConstants.LF_SYMLINK;
@@ -47,24 +49,17 @@ import static org.apache.tools.tar.TarConstants.LF_SYMLINK;
*/
final class TarArchiver extends Archiver {
private final byte[] buf = new byte[8192];
- private final TarOutputStream tar;
+ private final TarArchiveOutputStream tar;
TarArchiver(OutputStream out) {
- tar = new TarOutputStream(new BufferedOutputStream(out) {
- // TarOutputStream uses TarBuffer internally,
- // which flushes the stream for each block. this creates unnecessary
- // data stream fragmentation, and flush request to a remote, which slows things down.
- @Override
- public void flush() throws IOException {
- // so don't do anything in flush
- }
- });
- tar.setLongFileMode(TarOutputStream.LONGFILE_GNU);
+ tar = new TarArchiveOutputStream(out);
+ tar.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR);
+ tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
}
@Override
public void visitSymlink(File link, String target, String relativePath) throws IOException {
- TarEntry e = new TarEntry(relativePath, LF_SYMLINK);
+ TarArchiveEntry e = new TarArchiveEntry(relativePath, LF_SYMLINK);
try {
int mode = IOUtils.mode(link);
if (mode != -1) {
@@ -73,16 +68,11 @@ final class TarArchiver extends Archiver {
} catch (PosixException x) {
// ignore
}
+
+ e.setLinkName(target);
- try {
- StringBuffer linkName = (StringBuffer) LINKNAME_FIELD.get(e);
- linkName.setLength(0);
- linkName.append(target);
- } catch (IllegalAccessException x) {
- throw new IOException("Failed to set linkName", x);
- }
-
- tar.putNextEntry(e);
+ tar.putArchiveEntry(e);
+ tar.closeArchiveEntry();
entriesWritten++;
}
@@ -97,14 +87,14 @@ final class TarArchiver extends Archiver {
if(file.isDirectory())
relativePath+='/';
- TarEntry te = new TarEntry(relativePath);
+ TarArchiveEntry te = new TarArchiveEntry(relativePath);
int mode = IOUtils.mode(file);
if (mode!=-1) te.setMode(mode);
te.setModTime(file.lastModified());
if(!file.isDirectory())
te.setSize(file.length());
- tar.putNextEntry(te);
+ tar.putArchiveEntry(te);
if (!file.isDirectory()) {
FileInputStream in = new FileInputStream(file);
@@ -117,25 +107,11 @@ final class TarArchiver extends Archiver {
}
}
- tar.closeEntry();
+ tar.closeArchiveEntry();
entriesWritten++;
}
public void close() throws IOException {
tar.close();
}
-
- private static final Field LINKNAME_FIELD = getTarEntryLinkNameField();
-
- private static Field getTarEntryLinkNameField() {
- try {
- Field f = TarEntry.class.getDeclaredField("linkName");
- f.setAccessible(true);
- return f;
- } catch (SecurityException e) {
- throw new AssertionError(e);
- } catch (NoSuchFieldException e) {
- throw new AssertionError(e);
- }
- }
}
diff --git a/core/src/main/java/hudson/util/jna/DotNet.java b/core/src/main/java/hudson/util/jna/DotNet.java
index 4011767b19..4d820149ca 100644
--- a/core/src/main/java/hudson/util/jna/DotNet.java
+++ b/core/src/main/java/hudson/util/jna/DotNet.java
@@ -46,7 +46,7 @@ public class DotNet {
try {
// see http://support.microsoft.com/?scid=kb;en-us;315291 for the basic algorithm
// observation in my registry shows that the actual key name can be things like "v2.0 SP1"
- // or "v2.0.50727", so the regexp is written to accomodate this.
+ // or "v2.0.50727", so the regexp is written to accommodate this.
RegistryKey key = RegistryKey.LOCAL_MACHINE.openReadonly("SOFTWARE\\Microsoft\\.NETFramework");
try {
for( String keyName : key.getSubKeys() ) {
diff --git a/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java b/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java
index 18fd97ec98..3734c47245 100644
--- a/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java
+++ b/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java
@@ -39,6 +39,8 @@ import hudson.util.RobustReflectionConverter;
import java.util.ArrayList;
import java.util.List;
+import jenkins.util.xstream.CriticalXStreamException;
+
/**
* {@link ImmutableList} should convert like a list, instead of via serialization.
*
@@ -76,6 +78,8 @@ public class ImmutableListConverter extends CollectionConverter {
try {
Object item = readItem(reader, context, items);
items.add(item);
+ } catch (CriticalXStreamException e) {
+ throw e;
} catch (XStreamException e) {
RobustReflectionConverter.addErrorInContext(context, e);
} catch (LinkageError e) {
diff --git a/core/src/main/java/jenkins/model/BlockedBecauseOfBuildInProgress.java b/core/src/main/java/jenkins/model/BlockedBecauseOfBuildInProgress.java
new file mode 100644
index 0000000000..f55537c2ca
--- /dev/null
+++ b/core/src/main/java/jenkins/model/BlockedBecauseOfBuildInProgress.java
@@ -0,0 +1,55 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2015 Jesse Glick.
+ *
+ * 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.model;
+
+import hudson.model.Executor;
+import hudson.model.Job;
+import hudson.model.Run;
+import hudson.model.queue.CauseOfBlockage;
+
+/**
+ * Indicates that a new build is blocked because the previous build is already in progress.
+ * Useful for implementing {@link hudson.model.Queue.Task#getCauseOfBlockage} from a {@link Job} which supports {@link hudson.model.Queue.Task#isConcurrentBuild}.
+ * @since 1.624
+ */
+public class BlockedBecauseOfBuildInProgress extends CauseOfBlockage {
+
+ private final Run, ?> build;
+
+ public BlockedBecauseOfBuildInProgress(Run, ?> build) {
+ this.build = build;
+ }
+
+ @Override public String getShortDescription() {
+ Executor e = build.getExecutor();
+ String eta = "";
+ if (e != null) {
+ eta = Messages.BlockedBecauseOfBuildInProgress_ETA(e.getEstimatedRemainingTime());
+ }
+ int lbn = build.getNumber();
+ return Messages.BlockedBecauseOfBuildInProgress_shortDescription(lbn, eta);
+ }
+
+}
diff --git a/core/src/main/java/jenkins/model/CauseOfInterruption.java b/core/src/main/java/jenkins/model/CauseOfInterruption.java
index d733ffe33e..dbec0221ac 100644
--- a/core/src/main/java/jenkins/model/CauseOfInterruption.java
+++ b/core/src/main/java/jenkins/model/CauseOfInterruption.java
@@ -70,7 +70,7 @@ public abstract class CauseOfInterruption implements Serializable {
}
/**
- * Indicates that the build was interrupted from UI by an user.
+ * Indicates that the build was interrupted from UI.
*/
public static final class UserInterruption extends CauseOfInterruption {
private final String user;
@@ -112,32 +112,5 @@ public abstract class CauseOfInterruption implements Serializable {
private static final long serialVersionUID = 1L;
}
- /**
- * Indicates that the build was interrupted as a result of another a problem.
- *
- *
- * This is a less specific (thus less desirable) {@link CauseOfInterruption}
- * in case there's no suitable {@link CauseOfInterruption}. Use sparingly.
- */
- class ExceptionInterruption extends CauseOfInterruption {
- private final Throwable cause;
-
- public ExceptionInterruption(Throwable cause) {
- this.cause = cause;
- }
-
- public Throwable getCause() {
- return cause;
- }
-
- @Override
- public String getShortDescription() {
- return "Exception: "+ cause.getMessage();
- }
-
- private static final long serialVersionUID = 1L;
- }
-
-
private static final long serialVersionUID = 1L;
}
diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java
index c8dedf7577..ade0908991 100644
--- a/core/src/main/java/jenkins/model/Jenkins.java
+++ b/core/src/main/java/jenkins/model/Jenkins.java
@@ -552,6 +552,8 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
public transient volatile TcpSlaveAgentListener tcpSlaveAgentListener;
+ private transient final Object tcpSlaveAgentListenerLock = new Object();
+
private transient UDPBroadcastThread udpBroadcastThread;
private transient DNSMultiCast dnsMultiCast;
@@ -821,16 +823,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
if(KILL_AFTER_LOAD)
System.exit(0);
- if(slaveAgentPort!=-1) {
- try {
- tcpSlaveAgentListener = new TcpSlaveAgentListener(slaveAgentPort);
- } catch (BindException e) {
- new AdministrativeError(getClass().getName()+".tcpBind",
- "Failed to listen to incoming slave connection",
- "Failed to listen to incoming slave connection. Change the port number to solve the problem.",e);
- }
- } else
- tcpSlaveAgentListener = null;
+ launchTcpSlaveAgentListener();
if (UDPBroadcastThread.PORT != -1) {
try {
@@ -946,17 +939,32 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
*/
public void setSlaveAgentPort(int port) throws IOException {
this.slaveAgentPort = port;
+ launchTcpSlaveAgentListener();
+ }
- // relaunch the agent
- if(tcpSlaveAgentListener==null) {
- if(slaveAgentPort!=-1)
- tcpSlaveAgentListener = new TcpSlaveAgentListener(slaveAgentPort);
- } else {
- if(tcpSlaveAgentListener.configuredPort!=slaveAgentPort) {
+ private void launchTcpSlaveAgentListener() throws IOException {
+ synchronized(tcpSlaveAgentListenerLock) {
+ // shutdown previous agent if the port has changed
+ if (tcpSlaveAgentListener != null && tcpSlaveAgentListener.configuredPort != slaveAgentPort) {
tcpSlaveAgentListener.shutdown();
tcpSlaveAgentListener = null;
- if(slaveAgentPort!=-1)
+ }
+ if (slaveAgentPort != -1 && tcpSlaveAgentListener == null) {
+ String administrativeMonitorId = getClass().getName() + ".tcpBind";
+ try {
tcpSlaveAgentListener = new TcpSlaveAgentListener(slaveAgentPort);
+ // remove previous monitor in case of previous error
+ for (Iterator it = AdministrativeMonitor.all().iterator(); it.hasNext(); ) {
+ AdministrativeMonitor am = it.next();
+ if (administrativeMonitorId.equals(am.id)) {
+ it.remove();
+ }
+ }
+ } catch (BindException e) {
+ new AdministrativeError(administrativeMonitorId,
+ "Failed to listen to incoming slave connection",
+ "Failed to listen to incoming slave connection. Change the port number to solve the problem.", e);
+ }
}
}
}
@@ -1702,6 +1710,16 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
return nodes.getNodes();
}
+ /**
+ * Get the {@link Nodes} object that handles maintaining individual {@link Node}s.
+ * @return The Nodes object.
+ */
+ @Restricted(NoExternalUse.class)
+ public Nodes getNodesObject() {
+ // TODO replace this with something better when we properly expose Nodes.
+ return nodes;
+ }
+
/**
* Adds one more {@link Node} to Jenkins.
*/
@@ -3998,6 +4016,11 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
return true;
}
+ @Override
+ public Boolean isUnix() {
+ return !Functions.isWindows();
+ }
+
/**
* Report an error.
*/
diff --git a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java
index d9ed205ef0..f626750deb 100644
--- a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java
+++ b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java
@@ -77,7 +77,7 @@ public class JenkinsLocationConfiguration extends GlobalConfiguration {
/**
* Gets the service administrator e-mail address.
- * @return Admin adress or "address not configured" stub
+ * @return Admin address or "address not configured" stub
*/
public @Nonnull String getAdminAddress() {
String v = adminAddress;
@@ -92,7 +92,7 @@ public class JenkinsLocationConfiguration extends GlobalConfiguration {
public void setAdminAddress(@CheckForNull String adminAddress) {
String address = Util.nullify(adminAddress);
if(address != null && address.startsWith("\"") && address.endsWith("\"")) {
- // some users apparently quote the whole thing. Don't konw why
+ // some users apparently quote the whole thing. Don't know why
// anyone does this, but it's a machine's job to forgive human mistake
address = address.substring(1,address.length()-1);
}
diff --git a/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java b/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java
index 1fff85ec12..07d1e61e6b 100644
--- a/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java
+++ b/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java
@@ -41,6 +41,7 @@ import hudson.model.queue.QueueTaskFuture;
import hudson.search.SearchIndexBuilder;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
+import hudson.util.AlternativeUiTextProvider;
import hudson.views.BuildButtonColumn;
import java.io.IOException;
import java.util.ArrayList;
@@ -94,17 +95,39 @@ public abstract class ParameterizedJobMixIn & Param
}
/**
- * Convenience method to schedule a build with the ability to wait for its result.
- * Often used during functional tests ({@code JenkinsRule.assertBuildStatusSuccess}).
+ * Provides a standard implementation of an optional method of the same name in a {@link Job} type to schedule a build with the ability to wait for its result.
+ * That job method is often used during functional tests ({@code JenkinsRule.assertBuildStatusSuccess}).
* @param quietPeriod seconds to wait before starting (normally 0)
* @param actions various actions to associate with the scheduling, such as {@link ParametersAction} or {@link CauseAction}
* @return a handle by which you may wait for the build to complete (or just start); or null if the build was not actually scheduled for some reason
*/
public final @CheckForNull QueueTaskFuture scheduleBuild2(int quietPeriod, Action... actions) {
- return scheduleBuild2(quietPeriod, Arrays.asList(actions));
+ Queue.Item i = scheduleBuild2(quietPeriod, Arrays.asList(actions));
+ return i != null ? (QueueTaskFuture) i.getFuture() : null;
}
- private @CheckForNull QueueTaskFuture scheduleBuild2(int quietPeriod, List actions) {
+ /**
+ * Convenience method to schedule a build.
+ * Useful for {@link Trigger} implementations, for example.
+ * If you need to wait for the build to start (or finish), use {@link Queue.Item#getFuture}.
+ * @param job a job which might be schedulable
+ * @param quietPeriod seconds to wait before starting; use {@code -1} to use the job’s default settings
+ * @param actions various actions to associate with the scheduling, such as {@link ParametersAction} or {@link CauseAction}
+ * @return a newly created, or reused, queue item if the job could be scheduled; null if it was refused for some reason (e.g., some {@link Queue.QueueDecisionHandler} rejected it), or if {@code job} is not a {@link ParameterizedJob} or it is not {@link Job#isBuildable})
+ * @since 1.621
+ */
+ public static @CheckForNull Queue.Item scheduleBuild2(final Job,?> job, int quietPeriod, Action... actions) {
+ if (!(job instanceof ParameterizedJob)) {
+ return null;
+ }
+ return new ParameterizedJobMixIn() {
+ @Override protected Job asJob() {
+ return job;
+ }
+ }.scheduleBuild2(quietPeriod == -1 ? ((ParameterizedJob) job).getQuietPeriod() : quietPeriod, Arrays.asList(actions));
+ }
+
+ @CheckForNull Queue.Item scheduleBuild2(int quietPeriod, List actions) {
if (!asJob().isBuildable())
return null;
@@ -112,8 +135,7 @@ public abstract class ParameterizedJobMixIn & Param
if (isParameterized() && Util.filter(queueActions, ParametersAction.class).isEmpty()) {
queueActions.add(new ParametersAction(getDefaultParametersValues()));
}
- Queue.Item i = Jenkins.getInstance().getQueue().schedule2(asJob(), quietPeriod, queueActions).getItem();
- return i != null ? (QueueTaskFuture) i.getFuture() : null;
+ return Jenkins.getInstance().getQueue().schedule2(asJob(), quietPeriod, queueActions).getItem();
}
private List getDefaultParametersValues() {
@@ -240,13 +262,39 @@ public abstract class ParameterizedJobMixIn & Param
return new CauseAction(cause);
}
+ /**
+ * Allows customization of the human-readable display name to be rendered in the Build Now link.
+ * @see #getBuildNowText
+ * @since TODO
+ */
+ public static final AlternativeUiTextProvider.Message BUILD_NOW_TEXT = new AlternativeUiTextProvider.Message();
+
/**
* Suggested implementation of {@link ParameterizedJob#getBuildNowText}.
+ * Uses {@link #BUILD_NOW_TEXT}.
*/
public final String getBuildNowText() {
- // TODO is it worthwhile to define a replacement for AbstractProject.BUILD_NOW_TEXT?
- // TODO move these messages (& translations) to this package
- return isParameterized() ? hudson.model.Messages.AbstractProject_build_with_parameters() : hudson.model.Messages.AbstractProject_BuildNow();
+ return isParameterized() ? Messages.ParameterizedJobMixIn_build_with_parameters() : AlternativeUiTextProvider.get(BUILD_NOW_TEXT, asJob(), Messages.ParameterizedJobMixIn_build_now());
+ }
+
+ /**
+ * Checks for the existence of a specific trigger on a job.
+ * @param a trigger type
+ * @param job a job
+ * @param clazz the type of the trigger
+ * @return a configured trigger of the requested type, or null if there is none such, or {@code job} is not a {@link ParameterizedJob}
+ * @since 1.621
+ */
+ public static @CheckForNull > T getTrigger(Job,?> job, Class clazz) {
+ if (!(job instanceof ParameterizedJob)) {
+ return null;
+ }
+ for (Trigger> t : ((ParameterizedJob) job).getTriggers().values()) {
+ if (clazz.isInstance(t)) {
+ return clazz.cast(t);
+ }
+ }
+ return null;
}
/**
@@ -265,6 +313,7 @@ public abstract class ParameterizedJobMixIn & Param
* Gets currently configured triggers.
* You may use {@code } to configure them.
* @return a map from trigger kind to instance
+ * @see #getTrigger
*/
Map> getTriggers();
diff --git a/core/src/main/java/jenkins/model/RunIdMigrator.java b/core/src/main/java/jenkins/model/RunIdMigrator.java
index 4666a5fb86..88dc17b900 100644
--- a/core/src/main/java/jenkins/model/RunIdMigrator.java
+++ b/core/src/main/java/jenkins/model/RunIdMigrator.java
@@ -350,6 +350,12 @@ public final class RunIdMigrator {
return;
}
for (File job : jobDirs) {
+
+ if (job.getName().equals("builds")) {
+ // Might be maven modules, matrix builds, etc. which are direct children of job
+ unmigrateBuildsDir(job);
+ }
+
File[] kids = job.listFiles();
if (kids == null) {
continue;
@@ -361,7 +367,8 @@ public final class RunIdMigrator {
if (kid.getName().equals("builds")) {
unmigrateBuildsDir(kid);
} else {
- // Might be jobs, modules, promotions, etc.; we assume an ItemGroup.getRootDirFor implementation returns grandchildren.
+ // Might be jobs, modules, promotions, etc.; we assume an ItemGroup.getRootDirFor implementation
+ // returns grandchildren, unmigrateJobsDir(job) call above handles children.
unmigrateJobsDir(kid);
}
}
diff --git a/core/src/main/java/jenkins/slaves/restarter/SlaveRestarter.java b/core/src/main/java/jenkins/slaves/restarter/SlaveRestarter.java
index e0c7c2f912..506c1a6806 100644
--- a/core/src/main/java/jenkins/slaves/restarter/SlaveRestarter.java
+++ b/core/src/main/java/jenkins/slaves/restarter/SlaveRestarter.java
@@ -11,7 +11,7 @@ import java.util.logging.Logger;
* Extension point to control how to restart JNLP slave when it loses the connection with the master.
*
*
- * Objects are instantiated on the master, then transfered to a slave via serialization.
+ * Objects are instantiated on the master, then transferred to a slave via serialization.
*
* @author Kohsuke Kawaguchi
*/
diff --git a/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java b/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java
index be6078eb51..df08b6d8cc 100644
--- a/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java
+++ b/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java
@@ -32,6 +32,7 @@ import hudson.model.AbstractProject;
import hudson.model.Action;
import hudson.model.AutoCompletionCandidates;
import hudson.model.Cause;
+import hudson.model.CauseAction;
import hudson.model.DependencyGraph;
import hudson.model.Item;
import hudson.model.ItemGroup;
@@ -71,6 +72,8 @@ import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
+import javax.annotation.Nonnull;
+
/**
* Like {@link BuildTrigger} but defined on the downstream project.
* Operates via {@link BuildTrigger#execute} and {@link DependencyGraph},
@@ -83,12 +86,13 @@ import org.kohsuke.stapler.QueryParameter;
public final class ReverseBuildTrigger extends Trigger implements DependencyDeclarer {
private static final Logger LOGGER = Logger.getLogger(ReverseBuildTrigger.class.getName());
- private static final Map> upstream2Trigger = new WeakHashMap>();
+ private static final Map> upstream2Trigger = new WeakHashMap<>();
private String upstreamProjects;
private final Result threshold;
- @DataBoundConstructor public ReverseBuildTrigger(String upstreamProjects, Result threshold) {
+ @DataBoundConstructor
+ public ReverseBuildTrigger(String upstreamProjects, Result threshold) {
this.upstreamProjects = upstreamProjects;
this.threshold = threshold;
}
@@ -154,7 +158,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc
synchronized (upstream2Trigger) {
Collection triggers = upstream2Trigger.get(upstream);
if (triggers == null) {
- triggers = new LinkedList();
+ triggers = new LinkedList<>();
upstream2Trigger.put(upstream, triggers);
}
triggers.remove(this);
@@ -221,14 +225,14 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc
}
@Extension public static final class RunListenerImpl extends RunListener {
- @Override public void onCompleted(Run r, TaskListener listener) {
+ @Override public void onCompleted(@Nonnull Run r, @Nonnull TaskListener listener) {
Collection triggers;
synchronized (upstream2Trigger) {
Collection _triggers = upstream2Trigger.get(r.getParent());
if (_triggers == null || _triggers.isEmpty()) {
return;
}
- triggers = new ArrayList(_triggers);
+ triggers = new ArrayList<>(_triggers);
}
for (final ReverseBuildTrigger trigger : triggers) {
if (trigger.shouldTrigger(r, listener)) {
@@ -237,11 +241,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc
continue;
}
String name = ModelHyperlinkNote.encodeTo(trigger.job) + " #" + trigger.job.getNextBuildNumber();
- if (new ParameterizedJobMixIn() {
- @Override protected Job asJob() {
- return trigger.job;
- }
- }.scheduleBuild(new Cause.UpstreamCause(r))) {
+ if (ParameterizedJobMixIn.scheduleBuild2(trigger.job, -1, new CauseAction(new Cause.UpstreamCause(r))) != null) {
listener.getLogger().println(hudson.tasks.Messages.BuildTrigger_Triggering(name));
} else {
listener.getLogger().println(hudson.tasks.Messages.BuildTrigger_InQueue(name));
@@ -257,10 +257,9 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc
if (jenkins == null) {
return;
}
- for (ParameterizedJobMixIn.ParameterizedJob p : jenkins.getAllItems(ParameterizedJobMixIn.ParameterizedJob.class)) {
- Trigger> _t = p.getTriggers().get(jenkins.getDescriptorByType(DescriptorImpl.class));
- if (_t instanceof ReverseBuildTrigger) {
- ReverseBuildTrigger t = (ReverseBuildTrigger) _t;
+ for (Job,?> p : jenkins.getAllItems(Job.class)) {
+ ReverseBuildTrigger t = ParameterizedJobMixIn.getTrigger(p, ReverseBuildTrigger.class);
+ if (t != null) {
String revised = Items.computeRelativeNamesAfterRenaming(oldFullName, newFullName, t.upstreamProjects, p.getParent());
if (!revised.equals(t.upstreamProjects)) {
t.upstreamProjects = revised;
diff --git a/core/src/main/java/jenkins/util/xstream/CriticalXStreamException.java b/core/src/main/java/jenkins/util/xstream/CriticalXStreamException.java
new file mode 100644
index 0000000000..4c098ff1e4
--- /dev/null
+++ b/core/src/main/java/jenkins/util/xstream/CriticalXStreamException.java
@@ -0,0 +1,41 @@
+/*
+ * The MIT License
+ *
+ * Copyright (c) 2015 IKEDA Yasuyuki
+ *
+ * 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.util.xstream;
+
+import com.thoughtworks.xstream.XStreamException;
+import com.thoughtworks.xstream.converters.ConversionException;
+
+/**
+ * Wraps {@link XStreamException} to indicate it is critical for Jenkins.
+ *
+ * @since 1.625
+ */
+public class CriticalXStreamException extends ConversionException {
+ private static final long serialVersionUID = 1L;
+
+ public CriticalXStreamException(XStreamException cause) {
+ super(cause);
+ }
+}
diff --git a/core/src/main/resources/hudson/model/AbstractBuild/changes.jelly b/core/src/main/resources/hudson/model/AbstractBuild/changes.jelly
index 8b357557ff..f030f796e3 100644
--- a/core/src/main/resources/hudson/model/AbstractBuild/changes.jelly
+++ b/core/src/main/resources/hudson/model/AbstractBuild/changes.jelly
@@ -31,7 +31,17 @@ THE SOFTWARE.
${%Changes}
-
+
+
+
+
+
+ ${%Not yet determined}
+
+
+ ${%Failed to determine} (${%log})
+
+
diff --git a/core/src/main/resources/hudson/model/AbstractBuild/index_pt_BR.properties b/core/src/main/resources/hudson/model/AbstractBuild/index_pt_BR.properties
index e601d09c88..7e954f6854 100644
--- a/core/src/main/resources/hudson/model/AbstractBuild/index_pt_BR.properties
+++ b/core/src/main/resources/hudson/model/AbstractBuild/index_pt_BR.properties
@@ -1,6 +1,6 @@
# The MIT License
#
-# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Reginaldo L. Russinholi, Cleiber Silva, Fernando Boaglio
+# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Reginaldo L. Russinholi, Cleiber Silva, Fernando Boaglio, George Gastaldi
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -21,9 +21,9 @@
# THE SOFTWARE.
startedAgo=Iniciado {0} atr\u00e1s
-Build\ Artifacts=Artefatos da builds
+Build\ Artifacts=Artefatos da build
Changes\ in\ dependency=Mudan\u00E7as na depend\u00EAncia
-beingExecuted=Tempo de execu\u00E7\u00E3o da builds {0}
+beingExecuted=Tempo de execu\u00E7\u00E3o da build {0}
detail=detalhe
Not\ yet\ determined=Ainda n\u00e3o determinado
Failed\ to\ determine=Falhou ao determinar
diff --git a/core/src/main/resources/hudson/model/AbstractBuild/index_pt_PT.properties b/core/src/main/resources/hudson/model/AbstractBuild/index_pt_PT.properties
index cb85ec5b93..8a54bd9d03 100644
--- a/core/src/main/resources/hudson/model/AbstractBuild/index_pt_PT.properties
+++ b/core/src/main/resources/hudson/model/AbstractBuild/index_pt_PT.properties
@@ -1,6 +1,6 @@
# The MIT License
#
-# Copyright (c) 2004-2010, Sun Microsystems, Inc.
+# Copyright (c) 2004-2010, Sun Microsystems, Inc., George Gastaldi
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -20,8 +20,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-Build=Contru\u00E7\u00E3o
-Build\ Artifacts=Contru\u00E7\u00E3o de artefactos
+Build=Constru\u00E7\u00E3o
+Build\ Artifacts=Constru\u00E7\u00E3o de artefactos
Took=Demorou
beingExecuted=Compila\u00E7\u00E3o a ser executada h\u00E1 {0}
on=em
diff --git a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pt_PT.properties b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pt_PT.properties
index 70b25b6c11..8695d88bf5 100644
--- a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pt_PT.properties
+++ b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pt_PT.properties
@@ -20,5 +20,5 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-Next\ Build=Pr\u00F3xima builds
-Previous\ Build=Prever/ver contru\u00E7\u00E3o
+Next\ Build=Pr\u00F3xima build
+Previous\ Build=Prever/ver constru\u00E7\u00E3o
diff --git a/core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString.html b/core/src/main/resources/hudson/model/AbstractProject/help-label.html
similarity index 100%
rename from core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString.html
rename to core/src/main/resources/hudson/model/AbstractProject/help-label.html
diff --git a/core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString_zh_TW.html b/core/src/main/resources/hudson/model/AbstractProject/help-label_zh_TW.html
similarity index 100%
rename from core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString_zh_TW.html
rename to core/src/main/resources/hudson/model/AbstractProject/help-label_zh_TW.html
diff --git a/core/src/main/resources/hudson/model/Job/_api.jelly b/core/src/main/resources/hudson/model/Job/_api.jelly
index 684e8cc9fe..f2ee7bcf00 100644
--- a/core/src/main/resources/hudson/model/Job/_api.jelly
+++ b/core/src/main/resources/hudson/model/Job/_api.jelly
@@ -27,6 +27,14 @@ THE SOFTWARE.
+ Retrieving all builds
+
+ To prevent Jenkins from having to load all builds from disk when someone accesses the job API, the builds
+ tree only contains the 50 newest builds. If you really need to get all builds, access the allBuilds tree,
+ e.g. by fetching …/api/xml?tree=allBuilds[…]. Note that this may result in significant performance degradation
+ if you have a lot of builds in this job.
+
+
Fetch/Update job description
this URL
diff --git a/core/src/main/resources/hudson/model/LoadStatistics/main.properties b/core/src/main/resources/hudson/model/LoadStatistics/main.properties
index 8bd2d40967..9fc34ab657 100644
--- a/core/src/main/resources/hudson/model/LoadStatistics/main.properties
+++ b/core/src/main/resources/hudson/model/LoadStatistics/main.properties
@@ -57,8 +57,8 @@ blurb=\
adding more computers.\
\
\
-
Note:The number of busy executors and the number of available executors need not \
- necessarily be equal to the number of online executors as executors can be suspended from\
+
Note: The number of busy executors and the number of available executors need not \
+ necessarily be equal to the number of online executors as executors can be suspended from \
accepting builds and thus be neither busy nor available.
\
The graph is an exponential moving average of periodically collected data values. \
3 timespans are updated every 10 seconds, 1 minute and 1 hour respectively.
diff --git a/core/src/main/resources/hudson/model/Messages.properties b/core/src/main/resources/hudson/model/Messages.properties
index 3537e9978a..8e6420c92b 100644
--- a/core/src/main/resources/hudson/model/Messages.properties
+++ b/core/src/main/resources/hudson/model/Messages.properties
@@ -36,13 +36,9 @@ AbstractProject.AwaitingBuildForWorkspace=Awaiting build to get a workspace.
AbstractProject.AwaitingWorkspaceToComeOnline=We need to schedule a new build to get a workspace, but deferring {0}ms in the hope that one will become available soon
AbstractProject.Pronoun=Project
AbstractProject.Aborted=Aborted
-AbstractProject.BuildInProgress=Build #{0} is already in progress{1}
-AbstractProject.BuildNow=Build Now
-AbstractProject.build_with_parameters=Build with Parameters
AbstractProject.UpstreamBuildInProgress=Upstream project {0} is already building.
AbstractProject.DownstreamBuildInProgress=Downstream project {0} is already building.
AbstractProject.Disabled=Build disabled
-AbstractProject.ETA=\ (ETA:{0})
AbstractProject.NoBuilds=No existing build. Scheduling a new one.
AbstractProject.NoSCM=No SCM
AbstractProject.NoWorkspace=No workspace is available, so can\u2019t check for updates.
@@ -77,7 +73,7 @@ AbstractProject.AssignedLabelString.InvalidBooleanExpression=\
AbstractProject.AssignedLabelString.NoMatch=\
There's no slave/cloud that matches this assignment
AbstractProject.CustomWorkspaceEmpty=Custom workspace is empty.
-AbstractProject.LabelLink=Slaves in label: {2}
+AbstractProject.LabelLink=Label is serviced by {2,choice,0#no nodes|1#1 node|1<{2} nodes}{3,choice,0#|1# and 1 cloud|1< and {3} clouds}
Api.MultipleMatch=XPath "{0}" matched {1} nodes. \
Create XPath that only matches one, or use the "wrapper" query parameter to wrap them all under a root element.
diff --git a/core/src/main/resources/hudson/model/Messages_ca.properties b/core/src/main/resources/hudson/model/Messages_ca.properties
index 0f88dbec7e..2237bbee1d 100644
--- a/core/src/main/resources/hudson/model/Messages_ca.properties
+++ b/core/src/main/resources/hudson/model/Messages_ca.properties
@@ -1,2 +1 @@
-AbstractProject.BuildNow=Construir Ara
ManageJenkinsAction.DisplayName=Configuraci\u00F3 de Jenkins
diff --git a/core/src/main/resources/hudson/model/Messages_da.properties b/core/src/main/resources/hudson/model/Messages_da.properties
index 3300fc7388..e27f7a4826 100644
--- a/core/src/main/resources/hudson/model/Messages_da.properties
+++ b/core/src/main/resources/hudson/model/Messages_da.properties
@@ -161,7 +161,6 @@ Computer.BadChannel=Slave node offline eller ikke en fjernkanal (f.eks. en maste
AbstractProject.Aborted=Afbrudt
Queue.init=Genopretter byggek\u00f8en
Hudson.NodeDescription=master Jenkins noden
-AbstractProject.BuildInProgress=Byg #{0} er allerede i gang {1}
Job.NoRecentBuildFailed=Ingen byg har fejlet for nyligt.
Permalink.LastUnsuccessfulBuild=Seneste fejlede byg
RunParameterDefinition.DisplayName=K\u00f8rselsparameter
@@ -233,10 +232,8 @@ Note: direktoriet beh\u00f8ver ikke v\u00e6re synlig for master noden.
Label.GroupOf=Gruppe af {0}
Queue.InQuietPeriod=I en stilleperiode. udl\u00f8ber om {0}
Queue.AllNodesOffline=Alle noder med etiket ''{0}'' er offline
-AbstractProject.ETA=(ETA:{0})
Hudson.NoSuchDirectory=Intet direktorie ved navn: {0}
LoadStatistics.Legends.BusyExecutors=Optagede afviklere
HealthReport.EmptyString=
MultiStageTimeSeries.EMPTY_STRING=
-AbstractProject.BuildNow=Byg nu
ManageJenkinsAction.DisplayName=Bestyr Jenkins
diff --git a/core/src/main/resources/hudson/model/Messages_de.properties b/core/src/main/resources/hudson/model/Messages_de.properties
index ffd402aa63..7a8d5b1bf7 100644
--- a/core/src/main/resources/hudson/model/Messages_de.properties
+++ b/core/src/main/resources/hudson/model/Messages_de.properties
@@ -31,13 +31,9 @@ AbstractItem.Pronoun=Element
AbstractProject.NewBuildForWorkspace=Plane einen neuen Build, um einen Arbeitsbereich anzulegen.
AbstractProject.Pronoun=Projekt
AbstractProject.Aborted=Abgebrochen
-AbstractProject.BuildInProgress=Build #{0} ist bereits in Arbeit{1}
-AbstractProject.BuildNow=Jetzt bauen
-AbstractProject.build_with_parameters=Bauen mit Parametern
AbstractProject.UpstreamBuildInProgress=Vorgelagertes Projekt {0} ist bereits in Arbeit.
AbstractProject.DownstreamBuildInProgress=Nachgelagertes Projekt {0} ist bereits in Arbeit.
AbstractProject.Disabled=Build deaktiviert
-AbstractProject.ETA=\ (ETA:{0})
AbstractProject.NoSCM=Kein SCM
AbstractProject.NoBuilds=Es existiert kein Build. Starte neuen Build.
AbstractProject.NoWorkspace=Kein Arbeitsbereich verf\u00fcgbar, daher kann nicht auf Aktualisierungen \u00fcberpr\u00fcft werden.
diff --git a/core/src/main/resources/hudson/model/Messages_es.properties b/core/src/main/resources/hudson/model/Messages_es.properties
index 27eb91abc8..cd201a0246 100644
--- a/core/src/main/resources/hudson/model/Messages_es.properties
+++ b/core/src/main/resources/hudson/model/Messages_es.properties
@@ -28,10 +28,8 @@ AbstractItem.NoSuchJobExists=La tarea ''{0}'' no existe. \u00bfQuiz\u00e1s quier
AbstractProject.NewBuildForWorkspace=Lanzando una nueva ejecuci\u00f3n para crear el espacio de trabajo.
AbstractProject.Pronoun=Proyecto
AbstractProject.Aborted=Cancelado
-AbstractProject.BuildInProgress=La ejecuci\u00f3n #{0} ya est\u00e1 en progreso {1}
AbstractProject.UpstreamBuildInProgress=El proyecto padre {0} ya se est\u00e1 ejecutando.
AbstractProject.Disabled=Ejecuci\u00f3n desactivada
-AbstractProject.ETA= (ETA:{0})
AbstractProject.NoSCM=Sin SCM
AbstractProject.NoWorkspace=No hay espacio de trabajo, por tanto no se puede comprobar las actualizaciones.
AbstractProject.PollingABorted=Peticiones SCM abortadas
@@ -279,7 +277,6 @@ AbstractProject.AwaitingBuildForWorkspace=El trabajo est\u00e1 esperando para te
Run.ArtifactsPermission.Description=\
Este permiso sirve para poder utilizar los artefactos producidos en los proyectos.
AbstractProject.AssignedLabelString.InvalidBooleanExpression=Expresi\u00f3n booleana incorrecta: {0}
-AbstractProject.BuildNow=Construir ahora
ManageJenkinsAction.DisplayName=Administrar Jenkins
Computer.NoSuchSlaveExists=El nodo {0} no existe. ¿Quizás se esté refiriendo a {1}?
ResultTrend.StillFailing=Todavía falla
diff --git a/core/src/main/resources/hudson/model/Messages_fi.properties b/core/src/main/resources/hudson/model/Messages_fi.properties
index a5937f2baf..b8537b4403 100644
--- a/core/src/main/resources/hudson/model/Messages_fi.properties
+++ b/core/src/main/resources/hudson/model/Messages_fi.properties
@@ -1,2 +1 @@
-AbstractProject.BuildNow=K\u00E4\u00E4nn\u00E4 nyt
ManageJenkinsAction.DisplayName=Hallitse Jenkinsia
diff --git a/core/src/main/resources/hudson/model/Messages_fr.properties b/core/src/main/resources/hudson/model/Messages_fr.properties
index 82d0d98072..37d121a887 100644
--- a/core/src/main/resources/hudson/model/Messages_fr.properties
+++ b/core/src/main/resources/hudson/model/Messages_fr.properties
@@ -26,9 +26,7 @@ AbstractBuild.KeptBecause=conserv\u00e9 \u00e0 cause de {0}
AbstractProject.NewBuildForWorkspace=Demande d''un nouveau build afin d''avoir un r\u00e9pertoire de travail
AbstractProject.Pronoun=Projet
AbstractProject.Aborted=Annul\u00e9
-AbstractProject.BuildInProgress=Le build #{0} est d\u00e9j\u00e0 en cours {1}
AbstractProject.Disabled=Build d\u00e9sactiv\u00e9
-AbstractProject.ETA=\ (fin pr\u00e9vue \u00e0: {0})
AbstractProject.NoSCM=Pas d''outil de gestion de version
AbstractProject.NoWorkspace=Pas r\u00e9pertoire de travail disponible, donc impossible de r\u00e9cup\u00e9rer les mises \u00e0 jour.
AbstractProject.PollingABorted=Scrutation de l''outil de gestion de version annul\u00e9e
@@ -193,5 +191,4 @@ Cause.RemoteCause.ShortDescription=D\u00e9marr\u00e9 \u00e0 distance par {0}
MyViewsProperty.DisplayName=Mes vues
MyViewsProperty.GlobalAction.DisplayName=Mes vues
-AbstractProject.BuildNow=Lancer un build
ManageJenkinsAction.DisplayName=Administrer Jenkins
diff --git a/core/src/main/resources/hudson/model/Messages_hu.properties b/core/src/main/resources/hudson/model/Messages_hu.properties
index cbad071927..ed0c34be08 100644
--- a/core/src/main/resources/hudson/model/Messages_hu.properties
+++ b/core/src/main/resources/hudson/model/Messages_hu.properties
@@ -1,2 +1 @@
-AbstractProject.BuildNow=\u00C9p\u00EDt\u00E9s Most
ManageJenkinsAction.DisplayName=Jenkins Kezel\u00E9se
diff --git a/core/src/main/resources/hudson/model/Messages_it.properties b/core/src/main/resources/hudson/model/Messages_it.properties
index fd106bf53b..cb1fb51eca 100644
--- a/core/src/main/resources/hudson/model/Messages_it.properties
+++ b/core/src/main/resources/hudson/model/Messages_it.properties
@@ -33,12 +33,9 @@ AbstractProject.NewBuildForWorkspace=Scheduling a new build to get a workspace.
AbstractProject.AwaitingBuildForWorkspace=Awaiting build to get a workspace.
AbstractProject.Pronoun=Progetto
AbstractProject.Aborted=Interrotta
-AbstractProject.BuildInProgress=Build #{0} is already in progress{1}
-AbstractProject.BuildNow=Effettua build
AbstractProject.UpstreamBuildInProgress=Upstream project {0} is already building.
AbstractProject.DownstreamBuildInProgress=Downstream project {0} is already building.
AbstractProject.Disabled=Build disabled
-AbstractProject.ETA=\ (ETA:{0})
AbstractProject.NoBuilds=No existing build. Scheduling a new one.
AbstractProject.NoSCM=No SCM
AbstractProject.NoWorkspace=No workspace is available, so can''t check for updates.
diff --git a/core/src/main/resources/hudson/model/Messages_ja.properties b/core/src/main/resources/hudson/model/Messages_ja.properties
index 6d31b46cf5..e689c3945c 100644
--- a/core/src/main/resources/hudson/model/Messages_ja.properties
+++ b/core/src/main/resources/hudson/model/Messages_ja.properties
@@ -34,13 +34,9 @@ AbstractProject.NewBuildForWorkspace=\u65b0\u898f\u306e\u30d3\u30eb\u30c9\u3092\
AbstractProject.AwaitingBuildForWorkspace=\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u304c\u7528\u610f\u3067\u304d\u308b\u307e\u3067\u30d3\u30eb\u30c9\u3092\u4fdd\u7559\u3057\u307e\u3059\u3002
AbstractProject.Pronoun=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8
AbstractProject.Aborted=\u4e2d\u6b62
-AbstractProject.BuildInProgress=\u30d3\u30eb\u30c9 #{0} \u306f\u65e2\u306b\u5b9f\u884c\u4e2d\u3067\u3059\u3002{1}
-AbstractProject.BuildNow=\u30d3\u30eb\u30c9\u5b9f\u884c
-AbstractProject.build_with_parameters=\u30d1\u30e9\u30e1\u30fc\u30bf\u4ed8\u304d\u30d3\u30eb\u30c9
AbstractProject.UpstreamBuildInProgress=\u4e0a\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 {0} \u306f\u3059\u3067\u306b\u30d3\u30eb\u30c9\u4e2d\u3067\u3059\u3002
AbstractProject.DownstreamBuildInProgress=\u4e0b\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 {0} \u304c\u307e\u3060\u30d3\u30eb\u30c9\u4e2d\u3067\u3059\u3002
AbstractProject.Disabled=\u30d3\u30eb\u30c9\u306f\u7121\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002
-AbstractProject.ETA=\ (\u4e88\u5b9a\u6642\u9593:{0})
AbstractProject.NoBuilds=\u30d3\u30eb\u30c9\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u65b0\u3057\u3044\u30d3\u30eb\u30c9\u3092\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3057\u307e\u3059\u3002
AbstractProject.NoSCM=SCM\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
AbstractProject.NoWorkspace=\u5229\u7528\u53ef\u80fd\u306a\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u304c\u306a\u3044\u306e\u3067\u3001\u66f4\u65b0\u3092\u30c1\u30a7\u30c3\u30af\u3067\u304d\u307e\u305b\u3093\u3002
diff --git a/core/src/main/resources/hudson/model/Messages_nl.properties b/core/src/main/resources/hudson/model/Messages_nl.properties
index 88b53d8f21..b00c75ebbf 100644
--- a/core/src/main/resources/hudson/model/Messages_nl.properties
+++ b/core/src/main/resources/hudson/model/Messages_nl.properties
@@ -26,9 +26,7 @@ AbstractBuild.KeptBecause=Weerhouden omwille van {0}
AbstractProject.NewBuildForWorkspace=Om een werkplaats te krijgen wordt een nieuwe bouwpoging gepland.
AbstractProject.Pronoun=Project
AbstractProject.Aborted=Afgebroken
-AbstractProject.BuildInProgress=Bouwpoging #{0} is reeds actief {1}
AbstractProject.Disabled=Bouwen gedeactiveerd
-AbstractProject.ETA= (einde voorzien op:{0})
AbstractProject.NoSCM=Geen versiebeheersysteem beschikbaar
AbstractProject.NoWorkspace=Er is geen werkplaats beschikbaar. Ophalen van wijzigingen is dus onmogelijk.
AbstractProject.PollingABorted=Contact met versiebeheersysteem werd afgebroken.
@@ -102,5 +100,4 @@ Permalink.LastBuild=Laatste bouwpoging
Permalink.LastStableBuild=Laatste stabiele bouwpoging
Permalink.LastSuccessfulBuild=Laatste succesvolle bouwpoging
Permalink.LastFailedBuild=Laatst gefaalde bouwpoging
-AbstractProject.BuildNow=Start nu een bouwpoging
ManageJenkinsAction.DisplayName=Beheer Jenkins
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 5162dbd6b9..194725d338 100644
--- a/core/src/main/resources/hudson/model/Messages_pt_BR.properties
+++ b/core/src/main/resources/hudson/model/Messages_pt_BR.properties
@@ -25,9 +25,7 @@ AbstractBuild.KeptBecause=mantido por causa de {0}
AbstractProject.Pronoun=Projeto
AbstractProject.Aborted=Abortado
-AbstractProject.BuildInProgress=A builds #{0} j\u00e1 est\u00e1 em progresso{1}
AbstractProject.Disabled=builds desabilitada
-AbstractProject.ETA=\ (ETA:{0})
AbstractProject.NoSCM=Nenhum SCM
AbstractProject.NoWorkspace=Nenhum workspace est\u00e1 dispon\u00edvel, assim n\u00e3o pode checar por atualiza\u00e7\u00f5es.
AbstractProject.PollingABorted=Pesquisa SCM abortada
@@ -382,7 +380,6 @@ Label.GroupOf=Grupo de {0}
Queue.AllNodesOffline=Todos os rotulos ''{0}'' est\u00e3o offline.
# Busy executors
LoadStatistics.Legends.BusyExecutors=Executores ocupados.
-AbstractProject.BuildNow=Construir agora
ManageJenkinsAction.DisplayName=Gerenciar Jenkins
# Workspace of {0}
AbstractProject.WorkspaceTitle=Workspace de {0}
@@ -502,12 +499,9 @@ Jenkins.CheckDisplayName.NameNotUniqueWarning=O nome de exibi\u00e7\u00e3o "{0}"
AbstractProject.CustomWorkspaceEmpty=O workspace customizado est\u00e1 vazio.
# Wait for a node to become online.
CLI.wait-node-online.shortDescription=Aguarda por um n\u00f3 que se torne online
-# Slaves in label: {2}
-AbstractProject.LabelLink=Slaves em label: {2}
# Artifacts of {0} {1}
Run.ArtifactsBrowserTitle=Artefatos de {0} {1}
# Build with Parameters
-AbstractProject.build_with_parameters=Construir com par\u00e2metros
# Still unstable
ResultTrend.StillUnstable=Ainda inst\u00e1vel
# Running as {0}
diff --git a/core/src/main/resources/hudson/model/Messages_ru.properties b/core/src/main/resources/hudson/model/Messages_ru.properties
index c0be7aa273..ee5b0d00f5 100644
--- a/core/src/main/resources/hudson/model/Messages_ru.properties
+++ b/core/src/main/resources/hudson/model/Messages_ru.properties
@@ -25,9 +25,7 @@ AbstractBuild.KeptBecause=\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e
AbstractProject.Pronoun=\u041f\u0440\u043e\u0435\u043a\u0442
AbstractProject.Aborted=\u041f\u0440\u0435\u0440\u0432\u0430\u043d\u043e
-AbstractProject.BuildInProgress=\u0421\u0431\u043e\u0440\u043a\u0430 #{0} \u0443\u0436\u0435 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 {1}
AbstractProject.Disabled=\u0421\u0431\u043e\u0440\u043a\u0430 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430
-AbstractProject.ETA=\ (\u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c:{0})
AbstractProject.NoSCM=\u041d\u0435\u0442 \u0421\u0438\u0441\u0442\u0435\u043c\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0439
AbstractProject.NoWorkspace=\u0421\u0431\u043e\u0440\u043e\u0447\u043d\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043d\u0435\u0442, \u043d\u0435 \u043c\u043e\u0433\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f.
AbstractProject.PollingABorted=\u041e\u043f\u0440\u043e\u0441 SCM \u043f\u0440\u0435\u0440\u0432\u0430\u043d
@@ -102,5 +100,4 @@ Permalink.LastBuild=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u044
Permalink.LastStableBuild=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430
Permalink.LastSuccessfulBuild=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430
Permalink.LastFailedBuild=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0448\u0430\u044f\u0441\u044f \u0441\u0431\u043e\u0440\u043a\u0430
-AbstractProject.BuildNow=\u0421\u043E\u0431\u0440\u0430\u0442\u044C \u0441\u0435\u0439\u0447\u0430\u0441
ManageJenkinsAction.DisplayName=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Jenkins
diff --git a/core/src/main/resources/hudson/model/Messages_sl.properties b/core/src/main/resources/hudson/model/Messages_sl.properties
index a9fc958501..e69de29bb2 100644
--- a/core/src/main/resources/hudson/model/Messages_sl.properties
+++ b/core/src/main/resources/hudson/model/Messages_sl.properties
@@ -1 +0,0 @@
-AbstractProject.BuildNow=Prevedi takoj
diff --git a/core/src/main/resources/hudson/model/Messages_sv_SE.properties b/core/src/main/resources/hudson/model/Messages_sv_SE.properties
index 7c0ec4d60a..763f29cdd2 100644
--- a/core/src/main/resources/hudson/model/Messages_sv_SE.properties
+++ b/core/src/main/resources/hudson/model/Messages_sv_SE.properties
@@ -1,5 +1,4 @@
AbstractProject.Pronoun=Projekt
-AbstractProject.BuildNow=Starta bygge nu
Job.Pronoun=Projekt
diff --git a/core/src/main/resources/hudson/model/Messages_tr.properties b/core/src/main/resources/hudson/model/Messages_tr.properties
index 3ea32148ca..ccfc340cd4 100644
--- a/core/src/main/resources/hudson/model/Messages_tr.properties
+++ b/core/src/main/resources/hudson/model/Messages_tr.properties
@@ -26,9 +26,7 @@ AbstractBuild.KeptBecause={0} y\u00fcz\u00fcnden tutulmu\u015f
AbstractProject.NewBuildForWorkspace=\u00c7al\u0131\u015fma alan\u0131 olu\u015fturmak i\u00e7in bir yap\u0131land\u0131rma planlan\u0131yor
AbstractProject.Pronoun=Proje
AbstractProject.Aborted=Durduruldu
-AbstractProject.BuildInProgress=Yap\u0131land\u0131rma #{0} zaten i\u015flemde {1}
AbstractProject.Disabled=Yap\u0131land\u0131rma devre d\u0131\u015f\u0131 b\u0131rak\u0131ld\u0131
-AbstractProject.ETA=\ (ETA:{0})
AbstractProject.NoSCM=SCM yok
AbstractProject.NoWorkspace=Herhangi bir \u00e7al\u0131\u015fma alan\u0131 bulunmad\u0131\u011f\u0131ndan g\u00fcncellemeler kontrol edilemiyor.
AbstractProject.PollingABorted=SCM kontrol\u00fc durduruldu
@@ -103,5 +101,4 @@ Permalink.LastBuild=Son yap\u0131land\u0131rma
Permalink.LastStableBuild=Son stabil yap\u0131land\u0131rma
Permalink.LastSuccessfulBuild=Son ba\u015far\u0131l\u0131 yap\u0131land\u0131rma
Permalink.LastFailedBuild=Son ba\u015far\u0131s\u0131z yap\u0131land\u0131rma
-AbstractProject.BuildNow=\u015eimdi Yap\u0131land\u0131r
ManageJenkinsAction.DisplayName=Jenkins''\u0131 Y\u00f6net
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 d89016d3d2..c9945468dd 100644
--- a/core/src/main/resources/hudson/model/Messages_zh_CN.properties
+++ b/core/src/main/resources/hudson/model/Messages_zh_CN.properties
@@ -29,10 +29,8 @@ AbstractItem.NoSuchJobExists=No such job ''{0}'' exists. Perhaps you meant ''{1}
AbstractProject.NewBuildForWorkspace=Scheduling a new build to get a workspace.
AbstractProject.Pronoun=Project
AbstractProject.Aborted=Aborted
-AbstractProject.BuildInProgress=Build #{0} is already in progress{1}
AbstractProject.UpstreamBuildInProgress=Upstream project {0} is already building.
AbstractProject.Disabled=Build disabled
-AbstractProject.ETA=\ (ETA:{0})
AbstractProject.NoBuilds=No existing build. Scheduling a new one.
AbstractProject.NoSCM=No SCM
AbstractProject.NoWorkspace=No workspace is available, so can''t check for updates.
@@ -270,5 +268,4 @@ 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.
-AbstractProject.BuildNow=\u7acb\u5373\u6784\u5efa
ManageJenkinsAction.DisplayName=\u7cfb\u7edf\u7ba1\u7406
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 77437b859d..7acb779f2d 100644
--- a/core/src/main/resources/hudson/model/Messages_zh_TW.properties
+++ b/core/src/main/resources/hudson/model/Messages_zh_TW.properties
@@ -34,12 +34,9 @@ AbstractProject.NewBuildForWorkspace=\u6311\u500b\u6642\u9593\u5efa\u7f6e\uff0c\
AbstractProject.AwaitingBuildForWorkspace=\u7b49\u5019\u5efa\u7f6e\u7522\u51fa\u5de5\u4f5c\u5340\u3002
AbstractProject.Pronoun=\u5c08\u6848
AbstractProject.Aborted=\u4e2d\u65b7
-AbstractProject.BuildInProgress=\u5efa\u7f6e #{0} \u57f7\u884c\u4e2d{1}
-AbstractProject.BuildNow=\u99ac\u4e0a\u5efa\u7f6e
AbstractProject.UpstreamBuildInProgress=\u4e0a\u6e38\u5c08\u6848 {0} \u5efa\u7f6e\u4e2d\u3002
AbstractProject.DownstreamBuildInProgress=\u4e0b\u6e38\u5c08\u6848 {0} \u5efa\u7f6e\u4e2d\u3002
AbstractProject.Disabled=\u5efa\u7f6e\u505c\u7528
-AbstractProject.ETA=\ (\u9810\u4f30\u6642\u9593:{0})
AbstractProject.NoBuilds=\u6c92\u6709\u5efa\u7f6e\u8a18\u9304\u3002\u99ac\u4e0a\u5efa\u7f6e\u4e00\u6b21\u5427\u3002
AbstractProject.NoSCM=\u7121 SCM
AbstractProject.NoWorkspace=\u6c92\u6709\u5de5\u4f5c\u5340\uff0c\u7121\u6cd5\u6aa2\u67e5\u66f4\u65b0\u3002
diff --git a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/column.jelly b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/column.jelly
index c71982967e..81a19eb0a9 100644
--- a/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/column.jelly
+++ b/core/src/main/resources/hudson/node_monitors/DiskSpaceMonitor/column.jelly
@@ -29,7 +29,7 @@ THE SOFTWARE.
N/A |
- |
+ |
-
\ No newline at end of file
+
diff --git a/core/src/main/resources/hudson/node_monitors/SwapSpaceMonitor/column.jelly b/core/src/main/resources/hudson/node_monitors/SwapSpaceMonitor/column.jelly
index 5a817a5305..35fa757e79 100644
--- a/core/src/main/resources/hudson/node_monitors/SwapSpaceMonitor/column.jelly
+++ b/core/src/main/resources/hudson/node_monitors/SwapSpaceMonitor/column.jelly
@@ -32,4 +32,4 @@ THE SOFTWARE.
|
-
\ No newline at end of file
+
diff --git a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/column.jelly b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/column.jelly
index ac42d83e35..5c1a410d1b 100644
--- a/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/column.jelly
+++ b/core/src/main/resources/hudson/node_monitors/TemporarySpaceMonitor/column.jelly
@@ -29,7 +29,7 @@ THE SOFTWARE.
N/A |
- |
+ |
-
\ No newline at end of file
+
diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo.jelly b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo.jelly
index f44b0a7269..f9b93b6e8c 100644
--- a/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo.jelly
+++ b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo.jelly
@@ -44,7 +44,7 @@ THE SOFTWARE.
-
+
${it.oSDescription} slave, version ${it.slaveVersion}
@@ -59,4 +59,4 @@ THE SOFTWARE.
-
\ No newline at end of file
+
diff --git a/core/src/main/resources/hudson/tools/InstallSourceProperty/help.html b/core/src/main/resources/hudson/tools/InstallSourceProperty/help.html
index dcf41ecf37..25ecfe6d61 100644
--- a/core/src/main/resources/hudson/tools/InstallSourceProperty/help.html
+++ b/core/src/main/resources/hudson/tools/InstallSourceProperty/help.html
@@ -1,6 +1,5 @@
- Choose this option to let Jenkins install this tool for you on demand,
- to the location you configured above.
+ Choose this option to let Jenkins install this tool for you on demand.
If you check this option, you'll then be asked to configure a series
diff --git a/core/src/main/resources/jenkins/model/CauseOfInterruption/ExceptionInterruption/summary.groovy b/core/src/main/resources/jenkins/model/CauseOfInterruption/ExceptionInterruption/summary.groovy
deleted file mode 100644
index bcc6ce1492..0000000000
--- a/core/src/main/resources/jenkins/model/CauseOfInterruption/ExceptionInterruption/summary.groovy
+++ /dev/null
@@ -1,5 +0,0 @@
-package jenkins.model.CauseOfInterruption.ExceptionInterruption
-
-import hudson.util.FormValidation;
-
-raw(FormValidation.error(my.cause, my.cause.message).renderHtml());
diff --git a/core/src/main/resources/jenkins/model/Messages.properties b/core/src/main/resources/jenkins/model/Messages.properties
index 98c360e524..75452a53e7 100644
--- a/core/src/main/resources/jenkins/model/Messages.properties
+++ b/core/src/main/resources/jenkins/model/Messages.properties
@@ -66,3 +66,7 @@ Mailer.Localhost.Error=Please set a valid host name, instead of localhost
PatternProjectNamingStrategy.DisplayName=Pattern
PatternProjectNamingStrategy.NamePatternRequired=Name Pattern is required
PatternProjectNamingStrategy.NamePatternInvalidSyntax=regular expression's syntax is invalid.
+ParameterizedJobMixIn.build_with_parameters=Build with Parameters
+ParameterizedJobMixIn.build_now=Build Now
+BlockedBecauseOfBuildInProgress.shortDescription=Build #{0} is already in progress{1}
+BlockedBecauseOfBuildInProgress.ETA=\ (ETA:{0})
diff --git a/core/src/main/resources/jenkins/model/Messages_ca.properties b/core/src/main/resources/jenkins/model/Messages_ca.properties
new file mode 100644
index 0000000000..a5ded4670c
--- /dev/null
+++ b/core/src/main/resources/jenkins/model/Messages_ca.properties
@@ -0,0 +1 @@
+ParameterizedJobMixIn.build_now=Construir Ara
diff --git a/core/src/main/resources/jenkins/model/Messages_da.properties b/core/src/main/resources/jenkins/model/Messages_da.properties
index c355612da1..cabc921cf8 100644
--- a/core/src/main/resources/jenkins/model/Messages_da.properties
+++ b/core/src/main/resources/jenkins/model/Messages_da.properties
@@ -52,3 +52,6 @@ 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
+ParameterizedJobMixIn.build_now=Byg nu
+BlockedBecauseOfBuildInProgress.shortDescription=Byg #{0} er allerede i gang {1}
+BlockedBecauseOfBuildInProgress.ETA=(ETA:{0})
diff --git a/core/src/main/resources/jenkins/model/Messages_de.properties b/core/src/main/resources/jenkins/model/Messages_de.properties
index dc2b7ce547..1028a7dffb 100644
--- a/core/src/main/resources/jenkins/model/Messages_de.properties
+++ b/core/src/main/resources/jenkins/model/Messages_de.properties
@@ -61,3 +61,7 @@ Mailer.Localhost.Error=Bitte verwenden Sie einen konkreten Hostnamen anstelle vo
PatternProjectNamingStrategy.DisplayName=Muster
PatternProjectNamingStrategy.NamePatternRequired=Der Regul\u00e4re Ausdruck darf nicht leer sein.
PatternProjectNamingStrategy.NamePatternInvalidSyntax=Der Regul\u00e4re Ausdruck ist ung\u00fcltig.
+ParameterizedJobMixIn.build_with_parameters=Bauen mit Parametern
+ParameterizedJobMixIn.build_now=Jetzt bauen
+BlockedBecauseOfBuildInProgress.shortDescription=Build #{0} ist bereits in Arbeit{1}
+BlockedBecauseOfBuildInProgress.ETA=\ (ETA:{0})
diff --git a/core/src/main/resources/jenkins/model/Messages_es.properties b/core/src/main/resources/jenkins/model/Messages_es.properties
index 4b4c61a764..03517c0087 100644
--- a/core/src/main/resources/jenkins/model/Messages_es.properties
+++ b/core/src/main/resources/jenkins/model/Messages_es.properties
@@ -62,3 +62,6 @@ PatternProjectNamingStrategy.NamePatternInvalidSyntax=La sintaxis de la expresi
Mailer.Address.Not.Configured=Dirección no configurada todavía
Mailer.Localhost.Error=Escriba un nombre de servidor correcto en lugar de "localhost"
+ParameterizedJobMixIn.build_now=Construir ahora
+BlockedBecauseOfBuildInProgress.shortDescription=La ejecuci\u00f3n #{0} ya est\u00e1 en progreso {1}
+BlockedBecauseOfBuildInProgress.ETA= (ETA:{0})
diff --git a/core/src/main/resources/jenkins/model/Messages_fi.properties b/core/src/main/resources/jenkins/model/Messages_fi.properties
new file mode 100644
index 0000000000..ad6283cffe
--- /dev/null
+++ b/core/src/main/resources/jenkins/model/Messages_fi.properties
@@ -0,0 +1 @@
+ParameterizedJobMixIn.build_now=K\u00E4\u00E4nn\u00E4 nyt
diff --git a/core/src/main/resources/jenkins/model/Messages_fr.properties b/core/src/main/resources/jenkins/model/Messages_fr.properties
index ee643ff342..2a179edf07 100644
--- a/core/src/main/resources/jenkins/model/Messages_fr.properties
+++ b/core/src/main/resources/jenkins/model/Messages_fr.properties
@@ -42,3 +42,6 @@ Hudson.ReadPermission.Description=\
— retirez ce droit \u00e0 l''utilisateur anonymous, puis \
ajoutez le pseudo-utilisateur "authenticated" et accordez-lui le droit en lecture.
+ParameterizedJobMixIn.build_now=Lancer un build
+BlockedBecauseOfBuildInProgress.shortDescription=Le build #{0} est d\u00e9j\u00e0 en cours {1}
+BlockedBecauseOfBuildInProgress.ETA=\ (fin pr\u00e9vue \u00e0: {0})
diff --git a/core/src/main/resources/jenkins/model/Messages_hu.properties b/core/src/main/resources/jenkins/model/Messages_hu.properties
new file mode 100644
index 0000000000..d75db0b3e3
--- /dev/null
+++ b/core/src/main/resources/jenkins/model/Messages_hu.properties
@@ -0,0 +1 @@
+ParameterizedJobMixIn.build_now=\u00C9p\u00EDt\u00E9s Most
diff --git a/core/src/main/resources/jenkins/model/Messages_it.properties b/core/src/main/resources/jenkins/model/Messages_it.properties
new file mode 100644
index 0000000000..bc659061b2
--- /dev/null
+++ b/core/src/main/resources/jenkins/model/Messages_it.properties
@@ -0,0 +1,3 @@
+ParameterizedJobMixIn.build_now=Effettua build
+BlockedBecauseOfBuildInProgress.shortDescription=Build #{0} is already in progress{1}
+BlockedBecauseOfBuildInProgress.ETA=\ (ETA:{0})
diff --git a/core/src/main/resources/jenkins/model/Messages_ja.properties b/core/src/main/resources/jenkins/model/Messages_ja.properties
index 115d02941b..460d284977 100644
--- a/core/src/main/resources/jenkins/model/Messages_ja.properties
+++ b/core/src/main/resources/jenkins/model/Messages_ja.properties
@@ -62,3 +62,7 @@ PatternProjectNamingStrategy.NamePatternInvalidSyntax=\u6b63\u898f\u8868\u73fe\u
Mailer.Address.Not.Configured=\u307e\u3060\u30a2\u30c9\u30ec\u30b9\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002
Mailer.Localhost.Error=localhost\u306e\u4ee3\u308f\u308a\u306b\u59a5\u5f53\u306a\u30db\u30b9\u30c8\u540d\u3092\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002
+ParameterizedJobMixIn.build_with_parameters=\u30d1\u30e9\u30e1\u30fc\u30bf\u4ed8\u304d\u30d3\u30eb\u30c9
+ParameterizedJobMixIn.build_now=\u30d3\u30eb\u30c9\u5b9f\u884c
+BlockedBecauseOfBuildInProgress.shortDescription=\u30d3\u30eb\u30c9 #{0} \u306f\u65e2\u306b\u5b9f\u884c\u4e2d\u3067\u3059\u3002{1}
+BlockedBecauseOfBuildInProgress.ETA=\ (\u4e88\u5b9a\u6642\u9593:{0})
diff --git a/core/src/main/resources/jenkins/model/Messages_nl.properties b/core/src/main/resources/jenkins/model/Messages_nl.properties
index 6e0492c762..6c17f7168d 100644
--- a/core/src/main/resources/jenkins/model/Messages_nl.properties
+++ b/core/src/main/resources/jenkins/model/Messages_nl.properties
@@ -30,3 +30,6 @@ Hudson.NoJavaInPath=java is niet beschikbaar op uw pad. Misschien moet je een /.+
# cobertura also writes out annotated sources to a dir under the job:
allow create,mkdirs,read,stat,write /jobs/.+/cobertura.*
-# all the other accesses that aren't specified here will be left upto other rules in this directory.
+# all the other accesses that aren't specified here will be left up to other rules in this directory.
# if no rules in those other files matches, then the access will be rejected.
diff --git a/core/src/main/resources/lib/form/dropdownDescriptorSelector.jelly b/core/src/main/resources/lib/form/dropdownDescriptorSelector.jelly
index aad0a87e51..7b0ca4df26 100644
--- a/core/src/main/resources/lib/form/dropdownDescriptorSelector.jelly
+++ b/core/src/main/resources/lib/form/dropdownDescriptorSelector.jelly
@@ -57,7 +57,7 @@ THE SOFTWARE.
lazy="descriptor">
-
+
diff --git a/core/src/main/resources/lib/hudson/scriptConsole.properties b/core/src/main/resources/lib/hudson/scriptConsole.properties
index 518475dc89..69c972a938 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole.properties
@@ -21,7 +21,7 @@
# THE SOFTWARE.
description=\
- Type in an arbitrary Groovy script and \
+ Type in an arbitrary Groovy script and \
execute it on the server. Useful for trouble-shooting and diagnostics. \
Use the \u2018println\u2019 command to see the output (if you use System.out, \
it will go to the server\u2019s stdout, which is harder to see.) Example:
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_da.properties b/core/src/main/resources/lib/hudson/scriptConsole_da.properties
index 4593448d00..cf1afc4cbb 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_da.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_da.properties
@@ -23,7 +23,7 @@
Result=Resultat
Run=K\u00f8r
Script\ Console=Skriptkonsol
-description=Indtast et Groovyskript og \
+description=Indtast et Groovyskript og \
k\u00f8r det p\u00e5 serveren. Nyttigt til fejlfinding og diagnostik. \
Benyt ''println'' kommandoen for at se output (hvis du bruger System.out, \
vil output g\u00e5 til serverens stdout, hvilket kan v\u00e6re sv\u00e6rere at finde.) Eksempel:
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_de.properties b/core/src/main/resources/lib/hudson/scriptConsole_de.properties
index 488a8941a9..df68cd002f 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_de.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_de.properties
@@ -23,7 +23,7 @@
Script\ Console=Skript-Konsole
Result=Ergebnis
Run=Ausführen
-description=Geben Sie ein beliebiges Groovy-Skript \
+description=Geben Sie ein beliebiges Groovy-Skript \
ein und führen Sie dieses auf dem Server aus. Dies ist nützlich bei der Fehlersuche und zur Diagnostik. \
Verwenden Sie das ''println''-Kommando, um Ausgaben sichtbar zu machen (wenn Sie System.out \
verwenden, gehen die Ausgaben auf die Standardausgabe (STDOUT) des Servers, die schwieriger \
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_es.properties b/core/src/main/resources/lib/hudson/scriptConsole_es.properties
index 9531839f14..d7df2acb0d 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_es.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_es.properties
@@ -21,7 +21,7 @@
# THE SOFTWARE.
description=\
- Escribe un ''script'' Groovy script y \
+ Escribe un ''script'' Groovy script y \
ejecutaló en el servidor. Es útil para depurar e investigar problemas. \
Usa ''println'' para ver la salida (si usas System.out, se escribirá \
en la salida ''stdout'' del servidor, lo que es más difícil de visualizar). Ejemplo:
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_fr.properties b/core/src/main/resources/lib/hudson/scriptConsole_fr.properties
index ea256983eb..6f17fa4ae4 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_fr.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_fr.properties
@@ -23,6 +23,6 @@
Script\ Console=Console de script
Result=Résultat
Run=Exécuter
-description=Vous pouvez saisir ici un script Groovy quelconque pour l\u2019ex\u00E9cuter sur le serveur.
Utile pour diagnostiquer et r\u00E9soudre des probl\u00E8mes.
Utilisez la commande "println" pour voir la sortie (si vous utilisez System.out, cela ira vers la sortie standard du serveur, qui est plus complexe \u00E0 retrouver.)
Par exemple :
+description=Vous pouvez saisir ici un script Groovy quelconque pour l\u2019ex\u00E9cuter sur le serveur.
Utile pour diagnostiquer et r\u00E9soudre des probl\u00E8mes.
Utilisez la commande "println" pour voir la sortie (si vous utilisez System.out, cela ira vers la sortie standard du serveur, qui est plus complexe \u00E0 retrouver.)
Par exemple :
description2=Toutes les classes de tous les plugins sont visibles. jenkins.*, jenkins.model.*, hudson.*, et hudson.model.* sont pr\u00E9-import\u00E9es.
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_ja.properties b/core/src/main/resources/lib/hudson/scriptConsole_ja.properties
index da54325180..1360878239 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_ja.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_ja.properties
@@ -24,7 +24,7 @@ Script\ Console=\u30b9\u30af\u30ea\u30d7\u30c8\u30b3\u30f3\u30bd\u30fc\u30eb
Run=\u5b9f\u884c
Result=\u7d50\u679c
description= \
- \u4efb\u610f\u306eGroovy\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u5165\u529b\u3057\u3066\u3001 \
+ \u4efb\u610f\u306eGroovy\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u5165\u529b\u3057\u3066\u3001 \
\u30b5\u30fc\u30d0\u30fc\u4e0a\u3067\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u3084\u8a3a\u65ad\u306b\u4fbf\u5229\u3067\u3059\u3002 \
\u51fa\u529b\u3092\u898b\u308b\u306b\u306f''println''\u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u7528\u3057\u307e\u3059 \
(System.out\u3092\u4f7f\u7528\u3059\u308b\u3068\u30b5\u30fc\u30d0\u30fc\u306e\u6a19\u6e96\u51fa\u529b\u306b\u51fa\u529b\u3055\u308c\u307e\u3059\u304c\u3001\u898b\u306b\u304f\u3044\u3067\u3059\uff09\u3002\u4f8b:
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_ko.properties b/core/src/main/resources/lib/hudson/scriptConsole_ko.properties
index 6e8c7a8bf9..523c9f7126 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_ko.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_ko.properties
@@ -23,7 +23,7 @@
Result=\uACB0\uACFC
Run=\uC2E4\uD589
Script\ Console=\uC2A4\uD06C\uB9BD\uD2B8 \uCF58\uC194
-description=\uC784\uC758\uC758 Groovy\uC2A4\uD06C\uB9BD\uD2B8\uB97C \uC785\uB825\uD558\uC5EC \uC11C\uBC84\uC5D0\uC11C \uC2E4\uD589\uD569\uB2C8\uB2E4.
\uBB38\uC81C\uD574\uACB0\uACFC \uC9C4\uB2E8\uC2DC\uC5D0 \uC720\uC6A9\uD569\uB2C8\uB2E4. \uCD9C\uB825\uBB3C\uC744 \uBCF4\uB824\uBA74 ''println'' \uBA85\uB839\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.
(System.out\uB97C \uC0AC\uC6A9\uD558\uBA74 \uC11C\uBC84\uC758 \uD45C\uC900\uCD9C\uB825\uC73C\uB85C \uBCF4\uB0B4\uC9C0\uACE0, \uAC00\uB3C5\uC131\uC774 \uB5A8\uC5B4\uC9D1\uB2C8\uB2E4.)
+description=\uC784\uC758\uC758 Groovy\uC2A4\uD06C\uB9BD\uD2B8\uB97C \uC785\uB825\uD558\uC5EC \uC11C\uBC84\uC5D0\uC11C \uC2E4\uD589\uD569\uB2C8\uB2E4.
\uBB38\uC81C\uD574\uACB0\uACFC \uC9C4\uB2E8\uC2DC\uC5D0 \uC720\uC6A9\uD569\uB2C8\uB2E4. \uCD9C\uB825\uBB3C\uC744 \uBCF4\uB824\uBA74 ''println'' \uBA85\uB839\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.
(System.out\uB97C \uC0AC\uC6A9\uD558\uBA74 \uC11C\uBC84\uC758 \uD45C\uC900\uCD9C\uB825\uC73C\uB85C \uBCF4\uB0B4\uC9C0\uACE0, \uAC00\uB3C5\uC131\uC774 \uB5A8\uC5B4\uC9D1\uB2C8\uB2E4.)
\uC608\uC81C:
\uC608\uC81C:
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_nb_NO.properties b/core/src/main/resources/lib/hudson/scriptConsole_nb_NO.properties
index 524bfd281b..ef03bcb2ec 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_nb_NO.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_nb_NO.properties
@@ -22,7 +22,7 @@
Run=Kj\u00F8r
Script\ Console=Skript-konsoll
-description=Skriv inn et vilk\u00E5rlig Groovy script og kj\u00F8r det p\u00E5 serveren. Nyttig i forbindelse med feils\u00F8king og diagnostisering. Bruke "println"-kommandoen for \u00E5 se utdataene. (Hvis du bruker System.out havner det i serverens STDOUT, som er vanskeligere \u00E5 se.
+description=Skriv inn et vilk\u00E5rlig Groovy script og kj\u00F8r det p\u00E5 serveren. Nyttig i forbindelse med feils\u00F8king og diagnostisering. Bruke "println"-kommandoen for \u00E5 se utdataene. (Hvis du bruker System.out havner det i serverens STDOUT, som er vanskeligere \u00E5 se.
Eksempel:
println(hudson.model.Hudson.instance.pluginManager.plugins)
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_nl.properties b/core/src/main/resources/lib/hudson/scriptConsole_nl.properties
index 68b9130c6f..263f9a0fa1 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_nl.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_nl.properties
@@ -23,4 +23,4 @@
Script\ Console=Scriptconsole
Run=Voer uit
Result=Resultaat
-description=Geef een willekeurig Groovy script in en voer het uit op de server. Dit is nuttig voor troubleshooting en het stellen van diagnoses. Gebruik het "println"-commando om uitvoer te zien (wanneer je System.out gebruikt, gaat de uitvoer naar de stdout van de server, en deze is moeilijker te bekijken.) Bijvoorbeeld:
+description=Geef een willekeurig Groovy script in en voer het uit op de server. Dit is nuttig voor troubleshooting en het stellen van diagnoses. Gebruik het "println"-commando om uitvoer te zien (wanneer je System.out gebruikt, gaat de uitvoer naar de stdout van de server, en deze is moeilijker te bekijken.) Bijvoorbeeld:
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_pl.properties b/core/src/main/resources/lib/hudson/scriptConsole_pl.properties
index bb22871fb6..666edf81bf 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_pl.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_pl.properties
@@ -3,6 +3,6 @@
Result=Rezultat
Run=Wykonaj
Script\ Console=Konsola Skrypt\u00F3w
-description=Wpisz skrypt Groovy script i wykonaj go na serwerze. U\u017Cyteczne w przypadku problem\u00F3w i diagnostyki. U\u017Cyj komendy ''''println'''' aby zobaczy\u0107 wynik (je\u015Bli u\u017Cyjesz System.out, wynik b\u0119dzie trudniejszy do znalezienia). Przyk\u0142ad:
+description=Wpisz skrypt Groovy script i wykonaj go na serwerze. U\u017Cyteczne w przypadku problem\u00F3w i diagnostyki. U\u017Cyj komendy ''''println'''' aby zobaczy\u0107 wynik (je\u015Bli u\u017Cyjesz System.out, wynik b\u0119dzie trudniejszy do znalezienia). Przyk\u0142ad:
description2=Wszystkie klasy ze wszystkich dodatk\u00F3w s\u0105 widoczne. jenkins.*, jenkins.model.*, hudson.*, i hudson.model.* s\u0105 wst\u0119pnie zaimportowane.
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_pt_BR.properties b/core/src/main/resources/lib/hudson/scriptConsole_pt_BR.properties
index 04f4d0a53f..9013530e50 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_pt_BR.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_pt_BR.properties
@@ -23,11 +23,11 @@
Script\ Console=Console de script
Run=Executar
Result=Resultado
-# Type in an arbitrary Groovy script and \
+# Type in an arbitrary Groovy script and \
# execute it on the server. Useful for trouble-shooting and diagnostics. \
# Use the ''println'' command to see the output (if you use System.out, \
# it will go to the server''s stdout, which is harder to see.) Example:
-description=Digite um comando Groovy script qualquer e \
+description=Digite um comando Groovy script qualquer e \
execute-o no servidor. \u00DAtil para resolu\u00E7\u00E3o de problemas e diagn\u00F3sticos. \
Use o comando "println" para ver a sa\u00EDda (se voc\u00EA usa System.out tt>, \
ele ir\u00E1 para o log do servidor, que \u00E9 mais dif\u00EDcil de ver). Exemplo:
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_ru.properties b/core/src/main/resources/lib/hudson/scriptConsole_ru.properties
index 7149e33861..b0b68ceaf5 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_ru.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_ru.properties
@@ -23,5 +23,5 @@
Script\ Console=\u041a\u043e\u043d\u0441\u043e\u043b\u044c
Result=\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442
Run=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c
-description=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 Groovy \u0441\u043A\u0440\u0438\u043F\u0442 \u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u0435\u0433\u043E \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041F\u043E\u043B\u0435\u0437\u043D\u043E \u043F\u0440\u0438 \u0443\u0441\u0442\u0440\u0430\u043D\u0435\u043D\u0438\u0438 \u043D\u0435\u043F\u043E\u043B\u0430\u0434\u043E\u043A \u0438 \u0434\u0438\u0430\u0433\u043D\u043E\u0441\u0442\u0438\u043A\u0438. \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 "println" \u0434\u043B\u044F \u043F\u0435\u0447\u0430\u0442\u0438 \u0432 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u044B\u0439 \u0432\u044B\u0432\u043E\u0434 (\u0435\u0441\u043B\u0438 \u0432\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435\u0441\u044C System.out, \u0442\u043E \u0432\u044B\u0432\u043E\u0434 \u043F\u043E\u0439\u0434\u0451\u0442 \u0432 stdout \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0441\u043B\u043E\u0436\u043D\u0435\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044C). \u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440:
+description=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 Groovy \u0441\u043A\u0440\u0438\u043F\u0442 \u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u0435\u0433\u043E \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041F\u043E\u043B\u0435\u0437\u043D\u043E \u043F\u0440\u0438 \u0443\u0441\u0442\u0440\u0430\u043D\u0435\u043D\u0438\u0438 \u043D\u0435\u043F\u043E\u043B\u0430\u0434\u043E\u043A \u0438 \u0434\u0438\u0430\u0433\u043D\u043E\u0441\u0442\u0438\u043A\u0438. \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 "println" \u0434\u043B\u044F \u043F\u0435\u0447\u0430\u0442\u0438 \u0432 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u044B\u0439 \u0432\u044B\u0432\u043E\u0434 (\u0435\u0441\u043B\u0438 \u0432\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435\u0441\u044C System.out, \u0442\u043E \u0432\u044B\u0432\u043E\u0434 \u043F\u043E\u0439\u0434\u0451\u0442 \u0432 stdout \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0441\u043B\u043E\u0436\u043D\u0435\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044C). \u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440:
description2=\u0412\u0441\u0435 \u043A\u043B\u0430\u0441\u0441\u044B \u0438\u0437 \u0432\u0441\u0435\u0445 \u043F\u043B\u0430\u0433\u0438\u043D\u043E\u0432 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B. jenkins.*, jenkins.model.*, hudson.* \u0438 hudson.model.* \u0443\u0436\u0435 \u0438\u043C\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u044B \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E.
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_sv_SE.properties b/core/src/main/resources/lib/hudson/scriptConsole_sv_SE.properties
index 1710048f28..eb6893c691 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_sv_SE.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_sv_SE.properties
@@ -23,5 +23,5 @@
Result=Resultat
Run=K\u00F6r
Script\ Console=Skriptkonsoll
-description=Skriv in ett godtyckligt Groovy skript och k\u00F6r den p\u00E5 noden. Detta \u00E4r anv\u00E4ndbart vid fels\u00F6kning och diagnostik. Anv\u00E4nd''''println''''kommandot f\u00F6r att se resultatet (om du anv\u00E4nder System.out kommer det att g\u00E5 till serverns standard ut, som \u00E4r sv\u00E5rare att se.) Exempel:
+description=Skriv in ett godtyckligt Groovy skript och k\u00F6r den p\u00E5 noden. Detta \u00E4r anv\u00E4ndbart vid fels\u00F6kning och diagnostik. Anv\u00E4nd''''println''''kommandot f\u00F6r att se resultatet (om du anv\u00E4nder System.out kommer det att g\u00E5 till serverns standard ut, som \u00E4r sv\u00E5rare att se.) Exempel:
description2=Alla klasser fr\u00E5n pluginet \u00E4r synliga. jenkins.*, jenkins.model.*, hudson.*, and hudson.model.* are pre-imported.
diff --git a/core/src/main/resources/lib/hudson/scriptConsole_zh_TW.properties b/core/src/main/resources/lib/hudson/scriptConsole_zh_TW.properties
index 0a474875c7..6e968873db 100644
--- a/core/src/main/resources/lib/hudson/scriptConsole_zh_TW.properties
+++ b/core/src/main/resources/lib/hudson/scriptConsole_zh_TW.properties
@@ -23,7 +23,7 @@
Script\ Console=Script \u4e3b\u63a7\u53f0
description=\
- \u8f38\u5165\u4efb\u610f\u7684 Groovy Script\uff0c\u5728\u4f3a\u670d\u5668\u4e0a\u57f7\u884c\u3002\
+ \u8f38\u5165\u4efb\u610f\u7684 Groovy Script\uff0c\u5728\u4f3a\u670d\u5668\u4e0a\u57f7\u884c\u3002\
\u7591\u96e3\u6392\u89e3\u6216\u8a3a\u65b7\u6642\u5f88\u6709\u7528\u3002\u4f7f\u7528 "println" \u6307\u4ee4\u53ef\u4ee5\u770b\u5230\u8f38\u51fa\u7d50\u679c \
(\u5982\u679c\u60a8\u4f7f\u7528 System.out\uff0c\u5c07\u8f38\u51fa\u5230\u4f3a\u670d\u5668\u4e0a\u7684 stdout\uff0c\u6703\u6bd4\u8f03\u96e3\u770b\u5230)\u3002\u7bc4\u4f8b:
description2=\u6240\u6709\u5916\u639B\u7A0B\u5F0F\u7684 class \u90FD\u53EF\u4EE5\u4F7F\u7528\u3002\u5DF2\u9810\u5148 import \u4E86 jenkins.*, jenkins.model.*, hudson.* \u53CA hudson.model.* \u7B49 package\u3002
diff --git a/core/src/main/resources/lib/layout/layout.jelly b/core/src/main/resources/lib/layout/layout.jelly
index 7bbbbca502..9dc7317e9b 100644
--- a/core/src/main/resources/lib/layout/layout.jelly
+++ b/core/src/main/resources/lib/layout/layout.jelly
@@ -227,52 +227,45 @@ ${h.initPageVariables(context)}