Chez Nuxeo, nous nous efforçons de faciliter le travail des développeurs. Nous avons par exemple Nuxeo Studio, qui permet à nos clients (et à leurs équipes de développement) de personnaliser notre solution en fonction de leur logique opérationnelle en seulement quelques clics en définissant de nouveaux types de documents, de nouveaux workflows et de nouvelles règles. Mais lorsque la situation nécessite un niveau de personnalisation plus élevé, les développeurs doivent écrire du code en Java et déployer ce code dans Nuxeo Platform via de nouveaux bundles. Pour ce faire, nous mettons à disposition des packages Nuxeo personnalisés qui facilitent le déploiement.
Si vous suivez notre blog, vous aurez peut-être remarqué que nous sommes particulièrement intéressés par OpenShift Container Platform. Lorsque nous avons analysé les différentes options de déploiement, nous nous sommes naturellement tournés vers OpenShift. Nous voulions proposer un environnement de déploiement continu avec OpenShift, ce qui signifie que lorsque vous écrivez du nouveau code et de nouveaux tests et que vous pushez votre code vers GitHub, celui-ci sera déployé sur votre instance de développement Nuxeo. Voyons en détail comment c’est possible.
Source To Image OpenShift
L’une des possibilités pour déployer une instance dans OpenShift est d’utiliser sourceStrategy
. L’idée est de cibler un référentiel GitHub capable d’accueillir le projet.
Par défaut, le système peut concevoir des projets avec un Dockerfile
, mais vous pouvez spécifier une image capable de créer le projet, le placer dans un package et créer une image Docker contenant ce projet. Ce procédé est connu sous le nom Source To Image. Vous partez d’un bloc de code (par exemple Java) et vous arrivez avec une image Docker prête à l’emploi.
Dans la routine Docker Build, Ship, Run, Source To Image gère la partie Build*. Une fois créée, l’image est ensuite envoyée en tant qu’ImageStream dans OpenShift, qui gère la partie Ship. Enfin, vous pouvez utiliser cet ImageStream dans un DeploymentConfig. C’est la partie Run**.
Image Nuxeo S2I
Pour mettre en application ce cycle de déploiement complet, nous avons créé une image Docker Nuxeo S2I (Source to Image) capable de créer un projet Nuxeo et contenant un JDK, Maven et des outils Node.
Créons un projet Nuxeo de test à l’aide de Nuxeo CLI :
# mkdir nuxeo-s2i-sample
# cd nuxeo-s2i-sample
# nuxeo bootstrap single-module
...
info You'll be prompted for generation of:
info nuxeo-s2i-sample-core: single-module
create Generate Module: nuxeo-s2i-sample-core
create Generating Single module
info Parameters: Parent group, Parent artifact, Parent version, Nuxeo version, Project group, Project artifact, Project version, Project description
? Parent Group id (use white space to cancel default value.): org.nuxeo
? Parent Artifact id: nuxeo-addons-parent
? Parent Version: 9.2
? Project Group id: org.nuxeo.sample
? Project Artifact id: nuxeo-s2i-sample
? Project version: 1.0-SNAPSHOT
? Project description: Sample project to demonstrate S2I usage
create pom.xml
create src/main/resources/META-INF/MANIFEST.MF
create src/main/java/org/nuxeo/sample/package-info.java
create src/test/resources/jndi.properties
create src/test/resources/log4j.xml
info You can start editing code or you can continue with calling another generator (nuxeo bootstrap [<generator>..])
Cela vous permet de créer un projet Nuxeo vide que vous pouvez déployer avec Maven. Au lieu de ça, nous allons invoquer le client s2i
pour qu’il déploie une image Docker Nuxeo contenant ce bundle.
s2i build . nuxeo/s2i:9.2 nuxeo-s2i-sample
Après un moment, vous obtiendrez une image Docker nuxeo-s2i-sample
que vous pouvez exécuter comme l’image Nuxeo avec :
docker run --rm -ti -p 8080:8080 nuxeo-s2i-sample
Vérifiez si votre package a été déployé ou non en vous rendant dans l’Admin Center à partir de la zone d’informations de la distribution.
Utiliser Source to Image dans OpenShift
OpenShift sait comment utiliser s2i
. Il nous suffit de créer des ressources qui référencent notre image Nuxeo S2I. Utilisez un ImageStream pour cette étape :
apiVersion: v1
kind: ImageStream
metadata:
name: nuxeo-s2i
annotations:
openshift.io/display-name: Nuxeo Source to image
spec:
tags:
- name: "latest"
annotations:
openshift.io/display-name: Nuxeo (latest)
description: |
Build and run a Nuxeo application. For more information about using this builder image, see https://github.com/nuxeo-sandbox/nuxeo-s2i
WARNING: By selecting this tag, your application will automatically update to use the latest version of Ruby available on OpenShift, including major versions updates.
iconClass: icon-java
tags: builder, java, nuxeo
supports: nuxeo
sampleRepo: https://github.com/nuxeo/nuxeo-sample-project
from:
kind: ImageStreamTag
name: "9.3-SNAPSHOT"
- name: "9.3-SNAPSHOT"
annotations:
openshift.io/display-name: Nuxeo 9.3-SNAPSHOT
description: |
Build and run a Nuxeo application. For more information about using this builder image, see https://github.com/nuxeo-sandbox/nuxeo-s2i
iconClass: icon-java
tags: builder, java, nuxeo
supports: nuxeo
sampleRepo: https://github.com/nuxeo/nuxeo-sample-project
from:
kind: DockerImage
name: nuxeo/s2i:master
On peut ensuite utiliser le bouton Add project pour créer un nouveau projet Nuxeo en sélectionnant l’ImageStream que nous venons de créer.
Nous allons référencer l’adresse du référentiel GitHub de notre projet Nuxeo :
Et c’est tout ! OpenShift va invoquer l’image S2I, distribuer notre projet Maven, trouver l’artéfact dans le répertoire cible, l’ajouter au répertoire bundles
de notre image Docker Nuxeo, distribuer l’image et la déployer dans une DeploymentConfig.
Après avoir lancé Nuxeo Platform, vérifiez si le package est installé avec rsh
dans le conteneur et que la liste de packages installée se trouve dans le répertoire bundles
.
# oc get po
NAME READY STATUS RESTARTS AGE
nuxeosample-1-7z7s2 1/1 Running 0 5m
# oc rsh nuxeosample-1-7z7s2
nux...z7s2:/opt/nuxeo/server$ ls /opt/nuxeo/server/nxserver/bundles | grep sample
nuxeo-s2i-sample-1.0-SNAPSHOT.jar
Déploiement continu
Notre projet Nuxeo est vide et nous voulons lui ajouter un comportement et le déployer à la place du pod actuel. Nous pourrions transmettre nos modifications à GitHub et lancer un nouveau build qui déclencherait un nouveau déploiement. Mais on peut également éviter cette étape manuelle en utilisant un webhook.
Dans OpenShift, nous allons éditer le build Nuxeo et ouvrir le panneau de paramètres avancés. Ensuite, il suffit de chercher la zone Triggers
et de copier la terminaison du webhook GitHub.
Nous allons configurer dans GitHub un webhook qui ciblera cette terminaison à chaque commit.
Nous allons maintenant créer un listener qui mettra à jour la description de chaque nouvelle note créée. Lors de la création d’un document Note
dans Nuxeo, sa description sera mise à jour avec le texte « Happily deployed thru s2i. »
# nuxeo bootstrap listener
...
create Generating Listener
info Parameters: Listener package, Listener class name, Trigger on event, Custom events, Is it an asynchronous listener, Is it a post commit listener
? Listener package: org.nuxeo.sample
? Listener class name: NoteCreationListener
? Trigger on events: aboutToCreate
? Is it an asynchronous Listener? No
? Is it a post-commit Listener? No
info Maven dependency: org.nuxeo.runtime:nuxeo-runtime-test:::test
info Maven dependency: org.nuxeo.ecm.platform:nuxeo-platform-test:::test
info Maven dependency: org.nuxeo.ecm.core:nuxeo-core-event
force pom.xml
force src/main/resources/META-INF/MANIFEST.MF
create src/main/java/org/nuxeo/sample/NoteCreationListener.java
create src/test/java/org/nuxeo/sample/TestNoteCreationListener.java
create src/main/resources/OSGI-INF/notecreationlistener-listener-contrib.xml
info You can start editing code or you can continue with calling another generator (nuxeo bootstrap [<generator>..])
Éditez ensuite le code Java du fichier src/main/java/org/nuxeo/sample/NoteCreationListener.java
pour que le listener mette le document à jour.
public class NoteCreationListener implements EventListener {
@Override
public void handleEvent(Event event) {
EventContext ctx = event.getContext();
if (!(ctx instanceof DocumentEventContext)) {
return;
}
DocumentEventContext docCtx = (DocumentEventContext) ctx;
DocumentModel doc = docCtx.getSourceDocument();
// Add some logic starting from here.
doc.setPropertyValue("dc:description","Happily deployed thru s2i");
}
}
Après un commit sur GitHub, Openshift lance le build et le déploiement. Pour vérifier que tout fonctionne, nous allons créer un document Note
de test. Et voilà notre description mise à jour !
Pour aller plus loin avec l’image S2I
Dans sa forme basique, l’image S2I prend les JAR présents dans le répertoire target
et les copie dans le répertoire $NUXEO_HOME/nxserver/bundles
. Ça peut être problématique si vous disposez d’un projet Maven multimodule. Pour faciliter la configuration, vous pouvez ajouter un fichier manifeste .nuxeo-s2i
à la racine du projet spécifiant les éléments à déployer. Et vous pouvez bien sûr spécifier un package Nuxeo. Voici un exemple de fichier test :
# Directory where to find JAR artifacts to deploy
#ARTIFACT_DIR=target
# Nuxeo package to deploy
#NUXEO_PACKAGE=sample-package/target/sample-package-*.zip
# Whether to start Nuxeo in a test phase and do some smoke tests
#NUXEO_SMOKE_TEST=false
Ce n’est que le début et nous allons certainement ajouter d’autres fonctionnalités, comme l’exécution de tests d’intégration Maven sur l’instance Nuxeo déployée. N’hésitez pas à nous envoyer vos retours !
Enfin, si notre script assemble
ne répond pas à vos besoins, vous pouvez toujours spécifier votre propre script en suivant les instructions Source-to-Image.
Un processus de développement continu
S2I peut être considéré comme un outil très simple permettant de transformer le code en image Docker exécutable. Mais avec OpenShift, il nous permet d’automatiser complètement notre expérience de développement et de déploiement.
L’image S2I Nuxeo est toujours en cours de finalisation. Une fois combinée avec Nuxeo Studio, vous aurez à votre disposition une chaîne complète vous permettant de développer rapidement vos applications. N’oubliez pas de nous faire part de vos retours sur vos essais avec les différentes options dont nous avons parlé aujourd’hui.