Skip to content

Instantly share code, notes, and snippets.

@rantav
Created May 23, 2011 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rantav/986541 to your computer and use it in GitHub Desktop.
Save rantav/986541 to your computer and use it in GitHub Desktop.
outbrain's glu script
2011/05/23 03:45:22.330 WARN [/CrawlerSpawn/i001] Exception while running monitor: Can't get http://hostname.../selftest?format=text to /outbrain/glu/org.linkedin.glu.packaging-all-1.5.1/org.linkedin.glu.agent-server-1.5.1/data/tmp/CrawlerSpawn/i001/__tmp1708500738Dir/selftest
2011/05/23 03:45:22.331 WARN [/CrawlerSpawn/i001] Self test failed => forcing new state stopped
2011/05/23 03:45:23.886 WARN [BaseResource] unexpected error while processing request
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Throwable
at org.linkedin.groovy.util.state.StateMachineImpl$_waitForState_closure13.doCall(StateMachineImpl.groovy:308)
at sun.reflect.GeneratedMethodAccessor15011.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:273)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
at org.linkedin.groovy.util.concurrent.GroovyConcurrentUtils.awaitFor(GroovyConcurrentUtils.groovy:134)
at org.linkedin.groovy.util.concurrent.GroovyConcurrentUtils$awaitFor$3.call(Unknown Source)
at org.linkedin.groovy.util.state.StateMachineImpl.waitForState(StateMachineImpl.groovy:305)
at org.linkedin.groovy.util.state.StateMachine$waitForState.call(Unknown Source)
at org.linkedin.glu.agent.impl.script.ScriptNode.waitForState(ScriptNode.groovy:185)
at org.linkedin.glu.agent.impl.script.ScriptNode$waitForState.call(Unknown Source)
at org.linkedin.glu.agent.impl.script.ScriptManagerImpl.waitForState(ScriptManagerImpl.groovy:415)
at org.linkedin.glu.agent.impl.script.ScriptManager$waitForState.call(Unknown Source)
at org.linkedin.glu.agent.impl.script.StateKeeperScriptManager.waitForState(StateKeeperScriptManager.groovy:186)
at org.linkedin.glu.agent.impl.script.ScriptManager$waitForState.call(Unknown Source)
at org.linkedin.glu.agent.impl.AgentImpl$_waitForState_closure16.doCall(AgentImpl.groovy:411)
at sun.reflect.GeneratedMethodAccessor15023.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:273)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149)
at org.linkedin.glu.agent.impl.AgentImpl$_waitForState_closure16.doCall(AgentImpl.groovy)
at sun.reflect.GeneratedMethodAccessor15022.invoke(Unknown Source)
/**
* This script is run by the glu agent to deploy or undeploy a web app.
* <p>
* See https://github.com/linkedin/glu/wiki/Glu-script for specs
* and https://github.com/linkedin/glu/wiki/Agent
*
* @author: ran
*/
class GluAgentDeployer
{
// Define a state machine to add the transition [to: 'stopped', action: 'stop']
// for more details see http://glu.977617.n3.nabble.com/no-valid-transition-found-for-stop-from-currentState-stopped-valid-action-s-start-unconfigure-td2388438.html
def static stateMachine = [
NONE: [[to: 'installed', action: 'install']],
installed: [[to: 'stopped', action: 'configure'], [to: 'NONE', action: 'uninstall']],
stopped: [[to: 'running', action: 'start'], [to: 'installed', action: 'unconfigure'], [to: 'stopped', action: 'stop']],
running: [[to: 'stopped', action: 'stop']]
]
def install = {
log.info "Init params: ${params}"
String packageName = " ${params.app}-${params.version}-1.noarch";
if (params.version == 0) {
log.warn("Found version 0, assuming nothing to do ${packageName}")
return
}
log.info "Installing: yum --disablerepo=* --enablerepo=ob install -y ${packageName}"
String output = shell.exec("yum --disablerepo=* --enablerepo=ob install -y ${packageName}");
log.info "output: ${output}"
if (!output.contains("Installing") && !output.contains("already installed")) {
shell.fail("The package ${packageName} could not be installed by yum. " + output)
return
}
}
def configure = {
log.info "Configure ${params.app}"
if (params.version == 0) {
log.warn("Found version 0, assuming nothing to do")
return
}
if (params.contextBaseUrl) {
timers.schedule(timer: monitor, repeatFrequency: '5m')
}
}
def start = {
log.info "Start ${params.app}"
if (params.version == 0) {
log.warn("Found version 0, assuming nothing to do")
return
}
try {
log.info "starting: /etc/init.d/tomcat6 start"
String output = shell.exec("/etc/init.d/tomcat6 start");
log.info "output: ${output}"
} catch (Throwable t) {
log.info("Unable to start tomcat, maybe it's already running? " + t.getLocalizedMessage())
}
if (!params.contextBaseUrl) {
log.info "No validation required (contextBaseUrl is empty). This is probably an offline app"
return
}
// Check /version servlet to make sure the correct version is installed
log.info("Waiting for the version servlet now...")
if (!checkVersion()) {
String versionUrl = "${params.contextBaseUrl}version"
shell.fail("Validation failed, version mismatch. Expected to find version ${params.version} in ${versionUrl}")
}
// Check the /selftest
selftest()
log.info "*************** Great Success, started ${params.app}-${params.version} *******************"
}
def checkVersion = {
String versionUrl = "${params.contextBaseUrl}/version"
def versionXmlFile
shell.waitFor(timeout: '5m', heartbeat: '2000') {
try {
log.info "Checking version at ${versionUrl}. Expected version: ${params.version}"
versionXmlFile = shell.fetch(versionUrl)
return true
} catch (java.io.IOException e) {
log.warn "Got an IOException but will try again shoon. Sleeping for 5sec... " + e.getLocalizedMessage()
} catch (Throwable t) {
log.warn "Got an error while trying /version. Will give it another try soon... " + t.getLocalizedMessage()
}
return false
}
versionXmlFile = versionXmlFile.file
log.info "versionXmlFile = ${versionXmlFile}"
String revisionString = "<revision number=\"${params.version}\""
log.info "grepping for ${revisionString} in ${versionXmlFile}"
String output = null
try {
output = shell.exec("grep '${revisionString}' ${versionXmlFile}")
} catch (Throwable t) {
log.error("Unable to find grep '${revisionString}' ${versionXmlFile} ${t}")
}
log.debug "output = ${output}"
shell.rm(versionXmlFile)
if (!output) {
log.error "Found the wrong version in the /version servlet. Expected ${params.version} at ${versionUrl}"
return false
}
return true
}
def stop = {
log.info "Stop ${params.app}"
if (params.version == 0) {
log.warn("Found version 0, assuming nothing to do")
return
}
if (!params.contextBaseUrl) {
log.info "No validation required (contextBaseUrl is empty). This is probably an offline app"
return
}
try {
log.info "starting: /etc/init.d/tomcat6 stop"
String output = shell.exec("/etc/init.d/tomcat6 stop");
log.info "output: ${output}"
} catch (Throwable t) {
log.info("Unable to stop tomcat, maybe it's already stopped? " + t.getLocalizedMessage())
}
}
def unconfigure = {
log.info "Unconfigure ${params.app}"
if (params.version == 0) {
log.warn("Found version 0, assuming nothing to do")
return
}
if (params.contextBaseUrl) {
timers.cancel(timer: monitor)
}
}
def uninstall = {
log.info "Removing ${params.app}"
if (params.version == 0) {
log.warn("Found version 0, assuming nothing to do")
return
}
String output = shell.exec("yum remove -y ${params.app}");
log.info "output: ${output}"
}
def selftest = {
String selftestUrl = "${params.contextBaseUrl}/selftest?format=text"
log.info "Calling selftest at ${selftestUrl}"
def selftestResultFile = shell.fetch(selftestUrl) // If there was an exception (such as HTTP code 510) it'll get thrown here
selftestResultFile = selftestResultFile.file
String selftestResult = shell.exec("cat ${selftestResultFile}")
log.info "selftest result: ${selftestResult}"
return true
}
/**
* Defines the timer that will check for the service to be up and running and will act
* according if not (change state)
*/
def monitor = {
def ok
try {
ok = selftest()
// DOES THIS THROW A String and not an Exception?
} catch (Throwable th) {
ok = false
log.warn "Exception while running monitor: ${th.message}"
log.debug("Exception while running serverMonitor (ignored)", th)
}
def currentState = stateManager.state.currentState
def currentError = stateManager.state.error
def newState = null
def newError = null
// case when current state is running
if(currentState == 'running') {
if(ok) {
newState = 'running' // remain running but set in error
log.info 'Monitor result: passed'
} else {
newState = 'stopped'
newError = 'Self test failed'
log.warn "${newError} => forcing new state ${newState}"
}
} else {
if(ok) {
newState = 'running'
log.info "Server up detected."
}
}
if(newState) {
stateManager.forceChangeState(newState, newError)
}
log.debug "Server Monitor: ${stateManager.state.currentState} / ${ok}"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment