dimanche 24 avril 2011

Automating application installation - skeleton

In a previous post, we explained how any server and application installation could be automated using IzPack. In this post, we are going to decrypt the smallest configuration that may be used to build an IzPack installer from a Maven project.


Goals

At the end of this tutorial, we will have a project that meets the following requirements :

  • The project is built using Maven
  • It packages an IzPack installer
  • It will have only 2 panels (a "Welcome" panel and a "Installation Complete !" panel)
  • It does not perform any installation operation

Setting up the project

Let's start this tutorial by a simple operation : we need to create a maven project. To do so, we use the command mvn archetype:generate . When prompted, choose the artifact maven-archetype-quickstart, which is the default one.

$ mvn archetype:generate
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [archetype:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[...]
Choose a number:  (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36/37/38/39/40/41/42/43/44/45/46) 20: :
[INFO] artifact org.apache.maven.archetypes:maven-archetype-quickstart: checking for updates from central
Define value for groupId: : fr.pingtimeout
Define value for artifactId: : izpack-environment-installer
Define value for version:  1.0-SNAPSHOT: :
Define value for package:  fr.pingtimeout: :
Confirm properties configuration:
groupId: fr.pingtimeout
artifactId: izpack-environment-installer
version: 1.0-SNAPSHOT
package: fr.pingtimeout
 Y: :
[...]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 59 seconds
[INFO] Finished at: Tue Apr 19 17:20:49 CEST 2011
[INFO] Final Memory: 8M/14M
[INFO] ------------------------------------------------------------------------

Modifying the Maven project

The archetype maven-archetype-quickstart is the perfect one for us since it does not come with anything except the basic structure of any project and empty files.

First, we need to delete those files (src/main/java/App.java and src/test/java/AppTest.java). Then, we need to create the src/main/resources/ folder. It will contain the configuration of our installer.

Let's now modify the pom.xml so that we don't have à dependency to an old version of JUnit anymore. Add a new block that will package our installer during the Maven "package" phase. This new block will be parametrised by the following elements :

  • A property defines the version of IzPack we want to use
  • Another property refers to the working directory Maven will use to build the installer
  • The plugin maven-izpack-plugin is executed during the "package" package phase with the previous properties
  • The plugin maven-resources-plugin is used to copy our project resources in the working folder
Here is our new pom.xml :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>fr.pingtimeout</groupId>

 <artifactId>izpack-maven-empty-model</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>pom</packaging>

 <name>izpack-maven-empty-model</name>

 <url>http://www.pingtimeout.fr/</url>

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

  <izpack.standalone.compiler.version>4.3.2</izpack.standalone.compiler.version>
 </properties>

 <build>
  <plugins>
   <!-- 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>${izpack.staging.dir}</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>

   <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>${izpack.staging.dir}</outputDirectory>
       <resources>
        <resource>
         <directory>src/main/resources</directory>

        </resource>
       </resources>
      </configuration>
     </execution>
    </executions>
   </plugin>

  </plugins>
 </build>
</project>

IzPack configuration

The only thing that remains on our Todo list is to configure IzPack so that it builds our empty installer. First, we need an installer descriptor (a file named install.xml in src/main/resources/). This file contains the following elements.

In the info section, we tell IzPack that :

  • Our application is named "IzPack empty Model"
  • The current installer's version is 1.0
  • We do not want an uninstaller to be built
  • Java 1.6 must be installed
  • Our installer is compressed using the Pack200 algorithm

It is available in French and is executed in a resizable window of 640x480 pixels.

In the panels section, we define 2 screens. The first one is a basic welcome screen. The second one is a generic "Installation complete !" screen.

Finally, we define the lists of files that may be copied by the installer (a list is called a "pack"). In this tutorial, there is no such file. However, the IzPack documentation tells us that at least one pack is required, so let's create an empty one.


Building the installer

That's it. The whole Maven project is ready. The only thing we have to do is to package our installer by building our project with the usual mvn package.

$ mvn clean package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building izpack-maven-empty-model
[INFO]    task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
[INFO] [resources:copy-resources {execution: copy-resources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] [site:attach-descriptor {execution: default-attach-descriptor}]
[INFO] [izpack:izpack {execution: default}]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11 seconds
[INFO] Finished at: Thu Apr 21 11:54:40 CEST 2011
[INFO] Final Memory: 11M/21M
[INFO] ------------------------------------------------------------------------

Here are some screenshots of an installer based on this tutorial.

Panel 1 - Welcome

Panel 2 - Installation complete !


Conclusion

This tutorial allows us to set up IzPack pretty quickly in a Maven project. Ideally, it could even be used to create a Maven artifact.

Now, to make full use of IzPack, we need to read the official documentation (which is very complete).


Resources

The resources that were used during this tutorial are available using the following links :

Still not convinced by the power of IzPack or its easy integration in any project ? Tell us about it in the comments !

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. :-)

jeudi 21 avril 2011

Automatiser l'installation d'applications - Squelette

Dans un précédent article, nous expliquions comment automatiser l'installation de serveur et d'application en un seul processus via l'outil IzPack. Dans cet article, nous décrypterons le squelette minimal à mettre en place pour utiliser IzPack à l'intérieur d'un projet Maven.


Objectif

A la fin de ce tutorial, nous disposerons d'un code répondant aux critères suivants :

  • Le code sera compilé avec Maven
  • Il embarquera un installeur fait avec IzPack
  • L'installeur aura deux écrans (un écran d'accueil et un écran de fin)
  • L'installeur n'effectuera aucune opération

Mise en place du projet Maven

Commençons par créer le projet Maven que nous utiliserons. Pour cela, nous utiliserons la commande mvn archetype:generate en spécifiant le modèle maven-archetype-quickstart, c'est à dire le modèle par défaut.

$ mvn archetype:generate
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO]    task-segment: [archetype:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[...]
Choose a number:  (1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/21/22/23/24/25/26/27/28/29/30/31/32/33/34/35/36/37/38/39/40/41/42/43/44/45/46) 20: :
[INFO] artifact org.apache.maven.archetypes:maven-archetype-quickstart: checking for updates from central
Define value for groupId: : fr.pingtimeout
Define value for artifactId: : izpack-environment-installer
Define value for version:  1.0-SNAPSHOT: :
Define value for package:  fr.pingtimeout: :
Confirm properties configuration:
groupId: fr.pingtimeout
artifactId: izpack-environment-installer
version: 1.0-SNAPSHOT
package: fr.pingtimeout
 Y: :
[...]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 59 seconds
[INFO] Finished at: Tue Apr 19 17:20:49 CEST 2011
[INFO] Final Memory: 8M/14M
[INFO] ------------------------------------------------------------------------

Modification du projet Maven

Le modèle maven-archetype-quickstart a ceci d'intéressant qu'il nous crée rapidement la structure Maven classique de tout projet.

Commençons par supprimer les fichiers src/main/java/App.java et src/test/java/AppTest.java. Il nous faut ensuite créer le dossier src/main/resources/ qui contiendra la configuration de IzPack.

Modifions maintenant le pom.xml de manière à ne plus avoir de dépendance vers une ancienne version de JUnit et à packager notre installeur en même temps que le projet. Nous introduisons les éléments suivants :

  • Une propriété définit la version d'IzPack que nous utiliserons
  • Une autre propriété pointe vers le répertoire de travail que Maven utilisera pour construire l'installeur
  • L'appel du plugin maven-izpack-plugin est réalisé pendant la phase "package" avec les propriétés ci-dessus
  • Nous utilisons le plugin maven-resources-plugin pour copier les ressources de notre projet dans le dossier de travail utilisé par Maven
Le nouveau pom.xml est le suivant :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>fr.pingtimeout</groupId>

 <artifactId>izpack-maven-empty-model</artifactId>
 <version>1.0-SNAPSHOT</version>
 <packaging>pom</packaging>

 <name>izpack-maven-empty-model</name>

 <url>http://www.pingtimeout.fr/</url>

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

  <izpack.standalone.compiler.version>4.3.2</izpack.standalone.compiler.version>
 </properties>

 <build>
  <plugins>
   <!-- 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>${izpack.staging.dir}</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>

   <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>${izpack.staging.dir}</outputDirectory>
       <resources>
        <resource>
         <directory>src/main/resources</directory>

        </resource>
       </resources>
      </configuration>
     </execution>
    </executions>
   </plugin>

  </plugins>
 </build>
</project>

Configuration d'IzPack

Il ne reste plus qu'à configurer IzPack pour que ce dernier nous construire l'installeur tant attendu. Pour cela, nous créons le fichier install.xml dans le dossier src/main/resources/.

Dans la section info, nous définissons que :

  • L'application s'appelle "IzPack empty Model"
  • Elle est en version 1.0
  • Nous ne voulons pas de désinstalleur
  • La version 1.6 du JRE est requise
  • Nous utilisons la méthode de compression Pack200

Nous indiquons ensuite que l'installeur est en français et qu'il s'exécute dans une fenêtre redimensionnable de 640x480 pixels

Ensuite, nous créons deux écrans dans la section panels. Le premier est un écran d'accueil générique. Le second est un écran de fin d'installation, également générique.

Enfin, nous définissons la liste des fichiers que IzPack doit traiter. Dans notre cas, il n'y en a aucun. La documentation d'IzPack nous dit cependant que la section packs est requise et qu'au moins un pack doit y être présent. Nous créons donc un pack vide.


Génération de l'installeur

La configuration du projet Maven est maintenant terminée. Il ne nous reste plus qu'à générer notre installeur en compilant simplement le projet maven.

$ mvn clean package
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building izpack-maven-empty-model
[INFO]    task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
[INFO] [resources:copy-resources {execution: copy-resources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] [site:attach-descriptor {execution: default-attach-descriptor}]
[INFO] [izpack:izpack {execution: default}]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11 seconds
[INFO] Finished at: Thu Apr 21 11:54:40 CEST 2011
[INFO] Final Memory: 11M/21M
[INFO] ------------------------------------------------------------------------

Voici des captures d'écrans d'un installeur généré sur le même modèle.

Ecran 1 - Accueil

Ecran 2 - Fin de l'installation


Conclusion

Ce tutoriel nous permet rapidement de mettre en place, ou d'inclure, Izpack dans un projet Maven. Idéalement, il pourrait d'ailleurs être automatisé à l'aide d'un artefact Maven.

Pour parfaire notre installeur, il nous faut maintenant nous plonger dans la documentation très complète d'IzPack.


Ressources

Les ressources utilisées dans ce tutoriel sont les suivantes :

Pas encore convaincu de la facilité d'intégration d'un installeur pour un projet Java ? Discutons-en dans les commentaires !

mardi 12 avril 2011

Automatiser l'installation d'applications - Partie 1

La procédure d'installation d'un système d'information complexe prend généralement des allures de cauchemard, avec un grand nombre d'actions relevant de l'utilisateur et une procédure d'installation à l'ergonomie douteuse. Dans cet article, nous verrons comment simplifier une installation à l'aide de l'outil IzPack.


Introduction

Nous disposons d'une application web baptisée hello-world-webapp-1.0.war. Elle doit être déployée dans un serveur Tomcat. Nous l'installons sur une machine dédiée, sur laquelle aucun composant n'est installé à l'exception de l'OS et de la machine virtuelle Java.

La procédure d'installation basique impliquerait les éléments suivants :

  • Copier l'archive zip de Tomcat sur le serveur
  • L'extraire dans un dossier donné
  • Créer un répertoire dans le dossier "webapps" de Tomcat
  • Copier l'application war sur le serveur
  • Extraire l'application dans le dossier nouvellement créé

Bien que les opérations à réaliser soient simples, nous remarquons tout de suite qu'elles sont déjà nombreuses pour un simple hello world.


Présentation de IzPack

IzPack est un logiciel Open-Source permettant de réaliser des installateurs (installers) à la manière d'un InstallShield, mais multi-plateformes.

IzPack fonctionne principalement grace à la compilation d'un installateur personnalisé grace à un fichier install.xml. Nous allons l'utiliser afin d'automatiser toutes les étapes listées précédemment.


Mise en place du projet Maven

Tout d'abord, nous créeons un projet Maven qui aura pour but de packager tout notre système, c'est à dire :

  • L'archive du serveur Tomcat
  • Notre application hello-world-webapp-1.0.war
  • Les fichiers requis par IzPack

Nous définissons les propriétés de notre projet (en particulier la version de IzPack et le dossier de travail) :

<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>

Ensuite, il ne reste plus qu'à inclure le plugin izpack-maven-plugin dans le processus de build :

<!-- 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>

Configuration d'IzPack

Bien qu'assez standard, nous allons décrire la configuration d'IzPack mise en oeuvre.

Les propriétés générales de l'application sont renseignées :

<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>

Nous disposons de 6 écrans au total, parmi lesquels les écrans d'accueil, d'information et d'affichage de la licence :

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

Nous pouvons maintenant nous intéresser au coeur de l'installateur : les paquets (packs). Premièrement, nous avons un "pack" contenant l'archive du serveur zip Tomcat. Nous la copions dans un dossier de travail.

<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>

Ensuite, nous copions les scripts qui automatiseront l'installation dans ce même dossier de travail. Durant cette phase, nous exécutons le script "unzip-tomcat.sh" qui permet d'extraire le serveur d'applications.

<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>

Enfin, nous déployons l'application "hello-world" dans un répertoire dédié du serveur Tomcat par le biais du script deploy-helloworld.sh.

<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>

Compilation de l'installateur

C'est terminé. Il ne nous reste qu'à exécuter la commande mvn clean install dans le dossier de notre projet pour que l'installateur soit généré.

Voici les captures d'écran de l'installateur ainsi créé.

Ecran 1 - Accueil

Ecran 2 - Informations générales

Ecran 3 - Licence

Ecran 4 - Dossier de destination

Ecran 5 - Avancement de l'installation

Ecran 6 - Fin de l'installation


Après l'installation, il ne reste plus qu'à exécuter le programme startup.sh de Tomcat pour pouvoir accéder à l'application déployée à l'adresse http://localhost:8080/hello-world/


Conclusion

IzPack permet de faciliter grandement le déploiement de systèmes d'informations. Ceci fera l'objet de quelques tutoriels supplémentaires sur PingTimeout.

Nous venons de réaliser un installateur capable d'installer un serveur d'application ainsi que de déployer une application dans ce serveur nouvellement créé. En procédant ainsi, nous réduisons les risques d'erreur liés à une mauvaise saisie et nous donnons un look beaucoup plus agréable à notre phase d'installation


Ressources

Les ressources utilisées dans ce tutoriel sont les suivantes :

Des astuces sur IzPack ? D'autres méthodes pour installer des applications ? Exprimez-vous dans les commentaires :)