Skip to content

Commit

Permalink
[JENKINS-31162] Merge from upstream/2.0 and resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
recena committed Mar 21, 2016
2 parents a552cdb + c4fb608 commit 3c17558
Show file tree
Hide file tree
Showing 142 changed files with 3,291 additions and 1,605 deletions.
25 changes: 21 additions & 4 deletions changelog.html
Expand Up @@ -55,20 +55,37 @@
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=>
<li class="bug">
Improve logging and error message when JNLP is already in use.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-33453">issue 33453</a>)
<li class="rfe">
Improved the Build Other Projects help message.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-32134">issue 32134</a>)
<li class="bug">
FutureImpl.cancel() doesn't cancel the linked job.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-33038">issue 33038</a>)
<li class="bug">
Reject marformed range syntax.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-33037">issue 33037</a>)
</ul>
</div><!--=TRUNK-END=-->
<h3><a name=v2.0-alpha-3>What's new in 2.0-alpha-3</a> (2016/03/10)</h3>
<h3><a name=v1.653>What's new in 1.653</a> (2016/03/13)</h3>
<ul class=image>
<li class="bug">
More compact representation of redundant build causes.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-33467">issue 33467</a>)
</ul>
<h3><a name=v1.652>What's new in 1.652</a> (2016/03/06)</h3>
<ul class=image>
<li class="bug">
Under some conditions Jenkins startup could fail because of incorrectly linked extensions; now recovering more gracefully.
(<a href-"https://issues.jenkins-ci.org/browse/JENKINS-25440">issue 25440</a>)
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-25440">issue 25440</a>)
</ul>
<h3><a name=v1.651>What's new in 1.651</a> (2016/02/28)</h3>
<ul class=image>
<li class="rfe">
Move periodic task log files from <code>JENKINS_HOME/*.log</code> to <code>JENKINS_HOME/logs/tasks/*.log</code> and rotate them periodically rather than overwrite every execution.
(<a href-"https://issues.jenkins-ci.org/browse/JENKINS-33068">issue 33068</a>)
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-33068">issue 33068</a>)
<li class="bug">
Fix documentation of proxy configuration.
(<a href="https://github.com/jenkinsci/jenkins/pull/2060">pull 2060</a>)
Expand Down
2 changes: 1 addition & 1 deletion cli/pom.xml
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.0-alpha-4-SNAPSHOT</version>
<version>2.0-alpha-5-SNAPSHOT</version>
</parent>

<artifactId>cli</artifactId>
Expand Down
4 changes: 2 additions & 2 deletions core/pom.xml
Expand Up @@ -29,7 +29,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>pom</artifactId>
<version>2.0-alpha-4-SNAPSHOT</version>
<version>2.0-alpha-5-SNAPSHOT</version>
</parent>

<artifactId>jenkins-core</artifactId>
Expand Down Expand Up @@ -147,7 +147,7 @@ THE SOFTWARE.
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>windows-package-checker</artifactId>
<version>1.0</version>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.kohsuke.stapler</groupId>
Expand Down
58 changes: 37 additions & 21 deletions core/src/main/java/hudson/ClassicPluginStrategy.java
Expand Up @@ -241,8 +241,8 @@ private static Manifest loadLinkedManifest(File archive) throws IOException {
}
}
}
for (DetachedPlugin detached : DETACHED_LIST)
detached.fix(atts,optionalDependencies);

fix(atts,optionalDependencies);

// Register global classpath mask. This is useful for hiding JavaEE APIs that you might see from the container,
// such as database plugin for JPA support. The Mask-Classes attribute is insufficient because those classes
Expand All @@ -260,6 +260,41 @@ private static Manifest loadLinkedManifest(File archive) throws IOException {
createClassLoader(paths, dependencyLoader, atts), disableFile, dependencies, optionalDependencies);
}

private static void fix(Attributes atts, List<PluginWrapper.Dependency> optionalDependencies) {
String pluginName = atts.getValue("Short-Name");

String jenkinsVersion = atts.getValue("Jenkins-Version");
if (jenkinsVersion==null)
jenkinsVersion = atts.getValue("Hudson-Version");

optionalDependencies.addAll(getImpliedDependencies(pluginName, jenkinsVersion));
}

/**
* Returns all the plugin dependencies that are implicit based on a particular Jenkins version
* @since 2.0
*/
@Nonnull
public static List<PluginWrapper.Dependency> getImpliedDependencies(String pluginName, String jenkinsVersion) {
List<PluginWrapper.Dependency> out = new ArrayList<>();
for (DetachedPlugin detached : DETACHED_LIST) {
// don't fix the dependency for itself, or else we'll have a cycle
if (detached.shortName.equals(pluginName)) {
continue;
}
if (BREAK_CYCLES.contains(pluginName + '/' + detached.shortName)) {
LOGGER.log(Level.FINE, "skipping implicit dependency {0} → {1}", new Object[] {pluginName, detached.shortName});
continue;
}
// some earlier versions of maven-hpi-plugin apparently puts "null" as a literal in Hudson-Version. watch out for them.
if (jenkinsVersion == null || jenkinsVersion.equals("null") || new VersionNumber(jenkinsVersion).compareTo(detached.splitWhen) <= 0) {
out.add(new PluginWrapper.Dependency(detached.shortName + ':' + detached.requireVersion));
LOGGER.log(Level.FINE, "adding implicit dependency {0} → {1} because of {2}", new Object[] {pluginName, detached.shortName, jenkinsVersion});
}
}
return out;
}

@Deprecated
protected ClassLoader createClassLoader(List<File> paths, ClassLoader parent) throws IOException {
return createClassLoader( paths, parent, null );
Expand Down Expand Up @@ -377,25 +412,6 @@ public String getShortName() {
public VersionNumber getSplitWhen() {
return splitWhen;
}

private void fix(Attributes atts, List<PluginWrapper.Dependency> optionalDependencies) {
// don't fix the dependency for yourself, or else we'll have a cycle
String yourName = atts.getValue("Short-Name");
if (shortName.equals(yourName)) return;
if (BREAK_CYCLES.contains(yourName + '/' + shortName)) {
LOGGER.log(Level.FINE, "skipping implicit dependency {0} → {1}", new Object[] {yourName, shortName});
return;
}

// some earlier versions of maven-hpi-plugin apparently puts "null" as a literal in Hudson-Version. watch out for them.
String jenkinsVersion = atts.getValue("Jenkins-Version");
if (jenkinsVersion==null)
jenkinsVersion = atts.getValue("Hudson-Version");
if (jenkinsVersion == null || jenkinsVersion.equals("null") || new VersionNumber(jenkinsVersion).compareTo(splitWhen) <= 0) {
optionalDependencies.add(new PluginWrapper.Dependency(shortName + ':' + requireVersion));
LOGGER.log(Level.FINE, "adding implicit dependency {0} → {1} because of {2}", new Object[] {yourName, shortName, jenkinsVersion});
}
}
}

private static final List<DetachedPlugin> DETACHED_LIST = Collections.unmodifiableList(Arrays.asList(
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/hudson/ExtensionList.java
Expand Up @@ -390,14 +390,14 @@ public static <T> ExtensionList<T> create(Jenkins jenkins, Class<T> type) {
/**
* Gets the extension list for a given type.
* Normally calls {@link Jenkins#getExtensionList(Class)} but falls back to an empty list
* in case {@link Jenkins#getInstance} is null.
* in case {@link Jenkins#getInstanceOrNull()} is null.
* Thus it is useful to call from {@code all()} methods which need to behave gracefully during startup or shutdown.
* @param type the extension point type
* @return some list
* @since 1.572
*/
public static @Nonnull <T> ExtensionList<T> lookup(Class<T> type) {
Jenkins j = Jenkins.getInstance();
Jenkins j = Jenkins.getInstanceOrNull();
return j == null ? create((Jenkins) null, type) : j.getExtensionList(type);
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/hudson/FilePath.java
Expand Up @@ -1133,7 +1133,7 @@ public VirtualFile toVirtualFile() {
* @since 1.571
*/
public @CheckForNull Computer toComputer() {
Jenkins j = Jenkins.getInstance();
Jenkins j = Jenkins.getInstanceOrNull();
if (j != null) {
for (Computer c : j.getComputers()) {
if (getChannel()==c.getChannel()) {
Expand Down
24 changes: 17 additions & 7 deletions core/src/main/java/hudson/Functions.java
Expand Up @@ -74,6 +74,8 @@
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;
Expand Down Expand Up @@ -207,20 +209,28 @@ public static String rfc822Date(Calendar cal) {

/**
* 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) {
Expand Down Expand Up @@ -1649,7 +1659,7 @@ public <T> List<T> singletonList(T t) {
*/
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();
}

Expand All @@ -1671,13 +1681,13 @@ public static List<Descriptor<CrumbIssuer>> getCrumbIssuerDescriptors() {
}

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() : "";
}
Expand Down Expand Up @@ -1907,7 +1917,7 @@ public static String breakableString(final String plain) {
* 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);
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/java/hudson/PluginManager.java
Expand Up @@ -1140,7 +1140,9 @@ private List<Future<UpdateCenter.UpdateCenterJob>> install(@Nonnull Collection<S
String pluginName = n.substring(0, index);
String siteName = n.substring(index + 1);
UpdateSite.Plugin plugin = getPlugin(pluginName, siteName);
// TODO: Someone that understands what the following logic is about, please add a comment.
// There could be cases like:
// 'plugin.ambiguous.updatesite' where both
// 'plugin' @ 'ambigiuous.updatesite' and 'plugin.ambiguous' @ 'updatesite' resolve to valid plugins
if (plugin != null) {
if (p != null) {
throw new Failure("Ambiguous plugin: " + n);
Expand All @@ -1150,6 +1152,7 @@ private List<Future<UpdateCenter.UpdateCenterJob>> install(@Nonnull Collection<S
index = n.indexOf('.', index + 1);
}
}

if (p == null) {
throw new Failure("No such plugin: " + n);
}
Expand Down
37 changes: 29 additions & 8 deletions core/src/main/java/hudson/ProxyConfiguration.java
Expand Up @@ -47,7 +47,9 @@
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import javax.annotation.CheckForNull;
import jenkins.model.Jenkins;
import jenkins.util.JenkinsJVM;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
Expand Down Expand Up @@ -215,8 +217,7 @@ public static ProxyConfiguration load() throws IOException {
* This method should be used wherever {@link URL#openConnection()} to internet URLs is invoked directly.
*/
public static URLConnection open(URL url) throws IOException {
Jenkins h = Jenkins.getInstance(); // this code might run on agents
ProxyConfiguration p = h!=null ? h.proxy : null;
final ProxyConfiguration p = get();
if(p==null)
return url.openConnection();

Expand All @@ -227,22 +228,21 @@ public static URLConnection open(URL url) throws IOException {
@Override
public PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType()!=RequestorType.PROXY) return null;
ProxyConfiguration p = Jenkins.getInstance().proxy;
return new PasswordAuthentication(p.getUserName(),
p.getPassword().toCharArray());
}
});
}

for (URLConnectionDecorator d : URLConnectionDecorator.all())
d.decorate(con);
if (JenkinsJVM.isJenkinsJVM()) { // this code may run on a slave
decorate(con);
}

return con;
}

public static InputStream getInputStream(URL url) throws IOException {
Jenkins h = Jenkins.getInstance(); // this code might run on agents
final ProxyConfiguration p = (h != null) ? h.proxy : null;
final ProxyConfiguration p = get();
if (p == null)
return new RetryableHttpStream(url);

Expand All @@ -264,6 +264,27 @@ public PasswordAuthentication getPasswordAuthentication() {
return is;
}

@CheckForNull
private static ProxyConfiguration get() {
if (JenkinsJVM.isJenkinsJVM()) {
return _get();
}
return null;
}

@CheckForNull
private static ProxyConfiguration _get() {
JenkinsJVM.checkJenkinsJVM();
// this code could be called between the JVM flag being set and theInstance initialized
Jenkins jenkins = Jenkins.getInstance();
return jenkins == null ? null : jenkins.proxy;
}

private static void decorate(URLConnection con) throws IOException {
for (URLConnectionDecorator d : URLConnectionDecorator.all())
d.decorate(con);
}

private static final XStream XSTREAM = new XStream2();

private static final long serialVersionUID = 1L;
Expand Down

0 comments on commit 3c17558

Please sign in to comment.