Installing TomEE from Puppet
Apache TomEE is an all-Apache stack aimed at Java EE 6 Web Profile certification where Tomcat is top dog. It is the conjunction of Tomcat + Java EE. Puppet is a tool designed to manage the configuration of our systems declaratively. We only have to describe system resources and their state. This description is stored in the core-files of Puppet, which are called Puppet manifests. In current post we are going to see how to define TomEE as Puppet resource, so it can be installed automatically in all computers that are managed by Puppet. I am using Ubuntu 12.04, but of course this could be adapted to your system. Because TomEE is written in Java, we obviously need to ensure that a JDK is present in our system, for our example we are going to use OpenJDK 1.6. The way to install a package to our system is using Package resource, which uses underlying package manager to find, download and install it.
Let’s create an init.pp manifest file and the first thing we are going to do is create an exec task which updates the package manager with a list of last packages available.
# update the (outdated) package list exec { 'update-package-list': command => 'usrbinsudo usrbinapt-get update', }
Then we can define a class that is in charge of installing the OpenJDK. A class in Puppet can be understood as a collection of resources that will be seen by Puppet as a unit.
class java_6 { package { "openjdk-6-jdk": ensure => installed, require => Exec["update-package-list"], } }
It is pretty intuitive I guess, first of all we are ensuring that openjdk-6-jdk package is already present in system. If it is not installed, then Exec[‘update-package-list’] resource is executed, and finally the package manager installs OpenJDK into the system. After executing this part we can run java -version or javac -version without any problem, OpenJDK is there.
Next step is installing TomEE. Probably TomEE package is not in your distribution package repository in software package format (for example in case of Debian.deb). For this reason we need a different approach to the one followed by OpenJDK. We are going to download tar.gz file from TomEE site and uncompress it to an installation directory.
class tomee { file {"/opt/tomee-1.5.1": ensure => directory, recurse => true, } -> exec { "download-tomee" : command => "/usr/bin/wget http://apache.rediris.es/openejb/openejb-4.5.1/apache-tomee-1.5.1-webprofile.tar.gz -O /tmp/tomee-1.5.1.tar.gz", creates => "/tmp/tomee-1.5.1.tar.gz", } -> exec { "unpack-tomee" : command => "/bin/tar -xzf /tmp/tomee-1.5.1.tar.gz -C /opt/tomee-1.5.1 --strip-components=1", creates => "/opt/tomee-1.5.1/bin", } }
As with OpenJDK we are creating a class called tomee. First we are creating the directory where TomEE will be installed (tar command requires that destination directory should be already created). Then we are downloading TomEE from Apache site using wget command, to finally uncompressing it to already created directory.
Note the use of ->. Puppet does not guarantee the order of execution of defined resources, so you cannot infer ‘a priori’ if TomEE will be downloaded first and then installed or vice versa. To define an order we are using -> operator which sets a priority between resources.
Now we have got Apache TomEE installed on computer, but obviously is not started and stopped automatically, you must execute /opt/tomee-1.5.1/bin/startup.sh to have TomEE available. Let’s change this by using service resource. As its name suggests it registers as service an installed server. So inside tomee class define next service resource:
service { "tomee" : provider => "init", ensure => running, start => "/opt/tomee-1.5.1/bin/startup.sh", stop => "/opt/tomee-1.5.1/bin/shutdown.sh", status => "", restart => "", hasstatus => false, hasrestart => false, require => [ Exec["unpack-tomee"], Package["openjdk-6-jdk"] ], }
Keep an eye in two points of previous declaration, the first one is the provider/start/stop declarations, provider is set to init, which means we want to use the standard init-style service management, but for example you could use launchd (case of Mac OS X), upstart, windows (for Windows machines), … see [ http://docs.puppetlabs.com/references/latest/type.html#service] for more information. And because TomEE is not implemented as a Linux service by default (basically because has not been installed from a native package like .deb), we need to specify which command should be executed to start and stop TomEE.
The second point is that service resource requires to have TomEE unpacked and OpenJDK installed, for this reason require attribute contains two declarations. See full script here.
Final notes about example:
- In Puppet, creates attribute inside exec task, is used to know if the resource should be executed or not (case that the file exists, exec will not be executed). In our case we are downloading TomEE in tmp directory. Most OS removes periodically this directory so it is a bad location for downloading it, but for this tutorial it works perfectly because I could re-execute the script every time as a new execution.
- For simplifications we have add all content inside a single file, in your enterprise I suggest creating a TomEE module so you could share across all your projects.
- TomEE version should be set as a variable/parameter/hiera so same class can be reused when new version of TomEE is released.
Reference: Installing TomEE from Puppet from our JCG partner Alex Soto at the One Jar To Rule Them All blog.