mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-03 15:15:54 +00:00
Merge branch 'master' into jenkins-45235
This commit is contained in:
commit
4bf99bae6e
1259 files changed
+28332
-12301
No files matched your search
@@ -25,8 +25,6 @@ package hudson;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.NonNull;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import hudson.security.ACLContext;
|
||||
import jenkins.util.SystemProperties;
|
||||
import hudson.PluginWrapper.Dependency;
|
||||
import hudson.init.InitMilestone;
|
||||
import hudson.init.InitStrategy;
|
||||
@@ -36,22 +34,26 @@ import hudson.model.AbstractModelObject;
|
||||
import hudson.model.AdministrativeMonitor;
|
||||
import hudson.model.Api;
|
||||
import hudson.model.Descriptor;
|
||||
import hudson.model.DownloadService;
|
||||
import hudson.model.Failure;
|
||||
import hudson.model.ItemGroupMixIn;
|
||||
import hudson.model.UpdateCenter;
|
||||
import hudson.model.UpdateSite;
|
||||
import hudson.model.UpdateCenter.DownloadJob;
|
||||
import hudson.model.UpdateCenter.InstallationJob;
|
||||
import hudson.model.UpdateSite;
|
||||
import hudson.security.ACL;
|
||||
import hudson.security.ACLContext;
|
||||
import hudson.security.Permission;
|
||||
import hudson.security.PermissionScope;
|
||||
import hudson.util.CyclicGraphDetector;
|
||||
import hudson.util.CyclicGraphDetector.CycleDetectedException;
|
||||
import hudson.util.FormValidation;
|
||||
import hudson.util.PersistedList;
|
||||
import hudson.util.Service;
|
||||
import hudson.util.VersionNumber;
|
||||
import hudson.util.XStream2;
|
||||
import jenkins.ClassLoaderReflectionToolkit;
|
||||
import jenkins.ExtensionRefreshException;
|
||||
import jenkins.InitReactorRunner;
|
||||
import jenkins.MissingDependencyException;
|
||||
import jenkins.RestartRequiredException;
|
||||
@@ -59,12 +61,12 @@ import jenkins.YesNoMaybe;
|
||||
import jenkins.install.InstallState;
|
||||
import jenkins.install.InstallUtil;
|
||||
import jenkins.model.Jenkins;
|
||||
import jenkins.security.CustomClassFilter;
|
||||
import jenkins.util.SystemProperties;
|
||||
import jenkins.util.io.OnMaster;
|
||||
import jenkins.util.xml.RestrictiveEntityResolver;
|
||||
|
||||
import net.sf.json.JSONArray;
|
||||
import net.sf.json.JSONObject;
|
||||
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
@@ -82,17 +84,24 @@ import org.jvnet.hudson.reactor.Reactor;
|
||||
import org.jvnet.hudson.reactor.ReactorException;
|
||||
import org.jvnet.hudson.reactor.TaskBuilder;
|
||||
import org.jvnet.hudson.reactor.TaskGraphBuilder;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.DoNotUse;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
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.StaplerProxy;
|
||||
import org.kohsuke.stapler.StaplerRequest;
|
||||
import org.kohsuke.stapler.StaplerResponse;
|
||||
import org.kohsuke.stapler.export.Exported;
|
||||
import org.kohsuke.stapler.export.ExportedBean;
|
||||
import org.kohsuke.stapler.interceptor.RequirePOST;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -100,6 +109,7 @@ import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
@@ -107,10 +117,12 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -121,6 +133,7 @@ import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
@@ -128,31 +141,15 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import static hudson.init.InitMilestone.*;
|
||||
import hudson.model.DownloadService;
|
||||
import hudson.util.FormValidation;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.JarURLConnection;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.jar.JarEntry;
|
||||
|
||||
import static java.util.logging.Level.FINE;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.SEVERE;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import jenkins.security.CustomClassFilter;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
import static java.util.logging.Level.*;
|
||||
|
||||
/**
|
||||
* Manages {@link PluginWrapper}s.
|
||||
@@ -176,7 +173,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
@ExportedBean
|
||||
public abstract class PluginManager extends AbstractModelObject implements OnMaster, StaplerOverridable {
|
||||
public abstract class PluginManager extends AbstractModelObject implements OnMaster, StaplerOverridable, StaplerProxy {
|
||||
/** Custom plugin manager system property or context param. */
|
||||
public static final String CUSTOM_PLUGIN_MANAGER = PluginManager.class.getName() + ".className";
|
||||
|
||||
@@ -920,6 +917,11 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
|
||||
// Redo who depends on who.
|
||||
resolveDependantPlugins();
|
||||
|
||||
try {
|
||||
Jenkins.get().refreshExtensions();
|
||||
} catch (ExtensionRefreshException e) {
|
||||
throw new IOException("Failed to refresh extensions after installing " + sn + " plugin", e);
|
||||
}
|
||||
LOGGER.info("Plugin " + p.getShortName()+":"+p.getVersion() + " dynamically installed");
|
||||
}
|
||||
}
|
||||
@@ -927,8 +929,15 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
|
||||
@Restricted(NoExternalUse.class)
|
||||
public synchronized void resolveDependantPlugins() {
|
||||
for (PluginWrapper plugin : plugins) {
|
||||
// Set of optional dependants plugins of plugin
|
||||
Set<String> optionalDependants = new HashSet<>();
|
||||
Set<String> dependants = new HashSet<>();
|
||||
for (PluginWrapper possibleDependant : plugins) {
|
||||
// No need to check if plugin is dependant of itself
|
||||
if(possibleDependant.getShortName().equals(plugin.getShortName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The plugin could have just been deleted. If so, it doesn't
|
||||
// count as a dependant.
|
||||
if (possibleDependant.isDeleted()) {
|
||||
@@ -938,10 +947,20 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
|
||||
for (Dependency dependency : dependencies) {
|
||||
if (dependency.shortName.equals(plugin.getShortName())) {
|
||||
dependants.add(possibleDependant.getShortName());
|
||||
|
||||
// If, in addition, the dependency is optional, add to the optionalDependants list
|
||||
if (dependency.optional) {
|
||||
optionalDependants.add(possibleDependant.getShortName());
|
||||
}
|
||||
|
||||
// already know possibleDependant depends on plugin, no need to continue with the rest of
|
||||
// dependencies. We continue with the next possibleDependant
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
plugin.setDependants(dependants);
|
||||
plugin.setOptionalDependants(optionalDependants);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1208,7 +1227,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
|
||||
|
||||
/**
|
||||
* Discover all the service provider implementations of the given class,
|
||||
* via <tt>META-INF/services</tt>.
|
||||
* via {@code META-INF/services}.
|
||||
* @deprecated Use {@link ServiceLoader} instead, or (more commonly) {@link ExtensionList}.
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -1485,7 +1504,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
|
||||
}
|
||||
updateCenter.persistInstallStatus();
|
||||
if(!failures) {
|
||||
try (ACLContext _ = ACL.as(currentAuth)) {
|
||||
try (ACLContext acl = ACL.as(currentAuth)) {
|
||||
InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_PLUGINS_INSTALLING);
|
||||
}
|
||||
}
|
||||
@@ -1816,6 +1835,44 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
|
||||
return requestedPlugins;
|
||||
}
|
||||
|
||||
@Restricted(DoNotUse.class) // table.jelly
|
||||
public MetadataCache createCache() {
|
||||
return new MetadataCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a list of plugins using a strategy for their dependants plugins.
|
||||
* @param strategy the strategy regarding how the dependant plugins are processed
|
||||
* @param plugins the list of plugins
|
||||
* @return the list of results for every plugin and their dependant plugins.
|
||||
* @throws IOException see {@link PluginWrapper#disable()}
|
||||
*/
|
||||
public @NonNull List<PluginWrapper.PluginDisableResult> disablePlugins(@NonNull PluginWrapper.PluginDisableStrategy strategy, @NonNull List<String> plugins) throws IOException {
|
||||
// Where we store the results of each plugin disablement
|
||||
List<PluginWrapper.PluginDisableResult> results = new ArrayList<>(plugins.size());
|
||||
|
||||
// Disable all plugins passed
|
||||
for (String pluginName : plugins) {
|
||||
PluginWrapper plugin = this.getPlugin(pluginName);
|
||||
|
||||
if (plugin == null) {
|
||||
results.add(new PluginWrapper.PluginDisableResult(pluginName, PluginWrapper.PluginDisableStatus.NO_SUCH_PLUGIN, Messages.PluginWrapper_NoSuchPlugin(pluginName)));
|
||||
} else {
|
||||
results.add(plugin.disable(strategy));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@Restricted(NoExternalUse.class) // table.jelly
|
||||
public static final class MetadataCache {
|
||||
private final Map<String, Object> data = new HashMap<>();
|
||||
public <T> T of(String key, Class<T> type, Supplier<T> func) {
|
||||
return type.cast(data.computeIfAbsent(key, _ignored -> func.get()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link ClassLoader} that can see all plugins.
|
||||
*/
|
||||
@@ -2063,4 +2120,19 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Restricted(NoExternalUse.class)
|
||||
public Object getTarget() {
|
||||
if (!SKIP_PERMISSION_CHECK) {
|
||||
Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape hatch for StaplerProxy-based access control
|
||||
*/
|
||||
@Restricted(NoExternalUse.class)
|
||||
public static /* Script Console modifiable */ boolean SKIP_PERMISSION_CHECK = Boolean.getBoolean(PluginManager.class.getName() + ".skipPermissionCheck");
|
||||
}
|
||||
Reference in new issue
Block a user