dimanche 24 avril 2011

Automating application installation - Part 1

Any complex system installation can sometimes turn into a complete nightmare, with lots of manual actions and user inputs and an installation notice user-not-so-friendly. In this article, we will explain how such an installation can be simplified using a tool named IzPack.

Introduction

We created a web application which is called hello-world-webapp-1.0.war. We want this application to be deployed in a Tomcat server. The installation will be made on a dedicated server which contains only an operating system and the Java Virtual Machine.

At least, a classic installation notice would contain the following elements :

  • Copy the Tomcat zip archive on the server
  • Extract it
  • Create a folder with the name of our application in tomcat "webapps" directory
  • Copy the application war on the server
  • Extract this war in the newly created folder

Although those operations are pretty simple, they are quite numerous for a basic hello world.


What is "IzPack" ?

IzPack is an open-source tool that allows us to create graphical installers, like InstallShield do, but cross-platform.

How does IzPack work ? Well, it compiles a user defined installation descriptor (a file named install.xml) and generates a graphical installer that does almost everything. We are going to use it to automate every installation step we described.


Setting up the Maven project

First, we need a Maven project which will package our installer, that is :

  • The zip archive of tomcat
  • Our application hello-world-webapp-1.0.war
  • IzPack runtime files

Then, we define some properties in the project (like the version of IzPack and its working directory) :

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <staging.dir>${project.build.directory}/staging</staging.dir>
    <izpack.standalone.compiler.version>4.3.2</izpack.standalone.compiler.version>
</properties>

Finally, we include the plugin izpack-maven-plugin in our project's build lifecycle :

<!-- Used to configure IzPack installer -->
<plugin>
    <groupId>org.codehaus.izpack</groupId>
    <artifactId>izpack-maven-plugin</artifactId>
    <version>1.0-alpha-5</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>izpack</goal>
            </goals>
            <configuration>
                <izpackBasedir>${staging.dir}/izpack</izpackBasedir>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.izpack</groupId>
            <artifactId>izpack-standalone-compiler</artifactId>
            <version>${izpack.standalone.compiler.version}</version>
        </dependency>
    </dependencies>
</plugin>
<!-- Instead of working in the src/ folder, create a staging directory and copy every ressources in this folder -->
<plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.4.2</version>
    <executions>
        <execution>
            <id>copy-resources</id>
            <phase>validate</phase>
            <goals>
                <goal>copy-resources</goal>
            </goals>
            <configuration>
                <encoding>UTF-8</encoding>
                <outputDirectory>${staging.dir}</outputDirectory>
                <resources>
                    <resource>
                        <directory>src/main/resources</directory>
                    </resource>
                </resources>
            </configuration>
        </execution>
    </executions>
</plugin>

IzPack configuration

Even though this configuration is quite basic, we are going to describe how it produces our installer.

Some general application properties are defined :

<info>
    <appname>pingtimeout-sample-installer</appname>
    <appversion>1.0</appversion>
    <authors>
        <author email="pierre@pingtimeout.fr" name="Pierre Laporte" />
    </authors>
    <url>http://www.pingtimeout.fr</url>
    <uninstaller write="no" />
    <javaversion>1.6</javaversion>
    <requiresjdk>yes</requiresjdk>
    <writeinstallationinformation>no</writeinstallationinformation>
    <pack200 />
</info>

Our installer in composed by 6 panels. amongst which the "Welcome" panel and the "Do you agree with the licence ?" panel :

<panels>
    <panel classname="HelloPanel" />
    <panel classname="InfoPanel" />
    <panel classname="LicencePanel" />
    <panel classname="TargetPanel" />
    <panel classname="InstallPanel" />
    <panel classname="SimpleFinishPanel" />
</panels>

Now, the most important part : the packs. The first one contains the Tomcat archive. We want it to be copied in the working directory

<pack name="Copy Apache Tomcat package" preselected="yes" required="yes">
    <description>Copy Apache Tomcat package in $INSTALL_PATH/work/</description>
    <file override="true"
          src="../tomcat/apache-tomcat-7.0.12.zip"
          targetdir="$INSTALL_PATH/work/">
        <os family="Unix" />
    </file>
</pack>

The second pack contains our installation scripts that will do every task we listed (unpacking Tomcat, create a directory, ...). Once these scripts are copied, we want IzPack to execute the "unzip-tomcat.sh" script (which unzips tomcat archive, obviously).

<pack name="Unzip Apache Tomcat" preselected="yes" required="yes">
    <description>Unzip Apache Tomcat in $INSTALL_PATH/work/</description>
    <depends packname="Copy Apache Tomcat package" />
    <file override="true"
          src="../scripts"
          targetdir="$INSTALL_PATH/work/">
        <os family="Unix" />
    </file>
    <executable failure="abort"
                keep="true"
                stage="postinstall"
                targetfile="$INSTALL_PATH/work/scripts/unzip-tomcat.sh">
        <args>
            <arg value="$INSTALL_PATH" />
        </args>
    </executable>
</pack>

The last pack will handle every task related to our "hello-world" application. That is : create a directory in the "webapps" folder and unzip the application war file.

<pack name="Install Hello World application" preselected="yes" required="yes">
    <description>Copy the Hello World WAR in Tomcat webapp directory</description>
    <depends packname="Unzip Apache Tomcat" />
    <file override="true"
          src="../applications/hello-world-webapp-1.0.war"
          targetdir="$INSTALL_PATH/work/">
        <os family="Unix" />
    </file>
    <executable failure="abort"
                keep="true"
                stage="postinstall"
                targetfile="$INSTALL_PATH/work/scripts/deploy-helloworld.sh">
        <args>
            <arg value="$INSTALL_PATH" />
        </args>
    </executable>
</pack>

Compiling the installer

That's it. We can now create our installer compiling our project (with the mvn clean install command).

Here are some screenshots of our installer.

Panel 1 - Welcome

Panel 2 - General informations

Panel 3 - Licence

Panel 4 - Destination folder

Panel 5 - Installation progress

Panel 6 - Installation complete


Once the installation is completed, we may run tomcat using startup.sh so that we can access our application (http://localhost:8080/hello-world/)


Conclusion

IzPack allows us to make the administrator's life simpler, as the installation of our system is now a piece of cake. Some more tutorial will soon be posted on PingTimeout.

We just created an installer capable of installing an application server, managing directories and deploying an application. Using IzPack, we reduce the risk of erroneous user input, and give our installation phase a nicer look.


Resources

The project used in this tutorial, and every related resources can be downloaded using the following links :

Do you have tips about IzPack ? Other installation practices ? Let's talk about it in the comments. :-)

1 commentaire:

  1. Bonjour, je ne parlent pas français, but i know english :D im working with bonitasoft, im installing Bos 5.4.1 user xp in glassfish 3.1 could you please help me??, i had saw the tutorial that you have made..but i didnt get it, thanks so much, merci :D

    RépondreSupprimer