Revue de presse Inno #2

Mobilité

FireStore : la nouvelle base de données en temps réel de Google

En tant que développeur mobile, nous rencontrons une problématique récurrente : la gestion de la synchronisation des données avec un back-end et la prise en compte d’un mode déconnecté.

Google apporte une nouvelle réponse à cette question : FireStore. Ce service, encore en version bêta, fait partie de la suite FireBase. Il est présenté comme la nouvelle solution de stockage en temps réel de Google. Ce stockage est orienté document (NoSQL), cela signifie que l’on y stocke des collections de données organisées en couple clé/valeur, à la manière de JSON. Cette solution gère ainsi de façon transparente la synchronisation des données entre plusieurs appareils, mais également la perte de connexion. En cas de coupure réseau, les données sont alors toujours accessibles localement et les mises à jour sont répercutées de façon transparente à la reprise de connexion. Ci-dessous deux tutoriaux Youtube de Brian Advent vous montrent la facilité d’intégration de ce service dans une application de messagerie. Les deux tutoriaux d’intégration du SDK FireStore sous iOS de Brian Advent sont disponibles aux adresses :

Vous pouvez aussi accéder à la documentation officielle de FireStore.

RxSwift 4, supportant Swift 4, se précise en version RC.

Les développeurs, comme à chaque montée de version de Swift, travaillent d’arrache-pied pour mettre à jour leurs librairies et ainsi supporter la nouvelle version du langage. C’est bien entendu le cas pour les développeurs derrière RxSwift, qui ont déployé ce 8 octobre la version candidate de RxSwift 4. Cette version est disponible via les différents outils de gestion de dépendances et Github. Les auteurs d’RxSwift encouragent la contribution et vous présente les règles à suivre.

Découverte de l’architecture Model View Intent

J’avais un gros à priori sur l’architecture MVI, à cause de son nom. Pour moi, un Intent = new Intent(). Du coup, j’ai tout de suite pensé tomber dans un pattern d’architecture se basant sur les Intent Android, j’imaginais déjà le code spaghetti remplaçant RX par des IntentReceiver/Broadcaster. Un gros retour arrière donc. Mais suite à la Droidcon NYC, mes petits camarades ont assisté à une présentation MVI et ont eu l’air convaincu.
J’ai donc retroussé mes manches et mis les mains dedans. J’ai d’abord trouvé cet article par Hannes Dorfmann qui explique de façon très didactique les avantages du MVI. Tout d’abord, le MVI adresse une problématique non abordée dans les autres patterns comme le MVVM ou le MVP : le State ou l’état de l’application. 
En implémentant un Reducer, on peut être capable de gérer les changements d’état de l’application de façon déterministe.  
Hannes Dorfmann propose son implémentation du MVI, mais, elle est écrite en java et utilise l’héritage. La prochaine étape serait de proposer une implémentation, en Kotlin par composition/protocol.

Revue de presse Inno #1

Mobilité

Kotlin : Faster Lazy for Android

Par Loïc Siret

L’utilisation de Lazy en Kotlin permet de déclarer une Property sans l’initialiser immédiatement : Elle le sera lors de son premier usage ! Particulièrement utile lorsque que l’on veut mapper une Property sur le résultat d’un appel à une base de donnée par exemple.

iOS : Présentation de Weavy au CocoaHeads Meetup du 21 septembre dernier

Par Thibault Wittemberg (conférencier)

Dans le monde réel, le tissage implique l’utilisation d’un métier à tisser pour entrelacer deux ensembles de fils à angle : le “Warp” qui s’étend verticalement et le “Weft” qui la traverse horizontalement. Dans cette présentation, nous avons démontré qu’une technique aussi ancienne peut être très utile, notamment lors de la navigation dans une application iOS. L’objectif est de se débarrasser des limitations inhérentes aux “segues” ou au code technique de modèles de conception comme “Coordinator”.

Weavy est un framework open source, basé sur un tel modèle de tissage, qui favorise la programmation réactive, la navigation déclarative, l’injection de dépendance et la séparation des préoccupations.

Développement Web

Intégration de React dans Drupal Core

Par Alexandre Lision

Des discussions ont été entamées à la DrupalCon Vienna pour intégrer React dans Drupal Core. Pourquoi cette discussion maintenant ? Car React a beaucoup plus de traction que d’autres framework JS, et s’est démocratisé. De plus le récent retournement de veste sur la nouvelle licence de React sous MIT va dans la bonne direction pour considérer son intégration dans Drupal. Toutefois, le manque d’expertise JS au sein de l’équipe de contributeurs Drupal pourraient être un bloquant.
Le mix entre Drupal et React native permettrait de bénéficier d’un CMS démocratisé et robuste avec une solution Front-end moderne.

Actualités diverses

Après-midi Contribution, vendredi 29 septembre

L’après-midi Contribution est un événement récurent organisé par le département Innovation digitale, Web et mobilité de Savoir-faire Linux. Il permet à nos consultants de consacrer une partie de leur temps à contribuer à des projets open-source ainsi qu’à se former sur de nouvelles technologies.

Découverte d’un module Python de reconnaissance optique de caractères (OCR)

Par Kevin Barralon

Tesseract est moteur de reconnaissance optique de caractères (OCR) qui reconnaît plus de 100 langues. Il existe un module Python permettant d’utiliser le moteur en important le paquet. Le paquet reconnaît les formats jpeg, png, gif, bmp, tiff, et d’autres grâce au paquet PIL (ou Pillow). Une après-midi a été dédiée à la découverte du paquet et à son installation dans un conteneur Docker dans le but de l’utiliser conjointement avec le micro-framework Python Flask et de créer une API Rest avec notamment un endpoint qui permettrait de renvoyer les résultats de la reconnaissance des caractères d’une image soumise via l’API.

Que nous réserve la LDAPCon 2017 ?

La LDAPCon est une conférence internationale autour de la technologie LDAP et des enjeux de gestion des identités, d’authentification et d’habilitation.

L’événement qui se déroulera cette année à Bruxelles du 19 au 20 octobre, se tient tous les deux ans dans un pays différent :

Savoir-faire Linux, déjà commanditaire en 2015 (consultez notre retour sur cette édition) renouvelle avec plaisir son soutien à cette communauté en étant une nouvelle fois partenaire de l’édition 2017.

2 jours et 19 conférences, un programme riche et rythmé

Le programme de cette édition promet des interventions intéressantes, parmi lesquelles :

  • ReOpenLDAP : Modification d’OpenLDAP pour une utilisation intensive chez un opérateur de télécommunications
  • OpenLDAP pour Samba 4 : Point sur l’intégration d’OpenLDAP dans Samba 4 en lieu et place de l’annuaire natif codé par l’équipe Samba
  • PHP-LDAP : Des nouvelles de l’évolution de l’API LDAP dans PHP, délaissée depuis plusieurs années et que les développements reprennent
  • OpenLDAP : Des nouvelles du projet OpenLDAP par Howard Chu, le développeur principal

Les sujets afférents à LDAP comme la gestion des identités dans le Cloud, les habilitations/autorisations, l’authentification unique ou encore la supervision seront abordés dans les différentes présentations.

Savoir-faire Linux fera le point sur les différents protocoles de SSO (CAS, SAML et OpenID Connect) dans une intervention donnée vendredi après-midi, juste avant la présentation du logiciel FusionDirectory, le logiciel d’administration des données d’un annuaire LDAP, utilisé dans notre infrastructure interne et chez certains de nos clients.

Si cette conférence vous intéresse, vous pouvez réserver vos billets en ligne sur le site de la conférence.

Définir des rôles avec Ansible pour Nexus Repository Manager v3.x


Savez-vous comment automatiser l’installation ainsi que la configuration de Nexus Repository Manager version 3.x avec Ansible ? Pas encore ? On vous donne un coup de pouce ici !

Pour rappel, Ansible est un outil de déploiement qui permet à des playbooks d’automatiser les déploiements d’applications et d’infrastructure. L’avantage clé d’Ansible est sa flexibilité puisqu’il permet de modifier les applications avec souplesse et de les appréhender en tant que service. Toutefois, Ansible possède également quelques faiblesses. Avec une conception volontairement simple, il fonctionne uniquement comme une application de paramètres sans tenir compte de la disponibilité de l’information et des problèmes de sécurité, qui doivent alors être gérés par d’autres systèmes. C’est pourquoi un grand nombre de développeurs préfèrent utiliser Ansible en complémentarité avec un système d’agent actif comme Puppet ou avec un outil de gestion centralisé comme Ansible Tower.

Automatisation avec Ansible

Ansible se concentre sur la configuration au niveau de l’application, les scripts d’approvisionnement pouvant être exécutés sur tout outil de support d’infrastructure (PaaS, conteneurs, bare-metal, Vagrant, etc.). Ansible ne nécessite qu’une connexion SSH et un compte sudo sur le système distant.

Les scripts d’approvisionnement Ansible sont écrits dans un style déclaratif à l’aide de fichiers YAML regroupés en rôles. Les instructions atomiques des rôles sont déclarées à l’aide d’un certain nombre de modules de base fournis par Ansible. Consultez la documentation Ansible pour une introduction en profondeur.

Réapprovisionnement et mise à jour de la configuration

L’un des modèles DevOps pour gérer les mises à jour de configuration consiste à fournir un nouvel environnement à partir de zéro et à éliminer complètement l’ancien (pensez à des images de conteneur). Cela implique une gestion fiable de votre cycle de vie des données. Dans notre cas particulier du Nexus Repository Manager, cela consiste à plusieurs gigaoctets d’artefacts téléchargés / mandatés, de certains journaux d’audit et d’objets OrientDB contenant la configuration. Par conséquent, en fonction des contraintes de l’environnement, il peut être logique de mettre à jour la configuration d’une instance Nexus préalablement approvisionnée. La nature déclarative des instructions de base d’Ansible est répond bien à cette contrainte, mais toute logique personnalisée écrite dans un rôle devrait être idempotente et prendre en compte la logique « créer ou éventuellement mettre à jour ».

Il faut également noter que certaines parties de la configuration Nexus ne peuvent pas être mises à jour. Voici quelques exemples :

  • Les paramètres relatifs aux BlobStores
  • Le mot de passe administrateur si vous le perdez (mise à jour: peut-être par cette voie)

Comment bien intégrer l’API Groovy de Nexus avec Ansible

Les étapes de base de l’installation sont très simples et peuvent toutes être écrites en utilisant des modules simples de base Ansible :

  • Télécharger et décompresser l’archive
  • Créer un utilisateur / groupe système
  • Créer un service systemd

(Ces étapes sont dans les tâches / nexus_install.yml)

Et puis vient la surprise : la configuration Nexus n’est pas disponible dans un fichier texte simple qui peut être édité à l’aide d’instructions simples Ansible. Elle est stockée dans une base de données OrientDB intégrée qui ne doit pas être modifiée directement. La manière documentée de configurer Nexus est soit par son interface utilisateur Web, soit par son API d’intégration.

La façon dont l’API d’intégration fonctionne est la suivante :

  1. Écrire un script Groovy qui gère vos changements de configuration;
  2. Charger le script sur Nexus à l’aide d’un requête HTTP PUT, créant une ressource REST pour ce script;
  3. Appeler le script via sa ressource HTTP GET / POST

Module URI à la rescousse !

Le module uri d’Ansible envoie des requêtes HTTP, fournissant une automatisation de ces étapes.

La première étape consiste à téléverser le script Groovy sur Nexus. Notez que le script peut déjà être présent. Par conséquent, lors des ré-exécutions du playbook, nous essayons de le supprimer avant d’entreprendre d’autres actions, par le biais de tasks/declare_script_each.yml, comme suit :

  ---
  - name: Removing (potential) previously declared Groovy script {{ item }}
    uri:
      url: "http://localhost:8081/service/siesta/rest/v1/script/{{ item }}"
      user: 'admin'
      password: "{{ current_nexus_admin_password }}"
      method: DELETE
      force_basic_auth: yes
      status_code: 204,404

  - name: Declaring Groovy script {{ item }}
    uri:
      url: "http://localhost:8081/service/siesta/rest/v1/script"
      user: 'admin'
      password: "{{ current_nexus_admin_password }}"
      body_format: json
      method: POST
      force_basic_auth: yes
      status_code: 204
      body:
        name: "{{ item }}"
        type: 'groovy'
        content: "{{ lookup('template', 'groovy/' + item + '.groovy') }}"

Les requêtes HTTP sont exécutées à partir de l’hôte cible, c’est pourquoi localhost est utilisé ici. force_basic_auth: yes s’assure que le client HTTP n’attende pas une réponse 401 avant de fournir des informations d’identification. Autrement, Nexus répondra immédiatement avec une réponse 403 lorsque aucune authentification n’est passée. status_code est l’état HTTP attendu de la réponse fournie par Nexus. Étant donné que le script Groovy peut ne pas nécessairement exister à ce moment-là, nous devons également accepter le code d’état 404.

L’étape suivante consiste à appeler le script Groovy créé via l’appel HTTP précédent. La plupart des scripts prendront certains paramètres d’entrée (par exemple, créer un utilisateur <x>), et c’est là que Ansible et Groovy aideront. Tous deux issus de l’âge des principes REST, ils peuvent parler et comprendre le format JSON de manière relativement transparente.

Du côté du script Groovy :

import groovy.json.JsonSlurper
parsed_args = new JsonSlurper().parseText(args)
security.setAnonymousAccess(Boolean.valueOf(parsed_args.anonymous_access))

Et pour appeler ce script à partir des arguments passés via Ansible  :

  - include: call_script.yml
    vars:
      script_name: setup_anonymous_access
      args: # this structure will be parsed by the groovy JsonSlurper above
        anonymous_access: true

Avec call_script.yml :

  ---
  - name: Calling Groovy script {{ script_name }}
    uri:
      url: "http://localhost:8081/service/siesta/rest/v1/script/{{ script_name }}/run"
      user: 'admin'
      password: "{{ current_nexus_admin_password }}"
      headers:
        Content-Type: "text/plain"
      method: POST
      status_code: 200,204
      force_basic_auth: yes
      body: "{{ args | to_json }}"

Cela nous permet de passer de manière transparente les paramètres structurés de Ansible aux scripts Groovy, en gardant la structure, les tableaux et les types de base des objets.

Scripts Groovy pour Nexus : conseils et astuces pour le développement

Voici quelques conseils qui peuvent aider les développeurs travaillant sur les scripts Groovy.

Configurer le Classpath dans votre IDE

Comme décrit dans la documentation Nexus, avoir les scripts Nexus dans le classpath de votre IDE peut vraiment vous aider à travailler. Si vous automatisez la configuration de Nexus autant que possible, vous allez inévitablement tomber sur certaines API internes sans documentation. De plus, certaines parties de l’API n’ont aucune source disponible (par exemple, l’API LDAP). Dans de tels cas, un décompilateur peut être utile.

Puisque notre rôle sur Github utilise Maven avec toutes les dépendances nécessaires, vous pouvez simplement l’ouvrir avec IntelliJ et éditer les scripts situés dans « files/groovy ».

Points d’entrée de l’API de Scripting

Comme documenté, il y a quatre points d’entrée implicites pour accéder aux entrailles de Nexus à partir de votre script:

  • core
  • repository
  • blobStore
  • security

Ceux-ci sont utiles pour des opérations simples, mais pour tout ce qui est plus compliqué, vous devrez résoudre plus en profondeur les services par:

  • Indirection à partir des points d’entrée principaux: blobStore.getBlobStoreManager ()
  • Résolution d’un @Singleton interne du contexte du conteneur : container.lookup (DefaultCapabilityRegistry.class.getName())

Prenez des exemples du code source de Nexus

Certaines parties de Nexus (7,4%, selon Github) sont également écrites à l’aide de Groovy, contenant de nombreux bons exemples de code: CoreApiImpl.groovy.

Créer des requêtes HTTP à partir de l’interface Web de configuration (requêtes AJAX) fournit également des indications sur les structures de données attendues, les paramètres ou les valeurs de certains paramètres.

Enfin, mettre en place un débogueur distant depuis votre IDE vers une instance Nexus peut aider, car il existe de nombreux endroits où une structure de données très générique est utilisée (comme Map <String, Object>) et seule l’inspection au moment de l’exécution peut rapidement indiquer les types réels nécessaires.

Exemples détaillés

Voici quelques exemples commentés de scripts Groovy tirés du rôle Ansible

Configuration d’une Capability

Les Capabilities de Nexus  peuvent être configurées à l’aide d’une interface utilisateur unifiée. Dans notre cas, cela couvre:

  1. L’accès anonyme
  2. L’URL publique de base
  3. La marque (en-tête et pied de page HTML personnalisés).

Instructions :


    import groovy.json.JsonSlurper
    import org.sonatype.nexus.capability.CapabilityReference
    import org.sonatype.nexus.capability.CapabilityType
    import org.sonatype.nexus.internal.capability.DefaultCapabilityReference
    import org.sonatype.nexus.internal.capability.DefaultCapabilityRegistry

    // unmarshall the parameters as JSON
    parsed_args = new JsonSlurper().parseText(args)

    // Type casts, JSON serialization insists on keeping those as 'boolean'
    parsed_args.capability_properties['headerEnabled'] = parsed_args.capability_properties['headerEnabled'].toString()
    parsed_args.capability_properties['footerEnabled'] = parsed_args.capability_properties['footerEnabled'].toString()

    // Resolve a @Singleton from the container context
    def capabilityRegistry = container.lookup(DefaultCapabilityRegistry.class.getName())
    def capabilityType = CapabilityType.capabilityType(parsed_args.capability_typeId)

    // Try to find an existing capability to update it
    DefaultCapabilityReference existing = capabilityRegistry.all.find {
        CapabilityReference capabilityReference -&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;
            capabilityReference.context().descriptor().type() == capabilityType
    }

    // update
    if (existing) {
        log.info(parsed_args.typeId + ' capability updated to: {}',
                capabilityRegistry.update(existing.id(), existing.active, existing.notes(), parsed_args.capability_properties).toString()
        )
    } else { // or create
        log.info(parsed_args.typeId + ' capability created as: {}', capabilityRegistry.
                add(capabilityType, true, 'configured through api', parsed_args.capability_properties).toString()
        )
    }

Configuration d’un mandataire de dépôt Maven

    import groovy.json.JsonSlurper
    import org.sonatype.nexus.repository.config.Configuration

    // unmarshall the parameters as JSON
    parsed_args = new JsonSlurper().parseText(args)

    // The two following data structures are good examples of things to look for via runtime inspection
    // either in client Ajax calls or breakpoints in a live server

    authentication = parsed_args.remote_username == null ? null : [
            type: 'username',
            username: parsed_args.remote_username,
            password: parsed_args.remote_password
    ]

    configuration = new Configuration(
            repositoryName: parsed_args.name,
            recipeName: 'maven2-proxy',
            online: true,
            attributes: [
                    maven  : [
                            versionPolicy: parsed_args.version_policy.toUpperCase(),
                            layoutPolicy : parsed_args.layout_policy.toUpperCase()
                    ],
                    proxy  : [
                            remoteUrl: parsed_args.remote_url,
                            contentMaxAge: 1440.0,
                            metadataMaxAge: 1440.0
                    ],
                    httpclient: [
                            blocked: false,
                            autoBlock: true,
                            authentication: authentication,
                            connection: [
                                    useTrustStore: false
                            ]
                    ],
                    storage: [
                            blobStoreName: parsed_args.blob_store,
                            strictContentTypeValidation: Boolean.valueOf(parsed_args.strict_content_validation)
                    ],
                    negativeCache: [
                            enabled: true,
                            timeToLive: 1440.0
                    ]
            ]
    )

    // try to find an existing repository to update
    def existingRepository = repository.getRepositoryManager().get(parsed_args.name)

    if (existingRepository != null) {
        // repositories need to be stopped before any configuration change
        existingRepository.stop()

        // the blobStore part cannot be updated, so we keep the existing value
        configuration.attributes['storage']['blobStoreName'] = existingRepository.configuration.attributes['storage']['blobStoreName']
        existingRepository.update(configuration)

        // re-enable the repo
        existingRepository.start()
    } else {
        repository.getRepositoryManager().create(configuration)
    }

Créer un rôle

    import groovy.json.JsonSlurper
    import org.sonatype.nexus.security.user.UserManager
    import org.sonatype.nexus.security.role.NoSuchRoleException

    // unmarshall the parameters as JSON
    parsed_args = new JsonSlurper().parseText(args)

    // some indirect way to retrieve the service we need
    authManager = security.getSecuritySystem().getAuthorizationManager(UserManager.DEFAULT_SOURCE)

    // Try to locate an existing role to update
    def existingRole = null

    try {
        existingRole = authManager.getRole(parsed_args.id)
    } catch (NoSuchRoleException ignored) {
        // could not find role
    }

    // Collection-type cast in groovy, here from String[] to Set&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;String&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;
    privileges = (parsed_args.privileges == null ? new HashSet() : parsed_args.privileges.toSet())
    roles = (parsed_args.roles == null ? new HashSet() : parsed_args.roles.toSet())

    if (existingRole != null) {
        existingRole.setName(parsed_args.name)
        existingRole.setDescription(parsed_args.description)
        existingRole.setPrivileges(privileges)
        existingRole.setRoles(roles)
        authManager.updateRole(existingRole)
    } else {
        // Another collection-type cast, from Set&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;String&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; to List&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;String&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;
        security.addRole(parsed_args.id, parsed_args.name, parsed_args.description, privileges.toList(), roles.toList())
    }

Le rôle est disponible sur Ansible Galaxy et Github. Il comporte:

  • Le téléchargement et l’extraction de Nexus
  • La création de l’unité de service systemd
  • (Facultatif) La configuration d’un reverse-proxy Apache supportant SSL
  • La configuration du mot de passe administrateur
  • La configuration LDAP
  • La configuration des privilèges et des rôles
  • La création des utilisateurs locaux
  • La configuration des Blobstores
  • La configuration de tous les types de dépôts
  • La spécification de l’URL de base
  • La mise en place de la marque (en-tête HTML et pied de page personnalisés)
  • La mise en place des tâches automatiques

 

DebConf17 : un événement mondial 100% Debian à Montréal

                                    


Du 5 et 12 août, Savoir-faire Linux était l’un des commanditaires majeurs de la DebConf17 qui se déroulait cette année à Montréal. Une occasion en or de soutenir la communauté Debian et de renouveler notre engagement à l’un des plus grands projets Open Source au monde.

DebConf17, la conférence annuelle des développeurs et collaborateurs de Debian, a rassemblé cette année plus de 405 personnes venues du monde entier, autour de 169 événements dont 89 entretiens, 61 séances de discussion et 6 ateliers. Nul doute, la DebConf17 fut un succès ! Pleinement engagés dans cet événement et fiers contributeurs de logiciel libre, nous avons endossé tour à tour des rôles de conférencier, commanditaire, participant à la foire de l’emploi et même hôte de soirée durant l’événement.  Retour sur une semaine intense 100% Debian !

L’honneur de faire partie des commanditaires majeurs de la DebConf17

Chez Savoir-faire Linux, nous nous sommes engagés à bâtir une économie durable fondée sur la coopération et le partage du savoir. Nous croyons fermement que notre force repose sur la qualité de notre partenariat avec les acteurs du monde du logiciel libre et nos contributions à de nombreux projets communautaires. Dans la logique de cet engagement, nous avons forgé au fil des ans, de solides partenariats avec notamment  la Free Software Foundation, la Linux Foundation, la communauté Debian, Python et d’autres projets de logiciels ouverts et collaboratifs. Évidemment, lorsque nous avons appris que la conférence annuelle de Debian se tenait à Montréal, nous étions ravis de soutenir et d’accueillir ce rassemblement mondial chez nous !

Des employés à la fibre DebConf17

Lucas Bajolet en conférence

Aussitôt confirmé, nos équipes ont commencé à réfléchir et proposer des animations, ateliers et conférences. Impliqués plus largement dans diverses communautés Linux, nous avons proposé de nombreux sujets gravitant autour du thème :

 

Dans l’ordre, Alexandre Viau et Andreas Traczyk
Présentation d’Amir Taherizadeh
Foire à l’emploi avec notre président Cyrille Béraud

Une foire à l’emploi fructueuse et conviviale

Le samedi 5 août, nous avons participé à l’activité officielle de réseautage professionnelle. Notre président, Cyrille Béraud, s’est également joint à l’événement pour répondre personnellement aux questions et rencontrer les nombreux talents qui sillonnaient le hall. Les rencontres et les surprises furent nombreuses,  les discussions riches et passionnantes, aboutissant parfois sur la promesse d’une nouvelle rencontre et même, d’une future collaboration.

Soirée Ring on ! Célébrez et échangez avec l’équipe Ring

Ring est une plateforme de communication (texte, audio et vidéo) libre et universelle qui préserve la confidentialité et la vie privé des utilisateurs. Reconnu paquet GNU par la Free Software Foundation, cette application fonctionne sur de nombreuses plateformes et ne cesse de gagner en fonctionnalités et en stabilité.

L’équipe Ring de Savoir-faire Linux

Nous souhaitions profiter de l’effervescence de la DebConf pour célébrer la sortie de la version stable de Ring : Ring 1.0 – Liberté, Égalité, Fraternité. Avec l’aide des organisateurs de DebConf, nous avons diffusé l’invitation pendant l’événement et avons accueilli une foule d’invités remarquables ! Parmi nos invités figuraient, Daniel Pocock (Projet Debian), John Sullivan (Freee Software Foundation), Michaël Meskes (Credativ) ainsi que de brillants développeurs, passionnés et collaborateurs proches. La soirée a été marquée par la présentation de l’équipe Ring de Savoir-faire Linux, saluée avec les honneurs pour son travail acharné depuis des mois et la sortie cette dernière version de Ring.

De gauche à droite, Chloé Nignol de DeGama, Amandine Gravier, directrice des communications chez Savoir-faire Linux et Dorina Mosku, coordonnatrice du projet Ring
Au centre, Daniel Pocock du projet Debian et à droite, John Sullivan de la Free Software Foundation

 

 

 

 

 

 

DebConf17 touche à sa fin mais la mission continue !

La triste vérité est qu’encore une fois, nous devions dire au revoir à DebConf et à son public bigarré et attachant ! Mais le mot de la fin est : DebConf18 sera encore plus sensationnel ! Peu importe si  la DebConf17 se termine, parce que le projet Debian fêtera pour la Debconf18 ses 25 ans d’existence avec toujours plus de nouveautés, de partage et d’excitation autour du plus populaire système d’exploitation Linux !