Skip to content

Commit

Permalink
Fixes #10567: Infinite \"rudder is loading\" page if rudder-init didn…
Browse files Browse the repository at this point in the history
…'t run
  • Loading branch information
fanf committed Apr 26, 2017
1 parent 972f7ac commit ab76b44
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,35 @@ class LiftInitContextListener extends ContextLoaderListener {
initSpringAuthentication()

val ms = System.currentTimeMillis()

/*
* translate exception to UnavailableException
*
* Note that that won't work for most exception thrown in RudderConfig, due to
* current arch: RudderConfig init all object in its constructor, and that will
* throw a java.lang.ExceptionInInitializerError (which can't be catched here,
* because it happens out of our scope, before init).
* None the less, that error will also stop jetty for that context, which is
* what we want in the end (it will be not so nice, thought)
* If any excpetion reach that point in init, we want to stop
* the application server.
* The "normal" way to handle that would have been to raise an
* UnavailableException, and so the web server would have then
* unloaded Rudder and responded with "error 503" to queries.
* But we are proxying Rudder with Apache and serving a "please
* wait, loading" page on that case.
* And in all case, an error in init almost always need a restart of Rudder.
*
* We can't simply "System.exit(1)", because it brokes everything.
* We can't simply throws an other exception, because for most of them,
* Jetty will mark the service unavailable (and so 503 and infinite "please
* wait" screen).
* So we need to make the JVM throw an IllegalStateException, which for some
* (totally unknown) reason make jetty unload the context and return 404 for
* queries on it (which we are correctly handling in Apache).
*
*/

try {
RudderConfig.init
} catch {
case ex if(!ex.isInstanceOf[UnavailableException]) =>
ApplicationLogger.error("Fatal error during boot", ex)
throw new UnavailableException("An unrecoverable error occured during boot")
case ex =>
ApplicationLogger.error("Fatal error during boot, Rudder will stop now", ex)
//make the JVM throw the exception
ThrowIllegalAccessException.referenceMe
}

//init Spring
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
*************************************************************************************
* Copyright 2017 Normation SAS
*************************************************************************************
*
* This file is part of Rudder.
*
* Rudder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In accordance with the terms of section 7 (7. Additional Terms.) of
* the GNU General Public License version 3, the copyright holders add
* the following Additional permissions:
* Notwithstanding to the terms of section 5 (5. Conveying Modified Source
* Versions) and 6 (6. Conveying Non-Source Forms.) of the GNU General
* Public License version 3, when you create a Related Module, this
* Related Module is not considered as a part of the work and may be
* distributed under the license agreement of your choice.
* A "Related Module" means a set of sources files including their
* documentation that, without modification of the Source Code, enables
* supplementary functions or services in addition to those offered by
* the Software.
*
* Rudder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Rudder. If not, see <http://www.gnu.org/licenses/>.
*
*************************************************************************************
*/
package bootstrap.liftweb;

/*
* This class must not be referenced but for throwing an IllegalStateException.
*
* It must be in Java to be able to use a static initializer and throw an
* IllegalArgumentException, which seems to be the only exception that make jetty
* unload the service WITHOUT making it returns 503 for it.
*/
public class ThrowIllegalAccessException {

/*
* Ah. Javac is somehow smart and look to see if the static initializer doesn't
* obviously fails. So we need to fool it (not very hard).
*/
private static boolean foolCompiler(boolean choice) {
if(choice) {
throw new RuntimeException("An unrecoverable error happened during boot");
} else {
return choice;
}
}

/*
* Actually throws our exception.
*/
static {
foolCompiler(true);
}

/*
* Something to reference to make the object be initialize.
*/
public static int referenceMe = 42;
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class CheckDIT(
FAIL { "There is some required entries missing in the LDAP directory: %s".format(
list.map {
case (Failure(m,_,_), dn) => "%s (error message: %s)".format(dn.toString, m)
case (Empty,dn) => "%s (no error message)".format(dn.toString)
case (Empty,dn) => dn.toString
case _ => "" //strange...
}.mkString(" | ")
)}
Expand Down Expand Up @@ -130,7 +130,7 @@ class CheckDIT(
FAIL { "There is some required entries missing in the LDAP directory: %s".format(
list.map {
case (Failure(m,_,_), dn) => "%s (error message: %s)".format(dn.toString, m)
case (Empty,dn) => "%s (no error message)".format(dn.toString)
case (Empty,dn) => dn.toString
case _ => "" //strange...
}.mkString(" | ")
)}
Expand Down

0 comments on commit ab76b44

Please sign in to comment.