Thématiques principales

samedi 24 mars 2018

Maven : assembly, targz et jdeb

Aujourd’hui nous allons nous intéresser à la production du livrable issue de la production logicielle. Le sujet ne va pas etre forcement tres long a traiter tant maven permet de chose si l’on utilise les bons plugins.

La production du livrable impose avant tout la définition de celui ci. Souvent, il va être dépendant de la plateforme et du langage. Dans notre cas, nous allons tâcher de produire nos composants dans le contexte d’utilisation du langage Java et nous nous projeterons dans une plateforme linux, la debian et la plateforme windows.

Bien sûr on aurait pu passer par l’utilisation de profile maven dans lequel nous aurions spécifier selon l’OS différents plugins afin de répondre à cette problématique de production. Par exemple en définissant les profiles suivants:

<profiles>
 <profile>
  <activation>
   <os>
    <family>windows</family>
   </os>
  </activation>
  <build>...</build>
  ...
 </profile>
 <profile>
  <activation>
   <os>
    <family>linux</family>
   </os>
  </activation>
  <build>...</build>
  ...
 </profile>
</profiles>


Nous n'utilisons pas cette approche car d’une part non nécessaire puisque Java est multiplateforme et d’autre part elle complexifie lourdement la production (l’utilisation de profile n’etant une bonne chose que si on en peut vraiment pas faire autrement)

Au lieu de cela, nous allons plutôt tricher un peu et prendre le parti pris que nous souhaitons livrer simplement un targz pour windows et un deb sous linux (comme cela, on pourra produire le même jar et livrer d’un côté un script bash pour lancer notre appli et de l’autre un bat.) Pour répondre à ce problème nous allons utiliser le plugin maven-assembly-plugin.

Ce plugin est un plugin indispensable pour la plupart des builds maven car au delà de l’utilisation ce que nous allons en faire, il permet de faire surtout toute sorte de compositions, de construire tout type de paquet de livraison mais aussi de pouvoir construire des jar au contenu spécifique (nous y reviendrons mais pas dans cet article) .

Nous avons donc deux types de packaging à réaliser, un pour le targz et un autre pour le deb. On va configurer le plugin pour qu’il fasse les deux en même temps en définissant deux fichiers d’assembly:

<plugin>
 <groupid>org.apache.maven.plugins</groupid>
 <artifactid>maven-assembly-plugin</artifactid>
 <version>2.5.3</version>
      <configuration>
  <finalname>${project.artifactId}-${project.version}</finalname>
  <ignoredirformatextensions>true</ignoredirformatextensions>
  <outputdirectory>${project.build.directory}</outputdirectory>
       </configuration>

 <executions>
  <!-- Packaging debian -->
  <execution>
   <id>assembly-debian</id>
   <phase>prepare-package</phase>
   <goals>
    <goal>single</goal>
   </goals>
   <configuration>
    <appendassemblyid>false</appendassemblyid>
    <descriptors>
     <descriptor>src/main/assembly/assembly-debian.xml</descriptor>
    </descriptors>
   </configuration>
  </execution>
  <execution>
   <id>assembly-targz</id>
   <phase>package</phase>
   <goals>
    <goal>single</goal>
   </goals>
   <configuration>
    <appendassemblyid>false</appendassemblyid>
    <descriptors>
     <descriptor>src/main/assembly/assembly-targz.xml</descriptor>
    </descriptors>
   </configuration>
  </execution>
 </executions>
</plugin>


Quelques explications sur l’utilisation du plugin dans le pom. On précise le répertoire de sortie et le nom général de la composition. On spécifie ensuite par type de composition un élément de configuration en utilisant appendAssemblyId. Ceci permet d’ajouter le classifier “assembly” au nom de la composition, mais ici on va s’en passer. On met false. On précise également pendant quelle phase et quel goal les assembly devront être construit. Enfin on donne au plugin le fichier d’assembly qui précise le contenu de la composition.

Le fichier assembly est la dernière partie permettant de construire la composition. Il s’agit d’un fichier xml définissant plusieur choses: le format de sortie, les dépendances à joindre et ou les déposer et enfin les répertoires annexes que la composition doit contenir. Regardons celui du targz:

<assembly>
 <id>bundle</id>
 <formats>
  <format>tar.gz</format>
 </formats>
 <includebasedirectory>false</includebasedirectory>

 <dependencysets>
<!--  Inclusion interfaces classifier et librairies-->
  <dependencyset>
   <unpack>false</unpack>
   <scope>runtime</scope>
   <useprojectartifact>false</useprojectartifact>
   <useprojectattachments>true</useprojectattachments>
   <outputdirectory>/opt/monappli</outputdirectory>
   <includes>
    <include>*:${project.artifactId}:*:assembly:*</include>
   </includes>
  </dependencyset>
 </dependencysets>

  <filesets>
      <fileset>
          <directory>src/main/debian/etc/init.d</directory>
          <outputdirectory>/etc/init.d</outputdirectory>
          <usedefaultexcludes>true</usedefaultexcludes>
          <filtered>true</filtered>
          <includes>
              <include>monappli</include>
          </includes>
      </fileset>
  </filesets>
</assembly>


Inutile de commenter le format, il parle de lui-même. Les dependencySet se construisent pour incorporer à la composition les éléments des dépendances qu’il faudra ajouter et sous quel forme. Par exemple on peut spécifier si elles seront dézipper dans la composition (cela est pratique par exemple lorsque l’on veut fusionner des artifacts ensemble pour faire un jar), le répertoire ou ces éléments seront déposé et enfin un ensemble d'artifact déclarer sous la forme d’une regex.

Les fileSet précisent de la même manière que pour les artifacts l’ensemble des fichiers et répertoires à construire dans notre composition. Ces éléments sont généralement issus des ressources du projets et il est possible de réaliser du remplacement clef/valeur dedans (via le resources filtering). A l’issu de l’application de l’assembly, on aura alors tous ces éléments dans un tar.gz… cool!

Bon bien du coup on fait pareil pour le paquet debian non? et bien pas tout à fait. sur le principe, on va procéder de la même manière en utilisant un fichier d’assembly rigoureusement identique sauf sur le format que nous définirons a “dir”. Ce format ne fait rien a part préparer les éléments de la composition. Pourquoi prendre ce format? Tout simplement parce que le plugin assembly n’est pas capable de construire quelque chose d’aussi complexe qu’un paquet debian. On va donc s’appuyer d’un autre plugin pour faire cela: jdeb. Avant cela je vous renvoie à [3] pour compléter vos ressources avec les fichiers de contrôles qui vont bien et les intégrer à l’assembly.

Ceci étant fait, penchons nous sur le plugin jdeb. Celui ci se configure assez classiquement en précisant sa phase de build et son goal. A cela, on va preciser le nom du paquet debian, le repertoire des fichiers de controles, et enfin un ensemble de dataset precisant tous les repertoire, fichiers et autres resources qui va falloir ajouter au paquet. Attention, a ce nieau, il faut avoir une vision clair des droits qui seront appliqué lors de l’installation, puisque l’on va les preciser ici. Voyons cela:

<plugin>
 <artifactid>jdeb</artifactid>
 <groupid>org.vafer</groupid>
 <version>1.5</version>
 <executions>
  <execution>
   <phase>package</phase>
   <goals>
    <goal>jdeb</goal>
   </goals>
   <configuration>
    <deb>${project.build.directory}/${project.artifactId}-${build}_${versiontimestamp}_all.deb</deb>
    <verbose>true</verbose>
    <controldir>${project.build.directory}/${project.artifactId}-${project.version}/DEBIAN</controldir>
    <dataset>
     <data>
      <src>${project.build.directory}/${project.artifactId}-${project.version}/opt</src>
      <type>directory</type>
      <mapper>
       <type>perm</type>
       <prefix>/opt</prefix>
      </mapper>
     </data>
    </dataset>
   </configuration>
  </execution>
 </executions>
</plugin>


Voilà, nous venons de passer en revu comment construire les livrables de nos projets. Bien sur faire du java permet déjà de packager les sources mais pour être propre, l'idéal est de fournir un composant standard comme un targz ou mieux un deb contenant tous les éléments permettant de faire vivre l’application (fichier de conf, de scripts, etc…)

Références: 

[1] https://maven.apache.org/plugins/maven-assembly-plugin/single-mojo.html
[2] https://github.com/tcurdt/jdeb/blob/master/src/examples/maven/pom.xml
[3] https://un-est-tout-et-tout-est-un.blogspot.fr/2017/12/construire-un-paquet-debian.html

Aucun commentaire:

Enregistrer un commentaire