mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-10-29 04:25:23 +00:00
Merge branch 'master' into printStackTrace-JDK-6507809
This commit is contained in:
commit
2abddbdfcc
3124 files changed
+75925
-26255
No files matched your search
@@ -25,6 +25,8 @@
|
||||
*/
|
||||
package hudson;
|
||||
|
||||
import hudson.model.Slave;
|
||||
import jenkins.util.SystemProperties;
|
||||
import hudson.cli.CLICommand;
|
||||
import hudson.console.ConsoleAnnotationDescriptor;
|
||||
import hudson.console.ConsoleAnnotatorFactory;
|
||||
@@ -74,7 +76,10 @@ import hudson.tasks.Publisher;
|
||||
import hudson.tasks.UserAvatarResolver;
|
||||
import hudson.util.Area;
|
||||
import hudson.util.FormValidation.CheckMethod;
|
||||
import hudson.util.HudsonIsLoading;
|
||||
import hudson.util.HudsonIsRestarting;
|
||||
import hudson.util.Iterators;
|
||||
import hudson.util.jna.GNUCLibrary;
|
||||
import hudson.util.Secret;
|
||||
import hudson.views.MyViewsTabBar;
|
||||
import hudson.views.ViewsTabBar;
|
||||
@@ -82,6 +87,7 @@ import hudson.widgets.RenderOnDemandClosure;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.management.LockInfo;
|
||||
@@ -126,7 +132,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import jenkins.model.GlobalConfiguration;
|
||||
import jenkins.model.GlobalConfigurationCategory;
|
||||
import jenkins.model.GlobalConfigurationCategory.Unclassified;
|
||||
import jenkins.model.Jenkins;
|
||||
import jenkins.model.ModelObjectWithChildren;
|
||||
import jenkins.model.ModelObjectWithContextMenu;
|
||||
@@ -149,14 +154,15 @@ import org.kohsuke.stapler.jelly.InternationalizedStringExpression.RawHtmlArgume
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import hudson.model.PasswordParameterDefinition;
|
||||
import hudson.util.RunList;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
import org.kohsuke.accmod.restrictions.DoNotUse;
|
||||
|
||||
/**
|
||||
* Utility functions used in views.
|
||||
@@ -208,20 +214,28 @@ public class Functions {
|
||||
|
||||
/**
|
||||
* During Jenkins start-up, before {@link InitMilestone#PLUGINS_STARTED} the extensions lists will be empty
|
||||
* and they are not guaranteed to be fully populated until after {@link InitMilestone#EXTENSIONS_AUGMENTED}.
|
||||
* and they are not guaranteed to be fully populated until after {@link InitMilestone#EXTENSIONS_AUGMENTED},
|
||||
* similarly, during termination after {@link Jenkins#isTerminating()} is set, it is no longer safe to access
|
||||
* the extensions lists.
|
||||
* If you attempt to access the extensions list from a UI thread while the extensions are being loaded you will
|
||||
* hit a big honking great monitor lock that will block until the effective extension list has been determined
|
||||
* (as if a plugin fails to start, all of the failed plugin's extensions and any dependent plugins' extensions
|
||||
* will have to be evicted from the list of extensions. In practical terms this only affects the
|
||||
* "Jenkins is loading" screen, but as that screen uses the generic layouts we provide this utility method
|
||||
* so that the generic layouts can avoid iterating extension lists while Jenkins is starting up.
|
||||
* If you attempt to access the extensions list from a UI thread while Jenkins is being shut down, the extensions
|
||||
* themselves may no longer be in a valid state and could attempt to revive themselves and block termination.
|
||||
* In actual terms the termination only affects those views required to render {@link HudsonIsRestarting}'s
|
||||
* {@code index.jelly} which is the same set as the {@link HudsonIsLoading} pages so it makes sense to
|
||||
* use both checks here.
|
||||
*
|
||||
* @return {@code true} if the extensions lists have been populated.
|
||||
* @since 1.607
|
||||
*/
|
||||
public static boolean isExtensionsAvailable() {
|
||||
final Jenkins jenkins = Jenkins.getInstance();
|
||||
return jenkins != null && jenkins.getInitLevel().compareTo(InitMilestone.EXTENSIONS_AUGMENTED) >= 0;
|
||||
final Jenkins jenkins = Jenkins.getInstanceOrNull();
|
||||
return jenkins != null && jenkins.getInitLevel().compareTo(InitMilestone.EXTENSIONS_AUGMENTED) >= 0
|
||||
&& !jenkins.isTerminating();
|
||||
}
|
||||
|
||||
public static void initPageVariables(JellyContext context) {
|
||||
@@ -461,6 +475,15 @@ public class Functions {
|
||||
public static boolean isWindows() {
|
||||
return File.pathSeparatorChar==';';
|
||||
}
|
||||
|
||||
public static boolean isGlibcSupported() {
|
||||
try {
|
||||
GNUCLibrary.LIBC.getpid();
|
||||
return true;
|
||||
} catch(Throwable t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<LogRecord> getLogRecords() {
|
||||
return Jenkins.logRecords;
|
||||
@@ -553,7 +576,7 @@ public class Functions {
|
||||
/**
|
||||
* Set to true if you need to use the debug version of YUI.
|
||||
*/
|
||||
public static boolean DEBUG_YUI = Boolean.getBoolean("debug.YUI");
|
||||
public static boolean DEBUG_YUI = SystemProperties.getBoolean("debug.YUI");
|
||||
|
||||
/**
|
||||
* Creates a sub map by using the given range (both ends inclusive).
|
||||
@@ -608,7 +631,7 @@ public class Functions {
|
||||
response.addCookie(c);
|
||||
}
|
||||
if (refresh) {
|
||||
response.addHeader("Refresh", System.getProperty("hudson.Functions.autoRefreshSeconds", "10"));
|
||||
response.addHeader("Refresh", SystemProperties.getString("hudson.Functions.autoRefreshSeconds", "10"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,7 +853,7 @@ public class Functions {
|
||||
*/
|
||||
public static String getFooterURL() {
|
||||
if(footerURL == null) {
|
||||
footerURL = System.getProperty("hudson.footerURL");
|
||||
footerURL = SystemProperties.getString("hudson.footerURL");
|
||||
if(StringUtils.isBlank(footerURL)) {
|
||||
footerURL = "http://jenkins-ci.org/";
|
||||
}
|
||||
@@ -843,6 +866,10 @@ public class Functions {
|
||||
return JobPropertyDescriptor.getPropertyDescriptors(clazz);
|
||||
}
|
||||
|
||||
public static List<JobPropertyDescriptor> getJobPropertyDescriptors(Job job) {
|
||||
return DescriptorVisibilityFilter.apply(job, JobPropertyDescriptor.getPropertyDescriptors(job.getClass()));
|
||||
}
|
||||
|
||||
public static List<Descriptor<BuildWrapper>> getBuildWrapperDescriptors(AbstractProject<?,?> project) {
|
||||
return BuildWrappers.getFor(project);
|
||||
}
|
||||
@@ -867,10 +894,24 @@ public class Functions {
|
||||
return SCM._for(project);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.12
|
||||
* @deprecated replaced by {@link Slave.SlaveDescriptor#computerLauncherDescriptors(Slave)}
|
||||
*/
|
||||
@Deprecated
|
||||
@Restricted(DoNotUse.class)
|
||||
@RestrictedSince("2.12")
|
||||
public static List<Descriptor<ComputerLauncher>> getComputerLauncherDescriptors() {
|
||||
return Jenkins.getInstance().<ComputerLauncher,Descriptor<ComputerLauncher>>getDescriptorList(ComputerLauncher.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.12
|
||||
* @deprecated replaced by {@link Slave.SlaveDescriptor#retentionStrategyDescriptors(Slave)}
|
||||
*/
|
||||
@Deprecated
|
||||
@Restricted(DoNotUse.class)
|
||||
@RestrictedSince("2.12")
|
||||
public static List<Descriptor<RetentionStrategy<?>>> getRetentionStrategyDescriptors() {
|
||||
return RetentionStrategy.all();
|
||||
}
|
||||
@@ -891,6 +932,13 @@ public class Functions {
|
||||
return MyViewsTabBar.all();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated replaced by {@link Slave.SlaveDescriptor#nodePropertyDescriptors(Slave)}
|
||||
* @since 2.12
|
||||
*/
|
||||
@Deprecated
|
||||
@Restricted(DoNotUse.class)
|
||||
@RestrictedSince("2.12")
|
||||
public static List<NodePropertyDescriptor> getNodePropertyDescriptors(Class<? extends Node> clazz) {
|
||||
List<NodePropertyDescriptor> result = new ArrayList<NodePropertyDescriptor>();
|
||||
Collection<NodePropertyDescriptor> list = (Collection) Jenkins.getInstance().getDescriptorList(NodeProperty.class);
|
||||
@@ -943,12 +991,8 @@ public class Functions {
|
||||
Descriptor d = c.getInstance();
|
||||
if (d.getGlobalConfigPage()==null) continue;
|
||||
|
||||
if (d instanceof GlobalConfiguration) {
|
||||
if (predicate.apply(((GlobalConfiguration)d).getCategory()))
|
||||
r.add(new Tag(c.ordinal(), d));
|
||||
} else {
|
||||
if (predicate.apply(GlobalConfigurationCategory.get(Unclassified.class)))
|
||||
r.add(new Tag(0, d));
|
||||
if (predicate.apply(d.getCategory())) {
|
||||
r.add(new Tag(c.ordinal(), d));
|
||||
}
|
||||
}
|
||||
Collections.sort(r);
|
||||
@@ -1387,7 +1431,7 @@ public class Functions {
|
||||
/**
|
||||
* If the value exists, return that value. Otherwise return the default value.
|
||||
* <p>
|
||||
* 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
|
||||
*/
|
||||
@@ -1399,10 +1443,15 @@ public class Functions {
|
||||
* Prints a stack trace from an exception into a readable form.
|
||||
* Unlike {@link Throwable#printStackTrace(PrintWriter)}, this implementation follows the suggestion of JDK-6507809
|
||||
* to produce a linear trace even when {@link Throwable#getCause} is used.
|
||||
* @param t any throwable
|
||||
* @return generally a multiline string ending in a (platform-specific) newline
|
||||
* @param t Input {@link Throwable}
|
||||
* @return If {@code t} is not null, generally a multiline string ending in a (platform-specific) newline;
|
||||
* otherwise, the method returns a default
|
||||
* "No exception details" string.
|
||||
*/
|
||||
public static @Nonnull String printThrowable(@Nonnull Throwable t) {
|
||||
public static @Nonnull String printThrowable(@CheckForNull Throwable t) {
|
||||
if (t == null) {
|
||||
return Messages.Functions_NoExceptionDetails();
|
||||
}
|
||||
StringBuilder s = new StringBuilder();
|
||||
doPrintStackTrace(s, t, null);
|
||||
return s.toString();
|
||||
@@ -1544,10 +1593,12 @@ public class Functions {
|
||||
/**
|
||||
* Computes the hyperlink to actions, to handle the situation when the {@link Action#getUrlName()}
|
||||
* returns absolute URL.
|
||||
*
|
||||
* @return null in case the action should not be presented to the user.
|
||||
*/
|
||||
public static String getActionUrl(String itUrl,Action action) {
|
||||
public static @CheckForNull String getActionUrl(String itUrl,Action action) {
|
||||
String urlName = action.getUrlName();
|
||||
if(urlName==null) return null; // to avoid NPE and fail to render the whole page
|
||||
if(urlName==null) return null; // Should not be displayed
|
||||
try {
|
||||
if (new URI(urlName).isAbsolute()) {
|
||||
return urlName;
|
||||
@@ -1584,15 +1635,11 @@ public class Functions {
|
||||
return projectName;
|
||||
}
|
||||
|
||||
public String getSystemProperty(String key) {
|
||||
return System.getProperty(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the host name of the Hudson server that clients can use to talk back to.
|
||||
* <p>
|
||||
* This is primarily used in <tt>slave-agent.jnlp.jelly</tt> to specify the destination
|
||||
* that the slaves talk to.
|
||||
* that the agents talk to.
|
||||
*/
|
||||
public String getServerName() {
|
||||
// Try to infer this from the configured root URL.
|
||||
@@ -1666,7 +1713,7 @@ public class Functions {
|
||||
*/
|
||||
public static List<PageDecorator> getPageDecorators() {
|
||||
// this method may be called to render start up errors, at which point Hudson doesn't exist yet. see HUDSON-3608
|
||||
if(Jenkins.getInstance()==null) return Collections.emptyList();
|
||||
if(Jenkins.getInstanceOrNull()==null) return Collections.emptyList();
|
||||
return PageDecorator.all();
|
||||
}
|
||||
|
||||
@@ -1688,13 +1735,13 @@ public class Functions {
|
||||
}
|
||||
|
||||
public static String getCrumb(StaplerRequest req) {
|
||||
Jenkins h = Jenkins.getInstance();
|
||||
Jenkins h = Jenkins.getInstanceOrNull();
|
||||
CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null;
|
||||
return issuer != null ? issuer.getCrumb(req) : "";
|
||||
}
|
||||
|
||||
public static String getCrumbRequestField() {
|
||||
Jenkins h = Jenkins.getInstance();
|
||||
Jenkins h = Jenkins.getInstanceOrNull();
|
||||
CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null;
|
||||
return issuer != null ? issuer.getDescriptor().getCrumbRequestField() : "";
|
||||
}
|
||||
@@ -1759,8 +1806,17 @@ public class Functions {
|
||||
*/
|
||||
public String getPasswordValue(Object o) {
|
||||
if (o==null) return null;
|
||||
if (o instanceof Secret) return ((Secret)o).getEncryptedValue();
|
||||
if (getIsUnitTest()) {
|
||||
if (o instanceof Secret) {
|
||||
StaplerRequest req = Stapler.getCurrentRequest();
|
||||
if (req != null) {
|
||||
Item item = req.findAncestorObject(Item.class);
|
||||
if (item != null && !item.hasPermission(Item.CONFIGURE)) {
|
||||
return "********";
|
||||
}
|
||||
}
|
||||
return ((Secret) o).getEncryptedValue();
|
||||
}
|
||||
if (getIsUnitTest() && !o.equals(PasswordParameterDefinition.DEFAULT_VALUE)) {
|
||||
throw new SecurityException("attempted to render plaintext ‘" + o + "’ in password field; use a getter of type Secret instead");
|
||||
}
|
||||
return o.toString();
|
||||
@@ -1789,7 +1845,7 @@ public class Functions {
|
||||
* the permission can't be configured in the security screen). Got it?</p>
|
||||
*/
|
||||
public static boolean isArtifactsPermissionEnabled() {
|
||||
return Boolean.getBoolean("hudson.security.ArtifactsPermission");
|
||||
return SystemProperties.getBoolean("hudson.security.ArtifactsPermission");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1804,7 +1860,7 @@ public class Functions {
|
||||
* control on the "Wipe Out Workspace" action.</p>
|
||||
*/
|
||||
public static boolean isWipeOutPermissionEnabled() {
|
||||
return Boolean.getBoolean("hudson.security.WipeOutPermission");
|
||||
return SystemProperties.getBoolean("hudson.security.WipeOutPermission");
|
||||
}
|
||||
|
||||
public static String createRenderOnDemandProxy(JellyContext context, String attributesToCapture) {
|
||||
@@ -1924,7 +1980,7 @@ public class Functions {
|
||||
* discovery of Jenkins.
|
||||
*/
|
||||
public static void advertiseHeaders(HttpServletResponse rsp) {
|
||||
Jenkins j = Jenkins.getInstance();
|
||||
Jenkins j = Jenkins.getInstanceOrNull();
|
||||
if (j!=null) {
|
||||
rsp.setHeader("X-Hudson","1.395");
|
||||
rsp.setHeader("X-Jenkins", Jenkins.VERSION);
|
||||
@@ -1932,7 +1988,7 @@ public class Functions {
|
||||
|
||||
TcpSlaveAgentListener tal = j.tcpSlaveAgentListener;
|
||||
if (tal !=null) {
|
||||
int p = TcpSlaveAgentListener.CLI_PORT !=null ? TcpSlaveAgentListener.CLI_PORT : tal.getPort();
|
||||
int p = tal.getAdvertisedPort();
|
||||
rsp.setIntHeader("X-Hudson-CLI-Port", p);
|
||||
rsp.setIntHeader("X-Jenkins-CLI-Port", p);
|
||||
rsp.setIntHeader("X-Jenkins-CLI2-Port", p);
|
||||
|
||||
Reference in new issue
Block a user