Wednesday 18 June 2008

Script to deploy Grails Applications Remote

I spent some time this week doing a script to deploy my grails applications in remote Jetty container.
To do my deploy script I use Gant, with Grails support. To deploy War in Jetty you have two options:
  • Static. To do in static way you only have to copy your War to "webapps" directory and restart container.
  • Hot deploy. I prefer hot deploy to avoid restart container and I have to copy War in "webapps" directory and generate XML with context description.
To copy War remote, Ant.scp is the best way, make sure that you have Ant optional task and and jsch.jar in classpath (you can copy from Eclipse to GRAILS_HOME/lib for example).

To generate XML, Groovy is fantastic I mix some withWriter closure to generate the head of the document, and MarkupBuilder to do the hard work.

And this is the script:
import org.codehaus.groovy.grails.commons.GrailsClassUtils as GCU
import groovy.xml.MarkupBuilder

grailsHome = Ant.project.properties."environment.GRAILS_HOME"

includeTargets << new File ( "${grailsHome}/scripts/War.groovy" )

target('default': "Deploy war in server") {
depends(war)

// avoid War with dots (problems with static deploy)
def warTmp = "${grailsAppName}.war"
Ant.copy(file:warName, tofile:warTmp)

def dir = "/opt/jetty"

def host = "myhost.com"
def port = "22"
def user = "myuser"
def dsa = "${basedir}/scripts/key/id_dsa"


def swriter = new StringWriter()
def xml = new MarkupBuilder(swriter)

xml.Configure('class': "org.mortbay.jetty.webapp.WebAppContext") {
Set(name: 'contextPath','/')
Set(name: 'war'){
SystemProperty(name: 'jetty.home', default: '.')
mkp.yield("/webapps/${warTmp}")
}
Set(name: 'defaultsDescriptor'){
SystemProperty(name: 'jetty.home', default: '.')
mkp.yield("/etc/webdefault.xml")
}

}
def xmlDescriptor = "${basedir}/${grailsAppName}.xml"
new File(xmlDescriptor).withWriter{ writer ->
writer << '<?xml version="1.0" encoding="ISO-8859-1"?>\r\n'
writer << '<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">\r\n'
writer << swriter.toString()
writer << '\r\n'
}

echo "Deploying files to remote: ${host}"
scp(file: warTmp, todir: "${user}@${host}:${dir}/webapps", keyfile:"${dsa}", port:"${port}", passphrase:"", trust:"true")
scp(file: xmlDescriptor, todir: "${user}@${host}:${dir}/contexts", keyfile:"${dsa}", port:"${port}", passphrase:"", trust:"true")
echo "Finished :)"
}

I have an issue with hot deploy in Jetty and Grails (if anyone can help?) , but the script works well :D