I like continuous deployment just like continuous integration. However it can be pain if you have too many environments to deploy to.
In the project that I am currently involved in, we have 3 environments for which continuous deployment makes sense. Deployment frequency is different, deployment policies are different but I am sure it is possible to automatize the deployment process up to some extend.
Just for that reason (and also because I am bored of doing deployment and I like writing scripts time to time), I spent a couple of hours to write a script that can be invoked by cron
to do deployment to tomcat
. The process is easy;
- Scripts checks all the war files under a specific folder
- For every war file under in that directory
- Checks if the war file is complete
- If so stops tomcat (only for once:) )
- Removes all the files related to the current war file from tomcat/webapps
- Copies war file to tomcat/webapps
- Starts tomcat
The full script is as follows. I am not a experienced bash coder, so be fair. Now all you have to do is to transfer the file to inbound directory. There are different ways for different build management tools. I am using maven so I defined an ant-run
goal to copy the deployables via ssh.
#!/bin/sh SCRIPT_USER="dev" TOMCAT_DIR="/appdata/apps/wcm" WAIT=10 TOMCAT_STOPPED=0 log_deployment() { ssh dev@43.191.66.23 'echo "Deployment was started at `date`" > /appdata/apache2/htdocs/deploy.txt' } start_tomcat() { if [ $TOMCAT_STOPPED -eq 1 ]; then log "Starting tomcat" $TOMCAT_DIR/bin/startup.sh log_deployment fi } # stops tomcat stop_tomcat() { if [ $TOMCAT_STOPPED -eq 0 ]; then log "Stopping tomcat" $TOMCAT_DIR/bin/shutdown.sh sleep $WAIT log "Making sure it is stopped by killing(-9) any process contains java and tomcat in their run command" kill -9 `ps ux | awk '/java/ && /tomcat/ && !/awk/ {print $2}'` TOMCAT_STOPPED=1 fi } # prepares deployable for deployment prepare_for_deploy() { log "Going to make deployment for $1, file size is stable" log "Moving deployable $1 to processed directory" BASE_NAME="`basename $1`" BASE_NAME=${BASE_NAME:0:${#BASE_NAME}-4} log "Cleaning tomcat webapps directory for $BASE_NAME" rm -rf $TOMCAT_DIR/webapps/$BASE_NAME* log "Moving $1 to tomcat webapps directory" mv $1 $TOMCAT_DIR/webapps/. } # logs a message with date log() { echo "`date` >> $1" } # logs an error with date error() { echo "`date` >> $1" 1>&2 } if [ $USER != $SCRIPT_USER ]; then error "You must run this script as user '$SCRIPT_USER'!" exit 1 fi log "Checking inbound for deployables" cd `dirname $0` mkdir -p inbound if [ -z `ls inbound/*.war` ]; then log "No deployables found" exit 0 fi for f in inbound/*.war; do LAST_ACCESS=$(stat -c%Y "$f") NOW=$(date +%s) let DIFF=$NOW-$LAST_ACCESS log "$f is accessed $DIFF seconds ago." SIZE1=$(stat -c%s "$f") sleep $WAIT SIZE2=$(stat -c%s "$f") if [ "$SIZE1" -eq "$SIZE2" ] then stop_tomcat prepare_for_deploy $f else log "File is still being copied" fi done start_tomcat