Jenkins, sers-moi donc un Chtijug !

Nicolas Géraud était venu nous parler des pipelines il y déja deux ans.Est-ce que cette présentation allait être mieux ? En tout cas, elle est bien différente.

Petit point sponsoring de l’IUT sur la taxe d’apprentissage : les entreprises peuvent déclarer des organismes de formation bénéficiaires de leur taxe d’apprentissage. Ca peut avoir une influence sur le budget de ces organismes.

Et c’est parti !

Avec d’abord un petit sondage :

  • qui connait Jenkins ? A main levée, tout le monde dans la salle.
  • qui a déja migré vers Jenkins 2 ? Encore à main levée, pas grand monde.

Jenkins 2

Donc Jenkins 2 … est totalement compatible avec Jenkins 1. Et c’est bien, parce que la montée de version va être simple. Dans l’ensemble, les plugins sont compatibles.

Avec Jenkins 2, il y a aussi de nouveaux sites

  • http://jenkins.io qui est bien plus grand public
  • le project Voltron sert de plugin store avec une chouette présentation. Limite comme le google play store, en fait.

Il y a maintenant au premier démarrage un mot de passe à aller chercher dans les logs de la machine. Ca va permettre de sécuriser le serveur Jenkins avec un admin par défaut. Evidement, on peut toujours avoir un Jenkins non sécurisé, mais il faut le vouloir. Ce qui change pas mal de Jenkins 1 qui, par défaut, n’était pas sécurisé. En bonus, une liste de plugins par défaut est disponible, pour faire une première personnalisation de Jenkins.

Et ensuite, on arrive aux fameux pipeline-as-code.

Pipeline as code

Un job est défini par un Jenkinsfile, écrit dans un DSL Groovy, qu’on peut stocker dans son SCM. L’avantage, c’est aussi de permettre d’utiliser les structures de contrôle de Groovy pour personnaliser le job.

Et ensuite

Il y a tout un tas de nouveaux trucs qui ne vont pas tarder à arriver

BlueOcean (déja disponible en pas beta, mais pas release non plus)

La fameuse nouvelle interface graphique pour Jenkins. Les captures sont très chouettes !

Franchement, l’affichage des pipelines est très chouette. Si j’avais eu ça chez Perigee, j’aurais pu montrer un vraiment très beau pipeline. Le plus incroyable, c’est quand même de pouvoir faire « pousser » un pipeline graphiquement. Il faut voir l’écran pour le croire, je trouve.

Pipeline déclaratif

En bonus, ça permet à des non-développeurs de modifier le build, ce qui n’est pas une si mauvaise idée, puisque le code exécuté est toujours en SCM. En fait, le pipeline généré n’est pas exactement identique à celui qu’un développeur écrirait : c’est un pipeline déclaratif.

D’une façon amusante, le speaker décrit la syntaxe d’un DSL Groovy comme « à mi-chemin entre YAML et Groovy ». Guillaume Laforge et tous ses amis pleurent des larmes de sang en entendant ça. Parce que quand on regarde un DSL Groovy, comme par exemple le MarkupBuilder, on est exactement dans la syntaxe visible à l’écran. Bon, je ne vais pas en vouloir au speaker : il connaît sans doute mieux Jenkins que je connais Groovy.

Back-end storage

Manifestement, l’objectif est de découpler le fonctionnement de Jenkins et le stockage des configurations d’exécution et des résultats. C’est une chouette idée, mais pas vraiment assistée par les capacités des plugins à écrire eux-mêmes des fichiers.

Donc Jenkins 2, c’est ?

Jenkins 2, c’est mieux, et orienté sur le continuous delivery. Et pas le continuous deployment. Autrement dit, l’équipe de cloudbees ne vise pas trop à utiliser Jenkins pour le déploiement en prod.

Quelques questions

Si les pipelines sont déclaratifs, comme maven ou gradle, pourquoi ne pas réutiliser leur outillage ?

Jenkins est utilisé pour faire le delivery, ce que ne font pas ces outils. En un sens, je comprend cette réponse : le scope fonctionnel est différent, et ce serait assez curieux de dire « on peut faire du gradle pour le déploiement ». Et puis, Cloudbees et Gradle inc ne vont pas fusionner demain.

Mais quand même, en transformant les jobs en bouts de code, je trouve que Cloudbees fait rentrer Jenkins dans une espace de continuum de build qui va de mon poste jusqu’aux artefacts déployables en prod.

Comment se compare l’API de pipeline-as-code et de job-dsl ?

L’inspiration initiale de pipeline-as-code était buildflow, mais ça a vite divergé.

Et la démo

  • Premier truc cool : les plugins installés sont toujours installés à la dernière version.
  • Deuxième truc cool : BlueOcean est déjà disponible comme plugin, et donc installable.
  • Troisième truc cool : le travail d’administrateur Jenkins s’arrête, pour les jobs, à créer les jobs et les connecter à des SCM. Tout le reste vient du Jenkinsfile.

Et donc, on passe à la création du Jenkinsfile. Et là, la structure des DSL Groovy réapparaît vraiment, et c’est bien.

  • Quatrième truc cool : les commandes checkout de SCM utilisent la révision du Jenkinsfilecomme référence. Par conséquent, l’enchaînement d’étapes se passera beaucoup mieux que dans Jenkins 1, puisqu’il n’y aura pas de révision à passer. Par contre, curieusement, le DSL ne semble pas contenir de commande maven, puisque notre speaker exécute les commandes maven via un sh "mvn clean package". Arf … apparement, le plugin exécutant maven est « mauvais ».
  • Cinquième truc cool : l’interface de Jenkins inclut un générateurs de snippets façon vieux wizards qui permet d’apprendre très rapidement le DSL des pipelines.
  • Sixième truc cool : l’affichage des pipelines en cours est vraiment très sympa, avec des logs par noeud du pipeline affichés en temps réel.
  • Septième truc cool : le DSL inclut une notion de stashes, valable uniquement pour la durée du pipeline, qui permet donc de ne pas déployer dans Nexus les artefacts temporaires.
  • Premier truc pas cool : le pipeline est toujours exécuté sur le master. Du coup, la montée en charge pourrait mal se passer.
  • Huitième truc cool : pour les pipelines déclaratifs, il est possible de demander à Jenkins d’analyser la syntaxe.
  • Deuxième truc pas cool : on peut relancer un pipeline à partir d’une étape uniquement dans la version commerciale de Jenkins. C’est moins bien … mais je comprend tout à fait.
  • Neuvième truc cool : il est possible de créer des morceaux de code partagés entre pipelines.
  • Dixième truc cool : les milestones permettent d’éviter de lancer plusieurs builds concurrents sur une ressource critique.

Et si vous voulez voir le Jenkinsfile utilisé pour ce live-coding, il est disponible sur github.

D’autres questions

Comment tester un pipeline ?

Eh bien, on ne peut pas : il faut le lancer dans une instance de Jenkins. Autrement dit, c’est le genre de truc où il faut une instance de test de Jenkins. Et mon collègue me souffle à l’oreille qu’on peut très bien utiliser l’annotation @StaticCompile de Groovy pour vérifier la syntaxe autant que possible (parce que @StaticCompile, sur un DSL, il doit bien s’amuser, tiens).

Conclusion

J’ai quand même hâte de voir les projets passer au moins aux pipelines as code, histoire d’avoir dans mon SCM, à côté de mon pom.xml, le Jenkinsfile qui va bien. Et histoire aussi d’ajouter un peu de Groovy dans tout ça !

Un chtijug élastique

D’abord, quelques annonces

A 20 € ! Ca va être dur de faire valider la note de frais.

Pour les slides, c’est par là

Elastic, c’est 4 projets open-source :

  • Logstash (malheureusement écrit en JRuby)
  • Beats (alternatives à Logstash en go beaucoup plus simple). il y a FileBeats, NetworkBeats, MetricBeats
  • Elasticsearch (moteur d’indexation et de recherche JSON. Ne loupez pas l’interview de notre speaker chez lescastcodeurs)
  • Kibana (outil de dashboard)

Et un ensemble de solution commerciales appelées génériquement X-Pack

En particulier, graph permet d’éviter le problèmes des supernoeuds dans les graphes (un problème auquel je suis assez sensible, mais je m’éloigne du sujet).
Et prelert va identifier les erreurs « exceptionnelles » grâce à de l’apprentissage.

A quoi sert elasticsearch ?

Ben à faire des recherches floues, où à trier les résultats de recherche selon … un score. Et floue, ça implique de gérer les fautes d’orthographe, les textes approchants, les synonymes, …

Et maintenant, le coeur de la présentation : ingest node

Avec ingest, on peut remplacer l’architecture classique

iyxfbszfiyqhkn3bp4briaqiaupaxelvvas7bogmpowa5ifpxazotebfsoa4r1ixorlc91qnp2o7foom9mtmmmtkjkco3cvfsa5c1vc85kpm5kqwtyzc0g00

par une architecture beaucoup plus simple

iyxfbszfiyqhkn3bp4briaqiaupaxekvvygmbsgc1wsc5ylda5hpag01gjopbpsrk8ihbwkkllvn3y880000

Du coup, le pipeline de transformation Logstash (grok, date, mutate) est remplacé par un équivalent ingest (grok, date, remove). Il y a naturellement tout un tas de plugins (dont la lecture d’attachments avec Tika). Bon, autrement dit, on remplace un ETL par un autre, espérons juste qu’il soit plus performant. Et évidement, on peut créer ses propres plugins.

Il y a quand même un gros intérêt, puisque les pipelines ingest sont utilisables dans la plupart des urls d’appel à Elasticsearch. Et en particulier, dans l’un des trucs les plus balaizes : le reindex. Ce reindex permet la migration facile d’un cluster Elasticsearch d’une vieille version vers une nouvelle. Et ça, ça me paraît vraiment très chouette.

Comme dans n’importe quel ETL, il est possible de définir des failure processors qui vont être utilisés en cas d’échec lors de la série de transformation. On peut les définir par pipeline ou par processeur.

Dans un cluster, (parce que oui, Elasticsearch fonctionne toujours en cluster), il est possible de laisser tous les noeuds faire de l’ingestion, on d’en forcer certains à faire l’ingestion. En prod, d’ailleurs, il vaut mieux séparer les noeuds d’ingestion des noeuds de données.

Et si on regardait un plugin ?

Par exemple, le fameux plugin BANO (déja mentionné chez les castcodeurs). BANO pour base nationale d’adresses, parce que David est fan des adresses postales. Et cette base, ce sont des documents CSV (ou JSON) disponibles chez OpenStreetMap.
Donc David a un plugin qui lui permet de charger dans Elasticsearch la base des adresses, puis d’enrichir les adresses et les localisations GPS en ajoutant la donnée inverse.

Et maintenant, c’est le moment de la démo !

Et franchement, au début, la définition de pipeline d’ingestion est assez facile, et la définition des failure processors est tout aussi facile. J’imagine très bien les interfaces très graphiques faisables là-dessus.
Pour la récupération des données, le fait que ce soit un moteur de recherche fait que des résultats moins pertinents pourront être retournés par les requêtes, mais derrière les résultats les plus pertinents.

Un autre élément intéressant, c’est que la recherche est foutrement rapide : l’ingestion d’une coordonnée GPS avec ajout automatique des adresses (et donc recherche dans l’index des coordonnées) est immédiate (pour autant qu’on puisse le voir). Même si la coordonnée GPS n’est pas exactement la bonne.

Et avec tout ça, et le processor GeoIP, il est par exemple possible d’envoyer un courier à l’adresse donnée lors de la requête HTTP. Ca fout la trouille, hein ?

Au passage, l’un des trucs les plus intéressants selon moi est l’utilisation de JSON pour exprimer les requêtes : le code n’est pas moins clair qu’avec un langage de requête dédié (genre SQL).

Un autre intérêt d’Elasticsearch, c’est qu’il supporte les tâches longues, qu’on peut suivre et gérer (pour par exemple tuer les tâches trop longues).

Non mais, et si on développait vraiment un plugin ?

Eh bien ce serait aussi simple que d’écrire une classe étendant une superclasse abstraite.
Evidement, quand on regarde le code, on voit des choses … curieuses : trouver le point le plus proche en calculant la distance de tous les points, je peux dire que c’est pas le plus efficace (il n’y a pas d’index géographiques ou quadtrees dans Lucene ? Ah si, à priori, avec les bkdtree de Lucene 6).
Dans le même ordre d’idée, déclarer ses plugins en associant une clé à une factory … alors qu’on peut faire du CDI ? C’est pas fameux. mais bon, tout le monde n’est pas censé écrire des plugins.

Conclusion

L’un des plus gros intérêts de cette présentation, c’est de sortir Elasticsearch de son rôle le plus connu de stockage ELK pour bien montrer qu’avant tout, c’est un ETL moderne qu’on sous-utilise volontiers.

Et personnellement, en voyant cette présentation, j’ai eu l’envie un peu folle de resortir mes projets de livestream pour les porter dans une base plus moderne.

Et pour la blague, le premier rang, c’est pratique pour démontrer la présence quand le speaker fait des selfies

Vite, un chtijug !

Je me demande si je n’ai pas déjà utilisé ce titre …

En attendant, hier soir, c’était chtijug spécial quickies.

HTTPS Everywhere avec let’s encrypt

Le HTTPS c’est mieux pour la confidentialité des utilisateurs. Let’s encrypt est une autorité de certification, dont le client essentiel est certbot.

certbot

Tourne sur n’importe quel Unix (oui oui). Il y a des plugins pour tous les serveurs web, même sur le Raspberry.

Démonstration avec un site Apache

S’ensuit une jolie démonstration avec des poneys en ascii-art. Et tant mieux, parce que certbot a une interface ncurses ! On note tout de suite les problèmes classiques liés à du https : le mixed content (images ou scripts chargés en http, …). Je note également le point « magique » de Let’s Encrypt : obtenir un certificat à la volée, c’est quand même vachement plus rapide que de le réclamer physiquement à un service de sécurité.

Validation du certificat

La partie intéressante de Let’s encrypt, c’est le mode de génération de certificat. Plutôt que d’utiliser la méthode traditionnelle avec échange de mail, ils reposent sur l’exposition d’un challenge en http sur le site pour lequel on veut un certificat. C’est assez malin, car plus facilement automatisable. Et j’imagine que certbot doit pouvoir automatiser ça

Démonstration avec nginx et webroot

Histoire de montrer les capacités de certbot, on refait la démo, mais avec une configuration manuelle, pour nginx.

Intérêt ?

Le certificat est renouvellé automatiquement tous les 90 jours ! Du coup, plus de problème d’expiration. Et ça, pour les noobs de la sécurité comme moi, c’est vraiment cool. Un point important à noter : Let’s encrypt ne fournit que des certificats de classe 1, donc avec une sécurité « moyenne ». Les classes 2 et 3 impliquent des vérifications physiques, qui sont évidement manuelles.

Point bonus : il y a une interface permettant de révoquer les certificats depuis le site de Let’s Encrypt, ce qui provoquera sans doute leur renouvellement automatique.

Ce que la revue de code m’a apporté

Julien commence par nous raconter sa vie de jeune développeur. Et, personnellement, je me reconnais mal là-dedans :

  • la fierté du code produit
  • la propriété du code (c’est le code de Julien)
  • Et enfin, il veut que son code soit beau longtemps

Du coup, ils ont mis en place chez Axa des revues de code avec des rôles identifiés pour limiter les procès en sorcellerie. Malheureusement, j’ai peur que ça ne suffise pas. Du coup, il faut apprendre plusieurs choses (qui, il me semble, font partie de l’expérience du développeur). La première étant évidement de faire preuve de bienveillance envers ses collègues, le fameux « dur avec le code, doux avec les gens ».

Axa consomme environ 5% de son temps à faire de la revue de code. C’est assez peu, vu que ça permet de détecter des bugs (en plus d’assurer une cohérence stylistique des livrables).

A priori, il faut environ 3 mois pour que les revues soient « apaisées ».

A la réflexion, il y a à mon avis quelque chose de complètement biaisé dans le fait que le développeur vienne présenter lui-même son code à un procès en sorcellerie. Il vaudrait sans doute mieux que le code soit défendu par un « avocat » sans que le développeur à l’origine du code puisse être reconnu. Parce que, comme je le dis toujours, le code qui est dans Subversion/Git n’est plus ton code, c’est celui de l’équipe. Et c’est ce qui le rend magiquement sale.

lunrjs

lunrjs est un portage de Lucene pour javascript, utilisé chez Decathlon. Et sur le site de Decathlon, actuellement, quand on change un filtre de recherche, la page est visiblement rechargée (ce qui n’est pas terrible en termes de performances). Un portage, mais un peu restreint, puisqu’on perd par exemple les recherches de termes approchants.

A noter qu’actuellement, le catalogue produits de Decathlon est hébergé en SAAS, ce qui est … osé, je trouve.

Cela dit, je n’ai pas trouvé ça si impressionnant. Parce qu’il existe déja des tonnes d’API javascript pour exploiter le local storage « correctement ». En fait, le seul intérêt de lunrjs, c’est de compléter les recherches disponibles dans Lucene pour les déconnexions, mais je trouve le cas d’utilisation assez rare pour ne pas investir spécifiquement dessus. A mon sens, travailler sur une vraie API client/serveur dans le navigateur permettrait plus facilement d’attaquer ce type de problème. Sauf, bien sûr, si l’objectif du projet est précisément d’étendre Lucene, mais c’est plus de l’ordre du patch que de l’évolution en profondeur.

Cerberus

Donc, cerberus est un outil de test fonctionnel automatique. Des outils comme ça, il y en a … déjà … des tonnes. Alors pourquoi La Redoute s’est lancée dans cette guerre des tranchées ? Comme d’hab, l’hubris (autrement dit « il n’existait pas de solution correspondant à leur besoin »). Cerberus se place donc entre les différentes équipes, pour fournir un référentiel commun. ce qui implique également que les tests puissent être décrits par les fonctionnels ou les développeurs. Et comme un outil comme HPQC, il offre tout un tas de fonctionnalités, comme le support multi-technologies, multi-langues, multi-environnements l’exécution adaptative des tests, la génération de rapports ou l’intégration dans les outils de développement du SI (IC, bug tracker, …).
Bon, j’avoue, j’ai décroché lors de la démo. Parce que vraiment, on est face à de l’outil de test fonctionnel très haut niveau, où les étapes peuvent être effectuées manuellement ou automatiquement. Ce qui ne m’inspire qu’une chose : ces outils ne sont pas faits pour le monde d’aujourd’hui, mais pour les bonnes grosses applications traditionnelles des entreprises qui ont encore des équipes dév, fonctionnelles, test, différentes, et des processus de livraison longs et lourds. Dans ce cadre, j’imagine que ça doit marcher. Mais dans le cadre hyper-mouvant du web de 2016, je ne suis pas sûr que ça bouge assez vite.

Conclusion

Je peux paraître un peu dur avec certains des talks, mais ça n’est pas mon but. Le contenu ne m’a peut-être pas autant intéressé que les orateurs l’auraient souhaité, mais ça n’ôte rien à leur prestation. Les quatre présentations étaient en effet bien préparées, construites, bien organisées. C’est juste que chaque auditeur met ses propres filtres sur les sujets qui lui sont présentés … Bravo encore au chtijug qui arrive toujours à trouver des choses intéressantes à nous présenter (eh oui, ça n’est pas parce que ça ne m’a pas plu que ça n’était ps intéressant).

Les furets sont au chtijug !

Tout ce qui est présenté est disponible sur GitHub, avec d’autres choses …

Donc, les furets font de l’assurance. Et ils ont fait d’abord différents sites au look … discutable.

En terme de code, actuellement, il y a 450K lignes de code, et un déploiement en prod par jour. Ca change pas mal des clients avec un déploiement par semestre …

DomainModel.stream()

A quoi ça sert

La classe Person, chez eux, est … grosse, et riche d’héritage. Normal pour un projet qui a 7 ans. Et évidement, ce modèle circule dans l’entreprise, du client Javascript à la base backoffice qui reprend les données sous des formats différents.

Evidement, comme c’est compliqué, ils ont cherché à simplifier tout ça, en utilisant globalement des domaines orientés colonne :

  • clé/valeur dans le client
  • modèle colonnes dans Cassandra
  • Vecteurs de données dans la base analytics

Du coup, utiliser un dictionnaire de clé partout devrait simplifier les choses.

Pour la suite, on va travailler sur un modèle simplifié.

Premier souci : comment ça se passe quand on a des relations 1-n ? A priori, « ca marche » … personnellement, je n’y crois pas trop, mais admettons.

Il y a aussi le souci des champs accessibles par plusieurs chemin, qui cette fois-ci sont dupliqués dans les données disponibles.

Et passons tout de suite au livecoding.

Manipulation simple du modèle

Donc, on a d’un côté notre modèle objet traditionnel, et de l’autre, grâce à un wrapper généré par l’outil des furets. Dans ce wrapper orienté clé/valeur, écrire des données se fait avec un simple

SampleModelWrapper.set(FieldId, value)

lire des données se fait simplement avec un

SampleModelWrapper.get(FieldId)

Et en terme d’implémentation, ça se fait facilement en générant des lambdas (évidement, avant Java8, ça aurait marché tout aussi bien avec des classes internes, mais bon, les lambdas sont à la mode). Et, en plus, l’inférence de type semble assez faible, puisque le type contenu dans le FieldId ne suffit pas à contraindre suffisament le type de sortie.

Manipulation avec des streams

Donc évidement, faire SampleModelWrapper#stream() retourne toutes les valeurs du modèle. Et on peut transformer les valeurs en map en traversant le même stream. Pratique, mais pas exceptionnel. Même si le speaker n’est pas de cet avis. Et en un sens, je le comprend, puisque le mapping est traditionnellement un problème compliqué : regardez Jackson/JAXB et autres qui galèrent pour bien faire les mêmes choses.

Petit bonus : on peut filtrer les éléments du wrapper selon différents tags, qui sont définis librement dans le wrapper. De cette manière, par exemple, on peut séparer les données du User et de l’Account du modèle d’exemple. Evidement, ça peut aussi servir à affiner l’accès à certaines interfaces selon les droits des utilisateurs.

A noter que le site des furets a environ 1000 clés dans les différents enums défnissant les modèles utilisés.

Introspection

Typiquement, quand on veut mettre les données dans une base Cassandra ou autre, il faut d’abord créer les colonnes typées associées, pour lesquelles on va naviguer le modèle, et pour chaque élément du modèle, on va créer une colonne dont le type sera obtenu grâce au FieldInfo correspondant à chaque champ.

Evidement, pour moi, il est assez curieux de voir des gens réinventer des notions analogues aux BeanInfo / PropertyDescriptor disponible dans le vieux monde des JavaBeans. Mais dans l’ensemble, ça fait le job assez (peut-être trop, en fait) simplement. Trop simplement, parce que par exemple, les annotations portées par le modèle initial ne sont pas transportées à travers le wrapper.

Conclusion partielle

Je comprend tout à fait l’intérêt de mapper un modèle de beans vers des séries de colonnes. En revanche, l’implémentation, certes joliment Java8, manque quand même de certains aspects clés : la gestion des collections fait vraiment peur, l’introspection est fichtrement limitée.

Cela dit, ça doit clairement bien limiter la complexité de la sérialisation, de la création d’interface graphique, ou même de persistence (non relationnelle, évidement, parce que sinon, c’est évidement merdique).

Il y a en fait là-dedans une idée très intéressante qui a sans doute un rapport certain avec le NoSQL. je m’explique. Lorsqu’on codait il y a dix/quinze ans avec une base de données relationnelle, avoir du code proprement décomposé était une bonne idée. Maintenant que la plupart des outils de stockage sont dénormalisés, à typage faible, bref, merdiques en terme de support des liens sémantiques, avoir un modèle riche est presque une gêne. Et c’est dans ce cadre que ce système de wrapper de modèle présente un intérêt.

Continuous delivery

Bon, si vous ne savez pas ce qu’est le continous delivery, c’est assez simple : c’est l’idée de pouvoir envoyer du code en prod au plus tôt. Et actuellement, les furets font plusieurs mises en prod par jour.

Historique

D’une façon amusante, en 2012, ils faisaient une MEP par mois, parce que leurs sprints SCRUM duraient un mois. Les tests étaient joués en fin de sprint et pouvaient entraîner des retards de MEP du fait de tests à corriger. Pas très pratique …

En 2013, ils ont tenté d’accélérer les choses avec des sprints « bonus » d’une semaine. Le premier impact est que le temps de build est passé de 15 mn à 3 mn.

En 2014/15, passage à Kanban avec une release chaque jour : les fonctionnalités sont marquées finies dans Kanban quand elles sont en prod. L’impact, évidement, c’est que la release est passée d’une journée entière à 2/3 heures. L’autre impact, c’est que les tests ont tous été automatisés. Histoire de se rassurer, les fonctionnalités passent quand même dans un environnement de staging pendant une journée pour vérifier que tout va bien.

Pour le futur, l’objectif est de livrer encore plus vite : les fonctionnalités devraient apparaître presque une par une en prod.

Curieusement, les MEP apportent toujours autant de code, voire même plus, parce qu’il y a beaucoup plus de fonctionnalités dedans.

Quelques aspects techniques

En-dehors des classiques environnements, il y a quelques points notables.

Les tests sont joués en parallèle sur un grid selenium, qui tourne sur une machine avec un RAMFS (128 Go de RAM chez OVH pour 300 €/mois).

Ils développé Zeno qui va sur une URL pour faire une capture d’écran. Et qui fait la différence entre la prod et la préprod. De cette façon, on peut vérifier que les différences visibles sont bien liées aux fonctionnalités développées (et pas à des bugs, par exemple). Cet outil pourrait par exemple être utilisé pour faire de la veille concurrentielle.

Evidement, le développement se fait en mode blue/green. Avec un double cluster.

Continuous delivery en détail

Il y a en gros 3 modèles de développement

  • trunk based : tout ce qui est dans le trunk part en prod. Ca implique le feature flipping qui est du code en trop.
  • feature branching : tout les dévs sont fait dans des branches, qui sont réintégrées dans le trunk au moment de la MEP. Ca pose évidement des problèmes d’intégration continue.
  • Et pour finir, le modèle github où le code est développé dans des branches, et réintégré dans le trunk via des pull requests, qui passeront dans l’intégration continue.

La grande astuce des furets pour simplifier tout ça est de tester les merge rapidement. Grâce à ce qu’ils appellent le continuous merge : lorsqu’un développeur a fini un développement, il est poussé sur un repository qui contient toutes les nouvelles features branches, et qui tente de les merger et de déployer le code sur l’environnement de staging.

git octopus

Chez eux, les branches en cours de dev s’appellent studies/ et celles qui sont finies s’appellent features/. Pour merger tout ça, ils ont un script appelé git octopus disponible sur github. Le truc magique, c’est qu’il peut détecter les conflits entre les branches à merger avant le merge final.

Pour résoudre les problèmes qui arrivent … ben là, essentiellement, c’est du git-fu (et vous savez ce que j’en pense). En fait, c’est pas vrai : tout ce qui est dit est également valable avec Subversion … et j’ai bien l’impression que c’est ce que gigomerge (mince, j’aurais bien mis le lien, mais je ne le retrouve plus) permet d’une certaine façon.

Pour faciliter la gestion des conflits, ils ont également créé un outil de gestion des conflits … qui en fait se contente de créer un workflow d’escalade des exceptions.

Conclusion

Deux présentations très intéressantes, faites par des gens qui se soucient manifestement beaucoup de ce qu’ils livrent, et de la façon dont ils le livrent. Il y a là-dedans des choses vraiment très intéressantes (git octopus, conceptuellement, est très bien, et cette histoire de repository définissant le niveau de maturité d’une feature est également très chouette) D’autres sont en revanche plus discutable (la résolution de conflit me paraît plus de l’ordre de l’astuce que de la solution vraiment propre).

Mais surtout, ce qui apparaît, c’est que, contrairement à bien des boîtes, ils ont l’ambition de se voir comme une boîte de développement logiciel, ce qui implique de produire de la qualité et de la visibilité. C’est sans doute ce qui leur permet de recruter des pointures, puisque nos deux intervenants paraissaient particulièrement compétents.

Rancheros au chtijug

Comme le dit Twitter,

Avec le présentateur le plus cow-boy de la planète DevOps

Et des slides extrêmement parlants

D’ailleurs, si vous voulez les slides, ils sont là

//fr.slideshare.net/slideshow/embed_code/key/wzoqbRpBYp0J1R

Buzzwords twitter mis à part, c’était quand même une session très intéressante, qui a remis au goût du jour l’ »integration spaghetti » des architectures SOA : à partir du moment où vous avez cinq ou dix (micro)services éventuellement clusterés, comment vous faites pour qu’un client leur parle correctement ?

Et il y a pour ça différents problèmes à régler :

  1. La latence (« facilement » adressable avec RxJava)
  2. La tolérance aux pannes (sur lequel on aura bientôt – j’espère – une présentation d’Hystrix)
  3. La répartition et le load-balancing, qui sont le coeur de cette présentation

Bon, à partir de là, ça devient franchement technique et plein de chouettes démos présentant globalement trois niveaux de load-balancing (le premier point présentant l’état « historique » avec des applications monolithiques)

  1. La version à l’ancienne à base de HAProxy ou f5 (je suis justement en train de faire ça, et donc pas mal de choses dites par Christophe résonnaient furieusement sous mon crâne – en particulier le pilotage en Python de f5 ou via Ansible), pénible parce que très bureaucratique
  2. La version « les dévs font le putsch » et gèrent le load-balancing dans le code grâce à des outils comme Ribbon qui a comme inconvénient essentiel de ramener de la config machine dans le code applicatif
  3. La version base de registres et REGEDIT, où les services s’enregistrent dans un registre implémenté de façon dépendante de la brique choisie. C’est franchement assez sympa, puisqu’il n’y a plus à mettre dans le code de configuration applicative
  4. Et finalement, la version dockerisée où tout le code est dans des conteneurs, et où toute la gestion de load-balancing est faite dans Rancher (ou Kubernetes). Ca faisait carrément rêver.

C’était vraiment une chouette présentation, qui m’a posé poussée à me poser plein de questions non triviales. Chapeau !

Scalakka au chtijug (mais pas que)

Hier soir, le chtijug recevait un showman : Quentin Adam, alias @waxzce qui venait nous présenter plusieurs sujets en un … après un échauffement marrant de hubert sablonnière qui nous présentait en cinq minutes chrono le machete order. En cette période de folie marketting Star Wars, c’était opportun.

Revenons à nos moutons … Enfin, à Quentin.

Il nous a présenté en un peu moins de deux heures une espèce de digest de ses meilleures oeuvres, en commençant par une histoire très haut niveau des révolutions industrielles et du fameux « software is eating the world ».

Pour être clair, il nous a présenté les 100 premiers slides de cette présentation

http://fr.slideshare.net/quentinadam/slideshelf

Et c’était très chouette.

Parce qu’il y a derrière ça bien plus qu’une simple vision d’entreprise sur ce qui est bien pour CleverCloud. Non, ce qui soutient cette longue introduction, c’est la vision inévitable de la manière dont les révolutions industrielles se construisent et transforment le monde pour, quasiment, le préparer à la révolution suivante. Dit comme ça, le transhumanisme n’est évidement pas loin. Cela dit, il est vrai que le métier de développeur est affreusement jeune, et que la manière dont on met en prod aujourd’hui ressemble conceptuellement à la manière dont les entreprises du XIXème siècle géraient leur production électrique : à la main. Aujourd’hui, on sait que ça n’était pas la bonne manière de faire, et on sait aussi que demain, quelques admins suffiront à gérer des milliers de machines virtuelles. Du coup, il faut transformer nos applications pour qu’elles intègrent plusieurs facteurs facilitant le déploiement, qui sont décrits dans la présentation. Typiquement, créer des applications stateless, sans session, et sans jamais utiliser de stockage fichier (ce qui pose évidement la question de la persistance au long terme, question que j’ai posé à Quentin, et qui a répondu avec le classique « utilise plus de VM »)

Il a ensuite enchaîné sur du livecoding akka/scala pour extraire les logs écrits dans ELK par un processus et les afficher en temps réel dans une petite appli Websocket.

Et là, c’était moins chouette.

Pas parce que la démonstration était inintéressante, bien au contraire : créer une application en une cinquantaine de lignes de code, c’est chouette.

Non, ce qui est moins chouette, c’est le Scala. Clairement, il s’agit pour moi d’un langage d’avant-garde expérimentant avec toute une série de concepts auxquels j’ai du mal à adhérer

  • les implicites, (et encore je ne sais pas si c’était des classes ou des paramètres)
  • la définition d’opérateurs (genre le ~> d’akka)

Tout ça, c’est mignon à essayer, mais franchement, à regarder l’exemple exposé par Quentin, j’aurais pu faire aussi bien en java8 avec des closures ou même en java7 « classique ». D’accord, le code aurait été quelques lignes plus long, mais oh combien plus compréhensible.

Cela dit, je ne vais pas bouder mon plaisir, c’était une sacrée chouette session, idéale pour fêter la fin d’une belle année du chtijug.

En bonus, l’accueil d’Adeo et le buffet d’Onyme étaient très bien (pour le buffet d’Onyme, j’avais l’habitude).

Vert.x au chtijug

Il ya déja près d’une semaine,  Yannick de Kercadio nous présentait les bases de vert.x à travers trois ou quatre exemples niveau Hello world. D’ailleurs, je vais devoir séparer le fond et la forme de cette présentation tant ils étaient dissemblables.

Mais avant ça, voici les slides :

https://drive.google.com/file/d/0BzquubdfqGRuc0pzc25VNmM4UlU/preview
 

vert.x

vert.x est donc un framework de développement d’applications HTTP qui utilise le pattern reactive pour offrir censément des performances supérieures aux serveurs web classiques en essayant d’être au maximum non bloquant. L’intérêt de la manoeuvre est de ne créer qu’un thread Java par CPU, et de stocker en mémoire uniquement les objets s’occupant de ces traitements. D’après Yannick, c’est ce côté non-bloquant qui permet à vert.x d’atteindre des performances 10 fois supérieures à celles d’un serveur web « classique ». Bon, en vrai, je me demande si ça n’est pas plutôt parce que vert.x se passe de toute la complexité de JavaEE (servlet, HTTRequest, HTTPResponse, …) qu’il est plus performant …

Un autre intérêt de vert.x est d’offrir un écosystème qui va permettre de manipuler de façon assynchrone toute un tas de connexions … même si la qualité n’est pas toujours au rendez-vous. Et là, Yannick nous donne l’exemple du connecteur Cassandra qui utilise le driver synchrone de Cassandra, annihilant l’intérêt majeur de vert.x …

Cela dit (et même si je ne l’ai pas dit durant la présentation), rien n’empêche à Yannick, ou aux équipes de Proxiad, de proposer un driver Cassandra réellement assynchrone. Rien ? sauf peut-être le côté non contributeur des SSII françaises 😉

Au chapitre des boulettes, deux ou trois imprécisions sur l’histoire de vert.x. Par exemple, Yannick ne semblait pas savoir que vert.x était, entre autres, l’oeuvre de Julien Viet (l’auteur de Crash, qui est d’ailleurs utilisé dans vert.x sous le nom vertex-shell … quoique ca ne semble pas si sûr que ça …) et maintenant de Clément Escoffier, qui bossent tous les deux chez RedHat. Bon en même temps, je ne lui en veux pas de ne pas connaître les détails de la vie des people Java 🙂

La présentation

Alors là par contre, c’était franchement génial. Parce que j’ai déjà vu des présentations en live-coding au chtijug (le thermomètre connecté était jusqu’à présent ma préférée), mais des présentations où le speaker fait live-coder des membres de l’assistance … c’était du jamais vu. Ca montre à la fois la simplicité de l’API de vert.x, mais aussi la confiance du speaker dans sa présentation. (bon, ça montre aussi le manque de connaissance des IDE dans l’assistance, mais c’est un autre sujet).

Du coup, évidement les sujets étaient assez bateau, mais la présentation était vivante, interactive, bref, très chouette. Bravo !

Et alors, ça va servir ou pas ?

Eh bien en fait, comme je fais du Wisdom depuis un an, et que Wisdom utilise vert.x … je l’utilise déjà, mais dans un contexte quasi-JavaEE, bref, le meilleur des deux mondes !

isomorphique de quoi ?

La semaine denrière, c’était chtijug.

Oui, je suis un peu en retard, mais c’est pas trop grave, parce que pendant ce temps, l’orateur a eu le temps de mettre ses slides sur internet.

Session un peu particulière, en particulier avec son titre assez … ronflant : « réalisation d’applications isomorphiques avec spring boot, React et Nashorn ».

En vérité, c’est beaucoup plus simple à décrire que ça : vous savez que votre JVM intègre, et depuis un moment, un interpréteur Javascript ? Non ? Eh bien c’est pourtant le cas, grâce à la JSR 223 (l’une des meilleures à mon avis), qui permet de lier sous une interface commune la plupart des interpréteurs pour la JVM. Ainsi, exécuter du javascript (grâce à Rhino ou Nashorn), du Python (grâce à Jython), du … Groovy (funky baby) ou même … oui, même … du Java interprété (grâce à Beanshell) est vraiment très facile.

Donc, la présentation de Sébastien utilise cette percée, et la disponibilité en masse de frameworks javascripts, pour remplacer le beaucoup trop vieux et trop moisi rendu JSP par un rendu fait grâce à mustache (que je connais bien grâce à Ractive) ou React. Je ne vais pas vraiment m’éterniser sur React, parce que franchement, le JSX, c’est la pire idée à laquelle je puisse penser. En revanche, conceptuellement, c’est assez élégant.

Je m’explique.

Quand vous faites votre application web, vous avez votre joli modèle Java bien typé. Et c’est bien. Mais, au moment où vous faites le rendu dans votre JSP (ou votre template thymeleaf si vous utilisez Wisdom, par exemple), vous passez dans le monde moche et pénible du string typed. Tout est string, et vos objets Java n’ont plus d’autres intérêt que d’e^tre des struct capables d’émettre du String. Et dans ce cas, passer par du Javascript … n’est pas idiot. Parce que le travail énorme réalisé dans le monde du javascript ne se contente plus du client. Et que node.js reste une assez piètre idée, assez peu scalable. Du coup, joindre le meilleure du Java (le modèle, les capacités de traitement d’entreprise) au meilleur du javascript (tous ces outils de templating conçus par et pour le web) est vraiment chouette.

D’ailleurs, ça me donne des idées à propos de ractive/requirejs/Wisdom (mon trio de choc). Des idées qui n’attendent plus que deux choses

  1. Facile : le fameux bout de code transformant un require() en chargement de ressources depuis le CLASSPATH (d’après ce que j’ai compris, Sébastien travaille dessus)
  2. Moins facile : passer un template HTML plutôt que Javascript. Parce que s’il est question de rendu isomorphe, j’aimerais autant que ce soit le même fichier qui soit rendu de la même façon (ou presque) côté client et côté serveur.

Vite, un chtijug !

Et oui, parce que hier soir, encore une fois, il y avait chtijug.

Et encore mieux, une session spécial quickies. Je dois bien avouer que j’ai pensé à un moment proposer un sujet (Wisdom ? RactiveJS ? je ne savais pas trop). Mais mon emploi du temps m’empêchant actuellement radicalement ce genre d’activité, j’ai … laissé tomber.

Heureusement, des présentateurs bien plus motivés et bien plus efficaces que moi sont venus me raconter des trucs sérieux (pendant qu’un vieux fan me glissait des trucs salaces à l’oreille, et réciproquement, si vous voyez ce que je veux dire). Bref …

Webjars

La présentation est téléchargeable sur github.com/awillemant/webjars-prez essentiellement parce qu’elle utilise des webjars pour récupérer reveal.js

Force m’est de reconnaître que le sujet ne m’était pas totallement inconnu … Pour être honnête, au moment où le speaker a expliqué qu’il était facile de demander un novueau webjar, je n’ai pas pu m’empêcher d’expliquer à mon voisin que j’avais déja fait ajouter plusieurs librairies javascript … Vanité, quand tu nous tient.

Cela dit, curieusement, mon voisin n’a pas semblé convaincu alors que, personnellement, je trouve que les webjars sont la seule façon saine de faire du front-end dans Maven (avec Wisdom, bien sûr, que JHipster ou le frontend-maven-plugin ne font qu’essayer de copier grossièrement).

Workflows Jenkins

Bon, je venais principallement pour cette présentation, pour plusieurs raisons

  1.  Je voulais voir le petit Nicolas Géraud (que j’avais connu jeune développeur chez Sogeti) faire le barbu 🙂
  2. Le terme me rappelait quelque chose qui m’avait paru vraiment très intéressant
  3. J’avais assez trollé sur twitter

Et j’ai bien cru que j’allais être salement déçu.

La première partie, avec le build pipeline plugin et le parameterized trigger me rappelait des errements que j’avais connu, et qui m’avaient donné l’impression que Jenkins « scalait » assez mal sur les gros projets d’entreprise. Et j’aiv raiment eu peur que Nicolas n’en sorte pas.

Heureusement, la deuxième partie, sur le workflow plugin lui-même, a répondu à toutes mes attentes.

Parce qu’avec ce plugin, au lieu de créer un job jenkins dans un clickodrome d’une esthétique qui sera discutée plus tard, on crée son job avec … Groovy. Et, franchement, vous le savez, si il y a du Groovy, ça ne peut pas être mauvais. Et, en bonus, le job écrit en groovy peut être tiré par Jenkins d’un SCM ! C’est-à-dire que le SCM ne contient plus seulement le POM du projet à builder, mais aussi comment on peut le builder. Si on veut être fou, on peut même releaser le job d’un projet comme un des livrables de ce projet (en termes maven, ça revient à prendre le job dans un dossier sous src, genre src/build/jenkins.groovy). Bref, un outil enthousiasmant, et une présentation rondement menée, puisque Nicolas a exploité avec un certain talent chacune des 15 minutes disponibles.

Et même mon voisin n’a pas fait le grognon, alors qu’il fait du Gradle.

C’est juste dommage que sa présentation ne soit disponible nulle part sur le web 🙂

Les CSS pour les moches

Dans cette présentation, Hubert (le faux jumeau officiel de Nicolas) nous donne les bases – et un peu plus – du box model CSS.
Je ne vais pas avoir l’air de négliger cette présentation, parce q’elle était chouette, bien menée, bien remplie, claire, bref, professionnelle. Mais je connais le sujet depuis … 2004, d’après mon Shaarli. Alors je n’ai aps été surpris que je l’aurais pu, mis à part lors de l’irruption inopinée d’un display: inline block;

jmh

Si vous suivez des twittos Java, vous en avez forcément entendu parler.

jmh, c’est l’outil préféré des Rémi Forax et autres fans des microbenchmarks. Pour les développeurs « entreprise », c’est un peu moins important … mis à part à la machine à café. Cela dit, la présentation de Nicolas précisait bien la raison principale de l’existence de cet outil : le fait que la JVM fasse un gros paquet de trucs dans le dos du développeur (que, curieusement, mon voisin connaissait au moins aussi bien que moi – mais je le savais depuis bien longtemps). Bref, intéressant pour les tests exploratoires aux échelles micro.

Personnellement, dans la vraie vie, j’ai tendance à lui préfer contiperf qui

  1. S’intègre dans jUnit
  2. Permet de répondre à la question « est-ce que mon code va assez vite » plutôt qu’à la question « quel code va le plus vite »

Même si jmh tient bien mieux compte des phases de démarrage de la VM.

Testez avec Sérénité

ou plutôt avec Serenity. C’est un outil de BDD qui, d’après ce que j’ai cru comprendre, est une surcouche à JBehave qui ajoute un tas de choses vraiment chouettes. Comme de la coloration syntaxique des scénarios, ou des fixtures vraiment faciles à écrire. Et c’est tant mieux parce que, quand je vois le bazar que ça peut devenir avec Fitnesse, j’ai tendance à me dire que toute autre solution ne peut être que meilleure.

L’idée présentée est donc prometteuse.

Malheureusement, je dois dire que l’effet du stress sur le speaker pendant la session de live-coding (qui lui a fait garder une main dans la poche façon Jamel Debouze, et lui a fait oublier de s’asseoir, ce qui l’aurait sans doute aidé à coder plus vite), m’a un peu agacé, puisque je sentais bien qu’il aurait pu nous en montrer bien plus, si il avait été un peu moins tendu.

J’imagine que ça n’est que partie remise.

Un classement

C’est méchant de me demander ça. Et vous me connaissez, la méchanceté … j’aime ça.

Voici donc un classement subjectif de ces présentations, de la plus frappante à la … moins frappante 🙂

  1. Workflow Jenkins, parce que j’étais venu pour ça, parce que Nicolas était clair, et que j’avais plein d’idées à la fin (dont une a déja été envoyée aux bonnes personnes).
  2. Serenity, qui comble un autre vide béant, et pour laquelle je pense que Guillaume devrait, avec un peu d’expérience de ce genre d’exercice, se révéler un chouette speaker
  3. jmh, qui ne correspond pas à mes besoins, et qui n’a pas eu droit à son live-coding … Même si j’imagine très bien que ce soit un peu plus délicat à mettre en oeuvre
  4. webjars que je connaissais déja, et pour lequel le speaker a oublié de parler des différents composants côté serveur permettant de ne pas taper ce trop pénible numéro de version de javascript (de mémoire, Wisdom – évidement – Play Framework, et au moins une implémentation de Servlet spécialement conçue pour raccourcir autant que possible le chemin)
  5. css, parce que même si Hubert est un speaker rompu à l’exercice, le sujet m’a paru .. un peu … désuet ? (à un moment, je me suis même dit que j’aurais préféré revoir le fash 30 vu au bureau sur flexbox). Mais encore une fois, hubert est un chouettte speaker, et a quand même bien réussi son truc

Et encore une fois, c’est un classement totalement subjectif.

Cela dit, j’ai passé une super soirée, merci encore au chtijug.

Ionic framework ?

Eh mais la semaine dernière, il y avait …

Et je n’en ai pas encore parlé ? C’est MOCHE.

Donc, ionic framework …

pour lequel Loïc fournit les slides :

Comme ça, je n’aurais pas à vous résumer le truc, mais juste à donner mon avis.

Ionic est donc une surcouche d’Apache Cordova pour y faciliter l’intégration d’AngluarJS et d’autres trucs. Ca permet de faire facilement des applis hybrides pour mobiles.

Les applis hybrides étant, pour ceux qui ne le sauraient pas, des applications web packagées pour ressembler aux applications système.

Au passage, un petit tacle à ceux qui croient que c’est moche : les jeux de chez Wargaming utilisent ce type d’application pour les garages de World of Tank/Warplanes/Battleships. Et pourtant, ça ressemble assez peu à un site web, il me semble. Donc dire que l’hybride est forcément une mauvaise solution me paraît un peu abusif.

Bref. On retrouve donc avec Ionic la possibilité de construire une appli mobile en web. Et, malheureusement, avec Angular. je dis malheureusement, parce que franchement, angular me sort autant par les yeux que JSF, et c’est pas peu dire.

Cela dit, la présentation était sympa.

J’ai même été particulièrement bluffé par l’intégration de Firebase. Je savais que cette base de données « as a service » existait. Mais je ne savais pas que c’était aussi chouette. Tellement que ça a éclipsé dans mon esprit toutes les idées du genre « mais pourquoi ne pas remplacer angular par Ractive ? »

Donc, une présentation réussie, mais pas pour son sujet principal.