Component XML

At the core of BlackBadger is the notion of a component. A component represents a logical piece of software that has a number of states that defines it's life cycle. The default set of states that component can be defined as is:

  • CLEAN - Called at the start to ensure the environment is clean for deployment
  • DEPLOY - Called to get the software downloaded and installed
  • RUN - Called when the system is ready to have the component startup
  • TEST - Called when the system is ready to start testing
  • TERMINATE - Called when either an exception/error has occurred or the system is to stop.

The MASTER executes each state in order, but most importantly ensures that all of the components in the system are in the same state before moving onto the next state. If an error occurs in any of the states executions then the system as a whole fails and must be corrected. This makes sure that you aren't for example, calling an SQL statement on a database that doesn't exist.

The component xml takes the format of an Ant build file with targets for each of the different states. The following example shows a component xml file for the Apache webserver. At the start we define the variables that this component requires. This allows you to setup defaults, or override them when you are defining the component in the <agent> block. For example here, we define the 'filename' variable which is the name of the tarball of the application code. We could pass instead, a value of say, apache_1_3_25patched.tar.gz to override the standard one.

The "clean" target is the first target called in a run and is designed to ensure the machine is in a clean state for this component to be started. That equates to deleting any files or directories that may have been left over from a previous run. In this example we remove the apache installation directory if it's there and recreate it as empty. We also delete the files that the deploy target downloads to the temporary directory.

The <target name="deploy"> block is a sequence of ant tasks that setup the machine in a state ready to run this component. We start by going to the named repository - http://repository.spikesource.com/ - and downloading the tar file named by the 'filename' property. Then unzip it into the directory, as specified by the 'dir_installation' property. Assuming nothing goes wrong, this component will be deemed successfully deployed.

Once all components for the entire system have been deployed without error, the system then enters the <run> state. In this example, we use the <exec> task to startup Apache.

In the 'test' state, this component does nothing. It's at this point the component responsible for running the tests will have a set of tasks to run to complete the testing that will have some reliance on Apache.

Conversely, should something go wrong, or a component wants to exit the system (for example the end of a test run), then the <terminate> block is called, which in this case, we merely call the shutdown script for apache.

<?xml version="1.0" encoding="UTF-8"?>
<project name="apache_currentstack">

  <!-- Define the variables that this component requires -->
  <property name="repository">http://repository.spikesource.com/</var>
  <property name="filename">apache_1.3.37.zip</var>
  <property name="dir_installation">/opt/apache/</var>

   <!-- CLEAN is the first state to be trigged -->
   <target name="clean">
     <!--- Clean up the installation directory -->
     <delete dir="${dir_installation}"/>
     <mkdir dir="${dir_installation}"/>

     <delete file="${tmp}${tarball}"/>
   </target>
 
   <!-- DEPLOY installs Apache -->
   <target name="deploy">

     <!-- Get the tarball from the remote site and untar it -->
     <get src="${system.repository}tarballs/${tarball}" dest="${tmp}${tarball}"/>
     <unzip src="${tmp}${tarball}" dest="${dir_installation}"/>

   </target>
	
   <!-- RUN is called to start the component up -->
   <target name="run">
     <!--- Startup Apache --->
     <exec executable="${dir_installation}/bin/apachectrl" parallel="false">
       <arg line="start"/>
     </exec>
   </target>

   <!-- TEST -->
   <target name="test">
     <!-- Don't need to do anything in here -->
   </target>
	
   <!-- TERMINATE is called when the component is to be killed -->
   <target name="terminate">
     <apply executable="${dir_installation}/bin/apachectrl" parallel="false">
       <arg value="stop"/>
     </apply>
   </target>
</project>

Note that this example only goes to illustrate the basic concept of the component xml file. It can be further improved by including a check to verify that Apache has started (Ant has a <waitfor> ideal for this), adding further properties like the port or docroot Apache to make it more flexible and reusable, and adding logging in the terminate state (see the Logging section for more details).