Merged revisions 23666-23667,23670,23711,23782-23785,23788,23809-23810,23817,23859,23870,23879,23899-23904,23906-23907,23909,23913 via svnmerge from

https://www.dev.java.net/svn/hudson/branches/managed-startup

........
  r23666 | kohsuke | 2009-11-11 15:56:46 -0800 (Wed, 11 Nov 2009) | 1 line
  
  Reworked the initialization logic
........
  r23667 | kohsuke | 2009-11-11 16:01:56 -0800 (Wed, 11 Nov 2009) | 1 line
  
  fixed a failing test
........
  r23670 | kohsuke | 2009-11-11 16:42:32 -0800 (Wed, 11 Nov 2009) | 1 line
  
  use a non-snapshot
........
  r23711 | kohsuke | 2009-11-13 14:27:28 -0800 (Fri, 13 Nov 2009) | 1 line
  
  Session -> Reactor
........
  r23782 | kohsuke | 2009-11-17 10:35:14 -0800 (Tue, 17 Nov 2009) | 1 line
  
  Poorman's clone of JDK6 ServiceLoader.
........
  r23783 | kohsuke | 2009-11-17 10:56:25 -0800 (Tue, 17 Nov 2009) | 1 line
  
  Integrated the fatal support so that all errors are sent to the listener.
........
  r23784 | kohsuke | 2009-11-17 10:58:07 -0800 (Tue, 17 Nov 2009) | 1 line
  
  with the new reactor initialization, things are getting too verbose
........
  r23785 | kohsuke | 2009-11-17 11:18:45 -0800 (Tue, 17 Nov 2009) | 1 line
  
  failing to load jobs are non-fatal, too
........
  r23788 | kohsuke | 2009-11-17 13:18:59 -0800 (Tue, 17 Nov 2009) | 1 line
  
  logging the exception properly
........
  r23809 | kohsuke | 2009-11-17 18:45:47 -0800 (Tue, 17 Nov 2009) | 1 line
  
  releasing 1.1 as milestone
........
  r23810 | kohsuke | 2009-11-17 18:47:37 -0800 (Tue, 17 Nov 2009) | 2 lines
  
  - use a better idiom for building a sequence
  - use null display name to signify internal book-keeping tasks that's not worth displaying
........
  r23817 | kohsuke | 2009-11-18 07:54:17 -0800 (Wed, 18 Nov 2009) | 1 line
  
  removed accidental JDK6 dependency.
........
  r23859 | kohsuke | 2009-11-19 11:03:28 -0800 (Thu, 19 Nov 2009) | 1 line
  
  introducing the strategy pattern to hook into key decision making points during the start up
........
  r23870 | kohsuke | 2009-11-19 14:33:07 -0800 (Thu, 19 Nov 2009) | 1 line
  
  bug fix. These steps add additional tasks to the reactor, so they need to also prevent future milestones from getting attained.
........
  r23879 | kohsuke | 2009-11-19 16:54:59 -0800 (Thu, 19 Nov 2009) | 1 line
  
  moved the logic to the strategy.
........
  r23899 | kohsuke | 2009-11-20 09:32:13 -0800 (Fri, 20 Nov 2009) | 1 line
  
  handle duplicate plugins better
........
  r23900 | kohsuke | 2009-11-20 10:06:42 -0800 (Fri, 20 Nov 2009) | 1 line
  
  support pre-exploded plugin
........
  r23901 | kohsuke | 2009-11-20 10:49:04 -0800 (Fri, 20 Nov 2009) | 1 line
  
  making it a subtype
........
  r23902 | kohsuke | 2009-11-20 10:54:42 -0800 (Fri, 20 Nov 2009) | 1 line
  
  allow InitStrategy to skip some tasks
........
  r23903 | kohsuke | 2009-11-20 11:03:38 -0800 (Fri, 20 Nov 2009) | 1 line
  
  doc improvement.
........
  r23904 | kohsuke | 2009-11-20 11:03:49 -0800 (Fri, 20 Nov 2009) | 1 line
  
  no need to throw exceptions
........
  r23906 | kohsuke | 2009-11-20 11:17:34 -0800 (Fri, 20 Nov 2009) | 1 line
  
  debug switch to disable the automatic launch of slaves
........
  r23907 | kohsuke | 2009-11-20 11:25:15 -0800 (Fri, 20 Nov 2009) | 1 line
  
  added a magic object for cancelling all saves
........
  r23909 | kohsuke | 2009-11-20 11:29:53 -0800 (Fri, 20 Nov 2009) | 1 line
  
  moving initialization up
........
  r23913 | kohsuke | 2009-11-20 13:32:08 -0800 (Fri, 20 Nov 2009) | 1 line
  
  seeing heap space problem during tests
........


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@23992 71c3de6d-444a-0410-be80-ed276b4c234a
This commit is contained in:
kohsuke committed 2009-11-23 19:33:33 +00:00
1 parent ef7768a0a9
commit fd13eee6d5
26 files changed
+1154 -325

No files matched your search

+119 -65
View File
@@ -23,17 +23,25 @@
*/
package hudson;
import static hudson.init.InitMilestone.PLUGINS_PREPARED;
import static hudson.init.InitMilestone.PLUGINS_STARTED;
import static hudson.init.InitMilestone.PLUGINS_LISTED;
import hudson.init.InitStrategy;
import hudson.model.AbstractModelObject;
import hudson.model.Failure;
import hudson.model.Hudson;
import hudson.model.UpdateSite;
import hudson.model.UpdateCenter;
import hudson.model.UpdateSite;
import hudson.util.Service;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.LogFactory;
import org.jvnet.hudson.reactor.Executable;
import org.jvnet.hudson.reactor.Reactor;
import org.jvnet.hudson.reactor.TaskBuilder;
import org.jvnet.hudson.reactor.TaskGraphBuilder;
import org.kohsuke.stapler.HttpRedirect;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.QueryParameter;
@@ -44,17 +52,17 @@ import org.kohsuke.stapler.WebApp;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -102,7 +110,7 @@ public final class PluginManager extends AbstractModelObject {
/**
* Strategy for creating and initializing plugins
*/
private PluginStrategy strategy;
private final PluginStrategy strategy;
public PluginManager(ServletContext context) {
this.context = context;
@@ -112,58 +120,8 @@ public final class PluginManager extends AbstractModelObject {
rootDir = new File(Hudson.getInstance().getRootDir(),"plugins");
if(!rootDir.exists())
rootDir.mkdirs();
Collection<String> bundledPlugins = loadBundledPlugins();
File[] archives = rootDir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".hpi") // plugin jar file
|| name.endsWith(".hpl"); // linked plugin. for debugging.
}
});
if(archives==null) {
LOGGER.severe("Hudson is unable to create "+rootDir+"\nPerhaps its security privilege is insufficient");
return;
}
strategy = createPluginStrategy();
// load plugins from a system property, for use in the "mvn hudson-dev:run"
List<File> archivesList = new ArrayList<File>(Arrays.asList(archives));
String hplProperty = System.getProperty("hudson.bundled.plugins");
if (hplProperty != null) {
for (String hplLocation: hplProperty.split(",")) {
File hpl = new File(hplLocation.trim());
if (hpl.exists())
archivesList.add(hpl);
else
LOGGER.warning("bundled plugin " + hplLocation + " does not exist");
}
}
for( File arc : archivesList ) {
try {
PluginWrapper p = strategy.createPluginWrapper(arc);
p.isBundled = bundledPlugins.contains(arc.getName());
plugins.add(p);
if(p.isActive())
activePlugins.add(p);
} catch (IOException e) {
failedPlugins.add(new FailedPlugin(arc.getName(),e));
LOGGER.log(Level.SEVERE, "Failed to load a plug-in " + arc, e);
}
}
for (PluginWrapper p : activePlugins.toArray(new PluginWrapper[activePlugins.size()]))
try {
strategy.load(p);
} catch (IOException e) {
failedPlugins.add(new FailedPlugin(p.getShortName(),e));
LOGGER.log(Level.SEVERE, "Failed to load a plug-in " + p.getShortName(), e);
activePlugins.remove(p);
plugins.remove(p);
}
}
/**
@@ -171,18 +129,114 @@ public final class PluginManager extends AbstractModelObject {
* This is a separate method so that code executed from here will see a valid value in
* {@link Hudson#pluginManager}.
*/
public void initialize() {
for (PluginWrapper p : activePlugins.toArray(new PluginWrapper[activePlugins.size()])) {
strategy.initializeComponents(p);
try {
p.getPlugin().postInitialize();
} catch (Exception e) {
failedPlugins.add(new FailedPlugin(p.getShortName(), e));
LOGGER.log(Level.SEVERE, "Failed to post-initialize a plug-in " + p.getShortName(), e);
activePlugins.remove(p);
plugins.remove(p);
public TaskBuilder initTasks(final InitStrategy initStrategy) {
return new TaskGraphBuilder() {
List<File> archives;
Collection<String> bundledPlugins;
{
Handle loadBundledPlugins = add("Loading bundled plugins", new Executable() {
public void run(Reactor session) throws Exception {
bundledPlugins = loadBundledPlugins();
}
});
Handle listUpPlugins = requires(loadBundledPlugins).add("Listing up plugins", new Executable() {
public void run(Reactor session) throws Exception {
archives = initStrategy.listPluginArchives(PluginManager.this);
}
});
requires(listUpPlugins).attains(PLUGINS_LISTED).add("Preparing plugins",new Executable() {
public void run(Reactor session) throws Exception {
TaskGraphBuilder g = new TaskGraphBuilder();
final Map<String,File> inspectedShortNames = new HashMap<String,File>();
for( final File arc : archives ) {
g.followedBy().notFatal().attains(PLUGINS_LISTED).add("Inspecting plugin " + arc, new Executable() {
public void run(Reactor session) throws Exception {
try {
PluginWrapper p = strategy.createPluginWrapper(arc);
if (isDuplicate(p)) return;
p.isBundled = bundledPlugins.contains(arc.getName());
plugins.add(p);
if(p.isActive())
activePlugins.add(p);
} catch (IOException e) {
failedPlugins.add(new FailedPlugin(arc.getName(),e));
throw e;
}
}
/**
* Inspects duplication. this happens when you run hpi:run on a bundled plugin,
* as well as putting numbered hpi files, like "cobertura-1.0.hpi" and "cobertura-1.1.hpi"
*/
private boolean isDuplicate(PluginWrapper p) {
String shortName = p.getShortName();
if (inspectedShortNames.containsKey(shortName)) {
LOGGER.info("Ignoring "+arc+" because "+inspectedShortNames.get(shortName)+" is already loaded");
return true;
}
inspectedShortNames.put(shortName,arc);
return false;
}
});
}
g.requires(PLUGINS_LISTED).attains(PLUGINS_PREPARED).add("Loading plugins",new Executable() {
/**
* Once the plugins are listed, schedule their initialization.
*/
public void run(Reactor session) throws Exception {
TaskGraphBuilder g = new TaskGraphBuilder();
// schedule execution of loading plugins
for (final PluginWrapper p : activePlugins.toArray(new PluginWrapper[activePlugins.size()])) {
g.followedBy().notFatal().attains(PLUGINS_PREPARED).add("Loading plugin " + p.getShortName(), new Executable() {
public void run(Reactor session) throws Exception {
try {
strategy.load(p);
} catch (IOException e) {
failedPlugins.add(new FailedPlugin(p.getShortName(), e));
activePlugins.remove(p);
plugins.remove(p);
throw e;
}
}
});
}
// schedule execution of initializing plugins
for (final PluginWrapper p : activePlugins.toArray(new PluginWrapper[activePlugins.size()])) {
g.followedBy().notFatal().attains(PLUGINS_STARTED).add("Initializing plugin " + p.getShortName(), new Executable() {
public void run(Reactor session) throws Exception {
try {
p.getPlugin().postInitialize();
} catch (Exception e) {
failedPlugins.add(new FailedPlugin(p.getShortName(), e));
activePlugins.remove(p);
plugins.remove(p);
throw e;
}
}
});
}
// register them all
session.addAll(g.discoverTasks(session));
}
});
// register them all
session.addAll(g.discoverTasks(session));
}
});
}
}
};
}
/**