With this in mind, I wanted to use the Grails command line to do automated deployment based off our Hudson continuous integration container via Ant build scripts.
First I created an init.d start/stop script for the server. At theTeam we can be working on multiple projects at the same time, so we need to set some conventions about port usage so we can manage our applications easier, so this is the first step towards just that.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NAME=projectname | |
PORT=port | |
ENVIRONMENT=staging | |
URI=$NAME.$ENVIRONMENT | |
DIRECTORY=/mnt/apps/$ENVIRONMENT/$NAME | |
case "$1" in | |
start) | |
lsof -i :$PORT | |
if [ $? -eq 0 ]; then | |
echo "The port "$PORT" is already in use" | |
else | |
echo -n "Starting daemon: "$NAME | |
nohup grails -Dserver.port=$PORT -Duri=$URI prod run-app & | |
echo "." | |
fi | |
;; | |
stop) | |
echo -n "Stopping daemon: "$NAME | |
ps -ef | grep $PORT | grep -v grep | awk '{print "kill " $2}' | sh | |
echo "." | |
;; | |
*) | |
echo "Usage: "$1" {start|stop}" | |
exit 1 | |
esac | |
exit 0 |
This script is simple enough, on start it checks to see if that port is used, if so it bombs out, if not it nohup's the Grails command, telling it which port to use, and also just for ease of management, adding the name of the site. This means running commands like ps -ef and pipping to grep shows what's running. Stopping searches for a process running with that port and kills it.
That's the first step. Next is the Ant script to deploy the latest code after tests and static analysis. In this, the target folder has the latest code, we stop any server that's running, do a Grails clean and then run the server. The script then waits to see if it can open an socket to the port that the server is running on, and fails it it cannot. This usually means the server has failed to startup. The variables are gathered from a properties file and should be fairly obvious.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<target name="staging.deploy"> | |
<echo message="Stopping the server"/> | |
<exec executable="${staging.directory}/etc/init.d/${staging.startstop}" dir="${staging.directory}"> | |
<arg line="stop"/> | |
</exec> | |
<echo message="Cleaning the environment"/> | |
<exec executable="grails"> | |
<env key="JAVA_HOME" value="/usr/lib/jvm/java-6-sun/"/> | |
<arg line="clean"/> | |
</exec> | |
<echo message="Starting the server"/> | |
<exec executable="${staging.directory}/etc/init.d/${staging.startstop}" dir="${staging.directory}" spawn="true"> | |
<env key="BUILD_ID" value="dontKillMe" /> | |
<env key="JAVA_HOME" value="/usr/lib/jvm/java-6-sun/"/> | |
<arg line="start"/> | |
</exec> | |
<echo message="Checking and waiting on port ${staging.port}"/> | |
<waitfor maxwait="120" maxwaitunit="second" checkevery="5" checkeveryunit="second" timeoutproperty="deploy.failed"> | |
<socket server="localhost" port="${staging.port}"/> | |
</waitfor> | |
<fail if="deploy.failed" message="Timed out waiting for deploy"/> | |
</target> |
Now, you might have noticed a few oddities in the script like setting JAVA_HOME and BUILD_ID. First, when running in Hudson, any processes are run using the JRE and JDK that is deployed with Hudson, and I wanted to ensure it was the system Java I had installed. The BUILD_ID is a little trick that tells Hudson not to terminate the process after the build has finished, which it had a habit of doing in earlier versions.
When starting Hudson, a flag should also be set to tell it not to kill child processes. My start command is thus:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
java -jar -Dhudson.util.ProcessTreeKiller.disable=true hudson.war |
Adding this all together means it's possible to get automated deployments with Grails added into your builds.
No comments:
Post a Comment