提交 0292f680 编写于 作者: J Jesse Glick

Merge branch 'stable-1.642' into security-stable-1.642

......@@ -54,28 +54,12 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=>
</ul>
</div><!--=TRUNK-END=-->
<h3><a name=v1.643>What's new in 1.643</a> (2015/12/20)</h3>
<ul class=image>
<li class="bug">
Fix when multiple clouds are set up and provisioning of a node is denied.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-31219">issue 31219</a>)
<li class="rfe">
Allow retrying core update when the first attempt failed.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-11016">issue 11016</a>)
<li class="rfe">
Allow specifying the default TCP slave agent listener port via system property.
(<a href="https://github.com/jenkinsci/jenkins/commit/653fbdb65024b1b528e21f682172885f7111bba9">commit 653fbdb</a>)
</ul>
<h3><a name=v1.642>What's new in 1.642</a> (2015/12/13)</h3>
<ul class=image>
<li class="major bug">
Various kinds of settings could not be saved since 1.640.
(<a href="https://issues.jenkins-ci.org/browse/JENKINS-31954">issue 31954</a>)
</ul>
</div><!--=TRUNK-END=-->
<h3><a name=v1.641>What's new in 1.641</a> (2015/12/09)</h3>
<ul class=image>
<li class="major bug">
......
......@@ -24,5 +24,4 @@ NewVersionAvailable=New version of Jenkins ({0}) is available for <a href="{1}">
(<a href="${changelog.url}">changelog</a>).
UpgradeComplete=Upgrade to Jenkins {0} is complete, awaiting <a href="{1}/safeRestart">restart</a>.
UpgradeCompleteRestartNotSupported=Upgrade to Jenkins {0} is complete, awaiting restart.
UpgradeProgress=Upgrade to Jenkins {0} is <a href="{1}">in progress</a>.
UpgradeFailed=Upgrade to Jenkins {0} failed: <a href="{2}">{1}</a>.
UpgradeProgress=Upgrade to Jenkins {0} is <a href="{1}">in progress or failed</a>.
......@@ -37,7 +37,6 @@ import com.google.inject.Scope;
import com.google.inject.Scopes;
import com.google.inject.name.Names;
import com.google.common.collect.ImmutableList;
import hudson.init.InitMilestone;
import hudson.model.Descriptor;
import hudson.model.Hudson;
import jenkins.ExtensionComponentSet;
......@@ -245,7 +244,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
*/
private List<IndexItem<?,Object>> sezpozIndex;
private final Map<Key,Annotation> annotations = new HashMap<>();
private final Map<Key,Annotation> annotations = new HashMap<Key,Annotation>();
private final Sezpoz moduleFinder = new Sezpoz();
/**
......@@ -261,7 +260,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
sezpozIndex = loadSezpozIndices(Jenkins.getInstance().getPluginManager().uberClassLoader);
List<Module> modules = new ArrayList<>();
List<Module> modules = new ArrayList<Module>();
modules.add(new AbstractModule() {
@Override
protected void configure() {
......@@ -325,7 +324,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
l.addAll(delta);
sezpozIndex = l;
List<Module> modules = new ArrayList<>();
List<Module> modules = new ArrayList<Module>();
modules.add(new SezpozModule(delta));
for (ExtensionComponent<Module> ec : moduleFinder.refresh().find(Module.class)) {
modules.add(ec.getInstance());
......@@ -338,7 +337,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
return new ExtensionComponentSet() {
@Override
public <T> Collection<ExtensionComponent<T>> find(Class<T> type) {
List<ExtensionComponent<T>> result = new ArrayList<>();
List<ExtensionComponent<T>> result = new ArrayList<ExtensionComponent<T>>();
_find(type, result, child);
return result;
}
......@@ -352,11 +351,14 @@ public abstract class ExtensionFinder implements ExtensionPoint {
private Object instantiate(IndexItem<?,Object> item) {
try {
return item.instance();
} catch (LinkageError | Exception e) {
} catch (LinkageError e) {
// sometimes the instantiation fails in an indirect classloading failure,
// which results in a LinkageError
LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING,
"Failed to load "+item.className(), e);
} catch (Exception e) {
LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING,
"Failed to load "+item.className(), e);
}
return null;
}
......@@ -373,7 +375,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
public <U> Collection<ExtensionComponent<U>> find(Class<U> type, Hudson jenkins) {
// the find method contract requires us to traverse all known components
List<ExtensionComponent<U>> result = new ArrayList<>();
List<ExtensionComponent<U>> result = new ArrayList<ExtensionComponent<U>>();
for (Injector i=container; i!=null; i=i.getParent()) {
_find(type, result, i);
}
......@@ -387,7 +389,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
Object o = e.getValue().getProvider().get();
if (o!=null) {
GuiceExtensionAnnotation gea = a!=null ? extensionAnnotations.get(a.annotationType()) : null;
result.add(new ExtensionComponent<>(type.cast(o), gea != null ? gea.getOrdinal(a) : 0));
result.add(new ExtensionComponent<U>(type.cast(o),gea!=null?gea.getOrdinal(a):0));
}
}
}
......@@ -441,7 +443,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
}
};
}
}
};
private static final Logger LOGGER = Logger.getLogger(GuiceFinder.class.getName());
......@@ -530,11 +532,14 @@ public abstract class ExtensionFinder implements ExtensionPoint {
}
}).in(scope);
}
} catch (Exception|LinkageError e) {
} catch (LinkageError e) {
// sometimes the instantiation fails in an indirect classloading failure,
// which results in a LinkageError
LOGGER.log(optional ? Level.FINE : Level.WARNING,
"Failed to load "+item.className(), e);
} catch (Exception e) {
LOGGER.log(optional ? Level.FINE : Level.WARNING,
"Failed to load "+item.className(), e);
}
}
}
......@@ -616,7 +621,7 @@ public abstract class ExtensionFinder implements ExtensionPoint {
* Finds all the matching {@link IndexItem}s that match the given type and instantiate them.
*/
private <T> Collection<ExtensionComponent<T>> _find(Class<T> type, List<IndexItem<Extension,Object>> indices) {
List<ExtensionComponent<T>> result = new ArrayList<>();
List<ExtensionComponent<T>> result = new ArrayList<ExtensionComponent<T>>();
for (IndexItem<Extension,Object> item : indices) {
try {
......@@ -636,12 +641,14 @@ public abstract class ExtensionFinder implements ExtensionPoint {
if(type.isAssignableFrom(extType)) {
Object instance = item.instance();
if(instance!=null)
result.add(new ExtensionComponent<>(type.cast(instance),item.annotation()));
result.add(new ExtensionComponent<T>(type.cast(instance),item.annotation()));
}
} catch (LinkageError|Exception e) {
} catch (LinkageError e) {
// sometimes the instantiation fails in an indirect classloading failure,
// which results in a LinkageError
LOGGER.log(logLevel(item), "Failed to load "+item.className(), e);
} catch (Exception e) {
LOGGER.log(logLevel(item), "Failed to load "+item.className(), e);
}
}
......@@ -671,7 +678,9 @@ public abstract class ExtensionFinder implements ExtensionPoint {
// according to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6459208
// this appears to be the only way to force a class initialization
Class.forName(extType.getName(),true,extType.getClassLoader());
} catch (Exception | LinkageError e) {
} catch (Exception e) {
LOGGER.log(logLevel(item), "Failed to scout "+item.className(), e);
} catch (LinkageError e) {
LOGGER.log(logLevel(item), "Failed to scout "+item.className(), e);
}
}
......
......@@ -2,7 +2,8 @@
* The MIT License
*
* Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi,
* Red Hat, Inc., Seiji Sogabe, Stephen Connolly, Thomas J. Black, Tom Huybrechts, CloudBees, Inc.
* Red Hat, Inc., Seiji Sogabe, Stephen Connolly, Thomas J. Black, Tom Huybrechts,
* CloudBees, Inc., Christopher Simons
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -1384,13 +1385,19 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces
public void doConfigSubmit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException {
checkPermission(CONFIGURE);
String name = Util.fixEmptyAndTrim(req.getSubmittedForm().getString("name"));
Jenkins.checkGoodName(name);
String proposedName = Util.fixEmptyAndTrim(req.getSubmittedForm().getString("name"));
Jenkins.checkGoodName(proposedName);
Node node = getNode();
if (node == null) {
throw new ServletException("No such node " + nodeName);
}
if ((!proposedName.equals(nodeName))
&& Jenkins.getActiveInstance().getNode(proposedName) != null) {
throw new FormException(Messages.ComputerSet_SlaveAlreadyExists(proposedName), "name");
}
Node result = node.reconfigure(req, req.getSubmittedForm());
replaceBy(result);
......
......@@ -466,7 +466,9 @@ public class Executor extends Thread implements ModelObject {
}
private void finish2() {
for (RuntimeException e1: owner.getTerminatedBy()) LOGGER.log(Level.WARNING, String.format("%s termination trace", getName()), e1);
for (RuntimeException e1 : owner.getTerminatedBy()) {
LOGGER.log(Level.FINE, String.format("%s termination trace", getName()), e1);
}
if (causeOfDeath == null) {// let this thread die and be replaced by a fresh unstarted instance
owner.removeExecutor(this);
}
......
......@@ -31,6 +31,7 @@ import hudson.node_monitors.ArchitectureMonitor.DescriptorImpl;
import hudson.util.IOUtils;
import hudson.util.Secret;
import static hudson.util.TimeUnit2.DAYS;
import static hudson.init.InitMilestone.COMPLETED;
import jenkins.model.Jenkins;
import net.sf.json.JSONObject;
......@@ -95,9 +96,12 @@ public class UsageStatistics extends PageDecorator {
* Returns true if it's time for us to check for new version.
*/
public boolean isDue() {
// user opted out. no data collection.
if(!Jenkins.getInstance().isUsageStatisticsCollected() || DISABLED) return false;
final Jenkins j = Jenkins.getInstance();
// user opted out or Jenkins not fully initialized. no data collection.
if (j == null || j.isUsageStatisticsCollected() || DISABLED || COMPLETED.compareTo(j.getInitLevel()) > 0) {
return false;
}
long now = System.currentTimeMillis();
if(now - lastAttempt > DAY) {
lastAttempt = now;
......
......@@ -23,17 +23,17 @@
*/
package hudson.security;
import hudson.Extension;
import hudson.model.Descriptor;
import jenkins.model.Jenkins;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.DataBoundConstructor;
import hudson.Extension;
import javax.inject.Inject;
import java.util.Collections;
import java.util.List;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.StaplerRequest;
/**
* {@link AuthorizationStrategy} that grants full-control to authenticated user
* (other than anonymous users.)
......@@ -41,10 +41,6 @@ import java.util.List;
* @author Kohsuke Kawaguchi
*/
public class FullControlOnceLoggedInAuthorizationStrategy extends AuthorizationStrategy {
@DataBoundConstructor
public FullControlOnceLoggedInAuthorizationStrategy() {
}
@Override
public ACL getRootACL() {
return THE_ACL;
......@@ -62,21 +58,15 @@ public class FullControlOnceLoggedInAuthorizationStrategy extends AuthorizationS
THE_ACL.add(ACL.ANONYMOUS,Permission.READ,true);
}
/**
* @deprecated as of 1.643
* Inject descriptor via {@link Inject}.
*/
@Restricted(NoExternalUse.class)
public static Descriptor<AuthorizationStrategy> DESCRIPTOR;
@Extension
public static class DescriptorImpl extends Descriptor<AuthorizationStrategy> {
public DescriptorImpl() {
DESCRIPTOR = this;
}
public static final Descriptor<AuthorizationStrategy> DESCRIPTOR = new Descriptor<AuthorizationStrategy>() {
public String getDisplayName() {
return Messages.FullControlOnceLoggedInAuthorizationStrategy_DisplayName();
}
}
@Override
public AuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData) throws FormException {
return new FullControlOnceLoggedInAuthorizationStrategy();
}
};
}
......@@ -23,11 +23,12 @@
*/
package hudson.security;
import hudson.Extension;
import hudson.model.Descriptor;
import jenkins.model.Jenkins;
import hudson.Extension;
import org.acegisecurity.acls.sid.GrantedAuthoritySid;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;
import net.sf.json.JSONObject;
import java.util.Collection;
import java.util.Collections;
......@@ -42,10 +43,6 @@ public final class LegacyAuthorizationStrategy extends AuthorizationStrategy {
add(new GrantedAuthoritySid("admin"), Jenkins.ADMINISTER,true);
}};
@DataBoundConstructor
public LegacyAuthorizationStrategy() {
}
public ACL getRootACL() {
return LEGACY_ACL;
}
......@@ -59,5 +56,9 @@ public final class LegacyAuthorizationStrategy extends AuthorizationStrategy {
public String getDisplayName() {
return Messages.LegacyAuthorizationStrategy_DisplayName();
}
public LegacyAuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData) throws FormException {
return new LegacyAuthorizationStrategy();
}
}
}
......@@ -155,14 +155,4 @@ public abstract class OfflineCause {
this.message = message;
}
}
/**
* Caused by idle period.
* @since TODO
*/
public static class IdleOfflineCause extends SimpleOfflineCause {
public IdleOfflineCause () {
super(hudson.slaves.Messages._RetentionStrategy_Demand_OfflineIdle());
}
}
}
......@@ -267,7 +267,7 @@ public abstract class RetentionStrategy<T extends Computer> extends AbstractDesc
// we've been idle for long enough
logger.log(Level.INFO, "Disconnecting computer {0} as it has been idle for {1}",
new Object[]{c.getName(), Util.getTimeSpanString(idleMilliseconds)});
c.disconnect(new OfflineCause.IdleOfflineCause());
c.disconnect(OfflineCause.create(Messages._RetentionStrategy_Demand_OfflineIdle()));
} else {
// no point revisiting until we can be confident we will be idle
return TimeUnit.MILLISECONDS.toMinutes(TimeUnit.MINUTES.toMillis(idleDelay) - idleMilliseconds);
......
......@@ -431,7 +431,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
private transient volatile boolean isQuietingDown;
private transient volatile boolean terminating;
private List<JDK> jdks = new ArrayList<JDK>();
private volatile List<JDK> jdks = new ArrayList<JDK>();
private transient volatile DependencyGraph dependencyGraph;
private final transient AtomicBoolean dependencyGraphDirty = new AtomicBoolean();
......@@ -566,7 +566,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
* TCP slave agent port.
* 0 for random, -1 to disable.
*/
private int slaveAgentPort = Integer.getInteger(Jenkins.class.getName()+".slaveAgentPort",0);
private int slaveAgentPort =0;
/**
* Whitespace-separated labels assigned to the master as a {@link Node}.
......@@ -886,6 +886,17 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
executeReactor(null, graphBuilder);
}
/**
* Maintains backwards compatibility. Invoked by XStream when this object is de-serialized.
*/
@SuppressWarnings({"unused"})
private Object readResolve() {
if (jdks == null) {
jdks = new ArrayList<>();
}
return this;
}
/**
* Executes a reactor.
*
......@@ -1663,9 +1674,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
return Messages.Hudson_DisplayName();
}
public synchronized List<JDK> getJDKs() {
if(jdks==null)
jdks = new ArrayList<JDK>();
public List<JDK> getJDKs() {
return jdks;
}
......@@ -1676,7 +1685,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve
* set JDK installations from external code.
*/
@Restricted(NoExternalUse.class)
public synchronized void setJDKs(Collection<? extends JDK> jdks) {
public void setJDKs(Collection<? extends JDK> jdks) {
this.jdks = new ArrayList<JDK>(jdks);
}
......
......@@ -39,14 +39,6 @@ THE SOFTWARE.
</j:otherwise>
</j:choose>
</j:when>
<j:when test="${upJob!=null and upJob.error != null}">
<form method="post" action="${rootURL}/updateCenter/upgrade">
${%UpgradeFailed(ucData.core.version,upJob.errorMessage,rootURL+'/updateCenter/')}
<j:if test="${ucData.canUpgrade()}">
<f:submit value="${%Retry}"/>
</j:if>
</form>
</j:when>
<j:when test="${upJob!=null}">
${%UpgradeProgress(ucData.core.version,rootURL+'/updateCenter/')}
</j:when>
......
......@@ -38,7 +38,7 @@ THE SOFTWARE.
The following value assumes that you have java in your PATH.
-->
<executable>java</executable>
<arguments>-Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=8080 --webroot="%BASE%\war"</arguments>
<arguments>-Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=8080</arguments>
<!--
interactive flag causes the empty black Java window to be displayed.
I'm still debugging this.
......
/*
* The MIT License
*
* Copyright (c) 2015 Red Hat, Inc.
* Copyright (c) 2015 Red Hat, Inc.; Christopher Simons
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -23,16 +23,26 @@
*/
package hudson.model;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.*;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import java.io.File;
import jenkins.model.Jenkins;
import hudson.slaves.DumbSlave;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.JenkinsRule.WebClient;
public class ComputerTest {
......@@ -52,4 +62,29 @@ public class ComputerTest {
assertTrue("Slave log should be kept", keep.toComputer().getLogFile().exists());
}
/**
* Verify we can't rename a node over an existing node.
*/
@Issue("JENKINS-31321")
@Test
public void testProhibitRenameOverExistingNode() throws Exception {
final String NOTE = "Rename node to name of another node should fail.";
Node nodeA = j.createSlave("nodeA", null, null);
Node nodeB = j.createSlave("nodeB", null, null);
WebClient wc = j.createWebClient();
HtmlForm form = wc.getPage(nodeB, "configure").getFormByName("config");
form.getInputByName("_.name").setValueAttribute("nodeA");
try {
j.submit(form);
fail(NOTE);
} catch (FailingHttpStatusCodeException e) {
assertThat(NOTE, e.getStatusCode(), equalTo(400));
assertThat(NOTE, e.getResponse().getContentAsString(),
containsString("Slave called ‘nodeA’ already exists"));
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册