13 juin 2014

Ce gars est un grand malade - et il n'est pas le seul

Quand on vous dit que les choses vont très vite dans l'écosystème Docker ...

Il y a quelques heures, David publiait son fiboid à base de docker imbriqués, il n'a pas fallu attendre bien longtemps pour voir les premiers commentaires, et en particulier celui de Solomon Hykes, fondateur de Docker...

Imbriquer des conteneurs Docker c'est possible mais évidemment on send que ce n'est pas une solution très "naturelle".

Docker étant basé sur un démon, auquel parle un client (la ligne de commande docker, ou tout autre client via une API REST), il est plus simple d'expose le démon de l'infrastructure aux containers qui ont besoin de lancer d'autres containers.

L'idée est simple : monter dans le container le socket exposé par le démon.
-v /var/run/docker.sock:/var/run/docker.sock

Du coup, quand dans un container qui a été outillé de cette façon on lance une command "docker run ..." c'est le démon de l'hôte qui va répondre, et lancer un nouveau container, non plus imbriqué, mais côte à côte. Plus besoin de bricoler pour pourvoir faire tourner un démon docker dans le container, exposer les cgroups, etc. C'est tout de même un peu moins "hack-ish" :P


Deux petits schémas pour résumer ça :

Lancer un container DANS un container - possible, mais on sent comme un truc pas net

Lancer un container DEPUIS un container - clean, et plus besoin de --priviledge





Fiboid - ce gars est un grand malade

Lors de notre session au Ch'tiJug, expliquant entre deux anecdotes que Docker peut même être lancé à l'intérieur d'un autre container Docker, on (amis, j'ai oublié ton nom) nous a suggéré de faire un calcul récursif de suite de Fibonacci via des containers Docker.

Il n'en fallait pas autant pour lancer David sur la piste d'un projet aussi inutile qu'indispensable, dont il a publié le résultat : https://github.com/dgageot/fiboid "Fibo Inside Docker". Ce gars ne dors jamais, ou bien il est vraiment cinglé, ou peut être les deux, en tout cas svp ne l'encouragez pas.

A quoi ça sert ?

Sur l'exemple de David : a rien - enfin si, à tester la capacité de Docker à fonctionner en mode "poupée russe" et voir jusqu'où il peut aller.

Dans l'absolu, je suis longtemps resté perplexe, mais j'ai depuis vu passer plusieurs usages.


1. Builder des images Docker.

eBay a adopté Mesos et Docker, et a publié un papier dessus. Depuis Jenkins, un container Docker est donc lancé sur le cluster Mesos pour héberger chaque build. Jusque là, c'est simple, sauf que ce build veut lui même construire et tester des images Docker, et va donc lancer Docker dans l'image Docker. On a donc un premier niveau d'imbrication.

2. Packager un environnement multi-noeud.

Tester rapidement un project composé de N containers, ça signifie aujourd'hui fournir N images Docker et le script de lancement qui va bien (voir aussi le format containers.yml de Google). Une autre façon de faire, c'est de définir un Dockerfile qui lance les N conteneurs Docker de l'application. A nouveau, imbrication de containers

Je suppose qu'il y a plein d'autres cas intéressant à inventer.

Là ou fiboid est intéressant, c'est qu'il montre COMMENT imbriquer les containers. Car l'approche naïve que j'ai moi aussi testée dans le TGV qui me ramenais à Rennes, coincé entre deux valises d'un wagon bondé, c'est de lancer sans plus de scrupules "docker run" dans mon Dockerfile - sauf que ça ne marche pas. Sans 3G et avec les cuisses qui cuisent, je n'ai pas insisté :'(



Il y a en effet une petite manip pas triviale, résumée dans l'exemple de David par le script startdocker

Le premier truc à savoir c'est qu'il faut que le container tourne en mode "privilégié" pour pouvoir exploiter les containers (auxquels il est lui-même soumis), à savoir les API cgroup, les restrictions AppArmor, etc (je ne détaille pas car je n'y connais rien).

Ensuite, exploiter les cgroups depuis un container nécessite un minimum de collaboration avec l'hôte qui porte le container courant. Il faut donc synchroniser les cgroups du container avec ceux de l'hôte. Le reste du script est lié a divers raffinements et contournements, pour finalement lancer un démon Docker dans le container, qui permettra de lancer la commande "docker run" comme prévu.

Le principe d'imbrication des containers a été démontré initialement (afaik) par Jerôme Petazzoni, dont David a repris la recette. Le script wrapdocker ayant 3 mois, soit une éternité dans le contexte de Docker, il est possible que certains hacks ne soient plus nécessaires. Si quelqu'un en maitrise les détails, faites lui une pull-request :)





12 juin 2014

Docker Security

A moins de vivre dans une grotte, vous n'avez pas pu rater l'annonce de Docker 1.0-FINAL production ready.

Il y a tout de même un petit bémol à prendre en considération sur ce "production ready".

Docker utilise les capacités du noyau Linux pour isoler et contrôler des groupes de process (respectivement : namespaces et cgroups). La promesse est donc que chaque container se comporte quasiment comme une VM, en beaucoup plus léger, assurant l'étanchéité et l'indépendance de chaque application par rapport à ses voisines qui sont au final co-locataires de la machine hôte.

Seulement dans la vraie vie, il reste une issue non encore résolue : pour lancer un container, il faut être root. Les process qui tournent dans le container sont root (le root du container) par défaut. On peut bien sur tourner dans le container avec un autre user, mais si on autorise à faire tourner n'importe quelle image, on doit partir du principe que l'utilisateur du container est root - ou peut le devenir en hackant son container en installant volontairement un soft dont il connait une faille de sécu, il ne suffit donc pas de forcer le USER.

Que se passe t-il si notre utilisateur dans le container, qui s'y connais bien et a des intentions indélicates, arrive à sortir du conteneur, exploitant la faille X de la version Y du noyau pas encore mis à jour sur l'infra ? Et bien notre petit malin va se retrouver root sur la machine hôte - et ça c'est pas glop. Tiens d'ailleurs, si quelqu'un connais une (vielle) version du noyau / distro qui aurait un bug de ce type ce serait sympa pour en faire une démo.



Cette contrainte, on peut vivre avec, surtout sur des environnements privés : dans votre DataCenter, le risque d'un hack de ce type est quasi nul vu que vous ne déployez que vos propres applis. Sur un environnement réellement multi-tenant comme un Cloud public par contre ...

Le noyau Linux fournit le mécanisme de user namespace, qui permet à l'utilisateur root du container (id=0) d'être en fait l'utilisateur tartempion avec des droits standard sur la machine hôte. Le jail-break, sans être complètement anodin, n'a alors plus du tout le même impact.

Docker pourrait utiliser ce namespace, qui nécessite "juste" un noyau très récent. Vous pouvez lire les commentaires sur cette issue par exemple, qui n'aborde qu'une partie d'un possible fix, pour comprendre que ce n'est pas si simple, et qu'écarter ce point pour une 1.0 avait du sens. Comme dit plus haut, cela n'interdit pas d'utiliser Docker dans un environnement privé et contrôlé.

Par contre c'est un gros frein pour son utilisation massive par les hébergeurs Cloud, sauf à y adjoindre un autre niveau de sécurité. Sans surprise, le support Docker proposé par Google utilise une VM par déploiement, ce qui en soit est une régression de la part de l'éditeur qui utilise des containers en interne depuis presque 10 ans.



Je m'interroge sur les solutions retenues par les autres hébergeurs qui proposent du Docker aujourd'hui. S'ils veulent bien me contacter pour en discuter en privé je serais ravi d'échanger sur le sujet.

Vous pouvez aussi lire http://blog.docker.com/2013/08/containers-docker-how-secure-are-they/ pour en savoir plus sur ce thème.

Regardez aussi cette vidéo qui montre ce qui se passe lorsqu'on sort du container et qu'on rencontre la protection SELinux, qui évite à "root" de devenir "root" :-\


11 juin 2014

DockerCon

Pendant deux jours, Docker a été à l'honneur avec la première édition de la DockerCon, à laquelle participait mon collègue Michael Neale que je maudis pour avoir eu une place et pas moi.



Pendant notre petit tour des JUG avec David Gageot, nous abordons en fin de session un "what's next" avec un gros disclaimer, de circonstance lorsque de l'autre côté de l'atlantique ont lieu des annonces officielles. 

Nous ne nous sommes pas trop trompés jusqu'ici, car les annonces majeures ce sont :

  1. Docker production ready 1.0 - ok, ça fait conference-driven-development, et un 1.0.1 va évidemment suivre, ceci dit la version 0.12 qui a précédé était déjà super-stable, donc ce n'est pas que du marketing.
  2. Des témoignages d'acteurs majeurs. RackSpace, NewRelic, Ebay, Twitter ... autant d'innovateurs qui ont déjà commencé a adopter Docker dans leur boite à outil. J'espère que vous allez leur emboiter le pas :)
  3. Le re-vamping de l'index (build et hébergement des images Docker) en "DockerHub". Michael a discuté avec eux de l'intégration Jenkins, présentée en keynote de la conférence. L'idée est de "laisser faire Jenkins pour valider une image, chacun son taf" et j'ai donc préparé l'indispensable plugin qui va avec, n'allez pas voir pour l'instant il ne fait rien :) Je vais surtout bosser sur une intégration OAuth propre, la partie "validation d'une image" ayant par définition une signification différente pour chacun.
  4. Des annonces en tout genre, entre autre le positionnement très fort de Google sur Docker. Il faut dire que Google est à l'origine de cgroup donc fait partie de l'écosystème des containers depuis un moment.
  5. De nouvelles briques pour l'écosystème Docker. Si vous avez vu notre prez', Docker gère le container mais laisse aux outils tiers l'orchestration de l'infrastructure. CoreOs et Mesos sont les gros-mots qui reviennent souvent sur ce sujet, mais l'équipe Docker a aussi lancé libChan (communication entre containers) et libSwarm (composition de services à base de containers).
Bref, nous n'avions certes pas tout prévu, et tant mieux, mais nous n'étions pas complètement à côté de la plaque :)


10 juin 2014

Votre avis nous intéresse (aka "LikeBox")

En tant qu'organisateur du BreizhCamp, un stress particulier concerne la programmation de la conférence. Les thèmes choisis reflètent-ils les attentes ? Notre sélection de speakers a t-elle été la bonne ?

Obtenir du feedback du public est donc indispensable. Nous avons testé le tableau de post-it pour collecter votre avis général sur la conférence, mais cela ne nous informe pas sur les sujets eux-même.

En 2013 nous avions placé en sortie de salle des feuilles de vote proposant trois smileys, et vous demandant de cocher celui qui correspond à votre état d'esprit. Si d'un point de vue logistique cette solution est simple, elle ne rencontre pas un succès terrible, peu de personne prenant le temps de s'arrêter pour choper un stylo, cocher, remettre le bouchon. Certains ont également regretté l'absence d'un mode d'emploi pour expliquer clairement nos attentes face à une feuille vierge.

Très clairement, la facilité et la rapidité de vote est un facteur important.

Lors de DevoxxFrance, Xebia avait mis en place des boitiers de vote à la sortie de chaque salle :



J'ai vu peu de monde s'attarder pour voter, même si les données recueillies ont été très utiles pour les organisateurs. Un souci important était de mon point de vue la complexité excessive du système :

  • 5 boutons, donc un choix assez délicat. J'ai du mal à imaginer que le bouton "très mauvais" ai beaucoup été utilisé. Le median non plus d'ailleurs, pourquoi s'arrêter pour voter si on a pas un avis spécialement tranché ? Accessoirement, sans repère visuel sur les boutons, leur sens n'était pas évident. Résultat, passer au vote nécessitait une réflexion et donc un frein à l'expression spontanée.
  • Une identification NFC, destinée à éviter les votes multiples. Si vous avez déjà vécu la sortie d'une salle Devoxx vous savez qu'on a guère le temps de voter, alors voter 3 fois ... Sans parler de la question fatidique "mais heu, c'est vraiment anonyme du coup ?


Leçon #1 : ne pas laisser trop de choix, sous peine de perdre en compréhensibilité et donc en spontanéité du vote, et au final en nombre de votants.

Leçon #2 : ne pas mettre en place de barrières à l'expression des votants. Le vote doit être quasi instantané et ne pas ralentir la sortie de la salle.

Leçon #3 : utiliser comme Xebia des pieds d'enceinte sono, solides et pas cher. 

Devoxx.be a de longue date tenté de récolter les avis des participants à chaud. La formule retenue est basée sur ce qui a participé au succès de FaceBook, les "like".


Ici aussi, on identifie le participant par puce NFC, cependant il n'y a que deux états "content" / "pas content". En 2013 ils avait rajouté au centre un capteur pour ajouter la session dans votre compte parleys, afin que les déçus de la salle pleine à craquer puisse avoir une seconde change offline.

Le système est simple, de compréhension évidente (surtout ce modèle avec les pouces intégrés dans la forme du boitier, mieux qu'en 2011). Le NFC reste un léger frein à la fluidité de la sortie de salle, et maintien une certaine interrogation sur l'exploitation des données personnelles,mais globalement le système fonctionne bien.

Leçon #4 : proposer une user-interface aussi explicite que possible.

Leçon #5 : le côté Geek du matos apparaissant en transparence est un élément clé de l'intérêt du public à expérimenter les systèmes de vote. De ce point de vue le boitier en alu brossé utilisé par Xebia était contre-productif (sans même évoquer les problèmes de masse qui leur a plombé leur nuit pré-devoxx).


Pour JavaOne, les organisateurs avait mis en place des boitiers avec 4 boutons de vote, du vert au rouge avec un joli dégradé de smileys.



J'ai vu bien peu de personnes prendre le temps de voter sur ces boitiers, mais l'approche est simple, explicite, et saine sur la nature des "données" fournies au système. Ici je passe devant et j'ai juste à mettre un coup de poing sur le bouton de mon choix.

Pour le BreizhCamp, nous n'avions pas l'intention de faire des bracelets avec puce NFC, entre autre en raison du coût de ces gadgets. Une solution de ce type était donc clairement ce qui nous correspondait le mieux.

Comment éviter les votes multiples ? D'ailleurs, qu'est-ce qu'un vote multiple ?

Celui qui est super-super-content et va rester 3 minutes devant la machine pour exprimer son contentement en votant 10 fois, finalement fournit une information utile. Le tout est de savoir l'exploiter (problème de BigData :P). Evidemment il y a le cas du Aurelien qui durant toute sa pres' vient voter +1 chaque minute, mais ça reste un cas isolé et très facilement identifiable.

Nous avons donc défini notre cahier des charges :


  1. le boitier doit être d'utilisation limpide, sans aucune interrogation sur sa bonne utilisation. Deux boutons +1 / -1 suffisent, et obligent à se positionner plutôt qu'à voter "neutre".
  2. le vote doit être physique, par bouton, pour être rapide et implicitement anonyme. 
  3. le double vote involontaire (rebond du bouton) doit être évité, pas forcément le vote multiple absolu
  4. le boitier doit être geek, fun, donc transparent. L'idée est rapidement venu d'intégrer leds / bip / écran pour signaler la prise en compte du vote.
  5. le boitier doit être costaud. Bouton coup-de-poing industriel, plexi de 8mm, pied d'enceinte 50kg.
  6. le CPU dédié à enregistrer les votes ne risquant pas la surcharge, la sortie vidéo HDMI est exploitée pour afficher programme, tweetwall, etc
  7. l'accès réseau se fait en filaire. Nous savons tous ce que donne le Wifi en conférence.

Dans la pratique il s'agit du cahier des charges a posteriori, ce projet ayant été conçu entre deux emails de manière très informelle.

Pour la réalisation, je vous met entre les mains de Laurent qui explique ça mieux que moi. Ma contribution a surtout consisté à découper au dernier moment les plaques de Plexy (d'où une finition douteuse) avec l'aide de Julien (7 ans, d'où un alignement des perçages ... hasardeux)


Nous avons également réalisé un test grandeur nature en nous mettant à trois en file, imitant une sortie de salle, pour valider les timings anti-rebond, l'affichage du LCD, etc. 

Nous avons bien sur tout un tas d'idées pour améliorer ce produit, que nous avons nommé "LikeBox" :

  • Utiliser des cartes BeagleBone, plus puissantes que la RaspBerry, et plus classe (PCB noir, LED bleues) 
  • Donner à nos boitiers la forme de la box Internet de l'opérateur historique, ce qui suppose de cintrer du plexiglass de 8mm #challenge.
  • intégrer un port pour connecter rapidement une console de debug - nous avons eu quelques surprises
  • ...

Bref, encore quelques soirées bricolage en perspective...



Ce boitier, nous le mettons à dispositions des conférences amies contre un dédommagement symbolique et une entrée gratuite (:P) => likebox@breizhcamp.org


06 juin 2014

Windows Sucks

Un problème récurrent que les clients CloudBees reportent au support est l'utilisation de machines de build Windows. Nous recommandons clairement d'utiliser un Linux pour le master, mais bien sur il est nécessaire à de nombreux projets de faire tourner les diverses variantes de Windows comme "esclave" de build.

Jenkins offre de contrôler les slaves Windows via DCOM. Soucis, ce protocole historique a deux modes : "marche" et "marche pas". Autrement dit, une quelconque erreur de configuration se traduit systématiquement par un "Access is denied. [0x00000005]" sans plus d'explication.


Bien plus grave, les différentes astuces référencées sur le wiki et récemment mises au propre par Jesse nécessitent toutes de bricoler les droits système et le registre Windows, sans compréhension claire de l'impact de ces changements sur le système. Il n'est pas exclu qu'on ouvre par ce biais une énorme faille de sécurité. Bonus, il s'avère que les versions 64 bits de Windows se comportent assez différemment, et nous avons des retours assez étrange sur l'utilisation de Windows 8. Je ne vous parle même pas des versions "serveur" de Windows (dont je n'ai jamais compris ce qu'il a de "serveur" mais bon).

Nous décourageons donc à nos clients d'utiliser ce mécanisme. L'approche alternative utilise Java Web Start, autrement dit la création d'une connection à l'initiative de la machine Windows, ce qui coupe court aux problèmes de sécurité. Installé comme service windows, l'agent jenkins slave va donc se connecter au Jenkins master au démarrage. Dans de nombreux cas c'est très nettement mieux, cependant il s'avère que cette connection est parfois instable, pour des raisons encore inexpliquées, et bien difficile à diagnostiquer.



Une autre solution, qui s'avère plus stable, est de remplacer le slave Windows par un slave GNU/Linux. Pas de panique, je parle en fait d'installer Cygwin sur la machine Windows, pour la "GNU-ifier" et d'y faire tourner un service openSSH. La machine peut alors être contrôlée par Jenkins comme n'importe quel esclave Linux SSH, ce qui accessoirement unifie l'infrastructure de build.

Ce qui est triste dans l'affaire c'est de se dire qu'on aurait pas besoin de toute cette tambouille si Windows avait un server SSH natif :'(




05 juin 2014

Docker "Oignon" FileSystem

Pour présenter le mécanisme de fichiers 'en couches' utilisé par Docker (Union File System) David s'amuse à lancer un container ubuntu, faire un méchant rm -RF /, quitter le container et relancer la commande pour montrer que "de retour dans le containeur, le file système est clean".

L'effet attendu est atteint, à savoir faire prendre conscience au public, plus habitué à FAT32 qu'aux capacités des filesystems avancés de type ZFS, du mécanisme de copy-on-write et d'empilage de couches sur le filesystem en mode delta.

Pour ce qui me concerne, je présente souvent ce mécanisme comme du "oignon-filesystem" pour bien montrer ce concept de couches fines empilées, qu'on peut à volonté dépiler/empiler sous réserve de respecter le même ordre.


Nous jouons cependant un peu avec le feu en introduisant une fausse idée sur ce qui se passe. Histoire de rétablir un peu de rigueur, explication de texte :

Lorsque vous lancez docker run -i -t ubuntu /bin/bash, docker crée un container avec le filesystem ubuntu en read-only et active une "couche" AUFS en copy-on-write que vous allez modifier lors de vos actions dans le shell - par exemple via un rm -rf /.

Lorsque vous quittez le shell, le container s'arrête - mais il existe encore pour le démon docker, il est simplement à l'état stopped. Vos modifications sont bien là, stockées par AUFS, il n'y a juste plus aucun process qui y accède.

Lorsque vous relancez la commande docker run -i -t ubuntu /bin/bash vous créez un second container, strictement équivalent au précédent lorsqu'il a été lancé initialement. C'est d'ailleurs le point intéressant en termes de processus de développement / déploiement : la reproductibilité de votre livrable.

Cependant nous ne sommes pas à proprement parlé "revenus dans le conteneur". Nous pourrions par contre relancer le container initialement modifié avec la commande docker start  pour relancer le conteneur initial. Comme il n'est pas évident d'obtenir les ID des conteneurs ni de les mémoriser, si vous voulez jouer à ça je vous conseille de nommer vos containers.

Bon ceci dit, ceci est juste une petite mise au point théorique, dans la pratique relancer un conteneur arrêté n'a pas un intérêt énorme amha par rapport à la possibilité de relancer un conteneur tout propre, sachant que les données que l'on doit persister sont confiées à un volume, autrement dit un répertoire de l'hôte.

Le seul cas d'utilisation que je peux imaginer - qui est tout de même non négligeable - c'est le diagnostic post-mortem d'une appli que vous avez lancée via docker et qui s'est arrêtée. Docker start vous permettra alors de lancer un bash et d'aller inspecter le cadavre.



04 juin 2014

Containerization vs Virtualization

En accompagnant David Gageot pour un East-JUG-Docker-Tour nous avons pu discuter de nos approches de présentation respectives et de la difficulté de bien faire comprendre un concept fondamentaux qui est la clé de voute de Docker : les containers.

Tel que je le présentais jusqu'ici, vu les questions qui suivaient la présentation, il est clair que j'allais trop vite et que du coup le message passait mal. David a repris toute cette partie pour l'expliciter dans le détail avec démos d'illustration. Nous testerons le résultat sur le public Strasbourgeois ce soir ...

Une image m'a été suggérée par Guillaume pour illustrer la différence entre un container et l'approche "à la virtualbox". Je l'ai intégrée à la présentation, car c'est le genre d'image choc qui marque les esprits et aide donc à bien mémoriser le concept.



A propos d'image marquantes, une photo souvenir. Pour la petite histoire, dans le train qui nous transportait de Nancy au prochain JUG de ce East-Tour, scotchés à nos écrans à essayer de bosser un peu (tout de même) et entendant le haut parleur crachoter l'annonce "notre train va arriver en gare de S..a..bourg" nous sommes descendus sans broncher, même pas surpris par la taille très modeste de la gare. Le temps de réaliser notre erreur, le train était reparti. #Boulets




02 juin 2014

Docker-tour squatt

Suite au succès de la session "la révolution Docker" à Devoxx, je me suis proposé de faire un petit tour des JUGs sur ce thème. Après consultation des organisateurs, il s'est rapidement avéré que David Gageot avait eu la même idée (j'ai du rater un tweet ...). Je passe donc du statut de speaker à celui de ... squatteur.


Blague à part, cela devrait être enrichissant de comparer nos approches du sujet. Rendez-vous demain 4 juin à Nancy et mercredi 5 juin à Strasbourg.

28 mai 2014

Publier sur Parleys

De retour du BreizhCamp, nous voici avec quelques Go de vidéo AVCHD à publier.

L'encodage de ces vidéos n'est pas distribué pour des raisons de volumétrie. Il faudra qu'on réfléchisse à une façon de gérer ce "problème" un jour, mais dans un premier temps j'ai Adobe Media Encoder qui tourne toute la nuit chaque jour, suivi d'un upload sur Youtube - je n'ai malheureusement pas la fibre, mais bon, l'encoding reste plus long que l'upload, donc ce n'est pas le facteur limitant.

Les vidéos sont donc mises à disposition sur la playlist BreizhCamp 2014 du BreizhJUG.

Le montage sur Parleys est une étape qui s'est grandement simplifiée au cours des années. C'est aujourd'hui une appli HTML5 directement intégrée au site. Si vous voulez nous aider, contactez team@breizhcamp.org pour être ajouté comme publisher.

Allez sur le channel du JUG sur lequel la session sera publiée. Cliquez "Add presentation" et indiquez le nom du talk tel qu'il est défini sur le programme.

Dans la session (vierge) qui s'affiche, sélectionnez "timeline", la partie édition de parleys s'affiche alors. Sélectionnez la Lirary, c'est ici que l'on va importer le contenu à monter : vidéo youtube et slides PDF.

Il suffit ensuite de glisser/déposer la vidéo dans la timeline, puis de sélectionner les slides PDF, lancer la vidéo, et tapper s+space à chaque changement de slide par le speaker - en vérifiant qu'il ai bien suivi l'ordre de ses slides :P. L'onglet "shortcut" indique d'autres raccourcis pour un montage rapide sans galérer avec la souris.


S'il y a un phase de démo, insérer une "chapter" vide, ce qui masquera les slides dans le lecteur parleys pour n'afficher que la vidéo (éventuellement en plus grand, selon la configuration sélectionnée par l'utilisateur final).



Choisissez un moment représentatif de la session pour capturer un image de couverture via le tab "Settings". Dans la partie "attachement", glisser/déposer les slides de la librairie,



quand tout semble ok,  [Publish] !

Le talk sera alors disponible à l'état staging. L'édition des méta-données (speakers, résumé) consiste à reprendre les infos du programme. Si vous n'avez pas ces infos (nouveau speaker dont vous n'avez pas l'e-mail) on s'en chargera, le gros du boulot aura été fait de toute façon. Indiquez juste l'état "staging" dans le spreadsheet, qu'on sache qu'il n'y a que la dernière étape de publication à prendre en charge




25 mai 2014

Machistes ?

On nous a signalé cet article sur la programmation du BreizhCamp.

Il y es dénoncé le machisme du comité de sélection qui aurait écarté les femmes du programme.
D'une part, je ne sais pas sur quels chiffres ces bien-pensants se basent, mais je n'ai jamais vu plus de 2 à 4% de femmes dans une équipe de développement - je parle bien de développement, pas de l'IT en général, le chiffre monte alors à 20% et quelques d'après le syntec, ce qui reste peu - j'ai l'impression que l'auteur se base sur ce chiffre quand il note "l’inégalité est flagrante, bien plus importante que la proportion réelle de femmes dans le domaine". Dommage de se baser sur des chiffres aussi générique lorsqu'on parle d'un domaine très ciblé.

Nous avons retenu 3 filles au programme et non une comme indiqué initialement par l'article, soit 50% de réussite à l'épreuve du call-for-papers, comme pour les hommes. Nous sommes en effet neutres et ne faisons pas de discrimination positive sur le sexe du speaker. Ce serait contre-productif à mon avis en proposant des sujets de moins bonne qualité et en les associants finalement aux speakeuses. Certaines femmes techos proposent d'excellent sujet, et n'ont pas besoin de cela pour être retenues.

On nous accuse aussi d'avoir une équipe 100% masculine à sélectionner les propositions. C'est en effet le cas, Marie-Christine étant partie à d'autres occupations, mais nous n'avons jamais communiqué la liste des membres du comité de sélection, il s'agit donc à nouveau d'une conclusion gratuite.

On nous accuse de ne pas prendre en compte le cas de femmes dans l'IT. Ca tombe bien, un sujet était au programme pour présenter Women in IT, co-présenté par un des organisateurs à l'initiative de ce mouvement sur Nantes.

Je suis moi-même membre de JDuchess, et bien que peu actif je pense être sensibilisé et tenter d'y apporter des réponse concrètes, comme d'héberger une après-midi Devoxx4Kids pendant le BreizhCamp et promouvoir ce mouvement, actuellement le meilleur moyen pour que la prochaine génération ne plafonne pas à nouveau à 2% dans les domaines techniques. L'un des membres de l'équipe (Nicolas Ledez) anime tout au long de l'année des ateliers, et est donc très impliqué dans la démarche.

Quand aux "maladresses (photos ou ton déplacé)" notées par l'auteur, qui sont en général le fait de quelques speakers et non des organisateurs, pour les femmes présentes que je connais elles sont bien vécues - certaines n'étant pas les dernières sur le sujet.

Alors quand je lis un article tirant de mauvaises conclusion sans plus de recherche, sur un site qui se veut observatoire du machisme dans les tech et de toute évidence bien mal informé, ça me fait mal. L'auteur, déjà contacté par quelques uns d'entre nous n'a pour l'instant pas répondu, en dehors d'un update mineur sur son décompte des speakeuses.

Je n'ai aucunement l'intention d'imposer un guide de bonne conduite à l'américaine. Au BreizhCamp il y aura aussi des gros mots, voir même quelques trolls contre PHP ou Python, j'espère que l'observatoire du bon parlé français ou le site des Pythonistes-béliquex ne nous en voudront pas - d'autant plus que c'est le but de la conférence : confronter les points de vue, parfois sur un ton ... canaillou :P. Donc si tu es une femme, que tu peux nous parler de la supériorité de PHP sur Java, et le tout sans le moindre gros-mot, tu es la bienvenue - par contre, pas de mauvaise blague sur les gens de couleur (*) ni sur les tendances sexuelles, on ne veut pas d'ennuis avec un autre site bien-pensant.

(*) nous avons un asiat' dans l'équipe. Il s'est de lui même proposé pour faire des sushis. Nous avons même quelque SysAdmins, c'est dire si on est ouverts.


14 mai 2014

workflow plugin

Il y a parfois des coincidences.

Je publiais hier un billet expliquant pourquoi j'abandonne le build-flow plugin au bon soins de la communauté. Quelques heures plus tard Kohsuke annonçait sur la mailing list jenkins son plugin de workflow.

Nous nous serions concertés pour faire un lancement produit nous n'aurions pas fait mieux ! Mais non, c'est juste une coincidence :P

Ce nouveau plugin n'est pas à proprement parler la continuité du build-flow, même s'il en partage certains aspects. On retrouve un DSL qui décrit le workflow, mais ici l'unité de base n'est plus un job, mais un build-step, qu'on va exécuter sur un slave donné.

Le plugin est encore assez jeune mais permet déjà de définir des choses comme :

git.checkout( repo: “git@sm.com:app.git”, branch: “master”)
mvn “install”

je ne doute pas que KK ai prévu tout le nécessaire pour que chaque plugin jenkins puisse ajouter ses propres mot clé au DSL et l'enrichir...

En regardant les slides de présentation, je me demande si ce même DSL (réduit) ne pourrait pas être utilisé pour définir le build via un fichier à la travis, autrement dit un .jenkins stocké dans le SCM dans lequel vous définiriez les étapes de build et tout ce qui va bien pour votre project, ne déclarant dans jenkins que la partie SCM.

A réfléchir ...

12 mai 2014

build flow future

Depuis trois ans je développe par petites touches le plugin Jenkins Build Flow, dont l'objectif est de fournir une solution d'orchestration de jobs jenkins, pour des process de build non triviaux et non nécessairement linéaires. L'idée est de reposer sur un DSL pour exprimer les relations entre jobs d'un même "pipeline", de manière concise et centralisée - et non dans chaque job via divers plugins spécialisés.

Ce plugin a été largement adopté (3500 installations) malgré tout je l'ai toujours considéré en phase expérimentale (d'où le numéro de version : 0.11). Ce succès a révélé un effet de bord majeur : de nombreux utilisateurs ont exploité la syntaxe Groovy du DSL pour venir "bidouiller" Jenkins à l'aide du build-flow. Initialement je pensais que le DSL devait être un pur langage indépendant des APIs de Jenkins, ce qui permettrait de faire évoluer le moteur interne. La facilité de créer un DSL en Groovy et l'absence totale d'expérience de ma part dans ce domaine a ouvert la boite de pandore. Aujourd'hui il est impensable de conserver la compatibilité et de revoir l'implémentation du moteur.

Or le build-flow a un défaut majeur : ce n'est pas une machine a état qui est modélisée puis exécutée, mais un thread java qui est lancé. Impossible de figer le flow (redémarrage de jenkins), de reprendre à flow à une étape précédente (reprise après erreur), etc. Bref, de prendre en charge des process de développement réellement complexes et de correspondre à ce que fait par exemple le plugin build-pipeline pour les cas "linéaires".

Bloqué par ce problème technique, je n'ai plus travaillé sur le plugin depuis un moment, et je manque de temps et d'idée pour m'y atteler. Accessoirement je n'utilise pas ce plugin moi même, le dogfood étant le meilleur moteur pour faire avancer un projet, celui-ci s'enlise.

J'ai donc décidé d'abandonner ce projet, qui est à la disposition de la communauté -  en termes d'écosystème Jenkins cela signifie que le premier qui prend le temps de le maintenir devient mainteneur officiel. J'ai lancé un appel à volontaire sur jenkins-dev. Si vous êtes tenté, je suis évidemment disposé à vous expliquer en bon Français le pourquoi du comment avant de vous passer la main, contactez-moi.

Ce plugin ayant ses fans, déçus par les tentatives de recentrage que j'ai appliqué après la version 0.10, je ne doute pas que quelqu'un prendra la main dessus, et le fera évoluer selon ses besoins. Il ne correspond plus à ma vision, mais peut tout à faire correspondre aux besoins de nombreux autres utilisateurs.

Kohsuke travaille sur un nouveau plugin de workflow. Je n'ai suivi son initiative que de loin pour le moment et je ne sais pas très bien le recouvrement. Je sais juste qu'il a profité des enseignements du build-flow, même si nous n'en avons pas nécessairement la même perception. Wait'n see.


07 mai 2014

test des accès base

Je vous présentais hier un petit outil bien fait pour écrire les tests d'API REST. Sur une application qui fait autre chose qu'un hello world, il faut cependant "bouchonner" les resources externes pour rendre ces appels prédictibles et donc reproductibles dans le cadre de tests automatisés.

Une pratique courante de test consiste à utiliser des Mocks, en considérant qu'on veut valider l'utilisation d'un système tiers, pas son implémentation. Dans le cas un peu particulier d'une base de donnée cependant on est confronté à un problème : le SQL

Les accès à la base de donnée sont en effet liés à son interprétation de ces fameuses requêtes, et le seul moyen de s'assurer que leur syntaxe est correcte, correspond au schéma de la base de données, et retourne bien les données attendues, c'est ... de l'exécuter.

Que l'on fasse du JDBC à l'ancienne ou qu'on utilise un outil de requêtage type-name-safe comme jooq le problème reste le même, une requête n'est vraiment fiable que si on a pu la valider sur une base de données réelle. La solution que tout le monde (?) utilise est une base de donnée H2 - base qui tourne en mémoire - ce qui permet de démarrer rapidement et sans complication une base juste pour la durée des tests. Je me suis fait une Rule junit pour monter cette base H2 et appliquer les scripts de création du schéma, qui sont - évidemment - stocké dans mon repo Git avec le code de mon appli (what else ?).

Pour mettre la base dans un état donné et valider le résultat de mes requêtes, à la recherche d'une solution sympa, légère et qui soit un peu plus productive que des fichiers xml DBunit, je suis tombé sur dbassert.

    @Rule
    public InMemoryDataBase dataBase = new InMemoryDataBase();

    @Test
    public void list_items() throws Exception {

        DbAssert db = DbAssert.init("dbassert.yml");
        DbSource h2 = db.source("h2", getClass());
        h2.clean_table("items");
        h2.fixture("items");

        // Proposal returned
        when()
            .get("/items")
        .then()
            .assertThat().body(containsString("Test item"));

    }

Ca reste un chouille verbeux, donc pour faire clair :

le init consiste à configurer DBAssert pour accéder à la base de test. La DBSource sert à définir où trouver les fichier de données - dans le même package que la classe indiquée. On applique ensuite des fixtures, des fichiers yml de données pour la table du nom correspondant. On peut de même comparer l'état de la base après un update.

Quelques points négatifs qui me font penser que c'est un projet encore jeune, ou bien qu'il y a mieux ailleurs :)


  • le projet est sous SVN sur google code. Clairement pas adapté pour la contribution a l'aire de GithHub.
  • la librairie n'est pas disponible sur maven central. J'ai fait un export des sources dans mon src/test/java, vu qu'il n'y a que quelques classes
  • l'API est perfectible. Je voudrais pouvoir initialiser DbAssert via une DataSource - que j'ai préparée par ailleurs dans ma InMemoryDatabase  - plutôt que via un fichier yml
  • l'application d'une fixture utilise un INSERT bête et méchant, sans rechercher les données déjà insérée. On doit donc faire un clean_table systématiquement.
Rien de bien grave, qui devrait pouvoir se corriger via une petite contribution (d'où le premier point).

Si vous connaissez un autre outil comparable, je suis preneur de vos retours d'expérience.




05 mai 2014

test de services Rest

Il y a quelques années, lorsque je développais des applications web (avant de devenir essentiellement un développeur  middleware/backend) il y avait une explosion de frameworks MVC. Struts, WebWork, Wicket, Stripes, pour n'en citer que quelques-uns.

Les applications actuelles tendent vers un modèle à base de vue riches JavaScript et un backend REST, et on voit émerger une foultitude de Frameworks JavaScript et de backend REST.

Je n'ai jamais été très fan des tests web, selenium ou htmlunit, qui ont toujours été délicat à stabiliser et bons pour la casse à la moindre refonte de l'UI. L'évolution vers une architecture JS+REST a l'avantage de permettre au moins de tester facilement la partie REST - je n'ai pas encore exploré les solutions pour la partie Web à proprement parler, c'est quelque part dans ma todo-list ...

Comme toujours, il y a pléthore de frameworks pour un même besoin, chacun avec ses propres spécificités et avantages. Je n'ai pas l'ambition de vous dire avoir trouvé la perle rare ni proposer un palmares exhaustif, vu que je n'en ai essayé qu'un : Rest-assured.

Ce que j'aime bien dans Rest-assured c'est la syntaxe très, très simple et lisible des conditions de test et des assertions, très inspirée de l'approche BDD ("given/when/then") :

    @Test
    public void should_create_user() {
        given()
           .body("{ \"name\": \"nicolas\" }")
        .when()
           .post("/users")
        .then()
           .assertThat().statusCode(CREATED);
    }

Très peu de code parasite dans la description d'un tel test d'API. Que le scénario de test soit lisible même par ma grand-mère (ou pire : ma MOA) comme le voudraient les partisans des tests fonctionnels m'importe peu, par contre que je puisse rapidement définir une condition de test sans partir dans des imbrications d'API sans fin, ça me parle.

L'approche "fluent" (qu'on appelait Builder Pattern dans le temps, mais c'est moins hype) apporte aussi beaucoup en lisibilité. En gros, si on fait abstraction de la ponctuation on peut lire une phrase quasi naturelle (enfin, humanoïde quoi), c'est ce qu'on appelle un Domain Specific Language. On retrouve ce pattern dans tous les frameworks récents, et les lambdas de Java 8 aident pas mal à étendre cette approche à de nouveaux cas d'application.

Ce que je constate surtout, c'est qu'à côté l'explosion des frameworks applicatifs on a aussi une explosion de l'outillage de test, souvent (toujours ?) la cinquième roue d'un développement, mal ficelé, mal entretenu, mal outillé. Pour ce qui me concerne je les redécouvre tardivement. Ne faites pas la même erreur que moi, gardez un oeil sur vos tests et la boite à outil qui va avec.


Bon ceci dit, c'est bien connu "tester c'est douter". Perso j'ai appris à mes dépends à douter et à prendre quelques précautions pour éviter les mauvaises surprises.



Small is beautiful

Faire des tests rapides, un build qui ne dépasse pas quelques minutes, ça reste un voeu pieux confronté à une appli de centaines de milliers (millions?) de lignes avec une architecture alambiquée. Je ne jette la pierre à personne, j'ai moi même largement contribué à rendre ces applications alambiquées à grand coup de Spring-truc et d'AOP.



Aujourd'hui, avec du recul et surtout en travaillant dans une équipe totalement distribuée (donc où il faut savoir limiter les besoins de synchronisation et  de communication), j'apprend les mérite d'une autre approche.

Vive les micro-services.

Le concept de micro-service est expliqué en détail par Martin Fowler et James Lewis. 

Une application mastodonte-monolithique est délicate à faire vivre et ardue à appréhender. Le découpage en couches à la JavaEE et les modules maven associés ne changent pas grand chose à la donne, et au contraire ont tendance à figer de possibles mauvais choix. Si par exemple j'ai développé mon UserRepository avec plein de beaux tests, et que je veux faire un savant refactoring de mon modèle, je vais m'assoir sur tous mes tests, car ils sont ciblés sur la vision de mon architecture à un instant t, alors que le besoin de départ est fonctionnel. On touche ici au distingo test unitaire / test fonctionnel. 

Selon une approche micro-service, plusieurs applications spécialisées prennent en charge des domaines métier restreints. Une équipe plus spécialisée et plus restreinte s'occupe de ce "fragment" et peut plus facilement le faire évoluer. Dans le cas d'une équipe distribuée à la CloudBees, ça donne des équipes de 1 :-)  Chaque service étant très spécialisé et ciblé il est facile de rentrer dans le code "en renfort".

Ces micro-services communiquent ensemble via des APIs, et peuvent utiliser des protocoles binaires pour limiter l'impact d'un appel HTTP sur les performances, mais ce qui compte ce sont les frontières qu'on a défini dans le modèle métier.


Ces frontières et la réduction du scope allègent grandement chaque service et permettent de mettre en place des pratiques de développement efficaces, et d'augmenter l'agilité de chaque service. L'agilité de l'application dans son ensemble s'améliore aussi, malgré un surcout de synchronisation des développements de chaque service. C'est un peu le principe des scrums-de-scrum.

Autre bénéfice qui émerge rapidement, chaque micro-service peut avoir sa propre architecture, voir son propre langage d'implémentation, et donc mieux répondre au besoin "local". 

Ce n'est pas forcement lié, mais si on ajoute Docker dans l'équation, tous ces services peuvent tourner sur la même machine et la communication entre micro-services a alors un coût minimal. Docker permet de donner des quotas à chaque service, et donc d'identifier facilement lequel part en vrille lorsque c'est le cas - ce qui est souvent un challenge ardu sur une grosse appli monolithique. Il permet aussi de gérer un dimensionnement différent de chaque service, un cycle de vie différent, etc.

Bref, vous l'aurez compris, je suis fan :)

02 mai 2014

To test or not to test ?

Pendant des années j'ai fait la promotion des tests unitaires, expérimenté tout un tas d'outils (c'est le côté rigolo) sans moi même trop me plier à la pratique. Je pouvais prétexter intervenir sur des couches techniques et/ou d'intégration qui sont d'un compliqué ma pauv' dame.

Bref faites ce que je dis, pas ce que je fais.

J'ai utilisé le TDD une fois lorsque j'ai voulu ré-implémenter fonzie proprement (la version initiale étant au mieux un jouet, ce qui n'a pas empêché de le mettre en production, m'enfin). Il faut reconnaître que ça marche du tonnerre si on arrive à se discipliner.

J'arrive après la bataille et je ne vais donc pas vous faire l'apologie des tests unitaires, d'autre l'ont fait et le font encore bien mieux que moi avec nettement plus de crédibilité. Ce que je constate par contre, c'est que c'est une pratique qui a un impact fort sur les choix d'architecture et de frameworks.

Architecture : une grosses appli Java EE de centaines de milliers de lignes, avec toute la bonne volonté du monde ça met vite un temps fou à builder/tester. Je pourrais vous parler de micro-services (un autre jour ?) mais il est évident qu'avec une suite de test qui prend plusieurs minutes et écroule la machine, le développeur ne va pas lancer les tests régulièrement, ni sans doute avant de committer des modifs mineures (sic!) sauf à faire la police dans l'open-space - bonne ambiance garantie.
Ca veut donc dire qu'il faut savoir cibler les tests à l'essentiels, le 100% de couverture qui teste tous les getter/setter (si si, y'en a) n'apporte vraiment que du surpoids au projet.

Frameworks : Je vous parlais hier de fluent-http, et sans surprise ce framework web permet d'écrire des tests très léger et très rapides. Il sait démarrer sur un port libre aléatoire (ce qui permet aux tests de tourner en parallèle), et ce en quelques centaines de millisecondes.

public class MyResourceTest {

    @BeforeClass
    public static void runWebServer() throws Exception {
        WebServer server = new WebServer(routes -> {
            routes.add(MyResource.class);
        }).startOnRandomPort();
    }


    @Test
    public void should_create_user() {
        given()
           .body("{ \"name\": \"nicolas\" }")
        .when()
           .post("/user")
        .then()
           .assertThat().statusCode(CREATED);
        // TODO test database insert was successful
    }
}


Ce tout petit test me permet de tester mon service REST, il manque juste un peu de mocking pour la partie backend. Il est de niveau API, donc orienté fonctionnel, et me permet de jouer avec l'implémentation.

Jouer c'est bien le mot, car avec des tests aussi rapides, on peut activer infinitest.

Infinitest joue les tests à chaque modification de code (compilation si vous utilisez IntelliJ Idea). On va donc tripatouiller le code par petites touches, Cmd+S et hop le test vérifie qu'on a pas tout cassé et/ou qu'on a enfin réussi à implémenter la fonctionnalité attendue.

On est donc dans une logique de type micro-intégration-continue, très très efficace. Evidemment, si vous n'avez pas des tests rapides, ça n'est pas d'un grand intérêt. C'est donc un ensemble complet de pratique, d'outils, et d'architecture auquel il faut s'attaquer, tous d'un même front.

Pour en arriver là sur des projets non triviaux, il faut aussi savoir découper son appli correctement. Mais je vous parlerais de micro-services une autre fois :)


30 avril 2014

fluent-http, un amis qui vous veut du bien

Le Call-for-Papers du BreizhCamp est une appli custom développées au fil du temps libre l'an dernier et un peu rafraichie cette année. J'ai pour ambition d'en faire une appli "as-a-service" pour toutes les conférence qui veulent bien s'en servir (n'est-ce pas un super business model ?)

Pour arriver à ce résultat, un grand coup de ménage s'impose, et c'est donc l'occasion pour toute équipe de dev de critiquer les choix techniques "historiques" et essayer de nouvelles choses.

J'ai été tenté par Spring Boot, pour finalement me tourner vers fluent-http. Plusieurs raisons à cela :


  1. fluent-http est un framework tout neuf, c'est donc motivant d'y mettre son nez
  2. fluent-http est fait par l'équipe codestory, avec tout plein de Gageot-eries dedans, et donc c'est beaucoup plus sympa de se dire qu'on peut en discuter avec eux autour d'une bière.
  3. fluent-http est incroyablement léger et rapide. Cela permet d'écrire des tests unitaires (voir plus loin) efficaces
  4. fluent-http nécessite java 8, donc pas d'excuse, il est temps de se mettre aux lambdas et pourquoi par de mettre null hors d'état de nuire à grand coups de Optional.
  5. ça nous fera un sujet pour proposer une conférence :)

L'un des points techniques majeur qu'apporte fluent-http c'est la légèreté. Le serveur démarre en vraiment pas longtemps, et s'il ne supporte pas (encore) le hot-reload le cycle stop/restart prend plus de temps à cliquer qu'à attendre le serveur. Pas d'initialisation à la Spring à parser du XML ou à scanner le classpath à la recherche d'annotations, fluent-http est taillé pour démarrer vite avec juste ce qu'il faut. 

Le "juste ce qu'il faut" est aussi amha un point important. A utiliser des frameworks sensés nous simplifier la vie, on finit par se créer des contraintes et perdre un temps fou sur des problèmes d'intégration. 

Exemple concret : sur la version initiale du CfP, écrite en Play/Java+Angular, la sécurité est confiée à SecureSocial. Sur le papier c'est génial, trois fichier de conf et roule ma poule. Dans la réalité, lorsqu'on veut introduire du multi-tenant, utiliser l'email comme clé d'identification des utilisateurs, etc, on galère (surtout quand l'implémentation LinkedIn ne récupère pas l'email). Ajoutez quelques bugs (?) : je m'inscrit avec github, je fait ma cuisine, je tente de me reconnecter avec Google, et là j'ai un nouveau compte. Ballot non ? 

Au final j'ai passé pas mal de temps à comprendre la structure de SecureSocial, puis finalement a en forker un bout (pour le multi-tenant). C'est certes intéressant, mais tout bien pesé, implémenter mon propre login en comprenant les mécanismes OAuth2 ne prend pas nécessairement plus de temps (la preuve).

Donc, faut-il tout recoder sois-même ? Non, soyons réalistes. Faut-il mettre des frameworks pour tout juste parce qu'ils couvrent mon besoin (plus tout un tas de trucs) ? Non. C'est ce en quoi je ne suis pas fan de JHipster. Sur le papier c'est super, mais rien que la structure de code générée par défaut me fait peur. On peut débattre du bienfait d'avoir tous ces outils pré-cablés, qui seront nécessaires à un moment ou à un autre et ne coutent pas plus cher, mais personnellement ça ne me donne pas envie. J'ai par exemple peur de ce que va devenir mon build Grunt que je n'ai pas du tout conçu moi même. En gros, on m'impose des outils dont je ne sais rien, que je n'ai pas demandés, et que je ne maîtrise pas.

fluent-http se contente (sic) de prendre en charge la couche HTTP et l'exposition de resources REST, en ajoutant le support de templates html. Juste ce qu'il me faut, à moi de définir sur mesure ce que je veux ajouter dessus, au cas par cas.

J'ai glissé un mot sur les tests. Et oui, ça sent le Gageot entre chaque ligne de code. Fluent-http est très rapide à démarrer, non pas pour booster vos serveurs de production (quoi que ...) mais surtout pour permettre d'écrire des tests web rapides. 

Je vous en dirais un mot vendredi, il parait que c'est bien de faire un billet de blog par jour :)




16 avril 2014

la rançon du succès

Si vous ne le saviez pas, cette semaine c'est DevoxxFrance...

Je ne vais pas vous parler des divers talks de la journée, mais d'un événement tout à fait indirect.

Les organisateur de Devoxx on en effet du faire face à de la publicité sauvage, sur le trotroir juste devant le centre de conférence :



Ce marquage est fait au karsher, c'est donc écrit en "propre sur fond sale", rien à reprocher en termes de la dégradation de la voie publique.


  • D'un point de vue communication c'est inattaquable et  assez génial, il faut l'avouer
  • Du point de vue de DevoxxFrance, c'est une marque de reconnaissance indirecte : se faire ainsi "hacker" pour une campagne de pub, c'est montrer qu'ils sont incontournable.
  • Du point de vue du respect de la conférence, c'est nettement plus discutable. DevoxxFrance vie de l'énergie d'une quinzaine de bénévoles, et avec l'aide de sponsors qui payent leur place. Détourner ainsi cette énergie à des fins de promotion pirate est assez lamentable. En écrivant ce billet je me rend compte que je relaie leur message, mais en même temps j'espère vous faire comprendre à qui vous avez affaire. Détourner ainsi, sans contrepartie, les efforts d'une équipe qui se plie en quatre pour faire bouger notre écosystème, c'est minable.

Donc, si vous cherchez du taf, dites le moi, je publierais les CV des 10 premiers qui me contactent, juste pour montrer qu'il y a des manières plus respectueuses de faire les choses.

14 avril 2014

Jenkins meets Docker - round 2

On my previous blog post I explained how to use docker from Jenkins.



I can see some issues with this setup :


  1. You have to register the docker image you want to use as a slave in Jenkins global configuration, and rebuild the image when your environment requires some changes. 
  2. Dockefile has to define a ssh server, just to act as a jenkins slave, unrelated to your project needs.
  3. Docker plugin isn't elastic, even being a "Cloud" Jenkins plugin. It relies on a static docker-enabled host to run containers. I'd like to keep the Cloud principle to get resources as needed.


So, please welcome oki-docki jenkins plugin. This is still an experimental, unreleased, work-in-progress, use-at-your-own-risk plugin, but here's the concept :

You use your SCM to store both project source code, build script and a Dockerfile that describes your build environment. oki docki will use your Dockerfile to build+run a container and execute build script.


Plugin actually

  • checks project workspace for a Dockerfile
  • computes its hash, to detect changes
  • search for an existing docker image to match, build one if required
  • run a container, mounting build workspace in container as /var/workspace
  • executes build script

You may notice the docker image isn't pushed to a repository. This is intentional. I like the idea I can rebuild my docker image at any time from scratch, not relying on some binary deployed somewhere. Thanks to Docker incremental build, this isn't such time-consuming.


Benefits :


  1. no need to setup anything on jenkins, just have docker-enabled slaves. I'm using a "docker" label for this purpose. This one can benefit from jenkins Cloud slave providers.
  2. Dockerfile just defines requirements to build your project. All yours to select a specific JDK, system packages or nodejs version. The same Dockerfile can be used by developers to get a ready-to-use development environment.
  3. project Dockerfile is stored in SCM, with application code and build scripts, and all is kept in sync without manual steps. You can have a distinct Dockerfile in a branch if needed.


The current implementation is more a Proof-of-concept than a production-ready plugin, but already let you run a build inside Dockerfile. My initial goal was to start the container and then let jenkins run any regular build steps inside, but this require some Jenkins-remoting redirection hack, which development skills I don't have. On the other side, I also think it make sense to define your CI process as a script store in SCM, not relying on a set of build steps configured in jenkins (must admit I like travis-ci approach on this topic).

I plan to demonstrate this at DevoxxFrance during my talk "La révolution Docker" - assuming I don't break my environment in the meantime :)