Fabric3 runtimes installation on linux from rpm packages

As I mentioned, we started to work with fabric3 and after some time we were in need of install/start/stop runtimes in a nicer cleaner (more automatic) way. Let's call it clean install - as our system administrators calls it. It was basicly their idea to let maven create rpm packages which could be easy installable on any RedHat/CentOS/Fedora based system with ease. Of course maven configuration was left on us, which wasn't as hard as I first thought. Basic knowledge of rpm is required. I think some light browsing of maven rpm plugin page could be a good start...

As example is woth more than empty words I will show listings from maven pom.xml file, which will help to anyone who works with maven. I will demonstrate creating rpm packages from fabric3 runtimes on project with controller and two runtimes. Pretty simple and of course creating a bigger project is not a problem when you get the basics here. This project will consists from one rpm which will contains all. That's not a very good aproach - according to our admins (it has some disadvantages), but for the simplicity it will suffice. The best will be to have one main rpm with not writable (common) dirs and another rpms (for example one for each zone) with writable dirs, which has dependency on the main one. But as I said, if you get the basics from simple example, creation
of more advanced one is piece of cake (I can provide some examples, if someone will require it)...

First here is fabric3 new directory layout (as from 1.6 version):

  • /bin - startup modules 
  • /lib - modules required to start the runtime host 
  • /boot - modules required for the runtime bootstrap and primordial system services 
  • /host - libraries shared between the runtime and applications (e.g. web services annotations)
  • /extensions - extension modules that are to be loaded by all runtime instances  
  • /runtimes - specific runtime instance configuration is hosted by default under this directory - top level directory for a runtime configuration * */config - contains systemConfig.xml for configuring the runtime and extensions 
    • /deploy - file system deploy directory for the controller and single-VM runtimes
    • /data - persistent data directory for a runtime instance (e.g. transaction logs) 
    • /tmp - temporary data and artifact cache for a runtime instance 
    • /repository ** */runtime - extensions loaded only for the runtime image 
      • /user - user contributions (only populated on the controller and single-VM runtimes

Ok, we have simple maven project with one module and pom packaging. What we need is just some dirs with config files (systemConfig.xml), which will be installed to   writable dirs.
Our directory structure will be as follows:

/opt/myapp/ - common, not writable dirs
/var/myapp/ - writable dirs (temps, config, ...)

Before reading any further, I have to say, that this wasn't working for us on windows. That was actually the final drop to change our developers machines to linux. On servers we have CentOS and on developers machines we have fedora. Until now fedora was just a pleasure to work with (if you have skilled admins for support :-) )...

I will describe the maven project pom.xml. Besides that, there is almost nothing in the project (just some starting/stopping scripts and config files - I will get to that later).

 First you need to have fabric3-assembly-plugin in your pom, it will assemble the whole runtime to maven build dir:

<plugin>
      <groupId>org.codehaus.fabric3</groupId>
      <artifactId>fabric3-assembly-plugin</artifactId>
      <version>${fabric3.version}</version>
      <executions>
        <execution>
          <id>fabric3-assembly</id>
          <goals>
            <goal>fabric3-assembly</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <runtimeVersion>${fabric3.version}</runtimeVersion>
        <profiles>
          <!-- JMS support -->
          <profile>
            <groupId>org.codehaus.fabric3</groupId>
            <artifactId>profile-jms</artifactId>
            <version>${fabric3.version}</version>
          </profile>
          <!-- Web App support -->
          <profile>
            <groupId>org.codehaus.fabric3</groupId>
            <artifactId>profile-web</artifactId>
            <version>${fabric3.version}</version>
          </profile>
          <!-- JPA support -->
          <profile>
            <groupId>org.codehaus.fabric3</groupId>
            <artifactId>profile-jpa</artifactId>
            <version>${fabric3.version}</version>
          </profile>
        </profiles>
      </configuration>
    </plugin>

As you can see, we have there profiles for JMS, JPA and WebApp - of course there are more of these profiles, you can use whatever you will need. Next is plugin for generating rpms:

<plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>rpm-maven-plugin</artifactId>
      <version>2.1-20100401.201322-4</version>
      <extensions>true</extensions>
      <configuration>
        <copyright>MyCompany</copyright>
        <distribution>someDistribution</distribution>
        <group>someGroup</group>
        <packager>somePackager</packager>
        <changelogFile>src/changelog</changelogFile>
        <projversion>${project.version}</projversion>
        <name>fabric3-runtimes-all</name>
        <defaultDirmode>755</defaultDirmode>
        <defaultFilemode>644</defaultFilemode>
        <defaultUsername>someUser</defaultUsername>
        <defaultGroupname>someGroup</defaultGroupname>
        <preinstallScriptlet>
          <script>
            <!-- e.g. some script to create user/group -->
          </script>
        </preinstallScriptlet>
        <postremoveScriptlet>
          <script>
            <!-- e.g. some script to delete user/group -->
          </script>
        </postremoveScriptlet>
        <mappings>
          <!-- Main dirs -->
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/bin</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/lib</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/boot</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/host</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/extensions</directory>
          </mapping>
          <mapping>
            <directory>/opt/myapp</directory>
            <directoryIncluded>true</directoryIncluded>
            <sources>
              <source>
                <location>${project.build.directory}/image/</location>
                <includes>
                  <include>bin/</include>
                  <include>lib/</include>
                  <include>boot/</include>
                  <include>host/</include>
                  <include>extensions/</include>
                </includes>
              </source>
            </sources>
          </mapping>
          <!-- Writable dirs -->
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/controller</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime1</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime2</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/controller/data</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/controller/config</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/controller/tmp</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/controller/deploy</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/controller/repository</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/controller/repository/user</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/controller/repository/runtime</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/controller/data</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime1/config</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime1/tmp</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime1/deploy</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime1/repository</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime1/repository/user</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime1/repository/runtime</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime2/data</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime2/config</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime2/tmp</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime2/deploy</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime2/repository</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime2/repository/user</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/var/myapp/runtimes/runtime2/repository/runtime</directory>
          </mapping>
          <!-- Config dirs -->
          <!-- Here are all systemConfig.xml files -->
          <mapping>
            <configuration>noreplace</configuration>
            <filemode>644</filemode>
            <directory>/var/myapp/runtimes</directory>
            <directoryIncluded>true</directoryIncluded>
            <sources>
              <source>
                <filter>true</filter>
                <location>${basedir}/src/main/runtimes/</location>
              </source>
            </sources>
          </mapping>
          <!-- Scripts -->
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/bin</directory>
            <directoryIncluded>true</directoryIncluded>
            <sources>
              <source>
                <filter>true</filter>
                <location>${basedir}/src/main/scripts/</location>
              </source>
            </sources>
          </mapping>
          <!-- Admin tools -->
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/adminTools</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/adminTools/bin</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/adminTools/config</directory>
          </mapping>
          <mapping>
            <filemode>755</filemode>
            <directory>/opt/myapp/adminTools/lib</directory>
          </mapping>
          <mapping>
            <filemode>644</filemode>
            <directory>/opt/myapp/adminTools/bin</directory>
            <dependency>
              <includes>
                <include>org.codehaus.fabric3:fabric3-admin-cli</include>
              </includes>
            </dependency>
          </mapping>
          <mapping>
            <filemode>644</filemode>
            <directory>/opt/myapp/adminTools/lib</directory>
            <dependency>
              <excludes>
                <exclude>org.codehaus.fabric3:fabric3-admin-cli</exclude>
              </excludes>
            </dependency>
          </mapping>
          <mapping>
            <configuration>noreplace</configuration>
            <filemode>644</filemode>
            <directory>/opt/myapp/adminTools/config</directory>
            <directoryIncluded>false</directoryIncluded>
            <sources>
              <source>
                <filter>true</filter>
                <location>${basedir}/src/main/adminTools/config/settings.xml</location>
              </source>
            </sources>
          </mapping>
          <mapping>
            <filemode>644</filemode>
            <directory>/opt/myapp/adminTools/bin</directory>
            <directoryIncluded>false</directoryIncluded>
            <sources>
              <source>
                <filter>true</filter>
                <location>${basedir}/src/main/adminTools/bin/</location>
              </source>
            </sources>
          </mapping>
        </mappings>
      </configuration>
    </plugin>

For creating rpm package be sure to have installed linux utility rpmbuild and run maven command:
mvn clean package rpm:attached-rpm
Ok, that's all for creating rpm package, actually pretty simple, as you can see. As you can see, I packed also fabric3 admin tools with the runtimes main dirs, so I can use it for deploying scripts. I will write more about all the scripts which was mentioned in plugin configuration in next article. Simple script for starting runtimes, deploying app, ...

If you want to install rpm package use
rpm -i packane_name.rpm
for uninstalling use
rpm -e packane_name 
But you can find out more about it in linux man pages about rpm.