| |
Continuous Deployment Example with Tomcat
From controltier
Requires Version 3.4.3 (help?)
In this example, we will demonstrate how to implement a Continuous Deployment mechanism using ControlTier, to automatically build and deploy a WAR to a Tomcat server after a code-change is performed.
Contents |
Description
Our Continuous Deployment example will create a War archive from a simple Subversion repository of code, and deploy that War to a Tomcat server.
Here is the Object composition model for this example:
Diagram: The Object Model
Our example environment consists of components of these types:
- TomcatServer
- Updater
- Site
- MavenBuilder
- CruiseControl service
- war (Package subtype)
- CruiseControlZip package
Dependencies
- Linux
- This demo is compatible with Linux only
This demo depends on three Third-Party software packages, for Cruise Control, Apache Tomcat, and Apache Maven 2. The versions referenced and used below are:
- Tomcat - 6.0.1.4
- Download: http://archive.apache.org/dist/tomcat/tomcat-6/v6.0.14/bin/apache-tomcat-6.0.14.zip
- Copy the downloaded Zip to
$CTIER_ROOT/examples/continuous-deployment/pkgs/apache-tomcat-6.0.14.zip
- Cruise Control - 2.7.1
- Download the "cruisecontrol-bin-2.7.1.zip" file: http://sourceforge.net/project/showfiles.php?group_id=23523&package_id=16338&release_id=518602
- Copy the downloaded Zip to
$CTIER_ROOT/examples/continuous-deployment/pkgs/cruisecontrol-bin-2.7.1.zip
- Maven - 2
- Download the "apache-maven-2.x.x.zip" file: http://maven.apache.org/download.html
- To install Maven, simply extract the archive, and place the dir "apache-maven-2.x.x" somewhere.
- The demo assumes it is installed at this location:
$CTIER_ROOT/examples/continuous-deployment/pkgs/apache-maven-2.0.9, but you can change the path in thedefaults.xmlfile as mentioned below.
The apache-tomcat-6.0.14.zip and cruisecontrol-bin-2.7.1.zip files will be installed as part of the demo below.
Building the Example
- See Using the Examples for complete detail about how to use the Examples
Build this example using this sequence of steps:
-
cd $CTIER_ROOT/examples/continuous-deployment
- Navigate to the
examples/continuous-deploymentdirectory under your$CTIER_ROOTdirectory.
- Navigate to the
-
vim templates/defaults.xml
- Use a text editor and make any necessary changes. Change
localhostto your server node name. - Maven: Set the <mavenhome> value to the location of Maven installed in the #Dependencies section.
- Use a text editor and make any necessary changes. Change
-
vim projectbuilder.xml
- Change
localhostto your server node name.
- Change
-
ctl -p demo -m ProjectBuilder -c Register -- -xml projectbuilder.xml -install
- This loads a ProjectBuilder object definition into the ControlTier Server.
-
ctl -p demo -m zip -c upload -- -filename pkgs/apache-tomcat-6.0.14.zip -xml templates/apache-tomcat-6.0.14.zip.xml
- Upload the "apache-tomcat-6.0.14.zip" file to the package repository. (See #Dependencies for download link.)
-
ctl -p demo -m zip -c upload -- -filename pkgs/cruisecontrol-bin-2.7.1.zip -xml templates/cruisecontrol-bin-2.7.1.zip.xml
- Upload the "cruisecontrol-bin-2.7.1.zip" file to the package repository. (See #Dependencies for download link.)
-
ctl -p demo -t ProjectBuilder -o continuous-deployment -c Build
- Builds a working example based on template files and your working environment. Later see Further Customization
You are now ready to run the example.
The Object Model
The bootstrapping steps above have generated a file called default-object.xml. This file is in the project-v10.xml format. For more information about creating an object model, see Project Model Basics.
Take a look at the default-object.xml file. You will notice that it defines <setting> objects to define values for the MavenBuilder. Also notice that there are <deployment> entries for each of the Updater, MavenBuilder, Site, CruiseControl, and TomcatServer types. The TomcatServer references a TomcatZip object, and the CruiseControl deployment references a CruiseControlZip. These two packages are defined in the two xml files you used with the upload commands above: templates/cruisecontrol-bin-2.7.1.zip.xml and templates/apache-tomcat-6.0.14.zip.xml. If you look at the content of those files you will see that the packages are defined with a simple <package> element.
- Why is there no definition of the war file we will deploy to tomcat?
- This is because we haven't built the war file yet! The MavenBuilder is configured to know how to import such a war into the repository and define it as a Package object. Once we have built it, we will use a command to automatically modify the model to add it to TomcatServer.
You can see that the model is now viewable in Workbench. Go to the Process Manager from the Workbench homepage. You will see the Updater object, and you can expand the Child Dependencies to see that the other objects are defined:
Configure the Webapp Source
Create a source tree
We will define a simple web-app that uses Maven2 to build it. To create the source content and import it, we are going to use a temp directory:
mkdir -p $CTIER_ROOT/examples/continuous-deployment/temp
The webapp source is available in the "demo1-webapp-src.zip" file included in the example code.
- This file is available in the example code at the path "$CTIER_ROOT/examples/continuous-deployment/content/demo1-webapp-src.zip".
Extract the zip content into the temp directory.
cd $CTIER_ROOT/examples/continuous-deployment/temp unzip $CTIER_ROOT/examples/continuous-deployment/content/demo1-webapp-src.zip
This will have a pom.xml and a source tree for you. Your directory content should look like:
$CTIER_ROOT/examples/continuous-deployment/temp/demo1/pom.xml $CTIER_ROOT/examples/continuous-deployment/temp/demo1/src $CTIER_ROOT/examples/continuous-deployment/temp/demo1/src/main $CTIER_ROOT/examples/continuous-deployment/temp/demo1/src/main/resources $CTIER_ROOT/examples/continuous-deployment/temp/demo1/src/main/webapp $CTIER_ROOT/examples/continuous-deployment/temp/demo1/src/main/webapp/index.jsp $CTIER_ROOT/examples/continuous-deployment/temp/demo1/src/main/webapp/WEB-INF $CTIER_ROOT/examples/continuous-deployment/temp/demo1/src/main/webapp/WEB-INF/web.xml
Notice that the file $CTIER_ROOT/examples/continuous-deployment/temp/demo1/src/main/webapp/index.jsp is a simple jsp file with a line that echoes the current date:
<p>Hello! The time is now <%= new java.util.Date() %></p>
Import the source tree to subversion
For purposes of the demo, we are going to create a simple subversion repository where we can store this source code.
Execute the following commands:
mkdir $CTIER_ROOT/examples/continuous-deployment/demo export SVNROOT=$CTIER_ROOT/examples/continuous-deployment/demo/svnroot svnadmin create $SVNROOT svn mkdir -m "create demo1 sourcebase" file://$SVNROOT/demo1 svn mkdir -m "create demo1 trunk" file://$SVNROOT/demo1/trunk
You should see the messages:
$ svn mkdir -m "create demo1 sourcebase" file://$SVNROOT/demo1 Committed revision 1. $ svn mkdir -m "create demo1 trunk" file://$SVNROOT/demo1/trunk Committed revision 2.
Now we need to import our source tree.
svn import -m "import demo1 content" $CTIER_ROOT/examples/continuous-deployment/temp/demo1 file://$SVNROOT/demo1/trunk
The output should show:
Adding /Users/greg/ctier3/examples/continuous-deployment/temp/demo1/src Adding /Users/greg/ctier3/examples/continuous-deployment/temp/demo1/src/main Adding /Users/greg/ctier3/examples/continuous-deployment/temp/demo1/src/main/resources Adding /Users/greg/ctier3/examples/continuous-deployment/temp/demo1/src/main/webapp Adding /Users/greg/ctier3/examples/continuous-deployment/temp/demo1/src/main/webapp/index.jsp Adding /Users/greg/ctier3/examples/continuous-deployment/temp/demo1/src/main/webapp/WEB-INF Adding /Users/greg/ctier3/examples/continuous-deployment/temp/demo1/src/main/webapp/WEB-INF/web.xml Adding /Users/greg/ctier3/examples/continuous-deployment/temp/demo1/pom.xml Committed revision 3.
We now have our code in the subversion repository. In order to get a working copy of this code we have to check it out.
cd $CTL_BASE/src svn checkout file://$SVNROOT/demo1/trunk demo1
Output:
A demo1/src A demo1/src/main A demo1/src/main/resources A demo1/src/main/webapp A demo1/src/main/webapp/index.jsp A demo1/src/main/webapp/WEB-INF A demo1/src/main/webapp/WEB-INF/web.xml A demo1/pom.xml Checked out revision 3.
You can now remove the directory "$CTIER_ROOT/examples/continuous-deployment/temp".
cd $CTIER_ROOT/examples/continuous-deployment rm -r temp
Recall that in our default-object.xml file, we have a <setting> entry for the "BuilderScmConnection" which points to the location of our source code with the value: "file://${env.CTIER_ROOT}/examples/continuous-deployment/demo/svnroot/demo1/trunk". This is where we have checked in our source and where the Builder will checkout the source code from.
Test the Build and Deploy
Let's test the Build and Deploy sequences indpendently before we move on to making them happen automatically using Cruise Control.
Since we have just loaded the model, we don't yet have a War of our example webapp created.
Create that now using the Build command for the Builder:
ctl -p demo -t MavenBuilder -o continuous-deployment -c Build -- -buildstamp test1
You can see that the demo1-test1.war package was created and uploaded to the repository.
Since we now want to deploy it to the server, let's use the Update command.
ctl -p demo -t Site -o continuous-deployment -c Update -- -buildstamp test1
This command first configures the dependencies of the TomcatServer to use the new War we just built, and then it tells the TomcatServer to Deploy itself, causing the installation of the TomcatZip (the server package itself), and then the demo1 War that we built.
You should now be able to view the demo1 war webapp by visiting http://localhost:9090/demo1/
Add Cruise Control
The data model that we have loaded into the server already has CruiseControl configured. The file default-object.xml defines the CruiseControl service deployment. The CruiseControl service has the CruiseControlZip and the MavenBuilder as resources.
We will proceed with two steps:
- Deploy the CruiseControl service to start the Continuous Integration, and make sure that it works
- Turn on the automatic Update feature to begin the Continuous Deployment
First Step - Continuous Integration
If you look at the Service List in Workbench, you should see the CruiseControl service, with its correct dependencies:
We have configured the CruiseControl object to have the MavenBuilder object as a resource. This combination will allow us to generate the appropriate configuration for Cruise Control using the Deploy workflow.
Go ahead and deploy Cruise Control by using the Deploy command:
ctl -p demo -t CruiseControl -o continuous-deployment -c Deploy
You should see output like:
... Running handler command: startService CruiseControl started. end workflow command (1/1) -> "assertServiceIsUp " end workflow command (4/4) -> "Start "
This should start up the CruiseControl server, which will immediately begin a source code build. View the status of Cruise Control by going to the URL: http://localhost:8081/
You should see the first build in process or already completed successfully:
In the Workbench Package List, you should now see a War package that corresponds to the build that Cruise Control just performed, as it has now been uploaded to the Package Repository. You should see a "demo1-1.0.3.war" file, which is so named because the last commit to the Subversion repository was revision 3:
We now have the following:
- Cruise Control control configured to automatically build packages when a source code commit occurs.
- If we wanted to, we could now do a full Deploy of that recently built package by invoking the Update command for our Site object.
Instead, let's implement the next step:
Second Step - Set up Automatic Deployment
This step is actually very simple. All we need to do is change our MavenBuilder to have a value of "true" for the "autoUpdate" attribute. We can simply change the BuilderAutoUpdate Setting object to have this value.
Change the file templates/defaults.xml file to set the <builder><autoUpdate> to "true":
.. <builder> <autoupdate>true</autoupdate> </builder> ..
Re-load it using the ProjectBuilder Build command
ctl -p demo -t ProjectBuilder -o continuous-deployment -c Build
You should now see a value of "true" for the "autoUpdate" attribute of your builder. Run the Properties command to see the attributes/properties:
ctl -p demo -t MavenBuilder -o continuous-deployment -c Properties
[MULTI_LINE] # demo1 [MavenBuilder] # A Builder to build and package the demo1 app using maven ## Attributes ## * autoUpdate: "true" ...
The final necessary step is to re-Deploy the CruiseControl service. This regenerates the config.xml for CruiseControl, to adopt the new autoUpdate behavior for your MavenBuilder.
$ ctl -p demo -t CruiseControl -o continuous-deployment -c Deploy
That's it! You have now implemented a full Continuous Deployment system. The next time that CruiseControl rebuilds your webapp, it will also automatically deploy it to your TomcatServer instance.
See it in action
To see the mechanism in action, simply commit a change to your source repository. Modify the index.jsp file:
vim $CTL_BASE/src/demo1/src/main/webapp/index.jsp
Add this content:
<b>This is a new build</b>
Then commit the file:
$ svn ci -m "change to kick off build" $CTL_BASE/src/demo1/src/main/webapp/index.jsp Sending src/demo1/src/main/webapp/index.jsp Transmitting file data . Committed revision 4.
Watching the Cruise Control console you should eventually see a new build begin:
This process will not only build the War and upload it to the repository, it will then automatically deploy it to your TomcatServer.
Once the build process completes, reload your tomcat server page: http://localhost:9090/demo1
You should see the new content:
You should also see that the War child dependency for your TomcatServer service has changed to the newest demo1-1.0.4.war package which was built by CruiseControl:
Stopping the Example Services
Once you have completed this demo, you may want to shut off the software services that were started:
-
ctl -p demo -t CruiseControl -o continuous-deployment -c Stop
- stops the CruiseControl service
-
ctl -p demo -t Site -o continuous-deployment -c Stop
- stops all services for the Site, including the TomcatServer service









