提交 0c5338df 编写于 作者: K Kohsuke Kawaguchi

expose additional variables

上级 729d41cf
...@@ -25,6 +25,7 @@ package hudson; ...@@ -25,6 +25,7 @@ package hudson;
import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
import com.thoughtworks.xstream.core.JVM; import com.thoughtworks.xstream.core.JVM;
import com.trilead.ssh2.util.IOUtils;
import hudson.model.Hudson; import hudson.model.Hudson;
import hudson.util.BootFailure; import hudson.util.BootFailure;
import jenkins.model.Jenkins; import jenkins.model.Jenkins;
...@@ -53,15 +54,19 @@ import javax.servlet.ServletResponse; ...@@ -53,15 +54,19 @@ import javax.servlet.ServletResponse;
import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.TransformerFactoryConfigurationError;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.security.Security; import java.security.Security;
import java.util.logging.LogRecord; import java.util.logging.LogRecord;
import static java.util.logging.Level.*;
/** /**
* Entry point when Hudson is used as a webapp. * Entry point when Hudson is used as a webapp.
* *
...@@ -84,6 +89,7 @@ public final class WebAppMain implements ServletContextListener { ...@@ -84,6 +89,7 @@ public final class WebAppMain implements ServletContextListener {
*/ */
public void contextInitialized(ServletContextEvent event) { public void contextInitialized(ServletContextEvent event) {
final ServletContext context = event.getServletContext(); final ServletContext context = event.getServletContext();
File home=null;
try { try {
// use the current request to determine the language // use the current request to determine the language
...@@ -111,7 +117,7 @@ public final class WebAppMain implements ServletContextListener { ...@@ -111,7 +117,7 @@ public final class WebAppMain implements ServletContextListener {
installLogger(); installLogger();
final FileAndDescription describedHomeDir = getHomeDir(event); final FileAndDescription describedHomeDir = getHomeDir(event);
final File home = describedHomeDir.file.getAbsoluteFile(); home = describedHomeDir.file.getAbsoluteFile();
home.mkdirs(); home.mkdirs();
System.out.println("Jenkins home directory: "+home+" found at: "+describedHomeDir.description); System.out.println("Jenkins home directory: "+home+" found at: "+describedHomeDir.description);
...@@ -119,6 +125,8 @@ public final class WebAppMain implements ServletContextListener { ...@@ -119,6 +125,8 @@ public final class WebAppMain implements ServletContextListener {
if (!home.exists()) if (!home.exists())
throw new NoHomeDir(home); throw new NoHomeDir(home);
recordBootAttempt(home);
// make sure that we are using XStream in the "enhanced" (JVM-specific) mode // make sure that we are using XStream in the "enhanced" (JVM-specific) mode
if(jvm.bestReflectionProvider().getClass()==PureJavaReflectionProvider.class) { if(jvm.bestReflectionProvider().getClass()==PureJavaReflectionProvider.class) {
throw new IncompatibleVMDetected(); // nope throw new IncompatibleVMDetected(); // nope
...@@ -191,13 +199,13 @@ public final class WebAppMain implements ServletContextListener { ...@@ -191,13 +199,13 @@ public final class WebAppMain implements ServletContextListener {
// if this works we are all happy // if this works we are all happy
} catch (TransformerFactoryConfigurationError x) { } catch (TransformerFactoryConfigurationError x) {
// no it didn't. // no it didn't.
LOGGER.log(Level.WARNING, "XSLT not configured correctly. Hudson will try to fix this. See http://issues.apache.org/bugzilla/show_bug.cgi?id=40895 for more details",x); LOGGER.log(WARNING, "XSLT not configured correctly. Hudson will try to fix this. See http://issues.apache.org/bugzilla/show_bug.cgi?id=40895 for more details",x);
System.setProperty(TransformerFactory.class.getName(),"com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); System.setProperty(TransformerFactory.class.getName(),"com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
try { try {
TransformerFactory.newInstance(); TransformerFactory.newInstance();
LOGGER.info("XSLT is set to the JAXP RI in JRE"); LOGGER.info("XSLT is set to the JAXP RI in JRE");
} catch(TransformerFactoryConfigurationError y) { } catch(TransformerFactoryConfigurationError y) {
LOGGER.log(Level.SEVERE, "Failed to correct the problem."); LOGGER.log(SEVERE, "Failed to correct the problem.");
} }
} }
...@@ -205,22 +213,25 @@ public final class WebAppMain implements ServletContextListener { ...@@ -205,22 +213,25 @@ public final class WebAppMain implements ServletContextListener {
context.setAttribute(APP,new HudsonIsLoading()); context.setAttribute(APP,new HudsonIsLoading());
final File _home = home;
initThread = new Thread("Jenkins initialization thread") { initThread = new Thread("Jenkins initialization thread") {
@Override @Override
public void run() { public void run() {
boolean success = false; boolean success = false;
try { try {
Jenkins instance = new Hudson(home, context); Jenkins instance = new Hudson(_home, context);
context.setAttribute(APP, instance); context.setAttribute(APP, instance);
BootFailure.getBootFailureFile(_home).delete();
// at this point we are open for business and serving requests normally // at this point we are open for business and serving requests normally
LOGGER.info("Jenkins is fully up and running"); LOGGER.info("Jenkins is fully up and running");
success = true; success = true;
} catch (Error e) { } catch (Error e) {
new HudsonFailedToLoad(e).publish(context); new HudsonFailedToLoad(e).publish(context,_home);
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
new HudsonFailedToLoad(e).publish(context); new HudsonFailedToLoad(e).publish(context,_home);
} finally { } finally {
Jenkins instance = Jenkins.getInstance(); Jenkins instance = Jenkins.getInstance();
if(!success && instance!=null) if(!success && instance!=null)
...@@ -230,16 +241,34 @@ public final class WebAppMain implements ServletContextListener { ...@@ -230,16 +241,34 @@ public final class WebAppMain implements ServletContextListener {
}; };
initThread.start(); initThread.start();
} catch (BootFailure e) { } catch (BootFailure e) {
e.publish(context); e.publish(context,home);
} catch (Error e) { } catch (Error e) {
LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",e); LOGGER.log(SEVERE, "Failed to initialize Jenkins",e);
throw e; throw e;
} catch (RuntimeException e) { } catch (RuntimeException e) {
LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",e); LOGGER.log(SEVERE, "Failed to initialize Jenkins",e);
throw e; throw e;
} }
} }
/**
* To assist boot failure script, record the number of boot attempts.
* This file gets deleted in case of successful boot.
*
* @see BootFailure
*/
private void recordBootAttempt(File home) {
FileOutputStream o=null;
try {
o = new FileOutputStream(BootFailure.getBootFailureFile(home), true);
o.write((new Date().toString() + System.getProperty("line.separator", "\n")).toString().getBytes());
} catch (IOException e) {
LOGGER.log(WARNING, "Failed to record boot attempts",e);
} finally {
IOUtils.closeQuietly(o);
}
}
public static void installExpressionFactory(ServletContextEvent event) { public static void installExpressionFactory(ServletContextEvent event) {
JellyFacet.setExpressionFactory(event, new ExpressionFactory2()); JellyFacet.setExpressionFactory(event, new ExpressionFactory2());
} }
......
package hudson.util; package hudson.util;
import hudson.WebAppMain;
import jenkins.util.groovy.GroovyHookScript; import jenkins.util.groovy.GroovyHookScript;
import org.kohsuke.stapler.WebApp; import org.kohsuke.stapler.WebApp;
import javax.annotation.CheckForNull;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
...@@ -11,6 +20,7 @@ import java.util.logging.Logger; ...@@ -11,6 +20,7 @@ import java.util.logging.Logger;
* Indicates a fatal boot problem, among {@link ErrorObject} * Indicates a fatal boot problem, among {@link ErrorObject}
* *
* @author Kohsuke Kawaguchi * @author Kohsuke Kawaguchi
* @see WebAppMain#recordBootAttempt(File)
*/ */
public abstract class BootFailure extends ErrorObject { public abstract class BootFailure extends ErrorObject {
protected BootFailure() { protected BootFailure() {
...@@ -22,15 +32,57 @@ public abstract class BootFailure extends ErrorObject { ...@@ -22,15 +32,57 @@ public abstract class BootFailure extends ErrorObject {
/** /**
* Exposes this failure to UI and invoke the hook. * Exposes this failure to UI and invoke the hook.
*
* @param home
* JENKINS_HOME if it's already known.
*/ */
public void publish(ServletContext context) { public void publish(ServletContext context, @CheckForNull File home) {
LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",this); LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",this);
WebApp.get(context).setApp(this); WebApp.get(context).setApp(this);
new GroovyHookScript("boot-failure") new GroovyHookScript("boot-failure")
.bind("exception",this) .bind("exception",this)
.bind("home",home)
.bind("servletContext", context)
.bind("attempts",loadAttempts(home))
.run(); .run();
} }
/**
* Parses the boot attempt file carefully so as not to cause the entire hook script to fail to execute.
*/
protected List<Date> loadAttempts(File home) {
List<Date> dates = new ArrayList<Date>();
if (home!=null) {
File f = getBootFailureFile(home);
try {
if (f.exists()) {
BufferedReader r = new BufferedReader(new FileReader(f));
String line;
while ((line=r.readLine())!=null) {
try {
dates.add(new Date(line));
} catch (Exception e) {
// ignore any parse error
}
}
}
} catch (IOException e) {
LOGGER.log(Level.WARNING,"Failed to parse "+f,e);
}
}
return dates;
}
private static final Logger LOGGER = Logger.getLogger(BootFailure.class.getName()); private static final Logger LOGGER = Logger.getLogger(BootFailure.class.getName());
/**
* This file captures failed boot attempts.
* Every time we try to boot, we add the timestamp to this file,
* then when we boot, the file gets deleted.
*/
public static File getBootFailureFile(File home) {
return new File(home, "failed-boot-attempts.txt");
}
} }
...@@ -3086,7 +3086,7 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro ...@@ -3086,7 +3086,7 @@ public class Jenkins extends AbstractCIBase implements ModifiableTopLevelItemGro
reload(); reload();
} catch (Exception e) { } catch (Exception e) {
LOGGER.log(SEVERE,"Failed to reload Jenkins config",e); LOGGER.log(SEVERE,"Failed to reload Jenkins config",e);
new JenkinsReloadFailed(e).publish(servletContext); new JenkinsReloadFailed(e).publish(servletContext,root);
} }
} }
}.start(); }.start();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册