1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in
Image:Imbox notice.png The ControlTier Wiki has moved. The new location is: http://wiki.controltier.org/

Continuous Deployment Example with Tomcat

From controltier

Jump to: navigation, search

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

Model diagram

Our example environment consists of components of these types:

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:

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

Build this example using this sequence of steps:

  1. cd $CTIER_ROOT/examples/continuous-deployment
    • Navigate to the examples/continuous-deployment directory under your $CTIER_ROOT directory.
  2. vim templates/defaults.xml
    • Use a text editor and make any necessary changes. Change localhost to your server node name.
    • Maven: Set the <mavenhome> value to the location of Maven installed in the #Dependencies section.
  3. vim projectbuilder.xml
    • Change localhost to your server node name.
  4. ctl -p demo -m ProjectBuilder -c Register -- -xml projectbuilder.xml -install
    • This loads a ProjectBuilder object definition into the ControlTier Server.
  5. 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.)
  6. 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.)
  7. 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:

First Model data in Workbench

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/

demo1 webapp running

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:

  1. Deploy the CruiseControl service to start the Continuous Integration, and make sure that it works
  2. 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:

Second model data in workbench

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:

CC first build

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:

CC first build imported as a package

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:

CC second automatic build

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:

This is a new build

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:

New War dependency

Stopping the Example Services

Once you have completed this demo, you may want to shut off the software services that were started:

  1. ctl -p demo -t CruiseControl -o continuous-deployment -c Stop
    • stops the CruiseControl service
  2. ctl -p demo -t Site -o continuous-deployment -c Stop
    • stops all services for the Site, including the TomcatServer service
Personal tools