Linux (fr)

  • Migrer Windows 10 d'un disque BIOS/MBR, vers un SSD en mode UEFI/GPT avec des logiciels libres (Journaux LinuxFR)

    Sommaire

    Introduction

    Ce tutoriel vous guide pas à pas pour migrer votre installation de
    Windows qui est actuellement sur un disque dur de votre PC vers un
    nouveau disque, en l'occurrence un SSD. A vrai dire, vous pouvez aussi
    bien migrer vers un autre HDD.

    La spécificité de ce tutoriel est qu'elle utilise les outils fournis par
    Microsoft avec Windows ainsi que des logiciels libres (Clonezilla
    principalement, mais si quelque chose devait mal tourner vous pouvez avoir
    besoin d'utiliser fdisk, gdisk ou testdisk pour ne citer qu'eux). Quand
    j'ai voulu faire cette migration je n'ai pas trouvé de tutoriel
    expliquant de bout en bout comment faire cette migration juste avec les
    outils de Microsoft et des logiciels libres.

    Typiquement, vous pouvez avoir envie/besoin de faire cela car vous avez
    acheté un nouveau disque pour remplacer l'ancien (par exemple car
    l'ancien montre des signes de faiblesse, ou vous voulez améliorer la
    réactivité de votre système).

    En plus de la migration du système d'exploitation, ce tutoriel vous
    explique comment passer d'un démarrage en mode BIOS/MBR à un démarrage
    en mode UEFI/GPT.

    Succinctement la démarche est la suivante, d'abord installer le nouveau
    disque dans le PC, et initialiser la table de partition selon les normes
    Microsoft. Puis cloner/dupliquer la partition contenant le système
    d'exploitation à l'aide de Clonezilla. Ensuite et avant de redémarrer
    dans le clone de Windows sur le SSD, faire quelques modifications dans
    le registre pour que la lettre de lecteur C: pointe vers la bonne
    partition et éventuellement modifier le mode SATA en AHCI si vous le
    modifiez aussi dans le UEFI/BIOS. Après cela, on va préparer la
    partition système EFI/ESP pour que le PC puisse démarrer dessus et qu'il
    démarre sur le Windows du SSD. Finalement, une fois dans le Windows du
    SSD, on va réactiver l'"environnement de récupération de Windows".

    Mise en garde : Faites une sauvegarde de vos données avant toute
    opération. Personne n'est à l'abri d'une mauvaise manipulation ou d'une
    erreur.

    Prérequis

    Compétences

    Niveau de difficulté : Difficile.

    Vous devez être à l'aise au niveau de l'utilisation de la ligne de
    commande dans Windows, mais aussi assez à l'aise pour gérer les
    partitions de votre disque. Savoir modifier le paramétrage de votre
    Firmware UEFI/BIOS et aussi nécessaire. Ce tutoriel guide pas à pas pour
    la majorité des opérations. Certaines n'ont pas été détaillées par souci
    de simplicité et d'efficacité.

    Matériel

    Le PC où vous voulez installer le SSD. Il faut qu'il soit en état de
    marche. De plus il doit avoir un firmware UEFI. S'il n'a que un BIOS
    standard, sans UEFI, ce tutoriel n'est pas adapté.

    Clé(s) USB ou plusieurs CD/DVD sur lequel vous aurez mis
    Clonezilla, System rescue
    CD
    et un environnement de démarrage
    Windows PE, ou Windows RE, ou le DVD/Disque d'installation de Windows.

    Le disque SSD (testé avec Samsung SSD 860 EVO 250GB). Il doit avoir une
    taille suffisante pour contenir votre partition de Windows. Dans tous
    les cas, la taille de la partition qui contiendra Windows sur le SSD
    doit être au moins égale à la taille de la partition Windows du HDD que
    vous voulez cloner. Au besoin, pour remplir ce critère, réduisez la
    taille de votre partition Windows avec le gestionnaire de disque de
    Windows par exemple (ou un autre outil de gestion de partition, comme
    gparted, sur le System Rescue CD). Cherchez sur internet si vous ne
    savez pas comment faire.

    Logiciel

    Windows 10 installé (en version 64 bits) (testé avec Win10 v1709)

    Windows 10 PE ou support d'installation de Windows 10 (clé USB ou DVD) -
    En Version 64 bits (testé avec un support d'installation de Win10 v1804)

    System rescue CD (version 5.2.2 par
    exemple)

    Clonezilla installé sur une clé ou un CD.
    Bien vérifier avant que votre système arrive à démarrer dessus. (Testé
    avec Clonezilla 2.5.5-38)

    Nomenclature

    SSD : désigne le nouveau SSD

    HDD : désigne votre disque actuel, sur lequel est installé Windows

    WinPE : un environnement de démarrage Windows PE, ou Windows RE, ou le
    DVD/Disque d'installation de Windows. Il doit être sur un support
    amovible (USB, CD ou DVD)

    S: La lettre de lecteur affectée à la partition Système EFI qui sera sur
    le nouveau SSD (parfois appelée ESP, EFI_System_Partition ou encore
    SYSTEM, ou EFI)

    N: Le clone de Windows, sur le SSD

    O: Le Windows cloné, sur le HDD

    C: La partition dans laquelle est installée Windows, lorsqu'on est dans
    Windows (que ce soit le windows cloné, ou le clone)

    Les commandes doivent être lancées en tant qu'administrateur.

    Procédure de base

    • Fixer et brancher le SSD dans l’ordinateur

    • Désactiver Windows FastStart (cf votre moteur de recherche préféré)

    • Initialiser et partitionner le disque à l'aide de Windows

      • Démarrer sur le Windows installé ou WinPE
      • Pour initialiser le disque, d'abord créer une table de partition, puis partitionner le disque. Pour ce faire :
        • Suivre les instructions de partitionnement UEFI/GPT selon Microsoft. Ci-dessous mon exemple, mais peut-être avez-vous besoin d'une partition "recovery" aussi, ou votre configuration nécessite quelques aménagements. Dans ce cas, voir les instructions de Microsoft et adapter pour vos besoins.
        • Par exemple: une partition EFI de 260Mo, une partition Microsoft Reserved (MSR) de 16Mo, une partition pour Windows (taille au moins égale à la taille de la partition de Windows à cloner). Pour informations, dans diskpart, les tailles que vous donnez en MB/Mo sont en réalité des MiB/Mio (220 = 10242 octets).
          • Ouvrir une invite de commande en mode administrateur et lancer diskpart . Et une fois dans diskpart :
            • list disk pour lister les disques et connaître le n° du SSD.
            • select disk # avec le numéro du SSD à la place de #
            • clean Supprime le contenu du disque / l'initialise
            • convert gpt Définit que le disque aura une table de partition GPT
            • create partition efi size=260 Crée une partition EFI de 260MiB
            • format quick fs=fat32 label="System" Formater la partition EFI au format FAT32
            • assign letter="S" Lui donner la lettre S
            • create partition msr size=16 Créer une partition Microsoft Reserved de 16MiB
            • create partition primary Créer la partition pour Windows (l'équivalent du C: )
            • format quick fs=ntfs label="Windows" Formater la partition pour Windows au format NTFS
            • assign letter="N" Lui donner la lettre N
            • list volume Liste les volumes. Permet de voir la table de partition.
            • exit Quitte diskpart
    • Cloner le Windows installé sur le HDD. Ceci sera fait à l'aide de
      Clonezilla

      • Redémarrer dans Clonezilla
      • Une fois dans clonezilla, et si vous êtes confortable avec les lignes de commande Linux, éventuellement supprimer de la partition Windows du HDD les fichiers pagefile.sys , hyberfil.sys (désactiver windows faststart avant), swapfile.sys .
      • Cloner la partition Windows du HDD vers le SSD (de préférence, partition de même taille, et de toutes façons, la partition de destination doit être plus grande que la source. Si ce n'est pas le cas, réduisez d'abord la taille de votre partition Windows depuis Windows). Dans clonezilla, utiliser le mode Partition vers Partition, et en mode Export. Utiliser les options -e1 auto (automatically adjust file system geometry for a ntfs boot partition if exists) -e2 (sfdisk uses CHS of hard drive from EDD (for non grub loader) -r (resize filesystem to fit partition size of target) -m (do NOT clone boot loader) -v (verbose)
      • Optionnellement cacher la partition contenant le windows source de la table de partition du disque source (si vous ne savez pas à quoi ça sert, passez votre chemin). Pour cela modifier le type de partition de la partition NTFS de windows (en principe, NTFS a un id de « 7 ». On peut utiliser id 17 pour la partition cachée : 17 correspond à « IFS Hidden »). Utiliser cfdisk ou fdisk pour faire ce changement (ce sont des programmes linux).
    • Dans le Firmware UEFI (ou BIOS-UEFI), on peut en profiter pour passer
      du mode SATA "IDE" vers "AHCI". Windows n'aime pas ce changement et
      il faut donc faire une opération dans le registre qui est
      détaillée ci-dessous. Tant que vous ne le faites pas, vous aurez un
      écran de plantage bleu de windows au démarrage (BSOD).

    • Si vous voulez être sûr de ne pas faire de bêtise dans le Windows que
      vous venez de cloner, je vous conseille d'éteindre l’ordinateur & de
      débrancher l’ancien disque. Ainsi vous ne risquez pas de modifier le
      mauvais fichier de registre (en l'occurrence celui de votre Windows
      sur le HDD)

    • Effectuer quelques opérations sur le Windows de destination (celui
      sur le SSD) avant qu'on ne démarre dessus. En particulier corriger le
      registre pour affecter la lettre de lecteur C: à la bonne partition,
      et si le paramétrage du Firmware UEFI (BIOS-UEFI) a été modifié pour
      passer de SATA Mode PCI vers AHCI, on va aussi faire ce changement
      pour que ca fonctionne.

      • Redémarrer dans WinPE (en Mode UEFI, pas MBR !)
        • Tout d'abord déterminer la lettre de lecteur affectée au clone de Windows, celui qui est sur le SSD. Ou, s'il n'y a pas de lettre affectée, lui en donner une, par exemple N: (lettre utilisée dans les exemples qui suivent)
          • Pour cela, lancer dans diskpart
            • list volume
              Ce qui retourne la liste des volumes avec la lettre de lecteur qui a été affectée à chacun.
          • Si aucune lettre de lecteur n'est affectée, il faut alors lui en affecter une. Pour cela, lancer dans diskpart
            • select volume # (avec # étant le numéro du volume qui contient le nouveau windows)
            • assign letter=N
              S'il n'est pas possible d'utiliser select volume alors faire comme ceci
            • list disk
            • select disk # (# étant le numéro affecté au SSD)
            • list partition
            • select partition # (# étant le numéro affecté à la partition de Windows sur le SSD, probablement 3)
            • assign letter=N
        • Faire un CHKDSK /F sur la lettre du nouveau Win
        • Pour que la partition C: utilisée par Windows soit celle du SSD et pas celle de l’ancien disque, modifier une clé de registre du nouveau Windows :
          • Lancer REGEDIT et dans le registre HKEY_LOCAL_MACHINE monter la ruche N:\Windows\System32\Config\SYSTEM . Lui donner le nom "NewWin" On s’intéresse à HKEY_LOCAL_MACHINE\NewWin\MountedDevices . Ce sont là les valeurs qui sont dans le registre " HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices " lorsqu'on est dans l'installation de Windows.
            • Dans HKEY_LOCAL_MACHINE\NewWin\MountedDevices modifier la lettre de lecteur C: en renommant \DosDevices\C: par \DosDevices\O: (car la valeur fait référence à la partition de l'ancien Windows sur le HDD et on ne veut pas, en démarrant, utiliser cette partition mais celle de son clone qui est sur le SSD). Ainsi, lorsqu'on démarrera dans le nouveau Windows, la partition contenant le Windows sur le HDD aura la lettre O:, et la partition contenant le Windows sur le SSD aura la lettre C:
            • Créer une nouvelle valeur binaire nommée \DosDevices\C: et lui donner comme contenu celui de \DosDevices\N: qui est renseignée dans le registre WinPE, c'est-à-dire là HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices ( C: étant la lettre qu'utilisait le Windows du HDD comme partition où il y a le dossier \Windows )
            • ATTENTION: Bien vérifier que la copie a fonctionné et qu'il y a les bonnes valeurs, car dans mes essais, j'ai du m'y reprendre à 2 fois car le 1er "coller" ne collait pas ce que je voulais.
            • En principe c'est tout. Mais d'après certaines sources, il y aurait une clé \\?\Volume{GUID} ayant le même contenu que le \DosDevices\O: qu’on vient de modifier. Chez moi ce n'était pas le cas. Si vous avez une telle valeur, alors il faut lui donner le contenu de \DosDevices\N: depuis le registre WinPE
        • Si en même temps que la migration on veut aussi passer du mode SATA IDE vers AHCI alors il faut encore faire ceci. Cela a été repris du site tomshardware.co.uk
          • Toujours dans REGEDIT avec la ruche montée en HKEY_LOCAL_MACHINE\NewWin
          • Aller à HKEY_LOCAL_MACHINE\NewWin\ControlSet000\Services\storahci\StartOverride
          • Changer la valeur DWORD de 3 à 0.
          • Au redémarrage, si ça n'a pas été fait, changer la paramétrage du contrôleur SATA de IDE à AHCI. Au redémarrage, Windows devrait directement démarrer correctement et sans plantage (BSOD).
        • Rendre le disque bootable en installant les outils EFI de microsoft et configurant le Magasin BCD (BCD Store)
          • D'abord assigner une lettre de lecteur à la partition ESP
            • MOUNTVOL S: /S
              Si ca n'a pas fonctionné, faire comme ceci dans diskpart
            • list disk
            • select disk # (# est le numero du SSD retourné par list disk)
            • list partition
            • select partition # (# est probablement 1)
            • assign letter=S
          • Puis lancer bcdboot N:\windows /l fr-fr /s S: /f UEFI
            • N:\Windows est le répertoire contenant le clone de Windows sur le SSD)
            • S: = partition EFI
    • Redémarrer, et avant le lancement de Windows vérifier votre UEFI
      (ou BIOS-UEFI). Il faut qu'il soit configuré pour démarrer par défaut
      en mode UEFI et pas en mode BIOS. Penser aussi à corriger le
      paramétrage SATA si cela a été modifié dans le registre de Windows.

      Le paramétrage du démarrage avec
      bcdboot N:\windows /l fr-fr /s S: /f UEFI a normalement créé le
      magasin BCD, mis tous les fichiers EFI sur la partition SYSTEME (ESP,
      partiton EFI, la 1ère du SSD) et dit au firmware UEFI qu'il doit
      automatiquement démarrer avec le gestionnaire de démarrage
      (boot manager) de Windows.

    • Une fois qu’on a réussi à démarrer dans la copie de Windows

      • Réactiver le "FastBoot"
      • Réactiver l'environnement de récupération de Windows en lançant, depuis une ligne de commande avec les droits administrateur, la commande reagentc.exe /enable . Vérifier avec reagentc.exe /info . Et s'il y a une erreur essayer avec reagentc.exe /enable /setreimage /path C:\Recovery\WindowsREC:\Recovery\WindowsRE est le dossier où se trouve le fichier Winre.wim
      • Vérifier que tout est en ordre. Eventuellement donner un nouveau nom à votre partition C: (pour la différencier de celle sur le HDD) en lançant: LABEL [drive:][label]
      • Redémarrer encore une fois en laissant le processus de démarrage se faire tout seul pour vérifier que tout est ok.
    • Réinsérer l'ancien disque dur.

    • Normalement, il devrait être possible de redémarrer dans l'ancien
      Windows, du moment que vous savez comment booter en MBR, et sous
      réserve de ne pas avoir modifié le mode SATA dans le UEFI/BIOS. SI
      c'est le cas, vous pouvez envisager de modifier le registre du
      Windows du HDD, ou de modifier le paramétrage du UEFI/BIOS.

      Si vous avez aussi Linux d'installé sur le HDD, il devrait toujours
      être possible de le démarrer en mode BIOS

    • On peut diminuer/augmenter la taille de la partition C: du SSD (Pour
      un SSD TLC ou VNAND, on peut par exemple laisser de l’espace libre à
      la fin ~10 % de la capacité du disque d'après le logiciel Samsung
      Magician, pour un SSD 860 EVO)

    • En principe, puisqu’on boot en EFI on peut enlever sur le clone
      Windows sur le SSD les fichiers \bootmgr et \Boot\BCD puisque ce
      sont ceux qui étaient utilisés pour un boot en mode BIOS/MBR et que
      désormais on est en EFI. Vous pouvez d'abord les renommer et vérifier
      que ca ne change rien au prochain boot, plutôt que de les supprimer
      tout de suite.

    Quelques pistes si ça ne fonctionne pas…

    • Faire un chkdsk sur la nouvelle partition
    • Recréer le bootsector du NTFS avec testdisk (dispo sur System Rescue CD, mais peut être aussi dans Clonezilla ? Je n'ai pas vérifié)
    • Vérifier le BCD:
    • Vérifier que la partition EFI est bien initialisée (présence des fichiers \EFI , \EFI\Boot\ , \EFI\Microsoft\ …) Si ce n'est pas le cas, il y a eu un problème avec bcdboot N:\windows /l fr-fr /s S: /f UEFI
    • Vérifier le boot manager du bios (démarrage en UEFI ou MBR ? Gestionnaire de démarrage par défaut ? Présence du gestionnaire de démarrage de Windows ?)
    • A priori, pas utile : Commandes à lancer dans WinPE
      • Pour recréer le boot sector de la partition systeme (EFI): bootrec /fixboot
      • Pour chercher les OS sur le disque et les mettre dans le bootloader bootrec /scanos
    • Quelques commandes de bcdedit pour modiser la valeur de certains éléments du magasin BCD. Inutile car le BCD Store qui est utilisé lorsqu'on démarre en mode EFI n'est pas le même que celui utilisé dans un démarrage en mode MBR. Donc, pas besoin de chercher à modifier le BCD. Je garde pour info : les lettres sont celles telles que définies dans le système où on est (WinPE par ex). Doc BCDEDIT
      • bcdedit /set {bootmgr} device \Device\HarddiskVolume1
      • bcdedit /set {default} device \Device\HarddiskVolume3
      • bcdedit /set {default} osdevice \Device\HarddiskVolume3
      • Ou à la place de \Device\HarddiskVolume1 mettre les lettres de lecteur :
      • bcdedit /set {bootmgr} device partition=S:
      • bcdedit /set {default} device partition=C:
      • bcdedit /set {default} osdevice partition=C:

    Documentation, pour aller plus loin…

    A propos du EFI/UEFI:

    A propos de l'entrée MountedDevices du registre:
    http://diddy.boot-land.net/firadisk/files/mounteddevices.htm

    Si on veut y accéder, par défaut les fichiers du BCD sont cachés. Pour
    les rendre visibles:

    • attrib bcd -s -h -r
    • mv bcd bcd.bak
    • bootrec /rebuildbcd

    Documentation bcdedit:

    MBR Partition ID

    A propos des disk ID (=Disk signatures):

    Si besoin de supprimer du registre les entrées de disques qui ne sont
    pas connectés ou sans lettre assignée lancer: mountvol /R. Ce
    programme permet aussi de lister les lettres de volumes avec leur GUID
    (GUID pour ce système uniquement, il n’est pas stocké dans la partition,
    ni ailleurs sur le disque, il est assigné par windows pour un couple
    (signature de disque/partition offset) dans une instance de windows
    alors que dans une autre instance de windows la même partition sur le
    même disque aura ce GUID différent)

    Changer le label du volume: commande LABEL [drive:][label]

    Historique de révisions

    • Vous trouverez la dernière version de ce tutoriel sur ma page perso
      de tutoriels informatique
      .
      Vous y trouverez aussi la version HTML, PDF et TXT.

    • 2018-06-17 : Ajout d'une note indiquant que ce tutoriel utilise des
      logiciels libres

    • 2018-06-11 : Correction de la forme et de fautes d'orthographe

    • 2018-05-28

    Commentaires : voir le flux atom ouvrir dans le navigateur

  • LinuxFr.org : première quinzaine de juin 2018 (Journaux LinuxFR)

    Nonante huitième épisode dans la communication entre les différents intervenants autour du site LinuxFr.org : l’idée est tenir tout le monde au courant de ce qui est fait par les rédacteurs, les admins, les modérateurs, les codeurs, les membres de l’association, etc.

    L’actu résumée ([*] signifie une modification du sujet du courriel) :

    Statistiques

    Du 1er au 15 juin 2018

    • 1528 commentaires publiés (dont 8 masqués depuis) ;
    • 248 tags posés ;
    • 80 comptes ouverts (dont 6 fermés depuis) ;
    • 35 entrées de forums publiées (dont 0 masquée depuis) ;
    • 20 liens publiés (dont 1 masqué depuis) ;
    • 21 dépêches publiées ;
    • 25 journaux publiés (dont 1 masqué depuis) ;
    • 3 entrées nouvelles, 1 corrigée dans le système de suivi ;
    • 1 sondage publié ;
    • 0 pages wiki publiées (dont 0 masquée depuis).

    Listes de diffusion (hors pourriel)

    Liste webmaster@ - [restreint]

    • R.A.S.

    Liste linuxfr-membres@ — [restreint]

    • [membres linuxfr] Bouffe des 20 ans le 28 juin à Paris

    Liste meta@ - [restreint]

    • [Meta] Incident du jour sur SSL/TLS
    • [Meta] Quel avenir pour la tribune ?

    Liste moderateurs@ - [restreint]

    • [Modérateurs] certificat linuxfr expiré
    • [Modérateurs] Incident du jour sur SSL/TLS
    • [Modérateurs] Certificat SSL
    • [Modérateurs] où se trouve les CSS de Linuxfr
    • [Modérateurs] forum - bug pour s'inscrire ?

    Liste prizes@ - [restreint]

    • [Prizes] LinuxFr prizes recap du samedi 9 juin 2018, 13:35:23 (UTC+0200)
    • [Prizes] J'ai gagné un livre!

    Liste redacteurs@ - [public]

    • [Rédacteurs] Incident du jour sur SSL/TLS

    Liste team@ - [restreint]

    • [team linuxfr] Certificat SSL du site linuxfr.org expiré
    • [team linuxfr] Tweet de Laurent Jouanneau (@ljouanneau)
    • [team linuxfr] Incident du jour sur SSL/TLS
    • [team linuxfr] Purge du compte X [*]
    • [team linuxfr] réouverture de compte
    • [team linuxfr] Organisez des événements dans le cadre de la Fête des Possibles, du 15 au 30 septembre 2018

    Liste webmaster@ — [restreint]

    • R.A.S.

    Canal IRC adminsys (résumé)

    • certificat X.509 périmé (encore merci à tous ceux qui l'ont signalé), passage à Let's Encrypt et communication post-incident
    • renouvellement du domaine (encore merci Yann)
    • dernière version de Jessie (8.11) prévu le 23 juin, et ensuite passage en fin de vie
    • question relative à la configuration DMARC de la liste Sympa des modérateurs qui change le From de l'émetteur dans certains cas
    • rachat de GitHub par Microsoft et dépôts LinuxFr.org. Faut-il bouger et pourquoi.
    • Let's Encrypt et HTTP en clair pour le renouvellement ? Voir par exemple la discussion
    • discussion sur les aspects sécurité de l'affichage distant d'images sur la tribune
    • « 20 ans le bel âge pour mourir », ah non ça parle de Yahoo Messenger, pas de nous
    • 20 ans du site et POSS en décembre ?
    • courriels envoyés pour préparer les entretiens des 20 ans
    • peu de présents aux RMLL dans l'équipe. Snif. Me laissez pas tout seul.
    • migration de alpha et main en Jessie
    • travaux en cours pour nettoyer le dépôt git d'admin (avec des fichiers générés par ansible notamment). Sans oublier de finaliser la partie Let's Encrypt…
    • toujours un conteneur à migrer en Jessie, et ensuite trois en Stretch. Et aussi un hôte Trusty à mettre à jour.

    Tribune de rédaction (résumé)

    • idée de dépêche : NetHammer (finalement parue sous forme de lien)
    • avis de grand calme

    Tribune de modération (résumé)

    • peu de présents aux RMLL dans l'équipe. Snif. Me laissez pas tout seul.
    • du spam
    • améliorations de CSS proposées par voxdemonix
    • les admins du site ont des facilités techniques pour traquer les spammeurs et les multis, par rapport aux modérateurs
    • retour des Geek Faeries

    Commits/pushs de code https://github.com/linuxfrorg/

    • (springcleaning) admin-linuxfr.org en cours de conversion vers Ansible
    • Allow users to choose the source for their tribune smileys in prefere…
    • Add a border for missing title on images
    • Fix max height for image on computer screen

    Divers

    Commentaires : voir le flux atom ouvrir dans le navigateur

  • Exécution de commandes en parallèle avec ClusterShell (Dépêches LinuxFR)
    ClusterShell est une bibliothèque événementielle en Python qui permet d'exécuter en parallèle des commandes en local et à distance sur des noeuds d'un cluster, ferme de serveurs, stations de travail... Elle fournit également un ensemble de scripts utilitaires basés dessus (voir plus bas).

    ClusterShell est développée et utilisée au CEA par les équipes système de plusieurs grands clusters Linux de stockage et de calcul (qui comptent parmi les plus puissants du monde -- dont Tera100), elle est disponible sous licence CeCILL-C (CEA - CNRS - INRIA Logiciel Libre, compatible LGPLv2+).


    lien 1 : ClusterShell (avec documentation et exemples)
    lien 2 : Plus d'infos sur la gestion des groupes de noeuds
    (...)
  • LinuxFr.org : première quinzaine de juin 2018 (Journaux LinuxFR)

    Nonante-huitième épisode dans la communication entre les différents intervenants autour du site LinuxFr.org : l’idée est tenir tout le monde au courant de ce qui est fait par les rédacteurs, les admins, les modérateurs, les codeurs, les membres de l’association, etc.

    L’actu résumée ([*] signifie une modification du sujet du courriel) :

    Statistiques

    Du 1er au 15 juin 2018

    • 1528 commentaires publiés (dont 8 masqués depuis) ;
    • 248 tags posés ;
    • 80 comptes ouverts (dont 6 fermés depuis) ;
    • 35 entrées de forums publiées (dont 0 masquée depuis) ;
    • 20 liens publiés (dont 1 masqué depuis) ;
    • 21 dépêches publiées ;
    • 25 journaux publiés (dont 1 masqué depuis) ;
    • 3 entrées nouvelles, 1 corrigée dans le système de suivi ;
    • 1 sondage publié ;
    • 0 pages wiki publiées (dont 0 masquée depuis).

    Listes de diffusion (hors pourriel)

    Liste webmaster@ - [restreint]

    • R.A.S.

    Liste linuxfr-membres@ — [restreint]

    • [membres linuxfr] Bouffe des 20 ans le 28 juin à Paris

    Liste meta@ - [restreint]

    • [Meta] Incident du jour sur SSL/TLS
    • [Meta] Quel avenir pour la tribune ?

    Liste moderateurs@ - [restreint]

    • [Modérateurs] certificat linuxfr expiré
    • [Modérateurs] Incident du jour sur SSL/TLS
    • [Modérateurs] Certificat SSL
    • [Modérateurs] où se trouvent les CSS de Linuxfr [*]
    • [Modérateurs] forum - bug pour s'inscrire ?

    Liste prizes@ - [restreint]

    • [Prizes] LinuxFr prizes recap du samedi 9 juin 2018, 13:35:23 (UTC+0200)
    • [Prizes] J'ai gagné un livre!

    Liste redacteurs@ - [public]

    • [Rédacteurs] Incident du jour sur SSL/TLS

    Liste team@ - [restreint]

    • [team linuxfr] Certificat SSL du site linuxfr.org expiré
    • [team linuxfr] Tweet de Laurent Jouanneau (@ljouanneau)
    • [team linuxfr] Incident du jour sur SSL/TLS
    • [team linuxfr] Purge du compte X [*]
    • [team linuxfr] réouverture de compte
    • [team linuxfr] Organisez des événements dans le cadre de la Fête des Possibles, du 15 au 30 septembre 2018

    Liste webmaster@ — [restreint]

    • R.A.S.

    Canal IRC adminsys (résumé)

    • certificat X.509 périmé (encore merci à tous ceux qui l'ont signalé), passage à Let's Encrypt et communication post-incident
    • renouvellement du domaine (encore merci Yann)
    • dernière version de Jessie (8.11) prévu le 23 juin, et ensuite passage en fin de vie
    • question relative à la configuration DMARC de la liste Sympa des modérateurs qui change le From de l'émetteur dans certains cas
    • rachat de GitHub par Microsoft et dépôts LinuxFr.org. Faut-il bouger et pourquoi.
    • Let's Encrypt et HTTP en clair pour le renouvellement ? Voir par exemple la discussion
    • discussion sur les aspects sécurité de l'affichage distant d'images sur la tribune
    • « 20 ans le bel âge pour mourir », ah non ça parle de Yahoo Messenger, pas de nous
    • 20 ans du site et POSS en décembre ?
    • courriels envoyés pour préparer les entretiens des 20 ans
    • peu de présents aux RMLL dans l'équipe. Snif. Me laissez pas tout seul.
    • travaux en cours pour nettoyer le dépôt git d'admin (avec des fichiers générés par ansible notamment). Sans oublier de finaliser la partie Let's Encrypt…
    • toujours un conteneur à migrer en Jessie, et ensuite trois en Stretch. Et aussi un hôte Trusty à mettre à jour.

    Tribune de rédaction (résumé)

    • idée de dépêche : NetHammer (finalement parue sous forme de lien)
    • avis de grand calme

    Tribune de modération (résumé)

    • peu de présents aux RMLL dans l'équipe. Snif. Me laissez pas tout seul.
    • du spam
    • améliorations de CSS proposées par voxdemonix
    • les admins du site ont des facilités techniques pour traquer les spammeurs et les multis, par rapport aux modérateurs
    • retour des Geek Faeries

    Commits/pushs de code https://github.com/linuxfrorg/

    • (springcleaning) admin-linuxfr.org en cours de conversion vers Ansible
    • Allow users to choose the source for their tribune smileys in prefere…
    • Add a border for missing title on images
    • Fix max height for image on computer screen

    Divers

    Commentaires : voir le flux atom ouvrir dans le navigateur

  • Une faille nommée « shellshock » (Dépêches LinuxFR)

    « ShellShock », une faille dans l'usage du shell Bash, est sous les projecteurs depuis quelques jours. Le terme est un jeu de mot entre la stupeur propre à l'obusite des combattants de la première guerre mondiale et l'interface système shell. Nous vous proposons des explications sur cet évènement particulier, son périmètre, les conditions de son exploitation, les surfaces d'attaques, et les solutions proposées, déjà mises en œuvre ou à venir. Enfin, une revue de presse sera dressée, cette faille s'étant transformée en évènement.

    Sommaire

    Contexte et histoire

    Bash est l'interpréteur par défaut du projet GNU, c'est une amélioration du Shell Bourne, reprenant des idées du Korn Shell (ksh). Il est développé depuis 1988 et n'a cessé de s'améliorer.

    Bash est le shell par défaut d'un grand nombre de distributions GNU/Linux, mais pas toutes. Par exemple Ubuntu ne lance pas Bash avec son /bin/sh, mais dash, Bash n'étant disponible que pour l'utilisateur en session interactive. Bash se retrouve également dans Apple Mac OS X et dans Microsoft Windows via Cygwin (SFU, Services for Unix, utilise csh ou ksh).

    Quelques explications

    Il s'agit d'exploiter un bash-isme, une spécificité du shell Bash, permettant d'exporter une fonction et non seulement une variable. Les autres shells (ksh, zsh, dash, …) ne sont pas concernés par cette faille. Par ailleurs, Bash ne permet pas cet export de fonctions s'il est utilisé avec l'option -p ).

    Il est tout à fait normal de vouloir passer des variables d'environnement à un processus enfant.

    Mais Bash permet en outre de passer des fonctions vers le processus enfant. Aucun autre shell ne permet cela. Dans ce cadre relativement strict, la sécurité ne pose pas de problème : les droits et contextes d'exécution sont identiques et l'utilisateur, système ou non, est le même. Ceci est documenté, il s'agit de l'option -f de la commande export dans le shell Bash. « It is not a bug, it is a feature », le vieil adage prend ici tout son sens. Nous laissons le lecteur seul juge du bien-fondé de ce bashisme.

    Alors s'il n'y a pas de problème, où est le problème ? Le problème se situe dans l'usage de Bash par les autres programmes. Bash est devenu le shell par défaut de certaines distributions, et de nombreux programmes utilisent le shell par défaut pour passer des variables d'environnement entre leurs processus. Le contexte change donc : ce n'est plus un utilisateur local et de confiance qui utilise cela, mais une multitude de programmes, parfois distants.

    Ces programmes ne valident pas eux mêmes les données qu'ils donnent à Bash, et ne font souvent que passe-plat. Dans ce contexte, ce qui était auparavant une fonctionnalité se transforme alors en faille. Ceci explique l'ancienneté du problème.

    Explications techniques

    Une fonction dans le shell bash

    #!/bin/bash
    # déclaration de la fonction d'affichage du message "bonjour vous", nommée mafonction :
    mafonction() {
    echo "bonjour vous";
    }
    # exécution de la fonction :
    mafonction

    La même chose, pour passer la fonction à un sous-shell

    env mafonction='() { echo "bonjour vous"; }' bash -c 'mafonction;' 
    

    On prefixe avec la commande env pour faire tourner un programme dans un environnement modifié. Et à la fin on fait exécuter la fonction par un autre bash. OK ?

    La même chose, en détournant l'usage

    env mafonction='() { echo "bonjour vous"; }; echo "voici shellshock"' bash -c "mafonction;"
    

    Ici, l'exécution de la fonction mafonction ne se limite pas à un écho "bonjour vous", mais exécute aussi le code echo "voici shellshock" On notera la place du délimiteur '
    OK ?

    Et en fait il n'est même pas nécessaire d'exécuter la fonction définie :

    env mafonction='() { echo "bonjour vous"; }; echo "voici shellshock"' bash -c "true"
    voici shellshock
    

    Donc, le simple () { :;} suffit à résumer la situation.
    OK !

    Surfaces d'attaques et exploitabilité

    Les conditions de l'exploitation à distance de la faille sont relativement simples :

    • /bin/sh pointe sur /bin/bash ;
    • avoir SELinux désactivé ou non configuré ;
    • avoir un service qui écoute le réseau et qui va exécuter bash.

    L'exploitation de cette faille est très simple, et de nombreux preuves de concepts et exploits circulent actuellement sur Internet. Voici une liste non-exhaustive des logiciels qui peuvent être utilisés en passe-plat :

    • dhclient ;
    • apache, via mod_cgi (et sans mod_security correctement configuré) ;
    • exim ; postfix ; qmail ; procmail ;
    • OpenVPN ;
    • stunnel ;
    • probablement de très nombreux logiciels privateurs …
    • SIP, FTP, probablement d'autres …

    Preuves de Concept
    Un projet hébergé sur github rassemble une série de POC à cette adresse

    À noter que SELinux ne va pas bloquer un usage de « shellshock », il va cependant en réduire fortement les possibilités d'exploitation. Par exemple le contexte httpd_sys_script_t est attribué à tout CGI, contexte qui ne permet l'écriture que dans … /tmp! Le lecteur trouvera des explications complètes sur le blog de Dan Walsh à ce sujet.

    Ne sont donc pas concernées : toutes les distributions ayant un autre shell que Bash. Toutes les distributions ayant SELinux activé bénéficient d'une protection contre des exploitations de ce type. Mais également : tous les matériels embarqués et objets connectés, contrairement à ce que des articles de presse affirment, car ces matériels utilisent la plupart du temps busybox et son implémentation inline de Bash n'est pas vulnérable. Ne sont pas concernés non plus les téléphones portables (pas plus les Android que les iPhones). Les "box" internet ne le sont pas davantage, ni les télévisions, ni les lecteurs de salon, les autoradios, ni les avions, drones, missiles, sous-marins… Bref, nous avons eu le plaisir de lire un peu n'importe quoi sur le sujet et la revue de presse contient quelques jolies perles.

    NdM : le fabriquant de NAS QNAP vient d'alerter ses utilisateurs (cf article Next INpact)

    Chronologie des évènements

    • Stéphane Chazelas rapporte le problème à Redhat (bug déclaré le 14 septembre) ;
    • Le CVE-2014-6271 lui est attribué ;
    • Le 24 septembre, ce CVE est rendu public et un premier correctif est mis à disposition ;
    • Le jour même la communauté pointe l'insuffisance de ce correctif ;
    • Le CVE-2014-7169 est alors ouvert et attribué à Tavis Ormandy ;
    • Le 27 septembre le second correctif est publié

    Solutions mises en œuvre

    Correctifs disponibles et annonces des distributions

    La faille, CVE-2014-6271
    • Le test :
      env 'x=() { :;}; echo vulnerable' 'BASH_FUNC_x()=() { :;}; echo vulnerable' bash -c "echo test" Ne doit pas retourner le terme "vulnérable", quelque soit le formattage retour.

    • Les annonces :

    Le second problème, CVE-2014-7169
    • Le test :
      cd /tmp; rm -f echo; env 'x=() { (a)=>\' bash -c "echo date"; cat echo doit retourner que le fichier "/tmp/echo" n'existe pas.

    • Les annonces :

    Les CVE-2014-6277, CVE-2014-7186 et CVE-2014-7187 ne sont pas publics à ce jour (infos chez Redhat 0, 1 et 2).
    • D'autres correctifs sont à venir.
    mod_security, le filtrage

    Mod_security est un pare-feu applicatif pour le serveur Apache. Il peut être configuré pour filtrer certains caractères et expressions régulières. C'est donc un moyen efficace pour se prémunir contre le principal vecteur d'attaque : les scripts CGI. Si vous utilisez Redhat, vous pouvez l'installer ou le mettre à jour : il contient les règles tout prêtes pour filtrer « shellshock ». Ces règles sont de types : SecRule REQUEST_HEADERS "^\(\) {" & request_line.

    Le cas FreeBSD

    Le projet FreeBSD a décidé de désactiver la possibilité d'importation de fonction de Bash. Le système FreeBSD n'utilise pas Bash comme shell par défaut, mais tcsh, Bash n'étant même pas inclus dans une installation de base. Mais pour prémunir de tout problème lié à un changement de shell par défaut, le projet a décidé de supprimer la fonctionnalité incriminée, avec ce message laconique : « cela retire le risque de nouveaux problèmes conduisant à l’exécution de code, et le risque pour les scripts suid, aussi pour les applications mal écrites qui ne nettoient pas leurs environnements » Radical.

    Revue de presse

    Après les annonces sécurité et la réaction des projets (Bash, FSF - traduite en français par l'April), la presse spécialisée puis la presse généraliste ont multiplié les articles : pire que la faille Heartbleed ? (Slate.fr, LMI, Silicon.fr, L'Express, 20minutes, HuffingtonPost, New Zealand Herald), « panique » (Courrier International), « mégafaille » (01Net), « horrible » (ZdNet), « premières attaques » (01net), « plus grande menace de l'histoire du web » (ParisMatch, si si), « 500 millions de serveurs web vulnérables » (La Tribune, Washington Post), « Google et Amazon ont patchés » - super on est sauvés alors - (WallStreetJournal), d'autres failles Bash à prévoir (ArsTechnica), « ver fou ShellShock » (Wired ou le blog de R. Graham), « internet bâti sur de la glace fine » (Financial Times), etc.

    Conclusion

    D'une rencontre entre une fonctionnalité et des usages nait une faille qui fait grand bruit. Bruit généré par l'importance du problème, certes, mais également par le manque de discernement et le FUD autour. Ce qui met en valeur la place qu'ont pris les Logiciels Libres dans nos vies quotidiennes, sans que cela se voie. Il aura fallu moins de 4 jours entre la publication du problème (à ne pas confondre avec le signalement initial aux équipes sécurité) et sa résolution. Peu d'éditeurs peuvent se targuer d'être aussi rapides sur la résolution d'un problème de ce type et sur la transparence pour l'accès à l'information.

    Dans le même temps, l'inquiétude de savoir que cette possibilité existe depuis de nombreuses années est légitime. Et elle renforce la nécessité de participation. Combien d'éditeurs de solutions s'appuient sur des briques libres sans jamais rien verser aux projets ?

    Mettez et maintenez vos systèmes à jour! Et ne pensez pas qu'un programme qui n'a pas connu beaucoup de failles est forcément très sûr, peut-être que personne ne l'avait vraiment regardé jusque là.

    Lire les commentaires

  • Haskell et le tri (Journaux LinuxFR)

    Sommaire

    Bonjour nal.

    Introduction

    Cela fait longtemps que je n'ai pas posté ici, cela me manquait. Je trouve que LinuxFR ne parle pas assez de Haskell, alors je vais en parler un peu aujourd'hui sur une digression totalement inintéressante et proche de la masturbation intellectuelle. On va partir de rien et discuter de la fonction de tri fournie dans la librairie standard (base) de GHC, le compilateur le plus connu / utilisé.

    L'idée c'est de vous présenter un peu Haskell et sa syntaxe à partir d'un exemple simple à partir d'une fonction simple, le tri. Attention, on ne va pas implémenter de tri, mais on va voir comment utiliser les fonctions déjà existante pour construire une fonction de tri de plus haut niveau.

    Sort

    Cette fonction s'appelle sort et a comme signature :

    sort :: Ord a => [a] -> [a]

    Dit autrement, c'est une fonction qui prend [a], une liste de n'importe quel type a et renvoie une liste de n'importe quel type a. Seule contrainte sur a, ce type doit être Ordonable, c'est à dire que on doit pouvoir comparer les éléments de a entre eux. La liste est une liste simplement chaînées et elle est non modifiable, ainsi le tri ne se fait pas en place, mais crée une nouvelle liste.

    Cela ressemblerait un peu à cette fonction en c++ :

    template<typename A>
    std::list<A> sort(const std::list<A> &l);

    Exemple d'usage dans l'invite de commande ghci :

    > import Data.List
    > sort [1, 10, 3, 2, 0, -1]
    [-1,0,1,2,3,10]

    Sort By

    Super ! Bon, il existe un autre variantes de cette fonction, sortBy.

    sortBy :: (a -> a -> Ordering) -> [a] -> [a]

    sortBy accepte une fonction de comparaison en plus de type (a -> a -> Ordering), en gros, elle prend deux éléments et renvoi leur ordre. Exemple d'utilisation :

    > let compareName nameA nameB
    |       | nameA == "Chuck Norris" = GT
    |       | nameB == "Chuck Norris" = LT
    |       | otherwise = compare nameA nameB
    | 
    
    > sortBy compareName ["Chuck Norris", "Bruce Wayne", "Bruce Banner", "Zorro", "Denver"]
    ["Bruce Banner","Bruce Wayne","Denver","Zorro","Chuck Norris"]

    Notez comment j'écris une fonction de comparaison spécifique qui rend toute sa gloire à Chuck Norris.

    Cette example de code est équivalent au code python suivant, qui ne marche plus qu'en python 2, l'attribut cmp de sorted ayant disparu en python 3, ce que je regrette. :

    >>> sorted([1, 10, 3, 2, 0, -1])
    [-1, 0, 1, 2, 3, 10]
    
    >>> def compareName(nameA, nameB):
    ...     if nameA == "Chuck Norris": return 1
    ...     if nameB == "Chuck Norris": return -1
    ...     return cmp(nameA, nameB)
    ... 
    >>> sorted(["Chuck Norris", "Bruce Wayne", "Bruce Banner", "Zorro", "Denver"], cmp=compareName)
    ['Bruce Banner', 'Bruce Wayne', 'Denver', 'Zorro', 'Chuck Norris']

    Digression paresseuse

    Petite digression sur Haskell, connaissez vous la complexité de cette opération :

    > head (sort [1..100])
    1

    Naïvement on pourrait se dire, un tri, O(n log n). Mais non, Haskell est paresseux et rend le résultat en O(n) car il n'a pas besoin de calculer le tri entier avant d'obtenir le résultat. Super non ? En pratique cela aide rarement et souvent cela complexifie la réflexion.

    Tri inversé

    Revenons à nos fonctions de tri. Je veux pouvoir trier ma liste à l'envers. En python, rien de plus simple, il suffit d'utiliser le paramètre optionnel reverse :

    >>> sorted(["Chuck Norris", "Bruce Wayne", "Bruce Banner", "Zorro", "Denver"], cmp=compareName, reverse=True)
    ['Chuck Norris', 'Zorro', 'Denver', 'Bruce Wayne', 'Bruce Banner']

    En Haskell, ce n'est pas si simple… On peut utiliser reverse, mais cela va trier la liste dans un sens puis l'inverser, quelle perte de temps :

    reverse (sortBy compareName ["Chuck Norris", "Bruce Wayne", "Bruce Banner", "Zorro", "Denver"])
    ["Chuck Norris","Zorro","Denver","Bruce Wayne","Bruce Banner"]

    Mais on peut aussi se dire que si on inversait les arguments de la fonction compareName avec flip alors cela fonctionnerait sans soucis :

    > (sortBy (flip compareName) ["Chuck Norris", "Bruce Wayne", "Bruce Banner", "Zorro", "Denver"])
    ["Chuck Norris","Zorro","Denver","Bruce Wayne","Bruce Banner"]

    On peut donc facilement crée une fonction de plus haut niveau :

    > let reverseSortBy f = sortBy (flip f)
    | 
    > reverseSortBy compareName ["Chuck Norris", "Bruce Wayne", "Bruce Banner", "Zorro", "Denver"]
    ["Chuck Norris","Zorro","Denver","Bruce Wayne","Bruce Banner"]

    Règle de compilation

    On peut même crée une règle de compilation qui va remplacer automatiquement reverse (sortBy f l) par sortBy (flip f) l :

       {-# RULES
    "reverse/sortBy"    forall f l.  reverse (sortBy f l) = sortBy (flip f) l
    #-}

    C'est une chose que j’apprécie vraiment en Haskell, c'est que on peut écrire du code assez clair et plus tard le rendre efficace en transformant notre code automatiquement.

    Tri multiple

    Pour continuer, nous allons nous concentrer sur sortBy en Haskell ou l'attribut cmp de la fonction sorted de python.

    Je suis maintenant l'heureux utilisateur d'une liste de noms et de poids que je nommerais l :

    > let l = [("Bruce Lee", 50), ("Batman", 100), ("Hulk", 200), ("La montagne", 100)]

    J'aimerais trier ces gens par poids décroissant et par nom croissant en cas d'égalité. Nous allons faire cela en python, puis en Haskell, puis en Haskell for WarLdOrZOrgCoderZZZ.

    En python tout d'abord :

    >>> l = [("Bruce Lee", 50), ("Batman", 100), ("Hulk", 200), ("La montagne", 100)]
    
    >>> def compare(t0, t1):
    ...     c = cmp(t1[1], t0[1])
    ...     if c == 0:
    ...         return cmp(t0[0], t1[0])
    ...     else:
    ...         return c
    ... 
    >>> sorted(l, cmp=compare)
    [('Hulk', 200), ('Batman', 100), ('La montagne', 100), ('Bruce Lee', 50)]

    Rien de bien dramatique. C'est pas forcement beau, mais cela fait le boulot. Ma fonction de comparaison commence par comparer les indices [1] (donc les poids), observez l'inversion des arguments de cmp où je passe t1 puis t0 pour l'ordre décroissant. Si les deux sont égaux (car cmp renvoie 0) alors je regarde le nom, sinon je renvois le résultat de la comparaison.

    En Haskell maintenant :

    > let compare' t0 t1 = case (compare (snd t1) (snd t0)) of
    |                      EQ -> compare (fst t0) (fst t1)
    |                      ltOrGt -> ltOrGt
    | 
    > sortBy compare' l
    [("Hulk",200),("Batman",100),("La montagne",100),("Bruce Lee",50)]

    J'ai appelé ma fonction de comparaison compare' pour ne pas la confondre avec celle du système qui s'appelle compare. snd et fst sont sensiblement équivalents aux [0] et [1] de python. Ce que j'aime en Haskell c'est que bien que je n'ai mis aucune annotation de type, ils existent et sont vérifiés. J'aime aussi le fait que compare me renvoi EQ ou GT ou LT et non pas -0 ou -1 ou 1 comme le fait python. Bref, les avantages du typage statique sans les inconvénients.

    Un des défaut de cette méthode, c'est qu'elle va vite devenir complexe si j'ai plus de critères de tri. Nous allons régler ce problème.

    Première factorisation

    En premier lieu je n'aime pas la duplication de code qu'il y a sur compare (snd t1) (snd t0) et compare (fst t0) (fst t1). Je propose de factoriser cela dans une fonction que nous nommerons de façon malicieuse comparing, je ne me suis pas foulé, elle existe déjà avec ce nom la ;)

    > let comparing f a b = compare (f a) (f b)
    | 
    > let compare' t0 t1 = case (comparing snd t1 t0) of
    |                      EQ -> comparing fst t0 t1
    |                      ltOrGt -> ltOrGt
    | 
    > sortBy compare' l
    [("Hulk",200),("Batman",100),("La montagne",100),("Bruce Lee",50)]

    C'est plus simple ;) Comme comparing existe déjà dans la librairie standard, je vais me contenter de l'importer avec import Data.Ord (comparing).

    On va continuer à factoriser un peu. Je n'aime vraiment pas cette inversion des arguments de comparing snd t1 t0. Cela ressemble à un bug, il manque un commentaire pour dire que je veux trier en ordre descendant. Bref, c'est peu agréables. Je vais écrire deux variantes de comparing :

    ascending f a b = comparing f a b
    descending f a b = flip (comparing f) a b

    Application partielle

    Petite digression sur l'application partielle. En Haskell, tout est fonction. Il y a les fonctions constantes de type t et les fonctions unaires de type de type t -> t'. Par exemple, abs qui donne la valeur absolue, est une fonction unaire de Int -> Int. Mais le type de retour d'une fonction unaire peut être aussi une fonction. On peut donc avoir une fonction du type a -> (b -> r) qui peut s'écrire a -> b -> c. En appliquant cette fonction une unique fois sur une valeur de type a on obtient une fonction de type b -> c. Bref. On se sert souvent de cette propriété pour créer des fonctions avancée à partir de fonction plus simples. Exemple, la fonction d'addition s'écrit (+), notez dans l'exemple suivant comment on peut l'utiliser en forme infix ou postfix, et comment on peut créer une fonction partiellement appliquée inc :

    > (+) 1 2
    3
    > 1 + 2
    3
    > let inc = (+) 1
    > inc 5
    6

    De façon similaire, toutes ces notations sont équivalentes, seul changent le fait que les arguments sont explicitement présents ou pas :

    let add x y = (+) x y
    let add x y = x + y
    let add x = (+) x
    let add = (+)

    Seconde factorisation

    Revenons à nos fonctions ascending et descending. Voici le code prenant en compte ces nouvelles fonctions. Notez que j'ai un peu simplifié l'écriture de ascending et descending afin d'utiliser l'application partielle :

    > let ascending = comparing
    
    > let descending = flip . comparing
    
    > let compare' t0 t1 = case (descending snd t0 t1) of
    |                         EQ -> ascending fst t0 t1
    |                         ltOrGt -> ltOrGt
    |
    > sortBy compare' l
    [("Hulk",200),("Batman",100),("La montagne",100),("Bruce Lee",50)]

    Bon, les choses commencent à devenir intéressantes. Ma fonction compare' commence à être bien claire, si ce n'est le case pour enchaîner sur le critère suivant si le premier critère est égale à EQ. On pourrait définir un opérateur binaire permettant de réaliser ce traitement, appelons cet opérateur blork juste parce que c'est marrant de lui donner ce nom et qu'aucun autre ne me vient à l'esprit là maintenant…

    > let blork a b
    |        | a == EQ = b
    |        | otherwise = a

    Notez la syntaxe de guard, qui permet de tester différentes équations afin de trouver la valeur de retour.

    Réécrivons encore une fois notre code, notez que j'utilise blork comme opérateur infix.

    > let compare' t0 t1 = descending snd t0 t1 `blork` ascending fst t0 t1
    
    > sortBy compare' l
    [("Hulk",200),("Batman",100),("La montagne",100),("Bruce Lee",50)]

    On factorise encore plus

    Cela va commencer à devenir plus simple de chaîner les prédicats puisqu'au lieu d'une cascade de case je peux simplement ajouter une composition avec blork. On pourrait même commencer à virer compare' et à mettre en place une fonction lambda anonyme :

    > sortBy (\t0 t1 -> descending snd t0 t1 `blork` ascending fst t0 t1) l
    [("Hulk",200),("Batman",100),("La montagne",100),("Bruce Lee",50)]

    Bon. Mais je ne suis encore pas satisfait par ça. Je n'aime pas cette fonction, la presence de t0 et t1 de partout. Ce que j'aimerais c'est écrire une fonction blirk qui permet de combiner deux fonctions de comparaison ensemble. On va l'écrire vite :

    > let blirk f0 f1 a b = f0 a b `blork` f1 a b
    
    > sortBy (descending snd `blirk` ascending fst) l
    [("Hulk",200),("Batman",100),("La montagne",100),("Bruce Lee",5)]

    Et voila, là je suis super content… J'ai une belle api, cela permet d'expliquer vraiment simplement ce que je veux. Mais il y a toujours ces deux fonctions blirk et blork pour lesquels j'ai du mal à donner un nom.

    Monoids

    Je rappel, blork retourne le premier terme qui n'est pas EQ, tel que :

    EQ `blork` GT `blork` LT == GT
    LT `blork` EQ `blork` GT = LT

    Cela ne vous rappel rien ? :

    True and True and True == True
    True and False and True == False

    C'est très proche de l’opérateur and ou de l’opérateur or logique. En généralisant un peu, il s'agit d'un [Monoid]. Non, ce n'est pas une pub pour du shampoing, un monoid c'est un ensemble qui admet un élément neutre et une operation de réduction associative. Comme (+) et 0 ou (*) et 1 pour les entiers.

    Nos résultats d’égalité forment un monoid. L’élément neutre étant EQ et l'operation entre les éléments étant blork.

    On et bien avancé, oui ! Car ce concept est tellement courant qu'il y a une librairie standard dans Haskell qui gère les Monoids, Data.Monoid. Et coup de chance, Ordering, le type de EQ, LT et GT est géré.

    En haskell, les Monoids ont deux fonctions utiles, mappend et mempty. Regardons un peu celles-ci en action sur différents monoids.

    Tout d'abord les elements neutres, avec mempty. Ici, c'est un peu tordu, car mempty est une fonction constante polymorphique, c'est à dire que sa valeur dépend du type utilisé, d'où les annotation de type faites avec :: que j'ai rajoutées.

    > mempty :: Sum Int
    Sum {getSum = 0}
    > mempty :: Product Int
    Product {getProduct = 1}
    > mempty :: Ordering
    EQ
    > mempty :: String
    ""
    > mempty :: [Int]
    []

    Puis la fonction de réduction, mappend :

    > Sum 5 `mappend` Sum 12
    Sum {getSum = 17}
    > Product 5 `mappend` Product 12
    Product {getProduct = 60}
    > [1,2,3] `mappend` [4,5,6]
    [1,2,3,4,5,6]
    > "Hello" `mappend` "you"
    "Helloyou"
    > EQ `mappend` GT
    GT
    > EQ `mappend` LT
    LT
    > GT `mappend` LT
    GT
    > GT `mappend` LT

    Application au critères de tri

    Donc en fait, ici, mappend c'est la fonction blork. Et comme mappend est super utilisée, il a un synonyme, l'operateur (<>). Nous pouvons donc dégager blork et utiliser (<>) à la place.

    Qu'en est il de blirk ?. Rappel, cette fonction permettait de combiner ensemble plusieurs fonctions binaire retournant des monoids afin de crée une unique fonction binaire.

    Il se trouve que les fonctions sont aussi des monoids, voyons ce que cela implique.

    Je reprend donc ma définition de blirk:

    > let blirk f0 f1 a b = f0 a b `blork` f1 a b

    Je remplace blork par <> comme vu dernièrement :

    > let blirk f0 f1 a b = f0 a b <> f1 a b

    Au lieu d'appliquer l’opérateur <> entre les résultats de f0 et f1 appliqués à a et b, je peux appliquer l’opérateur <> entre f0 et f1 :

    > let blirk f0 f1 a b = (f0 <> f1) a b

    Bon… Super… Je vais nettoyer un peu en virant a et b grâce à l'application partielle :

    > let blirk f0 f1 = f0 <> f1

    C'est pas mal, blirk est bien plus simple maintenant, mais est toujours là… Juste pour la forme, je pourrais écrire <> sous forme prefix :

    > let blirk f0 f1 = (<>) f0 f1

    Tient, mais je peux utiliser l'application partielle ici ! :

    > let blirk = (<>)

    Et voila blirk n'est autre que l’opérateur de réduction des monoids… Je n'ai donc plus besoin de mes fonctions blirk et blork. Voici maintenant une session de shell complète me permettant d'arriver à mon résultat :

    > import Data.List (sortBy)
    > import Data.Ord (comparing)
    > import Data.Monoid ((<>))
    
    > let l = [("Bruce Lee", 50), ("Batman", 100), ("Hulk", 200), ("La montagne", 100)]
    
    > let ascending = comparing
    > let descending = flip . comparing
    
    > sortBy (descending snd <> ascending fst) l
    [("Hulk",200),("Batman",100),("La montagne",100),("Bruce Lee",50)]

    Voila. Grâce à trois fonctions de la librairie standard et deux définitions triviales pour ascending et descending, j'ai réalisé un mini langage me permettant de paramétrer ma fonction sortBy pour réaliser n'importe quel type de tri.

    Définir ses propres types

    Notez que dans la vraie vie, je n'aime pas les tuples anonymes, donc je ferais mon propre type super hero que j'exploiterais de cette manière :

    > data Hero = Hero {name :: String, weight :: Int} deriving (Show)
    > let l = [Hero "Bruce Lee" 50, Hero "Batman" 100, Hero "Hulk" 200, Hero "La montagne" 100]
    > sortBy (descending weight <> ascending name) l
    [Hero {name = "Hulk", weight = 200},Hero {name = "Batman", weight = 100},Hero {name = "La montagne", weight = 100},Hero {name = "Bruce Lee", weight = 50}]

    Ceci afin de vous montrer la souplesse d'Haskell à ce niveau là. Je crois que sortBy (descending weight <> ascending name) ne peut pas être plus clair et de façon intéressante, cela n'a demandé aucun boilerplate. L'annotation deriving (Show) permet de munir mon type "Hero" d'un affichage par défaut que nous voyons dans le résultat. C'est l'équivalent de la surcharge de __str__ en python ou de ostream &operator<<(ostream&) en C++, mais avec un comportement par défaut pas trop mal.

    Sort On

    Je disais que je regrettais la disparition du paramètre cmp de la fonction sorted de python. Il est maintenant remplacé par le paramètre key qui s'utilise un peu comme notre fonction comparing. En python :

     >>> sorted(["Hello", "My", "Friend"], key=len)
     ['My', 'Hello', 'Friend']
     >>> sorted(["Hello", "My", "Friend"], key=len, reverse=True)
     ['Friend', 'Hello', 'My']

    La difference étant que cette approche n'appelle la fonction key qu'une fois par élément de la liste contrairement à la version avec cmp qui appelle cette fonction en moyenne O(n log n) fois. Mais en pratique elle nécessite de stocker une liste temporaire en plus. C'est donc un compromis entre mémoire utilisée et efficacité de la fonction de comparaison.

    La fonction sortOn en Haskell fonctionne de façon similaire :

    > sortOn length ["Hello", "My", "Friend"]
    ["My","Hello","Friend"]

    Mais qu'en est il du tri inversé. Encore une fois il n'y a pas de fonction de tri avec reverse. L'idée étant que la fonction attendue par sortOn, ici length transforme nos éléments en une autre valeur qui est triable. Ici, Haskell propose un type, Down qui inverse les propriétés de tri du type interne. Exemple :

    > sortOn (Down . length) ["Hello", "My", "Friend"]
    ["Friend","Hello","My"]

    La différence en terme d'API avec python est faible, mais revenons à un example plus complexe comme celui du tri de notre liste de héros. Nous allons réaliser une fonction de tri qui transforme un hero en tuple (poids du hero descendant, nom du héro), les tuples étant triés dans l'ordre lexicographique, cela résous notre problème :

    > sortOn (\hero -> (Down (weight hero), name hero)) l
    [Hero {name = "Hulk", weight = 200},Hero {name = "Batman", weight = 100},Hero {name = "La montagne", weight = 100},Hero {name = "Bruce Lee", weight = 50}]

    A ma connaissance il n'y a pas d'équivalent direct de Down en python, alors nous allons l'écrire. J'en profite pour aussi crée le type Hero pour pouvoir facilement comparer :

    >>> class Hero:
    ...     def __init__(self, name, weight):
    ...        self.name = name
    ...        self.weight = weight
    ...     
    ...     def __repr__(self):
    ...         return "Hero(%r, %r)" % (self.name, self.weight)
    ... 
    >>> l = [Hero("Bruce Lee", 50), Hero("Batman", 100), Hero("Hulk", 200), Hero("La montagne", 100)]
    >>> class Down:
    ...     def __init__(self, obj):
    ...          self._obj = obj
    ...     def __lt__(self, other):
    ...          return self._obj.__gt__(other._obj)
    ...     def __gt__(self, other):
    ...          return self._obj.__lt__(other._obj)
    ...     def __eq__(self, other):
    ...          return self._obj.__eq__(other._obj)
    ... 
    >>> sorted(l, key=lambda hero: (Down(hero.weight), hero.name))
       [Hero('Hulk', 200), Hero('Batman', 100), Hero('La montagne', 100), Hero('Bruce Lee', 50)]

    Voila, on peut faire la même chose, mais la lib standard Haskell propose ici des solutions déjà implémentées.

    Conclusion

    Voila, j'espère que cette introduction à Haskell vous aura fait plaisir, j'ai essayé d'aborder un problème simple, le tri, et en tirant un peu dessus, montrer quelques subtilités du langage.

    A bientôt.

    Lire les commentaires

  • Tutorial Code_Aster (Journaux LinuxFR)

    Sommaire

    Bonjour Nal', une fois n'est pas coutume, il pleut en Haute-Garonne ! Alors j'ai tué le temps jetant un œil à Code Aster. Je laisse ici mes notes.

    Code_Aster, qu'est-ce c'est ?

    Code_Aster est un code de calcul de structure thermo-mécanique par la méthode des éléments finis isoparamétriques.
    Il est développé par EDF sous licence GNU/GPLv3.
    Il permet de faire à peu près tout ce qui est imaginable en mécanique, voir à ce propos-là plaquette de présentation

    Ce code de calcul est intégré à la suite de logiciels libres Salomé-Méca, qui contient un préprocesseur, Code_Aster, et un post-processeur/vieweur pour voir les résultats.

    Aujourd'hui, nous allons utiliser le code en version stand_alone, et nous utiliserons notre éditeur de texte préferé, gmsh, astk, puis de nouveau gmsh pour voir les résultats de nos calculs.

    Installation

    Cela se passe ici.
    Deux options:
    1. Soit on compile code_aster
    1. Soit on n'aime pas compiler et on télécharge le binaire de Salome-Méca qui contient code_aster de façon préinstallé, et quelques Gio d'outils dont ne nous servirons pas.

    La compilation se passe assez bien, et les paquets prérequis (voir les instructions de compilation sur leur site) se trouvent assez facilement.

    Calcul de Poutre

    Nous allons étudier le comportement mécanique d'une poutre encastrée d'un côté et soumise à un effort ponctuel de l'autre côté:
    poutre_encastre

    Nous allons le faire de 3 façons:

    1. En modélisation poutre 1D
    2. En modélisation plaque 2D
    3. En modélisation complète 3D

    Création de la géométrie avec Gmsh

    Pour fonctionner, Code_Aster a besoin d'un fichier de commande, et d'un fichier décrivant un maillage: une liste de nœuds et une liste d'éléments reliant ces nœuds. On pourrait lui fournir un fichier texte contenant les coordonnées géométriques de chaque nœud du maillage, mais vu qu'on a la flemme et que cela peut être assez ennuyeux pour des problèmes complexes, on va demander à Gmsh de le faire pour nous.

    On crée tout d'abord la géométrie de notre problème à l'aides de points, de lignes, surfaces et volumes, on doit aussi définir des groupes d’intérêts (la poutre entière, la partie encastrée, et la partie sur laquelle on applique la force). On peut jouer 5 minutes avec la partie GUI de Gmsh pour lequel on trouvera de nombreux tutoriaux sur le web, mais on en revient vite à un fichier texte.

    Voici donc poutre1d.geo:

    //== parametres ==
    //taille maillage autour des noeuds. 2.5mm entre deux noeuds.
    cl__1 = 2.5;
    
    // == geometrie ==
    //points
    Point(1) = {0,0, 0, cl__1}; // extremite encastre de ma poutre
    Point(2) = {100,0, 0, cl__1}; // extremite libre de ma poutre, soumise à une force
    //lignes
    Line(1) = {1, 2}; // on cree la ligne entre Point1 et Point2
    
    //== groupe ==
    Physical Point("encastr") = {1};
    // on encastrera le noeud correspondant à ce point
    
    Physical Point("force") = {2};
    //on appliquera la force sur le noeud correspondant à ce point
    
    Physical Line ("poutre") = {1};
    // notre poutre sera constitue des tous les noeuds et elements correspondant à cette ligne

    Une fois ce fichier poutre1d.geo crée, on l'ouvre avec gmsh (Terminal: gmsh poutre1d.geo)
    On clique sur Mesh > 1D, le maillage est fait, mais on ne le voit pas car seul la géometrie est affichée ! Donc Tools > Options, Onglet Visibily de Géometrie, on décoche Points et Lines et dans Mesh, on coche Nodes and Lines. Cela donne ceci:

    maillage1d

    Notez qu'avec Tools > Options, dans l'onglet list bowser, on peut visualiser/désafficher (toucher enter du clavier une fois cliqué sur le nom du groupe dans la fenêtre) les groupes que nous avons crée et leurs affectations. C'est très pratique. On voit par exemple bien que notre groupe "poutre" est constitué de tous les éléments de la poutre.

    Pour sauvegarder notre maillage, on fait File > Export et on choisit le format de maillage appelé .MED, on obtient donc un beau mesh1d.med. Surtout, on veille à ce que tout soit décoché dans la fenêtre pop-up qui apparaît et on clique rapidement sur OK.

    De même, voici poutre2d.geo, qu'on maille en 2D avec gmsh:

    //== parametres: ==
    //taille maillage autour des noeuds. 2.5mm entre deux noeuds.
    cl__1 = 2.5;
    L=100; //longeur poutre de 100mm
    R=5; // ratio longueur/largeur
    l=L/R;
    
    //== geometrie ==
    //points
    Point(1) = {0, 0, 0, cl__1};
    Point(2) = {L, 0, 0, cl__1};
    Point(3) = {L, l, 0, cl__1};
    Point(4) = {0, l, 0, cl__1};
    Point(5) = {L, l/2, 0, cl__1};
    //lignes
    Line(1) = {1, 2};
    Line(2) = {2, 5};
    Line(3) = {5, 3};
    Line(4) = {3, 4};
    Line(5) = {4, 1};
    
    //surface
    Line Loop(1) = {1, 2, 3, 4, 5}; //on cree une boucle de lignes
    Plane Surface(1) = {1}; // on crée une surface à partir de la boucle
    
    //== groupe ==
    Physical Line("encastr") = {5}; // on encastrera cette ligne
    Physical Point("force") = {5}; // lieu application force
    Physical Surface("poutre") = {1}; // notre poutre 2d

    maillage2d

    Et poutre3d.geo qu'on mesh en 3D avec gmsh:

    //== paramètres: ==
    //taille maillage autour des noeuds.
    cl__1 = 5;
    L=100; //longeur poutre
    R=5; // ratio longueur/largeur
    l=L/5;
    
    //== geometrie ==
    //points
    Point(1) = {0,0, 0, cl__1};
    Point(2) = {L,0, 0, cl__1};
    Point(3) = {L,l, 0, cl__1};
    Point(4) = {0,l, 0, cl__1};
    Point(5) = {L, l/2, 0, cl__1};
    //lignes
    Line(1) = {1, 2};
    Line(2) = {2, 3};
    Line(3) = {3, 4};
    Line(4) = {4, 1};
    //surface
    Line Loop(1) = {1, 2, 3, 4};
    Plane Surface(1) = {1};
    Point{5} In Surface{1}; // pour que le point 5 soit contenu dans la surface
    
    //volume
    Extrude {0,0,-3}{Surface{1};Layers{3}; Recombine;}
    //on extdure la surface 1 de -3mm selon l''axe Z
    //en créant 3 éléments dans l''épaiseur avec l''aide de layers
    
    
    //== groupe ==
    //on sait que c''est la surface 25 parce qu''on le visualise sous gmsh en affichant "surface label".
    //il peut y avoir une erreur lors de l''import si le numéro de la surface crée par l''extrusion n''est pas 25.'
    //      C''est pas grave, on regarde à quoi correspond la surface à encastrer, on trouve son label, et mon modifie les lignes ci-dessous.
    Physical Surface("encastr") = {25}; // on encastrera cette surface
    Physical Point("force") = {5}; // lieu application force
    Physical Volume("poutre") = {1}; // notre poutre 3d
    
    //== mailage ==
    Transfinite Line{1,3}=8*R+1; // 8*R élem dans la longueur = 41 noeuds entre lignes 1 et 3
    Transfinite Line{4,2}=8+1; // 8 élem dans la largeur =  9 noeuds entre lignes 4 et 2
    Transfinite Surface "*"; // on veut un maillage propre
    Recombine Surface "*"; // on veut un maillage quadra

    maillage3d

    Nous voici maintenant avec 3 maillages au format.med Il nous faut maitenant créer notre fichier de commande !

    Fichier de commande

    #U1.03.02
    DEBUT();
    
    #on charge le fichier de maillage .MED, unité logique 20
    mesh=LIRE_MAILLAGE(
        INFO=2,
        INFO_MED=2,
        UNITE=20,
        FORMAT='MED',
    );
    
    #on a importé le maillage et ses groupes, on crée d'autres groupes:
    
    mesh=DEFI_GROUP(
        reuse =mesh,
        INFO=2,
        MAILLAGE=mesh,
        #on crée un groupe nommé TOUT qui contient toutes les mailles du maillage.
        #on ne va pas s'en servir, mais ça peut être utile
        CREA_GROUP_MA=_F(NOM='TOUT',TOUT='OUI',),
        #on grée un groupe de noeud qui contient tous les noeuds de toutes les mailles.
        # Il faut le faire quand le maillage provient de Gmsh, car Gmsh transforme les noeuds en maille, on les retransforme ici en noeud
        CREA_GROUP_NO=_F(TOUT_GROUP_MA='OUI',),
    );
    
    #on affecte au groupe de maille 'poutre' crée avec gmsh,
    #   des éléments finis de types Poutre, ici POU_D_T
    model=AFFE_MODELE(
        MAILLAGE=mesh,
        AFFE=(
            _F(
              GROUP_MA=('poutre',),
              PHENOMENE='MECANIQUE',
              MODELISATION='POU_D_T',
            ),
        ),
    );
    
    #on définit un matériaux, ici de l''acier:
    #  Module d'Young' E = 210000 N/mm2
    #  Coefficient de Poisson, nu = 0.3
    #  masse volumique = 8e-9 tonne/mm3
    steel=DEFI_MATERIAU(ELAS=_F(E=210000.,NU=0.3,RHO=8e-9),);
    
    #U4.43.03
    #on assigne notre matériaux à nos mailles du groupe 'poutre'
    material=AFFE_MATERIAU(
        MAILLAGE=mesh,
        AFFE=_F(GROUP_MA=('poutre',), MATER=steel,),
    );
    
    
    #U4.42.01
    #On assigne à nos éléments poutre POU_D_T une section rectangulaire de largeur 20mm et d'épaisseur 3mm
    
    elemcar=AFFE_CARA_ELEM(
        MODELE=model,
        INFO=2,
        POUTRE=(
            _F(
                GROUP_MA=('poutre',),
                SECTION='RECTANGLE',
                CARA=('HY','HZ',),
                VALE=(3,20),
            ),
        ),
    );
    #on interdit toutes rotations et translations aux noeuds du groupe 'encastr' (1 seul noeud ici).
    #   cela simule l'encastrement
    encast=AFFE_CHAR_MECA(
        MODELE=model,
        DDL_IMPO=(
            _F(
                GROUP_NO=('encastr',),
                DX=0,DY=0,DZ=0,DRX=0,DRY=0,DRZ=0,
            ),
        ),
        INFO=1,
    );
    
    # on applique 500N selon la direction -Z au noeud de notre groupe 'force'
    force_f=AFFE_CHAR_MECA(
        MODELE=model,
        FORCE_NODALE=_F(
            GROUP_NO=('force',),
            FZ=-500,
        ),
        INFO=2,
    );
    
    #U4.51.01
    #on compile les précédents concepts pour le calcul
    stat=MECA_STATIQUE(
        MODELE=model,
        CHAM_MATER=material,
        CARA_ELEM=elemcar,
        EXCIT=(
            _F(CHARGE=encast,),
            _F(CHARGE=force_f,),
    
        ),
    );
    
    # Par défaut, sont calculés uniquement les déplacements et les réactions nodales aux points de gauss des éléments, je crois.
    # du coup on enrichit le concept "stat" pour lui demander d'autres choses.
    # SIEF_ELNO: ici, efforts théorie des poutres au niveau des nœuds des éléments
    # SIPO_ELNO: ici, contraintes dans la poutre, au niveau des nœuds des éléments
    # SIPM_ELNO: ici, contrainte max dans la poutre
    # REAC_NODA: forces/moments aux nœuds limites
    stat=CALC_CHAMP(
        reuse =stat,
        RESULTAT=stat,  
        CONTRAINTE=(
            'SIEF_ELNO','SIPO_ELNO','SIPM_ELNO',
        ),
        FORCE=('REAC_NODA',),
    );
    
    #on imprime ça dans un fichier de sortie .med, unité logique 80.
    #on n'imprime que les déplacements et les contraintes
    # (on n'affiche pas tout ce qu'on a calculé, genre SIPM_ELNO ou REAC_NODA pourquoi pas !)
    IMPR_RESU(
        FORMAT='MED', 
        UNITE=80,
        RESU=_F(
            RESULTAT=stat,
            NOM_CHAM=(
                'DEPL',
                'SIPO_ELNO',
                'SIPM_ELNO',
            ),
        ),
    );
    
    FIN();

    (Notez que les #U4.51.01 ou autres renvoient à la documentation )
    On enregistre ce fichier texte en 1d.comm par exemple, et nous allons lancer le calcul à l'aider d'astk.

    Astk

    Astk est l'outil permettant de mener à bien un calcul, on le lance via /opt/code_aster/bin/astk (si vous avez installé code_aster dans /opt/).

    On cherche à obtenir une fenêtre qui a cette allure :

    astk

    Ensuite :
    - File -> New
    - on choisit notre path / dossier de travail
    - dans la colonne d'icônes au milieu à droite, on clique sur l’icône en forme de dossier bleu, pour aller chercher son mesh1d.med et son 1d.comm
    - on clique sur l’icône du dessus pour ajouter deux lignes, puis dans type pour la ligne, on choisit mess et rmed, dans name on les appels ./log1d.mess et ./resu1d.rmed
    - File -> Save_As -> 1d.astk

    La colonne LU correspond à Logique Unité, c'est l'endroit de la mémoire où je ne sais quoi où on s'attend à trouver le fichier, dans le fichier.comm on a précisé que l'unité logique était 20 pour le maillage .med et 80 pour le résultat .med
    Les colonnes DRC veulent dire Datas, Récrire, Compressé.

    Une fois que cela est fait on clique sur Run ! Le calcul est lancé, il se termine, on va voir le log1d.mess qui a était crée, il contient toutes les infos relatives au calcul.
    L'information la plus importante étant la dernière ligne.

    Chez moi j'ai: EXECUTION_CODE_ASTER_EXIT_13223-localhost=0
    Si le code renvoit 0, c'est que cela a fonctionné ! S'il renvoit 1, c'est que ça a planté et qu'il faut débuger…

    Résultat

    Normalement tout a fonctionné, nous avons un beau resu1d.rmed que nous ouvrons aves gmsh (Terminal gmsh resu1d.rmed)

    On peut donc voir les déplacements et la contrainte, tout ce dont a besoin un mécanicien pour dimenssionner des systèmes mécaniques !

    Voici les paramètres sur lequels agir pour afficher le déplacement multiplié par 10. Il faut afficher des Vectors et non pas l'Original Field. Comme ci-dessous:

    gmsh poutre 1d

    Pour les contraintes, SIPO_ELNO contient la contribution de chaque force/moment aux contraintes de la poutre.

    C'est grossomodo un vecteur de 6 composantes que voici:

    contraintes

    Pour les afficher une par une, on se place dans Options > Visibility > et, en bas, la première case à droite de la liste déroulante Original Field/Scalar Force/Vector/Tensor. 0 Correspond à SN et 5 correspond à SNT, par rapport au tableau ci-dessus. (Je ne sais pas trop ce que présente SIPO_ELNO par défaut)

    SIPM_ELNO quant à lui présente par défaut la contrainte maximum selon XX.

    Voici d'autre visu avec les modèles 2D et 3D:

    2d_vmises
    3d_déplacement
    3d_vmises

    Aller plus loin

    Code_Aster est très vaste, il contient près de 400 types d'éléments finis ! Pour aller plus loin, n'hésitez pas à lire la doc, qui contient aussi des exemples de calcul qui sont livrés avec le code.

    Je vous conseille aussi notamment l'excellent livre sous licence libre de Jean-Pierre Aubry, qui est un passage obligatoire pour prendre en main le code ! (Le code date par contre de la version 11 de Code_Aster, mais une nouvelle version est en cours d'écriture !)
    On y fait notamment des analyses non-linéaires avec du contact entre pièces et du frottement.
    Aster Study vient aussi de faire son apparition.

    Voilou cher journal, n'hésite pas à t'amuser !

    Je poste en commentaire à ce journal les fichiers .comm de calcul en 2D et 3D.

    Lire les commentaires

  • LinuxFr.org : seconde quinzaine de mai 2018 (Journaux LinuxFR)

    Nonante-septième épisode dans la communication entre les différents intervenants autour du site LinuxFr.org : l’idée est tenir tout le monde au courant de ce qui est fait par les rédacteurs, les admins, les modérateurs, les codeurs, les membres de l’association, etc.

    L’actu résumée ([*] signifie une modification du sujet du courriel) :

    Avertissement

    Ceci est un second message pour prévenir certains de nos visiteurs qui nous transmettent inutilement des infos sensibles via leur lecteur de flux RSS/Atom, infos qui se retrouvent stockées dans nos logs web.

    Format par défaut d'un log du serveur web Nginx (source) :

    log_format combined '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent"';
    

    Certains utilisateurs nous transmettent leur nom d'utilisateur distant (pas forcément gênant, mais inutile).

    Par contre, certains nous transmettent leur nom d'utilisateur ET leur mot de passe. On a ainsi leur nom d'utilisateur dans le champ remote_user mais aussi leur nom d'utilisateur et leur mot de passe en clair dans le champ http_referer, sous la forme http://login:pass@linuxfr.org/journaux.atom ou https://login:pass@linuxfr.org/news.atom. Cela concerne 6 utilisateurs différents (tous utilisateurs de FreshRSS), dont 1 a été identifié et contacté en privé. Pour les cinq autres, à savoir Jeoffrey, jm, lionel, SVNET et titoko, je vous suggère d'arrêter de nous envoyer votre mot de passe, puis de changer de mot de passe étant donné qu'il a fuité, et aussi d'utiliser préférentiellement la version HTTPS du flux souhaité. N'hésitez pas à me contacter en privé si vous avez des questions (oumph CHEZ linuxfr.org).

    La version FreshRSS 1.11.0 du 2018-06-03 corrige ce problème Strip HTTP credentials from HTTP Referer in SimplePie #1891.

    Statistiques

    Du 16 au 31 mai 2018

    • 1371 commentaires publiés (dont 11 masqués depuis) ;
    • 344 tags posés ;
    • 99 comptes ouverts (dont 9 fermés depuis) ;
    • 33 entrées de forums publiées (dont 1 masquée depuis) ;
    • 32 liens publiés (dont 1 masqué depuis) ;
    • 26 dépêches publiées ;
    • 30 journaux publiés (dont 1 masqué depuis) ;
    • 3 entrées nouvelles, 1 corrigée dans le système de suivi ;
    • 0 sondage publié ;
    • 2 pages wiki publiées (dont 1 masquée depuis).

    Listes de diffusion (hors pourriel)

    Liste webmaster@ - [restreint]

    • R.A.S.

    Liste linuxfr-membres@ — [restreint]

    • R.A.S.

    Liste meta@ - [restreint]

    • R.A.S.

    Liste moderateurs@ - [restreint]

    • [Modérateurs] Dépêche Refaire linuxfr
    • [Modérateurs] contenu problématique
    • [Modérateurs] nfsw
    • [Modérateurs] URL d'une dépêche

    Liste prizes@ - [restreint]

    • R.A.S.

    Liste redacteurs@ - [public]

    • R.A.S.

    Liste team@ - [restreint]

    • [team linuxfr] Optimize MySQL
    • [team linuxfr] Login/mot de passe envoyé en clair dans une URL HTTP sur LinuxFr.org
    • [team linuxfr] Login/mot de passe envoyé en clair dans une URL HTTP sur LinuxFr.org
    • [team linuxfr] Login/mot de passe envoyé en clair dans une URL HTTP sur LinuxFr.org
    • [team linuxfr] Test passage en Jessie
    • [team linuxfr] Joker.com: Your domains are about to expire (expiration report)

    Liste webmaster@ — [restreint]

    • R.A.S.

    Canal IRC adminsys (résumé)

    • mises à jour de sécurité
    • le support sécurité normal pour Debian GNU/Linux 8 Jessie s'arrête au 17 juin
    • expiration du certificat au 3 juin et discussion sur le renouvellement
    • deux conteneurs mis à jour en Jessie, en attendant le passage en Stretch
    • le conteneur de développement redirige tout le trafic en HTTPS désormais
    • une boucle de courriels entre un système de ticket et notre gestionnaire de liste de diffusion
    • travaux en cours pour nettoyer le dépôt git d'administration système (avec des fichiers générés par l'outil d'automatisation Ansible notamment)

    Tribune de rédaction (résumé)

    • Migration de GIMP vers GitLab ajoutée dans la dépêche sur la 2.10.2
    • Demande de retours sur la dépêche GrafX2 par le développeur principal
    • Une correction post-publication

    Tribune de modération (résumé)

    • du spam (dont un robot réutilisant des extraits de phrases)
    • modération d'une image déplacée
    • expiration de notre certificat X509 Gandi Wildcard au 3 juin
    • évocation du renouvellement du CNNum (on aurait pu mentionner les entrées au comité de prospective de la CNIL)
    • migration de deux conteneurs en Debian Jessie

    Commits/pushs de code https://github.com/linuxfrorg/

    • Merge pull request #222 from fredplante/master
    • Fix typo
    • (svgtex) fixes duplicate xlink attribute on svg result
    • (epub) Use https for LinuxFr.org URLs

    Divers

    • Geek Faëries du 1 au 3 juin : conférence « LinuxFr.org, 20 ans que ça geeke » et table ronde « Ces plates‐formes du Libre qui soutiennent les communautés » avec l'Agenda du Libre et En Vente Libre. Plein de mercis à Bookynette pour le Village du libre, à l'équipe organisatrice des GF, et à Marco et Marius pour l'hébergement.
    • Proposition de conférence soumise + table ronde + demande de stand pour les RMLL 2018 Strasbourg

    Commentaires : voir le flux atom ouvrir dans le navigateur

  • AlterncCamp c'est dès jeudi 21 juin (Journaux LinuxFR)

    Salut

    Ayant déjà fait la dépéche et que le temps est passé, j'en profite pour rappeler que jeudi, vendredi et samedi il est possible d'aider à l'avancée du projet alternc

    Commentaires : voir le flux atom ouvrir dans le navigateur

  • Gnome et Logitech collaborent pour vous proposer des mises à jour de leur solution Unify (Journaux LinuxFR)

    Unify est une technologie propriétaire de Logitech qui permet de connecter plusieurs périphériques sans fils sur une machine avec un seul petit appareil USB.

    Logitech n'a jamais officiellement supporté Linux comme système d'exploitation, mais leur appareil fonctionne plutôt bien avec Linux et le logiciel "solaar" qui permet de configurer vos périphériques sur la clé USB sans passer par Windows.

    Seulement, plusieurs vulnérabilités ont été découvertes dans le protocol de communication Unify et Logitech a poussé sur les OS supportés une mise à jour du firmware pour leurs appareils Unify. Évidemment, comme Linux n'est pas supporté, il n'y a pas eu de mise à jour pour ce système d'exploitation.

    Comme Richard alias "hughsie", développeur GNOME travaillant chez Red Hat, l'explique, la vulnérabilité permet de prendre contrôle de votre machine à une distance de plus ou moins 50 mètres, ce qui rend assez dangereux de s'aventurer dans un café avec cet outil branché.

    Heureusement, GNOME a à disposition depuis quelques versions l'outil Gnome Software qui est capable de chercher sur Internet des mises à jour de firmware et de les appliquer graphiquement (la partie de recherche et de mise à jour est faite par le logiciel "fwupd"). Ainsi, Richard a pu entrer en discussion avec Logitech pour demander de la documentation sur le pocessus de mise à jour du firmware Unify.

    Nous pouvons remercier Logitech d'avoir accepté de collaborer avec Richard, car ils ont même accepté ensuite de publier les mises à jour sur un environnement public accessible donc par Gnome Softwaire. En plus, ils proposent maintenant la mise à jour sous forme de binaire utilisable directement par Linux au lieu de devoir le récupérer depuis le fichier ".exe" de Windows.

    Si vous voulez faire la mise à jour le plus vite possible, Richard explique à la fin de l'article comment activer le dépôt "testing" nécessaire pour l'instant pour appliquer la mise à jour avec "fwupd".

    Source:

    Lire les commentaires

  • Compilation de VSCode sous Centos 6 (Journaux LinuxFR)

    Il y a quelques mois, le camarade freem< nous avait fait part de ses déception concernant VSCode parce qu'il ne trouvait pas matière à troller de manière satisfaisante.

    J'ai voulu me faire mon propre avis et l'essayer par moi même. Malheureusement, ma machine pro est une Centos 6 et la libc disponible beaucoup trop vielle. Impossible de l'essayer et donc de partager avec vous mes impressions pertinentes et de kalitay :(. Quelques moules m'ont gentiment expliqué que je n'avais qu'à me sortir les doigts du fondement et le compiler moi même, que si je voulais vraiment, je pouvais.

    Plusieurs mois plus tard, j'ai enfin trouvé le temps et la motivation d'essayer. Et à ma grande surprise, ce fut plutôt facile.

    # Installation d'une version décente de GCC, python et git depuis les dépots 
    # Softawre Collections
    sudo yum install centos-release-scl
    sudo yum install devtoolset-7 python27 rh-git29
    
    # Installation de NodeJS et Yarn
    curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash -
    curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
    sudo yum install nodejs yarm
    
    # Activation de l'environnement de compilation
    scl enable python27 devtoolset-7 rh-git29 bash
    
    # Récupération des sources de VSCode
    git clone https://github.com/Microsoft/vscode.git
    cd vscode
    
    # Augmentation de la limite du nombre de fichiers ouverts à 166384
    # (il peut être nécessaire de modifier /etc/security/limits.conf pour atteindre
    # cette valeur)
    ulimit -n 166384
    
    # Récupération des dépendances
    # (On défini la variable CXX parce que sinon un des makefile utilise 
    # /usr/bin/g++ qui ne supporte pas C++11 )
    CXX=$(which g++) yarn
    
    # Construction du paquet
    yarn run gulp vscode-linux-x64-min
    
    # "Instalation"
    mv ../VSCode-linux-x64 ~/opt/vscode

    Et voilà ! À moi les joies des d'un éditeur moderne !

    $ ~/opt/vscode/bin/code-oss
    /home/killruana/opt/vscode/bin/../code-oss: error while loading shared libraries: libgtk-3.so.0: cannot open shared object file: No such file or directory

    Lourd est le parpaing de la réalité sur la tartelette aux fraises de nos illusions. :'(

    Rendez-vous dans quelques mois pour la suite de mes aventures avec vscode.

    Commentaires : voir le flux atom ouvrir dans le navigateur

  • RyDroid Web Proxy (1.0) : outil de capture de sessions Web (Dépêches LinuxFR)

    Pendant l’année scolaire 2016-2017, j’étais en dernière année d’école d’ingénieurs
    (l’ENSICAEN). J’ai donc fait un stage de fin d’études (à Orange, en France), avec le rapport qui va avec. J’ai fait un logiciel libre qui a été publié. En conséquence, il m’a paru logique de publier mon rapport, après avoir enlevé quelques parties (remerciements, présentation du collectif de production, conclusion personnelle, etc.) et fait de petites retouches pour qu’il soit cohérent avec ce nouveau format et la visibilité qui va avec. Cela permet de présenter plus largement ce que j’ai fait, tout en expliquant le pourquoi et comment, ce qui pourrait servir à d’autres personnes.

    Logo de CLIF Web Proxy (nom originel de RyDroid Web Proxy)

    Sommaire

    Le sujet

    Celui qui a été mon tuteur de stage participe activement au développement d'un outil de test de performance à travers le réseau, qui s'appelle CLIF et qui est présenté plus loin dans cet article. Le cas le plus courant est le test pour le web, avec le protocole HTTP et sa version chiffrée HTTPS. Pour faciliter l'usage pour ce cas commun, il faut que créer un scénario de test pour ce dernier soit aisé.

    Il existait déjà une solution : un proxy pouvait être configuré dans le navigateur web pour intercepter les flux réseaux et ainsi enregistrer les informations pertinentes dans le format adéquat (basé sur XML) pour rejouer une session web avec CLIF. Configurer un proxy dans un navigateur web peut être difficile pour certaines personnes ou perçu comme tel. De plus, le proxy ne gère pas le HTTPS (qui est de plus en plus courant), bien qu'il aurait été possible d'en ajouter la gestion, cela aurait nécessité d'ajouter un certificat dans le navigateur web. Mon tuteur voulait un outil plus simple à utiliser et qui gèrent le HTTPS, d'où ce stage.

    Comme CLIF, l'outil réalisé devait être du logiciel libre sous licence GNU LGPL en version 3.

    État de l’art

    Outils de test de charge

    La liste n'est pas exhaustive, mais il y a un article sur Wikipédia en anglais si on en désire une qui cherche à l'être. Cette partie a pour intérêt de présenter rapidement des outils cités plus loin dans l'article présent et de mettre en perspective le programme de mon tuteur de stage.

    Apache JMeter

    JMeter est un logiciel libre de la fondation Apache. Il est très populaire et packagé par au moins Debian et Trisquel GNU/Linux. Pour définir un test de charge, il faut lui soumettre un fichier XML. Il est extensible avec des modules complémentaires.

    Logo de Apache JMeter

    Gatling

    Gatling est un logiciel de test de charge, avec un focus sur les applications web. Il est sous licence Apache 2.0, donc libre. Il est écrit en Scala. Il est packagé par au moins Debian et Trisquel GNU/Linux.

    Selenium

    Selenium est un logiciel pour automatiser la navigation web à travers un navigateur web. Il peut donc servir à faire des tests, mais aussi automatiser des tâches administratives se faisant via le Web. Il est libre via la licence Apache 2.0.

    Tsung

    Tsung est un logiciel de test de charge distribué. Il gère différents protocoles (dont HTTP, XMPP, LDAP, et MQTT). Il est libre sous licence GNU GPL version 2.0. Le langage de programmation utilisé est Erlang. Il prend en entrée un fichier XML. Il est disponible sous forme de paquet dans au moins Trisquel GNU/Linux et Debian.

    Logo de Tsung

    Locust

    Locust a la particularité d'utiliser des scripts en Python pour définir le comportement des utilisateurs virtuels, alors que les autres outils utilisent généralement du XML et/ou une interface graphique. C'est un logiciel libre sous licence "MIT".

    Logo de Locust

    The Grinder

    The Grinder est un framework pour le test de charge. Il est adapté pour le test distribué sur plusieurs machines. Il est libre et écrit en langage Java.

    Taurus

    Taurus a pour but de cacher la complexité des tests fonctionnels et de performance. Il fait cela en étant une enveloppe pour JMeter, Gatling, Locust, Grinder, et Selenium WebDriver. Il prend en entrée un fichier au format YAML. C'est un logiciel libre sous licence Apache 2.0.

    Logo de Taurus

    CLIF

    CLIF est un logiciel libre initié, piloté, et maintenu par celui qui a été mon tuteur de stage (Bruno Dillenseger). C'est un acronyme récursif pour "CLIF is a Load Injection Framework". Ce projet est hébergé par le consortium OW2. Il est écrit dans le langage de programmation Java. Il a une interface en ligne de commande et une interface graphique sous forme de module complémentaire pour Eclipse. Il propose plusieurs manières de définir un test de charge, comme cela est expliqué dans une sous-sous-section (de cet article) partiellement dédiée. Il n'y a pas de paquet Debian, notamment à cause des nombreuses dépendances et d'au moins une dont les sources n'auraient pas été retrouvées.

    Logo de CLIF

    CLIF permet de déployer des injecteurs de requêtes répartis pour mesurer les temps de réponse. Il permet également de déployer des sondes afin de mesurer la consommation des ressources (processeur, réseau, mémoire, disque, etc.). Son environnement de scénario ISAC offre une façon formelle de définir les scénarios sous forme de comportements d'utilisateurs virtuels et d'une spécification du nombre d'utilisateurs virtuels actifs de chaque comportement au cours du temps. CLIF a été spécialement conçu pour être rapidement adaptable à toute sorte de cas de test (un assistant Eclipse permet de définir ses propres modules complémentaires pour intégrer de nouveaux protocoles ou de nouveaux jeux de données), y compris des hauts niveaux de charge (comme des centaines d'injecteurs et des millions d'utilisateurs virtuels). En pratique, CLIF est utilisé pour des tests de tenue en charge, mais également pour des tests fonctionnels, des tests en intégration continue et de la supervision de qualité d'expérience utilisateur, notamment via son module complémentaire pour Jenkins.

    Le code source est sur l'instance GitLab de OW2, à part le module complémentaire pour Jenkins qui est sur GitHub. CLIF est aussi disponible sur la forge historique de OW2 (qui propose des versions compilées).

    Loads et Molotov

    Loads et Molotov sont libres et écrits en langage Python. Ils permettent d'écrire des tests unitaires. Loads est développé et testé sur Python 2.6 et 2.7, tandis que Molotov nécessite Python 3.5 ou plus.

    Logo de Loads et Molotov par Juan Pablo Bravo

    HPE LoadRunner

    HPE LoadRunner est un logiciel privateur de test de charge, qui ne fonctionne complètement que sous Microsoft Windows. Il peut être étendu via des formats d'autres outils (comme JMeter) et des scripts dans différents langages (comme C et Java). Sa première version date de l'an 2000, il est depuis toujours amélioré, ce qu'il lui a permis d'acquérir une place importante dans le domaine du test de charge.

    megaLOAD

    megaLOAD est présenté comme étant une plateforme en ligne de test de charge qui serait facile à utiliser et capable de monter à l'échelle. Il aurait été spécialement créé pour tester les services de type back-end ayant vocation à être très robustes. Il est fait par Erlang Solutions. Il gère HTTP et serait suffisamment extensible pour gérer n'importe quel protocole. Il serait possible de l'utiliser via un navigateur web et/ou une interface de programmation RESTful. Il est disponible sur AWS (Amazon Web Services).

    Siege

    Siege est un outil libre pour tester la capacité de charge des implémentations des protocoles HTTP(S) (version 1.0 et 1.1) et FTP. Il est écrit en langage C et fonctionne sur divers systèmes d'exploitation POSIX (comme GNU/Linux et des BSD récents, mais pas Windows). Il est libre sous la licence GPL en version 3.0.

    Outils de capture d’utilisation Internet

    Différentes organisations proposent des services web pour l'injection de charge. Certaines d'entre elles proposent un outil pour facilement capturer une session d'usage du réseau, ce qui permet ensuite de la rejouer facilement.

    On pourrait naïvement penser que tcpdump, Wireshark, ou Scapy sont de bons candidats sans rien faire. Ce serait vrai si les communications passaient toutes, ou au moins une vaste majorité, en clair sur les réseaux et que cela n'était pas amené à changer. En effet, elles sont de plus en plus chiffrées (avec une accélération depuis 2013 suite aux révélations d'Edward Snowden), ce qui permet de "garantir" (par les mathématiques) la confidentialité de ce qui est chiffré (il y aura toujours un minimum de méta-données non chiffrées). Il faut donc trouver un moyen de contourner le chiffrement quand il y en a, ce que tcpdump, Wireshark, et Scapy ne font pas automatiquement. De plus, ces derniers montrent une quantité de détails techniques inutiles pour l'individu (dans notre contexte) et qui pourraient le perturber (par peur de l'inconnu et/ou difficulté à percevoir ce qui est pertinent).

    NeoLoad

    NeoLoad Recorder est une application qui enregistre un parcours utilisateur fait à travers un proxy. Pour cela, il crée un proxy sur la machine sur laquelle il est exécuté. Ensuite, il génère un certificat X.509 qui va servir à déchiffrer les échanges chiffrés via TLS. Puis, il démarre Firefox dans lequel il faut configurer le proxy et ajouter le certificat si on souhaite enregistrer les communications chiffrées via TLS. Après cela, il n'y a plus qu'à naviguer. Une fois que l'on veut arrêter, il faut penser à enlever le proxy (mais on s'en rendra vite compte si on oublie), et ne plus faire confiance au certificat (ce qui ne sera rappelé par aucune erreur).

    Cette solution technique est problématique si on doit passer par un proxy pour accéder à un réseau sur lequel le site web à tester est accessible. Techniquement, il est écrit en Java. Les données sont enregistrées dans un format inconnu et non trivial.

    Schéma du fonctionnement de NeoLoad Recorder

    HPE StormRunner Load

    HPE StormRunner Load est un service distant pour faire du test de charge et en analyser les résultats. Il est basé sur du logiciel privateur et se manipule via une interface web. Pour faciliter son usage, divers outils (non libres) sont mis à disposition.

    Pour rendre aisé la capture de la navigation web, il propose 2 outils : TruClient Lite et TruClient Standalone. Ils ont pour but de capturer (directement) ce qui se passe dans un navigateur web (donc sans proxy externe et sans certificat pour le HTTPS). TruClient Lite est un module complémentaire pour Chromium (et donc son principal dérivé Google Chrome), qui utilise les paramètres de proxy du navigateur web. TruClient Standalone est un logiciel (fonctionnant uniquement sur Windows) qui peut au choix se baser sur les moteurs de Firefox (Gecko), Chromium, ou Internet Explorer, mais également simuler un mobile ou une tablette (en configurant correctement la résolution du navigateur web et son agent utilisateur), il prend les contrôles sur le proxy du navigateur web. L'absence de contrôle sur le proxy est problématique si on doit passer par un proxy pour quitter un réseau interne, mais il est possible de lui indiquer un proxy après que le script soit généré. Ils enregistrent les clics sur les boutons avec leurs intitulés (même s'ils ne sont pas des liens), et se basent sur l'intitulé des boutons pour naviguer et pas sur les URLs, ce qui est pratique si les références des liens changent. Ils permettent également de rejouer (automatiquement) un script enregistré avec une visualisation graphique, cependant ils sont perdus s'ils essayent de rejouer mais que le texte du bouton n'est pas le même (par exemple à cause de la langue par défaut différente en fonction du navigateur web).

    Schéma du fonctionnement de HP TruClient

    BlazeMeter

    BlazeMeter est une plateforme SaaSS web. Il peut réaliser des tests de charge et montrer des statistiques (en temps réel) qui en résultent. Il propose une API web pour automatiser les tests, par exemple dans le cadre de l'intégration continue (via Jenkins ou un autre outil similaire). Il utilise divers logiciel libres (dont JMeter, Gatling, et Taurus) et gère donc leurs formats de données.

    Pour simplifier les tests web, un outil de capture de session web est proposé, BlazeMeter Proxy Recorder. C'est malheureusement du logiciel privateur. On peut le tester gratuitement pendant 1 mois. Pour l'utiliser, il faut s'inscrire et l'activer. Ensuite, il faut aller dans son interface, ce qui crée un proxy (sans intervention du testeur ou de la testeuse) et un certificat X.509 (souvent appelé d'une manière réductrice certificat TLS). Pour enregistrer ce que l'on fait via un client web, il faut activer le proxy (via un simple bouton) et configurer ce dernier dans notre client web. S'il l'on souhaite que les communications chiffrées soient enregistrées, il faut ajouter un certificat qui va permettre au proxy de déchiffrer avec une de ses clés privées (au lieu d'une clé privée du service web consulté). Au fur et à mesure de la navigation (via le proxy), l'interface graphique de BlazeMeter Recorder montre ce qu'il a capturé. Pour finaliser une session, il suffit de cliquer sur un bouton (de l'interface web). On peut ensuite avoir le résultat sous divers formes (URL pour BlazeMeter, fichier JMeter, fichier pour Selenium WebDriver, ou fichier pour Taurus).

    Schéma du fonctionnement de BlazeMeter Recorder

    SOASTA Cloud Test

    SOASTA Cloud Test est un SaaSS web pour le test de charge et l'analyse des données (en temps réel) qui en sont issues. Parmi les analyses qu'il propose, il a l'originalité de proposer une comparaison du temps de chargement et du revenu généré sur une période. Il permet de choisir où seront géographiquement les utilisateurs virtuels d'un test. Il propose une interface en 3 dimensions avec les flux réseaux qu'il génère sur une carte de la Terre, dont l'intérêt est probablement discutable, mais cela peut être pertinent pour se faire payer le service par un·e commercial·e. Il peut importer des fichiers JMeter.

    Contrairement à certains de ses concurrents, son outil de capture d'usage du réseau fonctionne sur plusieurs protocoles Internet (temps des connexions TCP, DNS, TLS, HTTP, etc.). C'est une machine virtuelle (sous CentOS) qui fonctionne avec VMware Player, ce qui est très lourd (en termes de puissance de calcul, de mémoire vive, et de place dans la mémoire persistante puisque le disque de la machine virtuelle fait 15Go). Ce choix technique le réserve à des informaticien·ne·s ayant du temps ou des personnes ne voulant pas se limiter au Web.

    La réalisation du projet

    Les outils utilisés

    Les outils pour le développement lui-même

    • Système d'exploitation : Debian GNU/Linux 9 "Stretch" (qui devenu stable pendant mon stage, inclut PHP 7, et est vastement utilisé)
    • Éditeur de code : GNU Emacs (parce qu'il ne nécessite pas de souris et qu'il est beaucoup plus léger qu'un environnement de développement intégré)
    • Langage de programmation : PHP 7 (qui a une librairie standard fourni pour le Web, permet la déclaration de type sur tous les types non objets, et a des avantages de facilité d'installation pour les applications se basant dessus comme cela est expliqué dans la partie qui est dédiée à ce sujet)

    Les outils pour gérer le développement

    • Gestionnaire de versions : git ("le gestionnaire de contenu stupide" (d’après son manuel) est un logiciel libre de gestion de versions décentralisé, libre, performant, et populaire)
    • Forges logicielles :
      • tuleap (une forge logicielle, comprenant des outils élaborés de gestion de projets et des possibilités de gestion fine des droits)
      • GitLab (de plus en plus utilisé, pensé avant tout pour les développeurs et développeuses, et je l'utilise pour des projets personnels)

    Les outils pour les tests

    Les outils « annexes »

    Le résultat

    Schéma du fonctionnement de mon proxy en PHP

    Comparaison avec un proxy classique

    Un proxy classique est légèrement plus dur à utiliser. En effet, il faut que l'utilisateur ou utilisatrice configure un proxy. De plus, pour les échanges chiffrés, il faut ajouter un certificat.

    Néanmoins, un proxy classique a un énorme avantage, il est techniquement plus simple, puisqu'il fait moins de choses, et est donc bien plus performant. En effet, le proxy que j'ai réalisé doit détecter puis analyser entre autres le HTML et le CSS, et enfin potentiellement les modifier, ce qui nécessite une puissance de calcul non négligeable si plusieurs agents l'utilisent en même temps.

    « Proxifier » une URL

    Mon proxy n'est pas un proxy "classique", il change les URLs pour qu'elles pointent toutes vers lui, c'est ce que l'on peut nommer la "proxification" d'URL. En simplifiant, cela revient à ajouter un préfixe à l'URL. Techniquement le préfixe est une référence du proxy (nom de domaine, adresse IP, ou nom purement symbolique comme localhost), puis la page qui "proxifie", et enfin le ou les différents paramètres GET à passer à la page.

    Il y a un paramètre obligatoire qui est l'URL de la page à "proxifier". Celui-ci peut contenir des caractères illégaux comme valeur de paramètre GET (comme un point d'interrogation "?" ou une esperluette "&"), il faut donc encoder ce paramètre au moment de la "proxification", et le décoder au moment de son usage. Cela est fait avec les fonctions PHP urlencode et urldecode (pour lesquels il existe des équivalents en JavaScript).

    Il y a aussi 2 paramètres GET facultatifs. Ils ont pour nom proxy-url et proxy-port et permettent d'indiquer à mon proxy d'utiliser un proxy classique (en spécifiant à minima une URL et potentiellement un numéro de port). Il y a d'autres moyens pour cela, mais ce moyen est prioritaire sur les autres. Si au moins un est indiqué, il faut le(s) propager à toutes les URLs à "proxifier".

    Récupérer une ressource Web

    Un proxy réseau sert d’intermédiaire pour récupérer une ressource. La problématique est banale, mais nécessite néanmoins un peu de temps pour être gérée correctement.

    La première approche que j'ai utilisée est d'utiliser la fonction file_get_contents. C'est une fonction de haut niveau qui prend en entrée obligatoire le chemin vers une ressource (du système de fichiers ou via le Web), et retourne le contenu si elle a réussi à l'obtenir. C'est très facile d'emploi, cependant elle a un gros manque : elle ne récupère pas les en-têtes HTTP, or elles peuvent être pertinentes pour rejouer une session web (ce qui pour rappel est la finalité indirecte de mon proxy). Il fallait donc proposer un autre moyen activé par défaut si disponible.

    Il y a une commande et une bibliothèque associée pour récupérer (entre autres) une ressource sur le Web qui est très connu et a de nombreuses options : il s'agit de curl. C'est libre et existe depuis longtemps (la première version date de 1997), ce qui explique au moins en partie qu'il y ait des fonctions pour utiliser curl dans la librairie standard de PHP. Dans les archives officielles de Debian, il est dans le paquet php-curl qui n'est pas une dépendance du paquet php, probablement pour mettre une installation minimaliste de PHP quand toute la librairie standard du langage n'est pas nécessaire.

    Une application web ne se sert pas nécessairement que de l'URL pour définir (et potentiellement générer) la ressource à envoyer. En effet, une ou des en-têtes HTTP de la requête peuvent être utilisées. Il a donc fallu faire suivre les en-têtes du client web envoyés au proxy au service web "proxifié". Cela a pu être fait avec les 2 méthodes de récupération de ressources.

    Certaines URLs commencent par //, ce qui indique qu'il faut deviner quel protocole utiliser. Le moyen employé pour gérer ce cas est de faire d'abord une requête en HTTPS (la version sécurisée de HTTP), puis renvoyer la réponse si elle est non nulle, sinon renvoyer la réponse de la requête en HTTP.

    Mon proxy peut nécessiter de passer par un proxy réseau non transparent pour accéder à Internet ou un autre réseau IP. C'est le cas dans un nombre non négligeables d'organisations, or certaines applications faites en interne peuvent n'être disponibles qu'en externe et le Web regorge d'exemples pour tester mon proxy. Il fallait donc que mon proxy puisse récupérer une ressource en passant par un proxy réseau non transparent. Cela a été implémenté avec les 2 méthodes de récupération de ressources et il y a plusieurs manières de configurer un proxy (paramètres HTTP GET, cookies, et fichiers INI).

    La gestion du HTML

    Il faut "proxifier" chaque URL d'un document HTML. Le HTML se manipule facilement via DOM et peut être parcouru avec XPath. Il parait donc assez simple de gérer le HTML. Ça l'est… dans la majorité des cas, mais quelques cas rares compliquent les choses.

    Dans les cas triviaux, on peut citer (avec l'expression XPath) : des liens avec a@href, des images avec img@src, les scripts avec script@src, les frames avec frame@src, des vidéos avec video@src, et d'autres. Mais comme nous allons le voir, le HTML est plus compliqué que cela.

    Démarrons avec un cas méconnu si on a appris le HTML récemment, car notoirement obsolète : l'attribut background. Il permet de définir un fond avec l'URL d'une image pour un élément HTML. Pour séparer la structure de la forme, il faudrait utiliser du CSS. Mais il reste de veilles pages web et des personnes n'ayant pas mis à jour leurs connaissances, il a donc fallu gérer ce cas. Cet attribut n'est valide que sur //html/body, mais en pratique certains sites web l'utilisent sur d'autres éléments (comme http://www.volonte-d.com/) et au moins Firefox prend en compte ce cas non standard, qu'il a fallu gérer.

    Poursuivons avec un cas inverse, que l'on ne connait bien que si on a des connaissances à jour : les images ! En effet, il y avait un temps où il y avait uniquement img@src. Cependant pour optimiser la bande passante et avoir une image matricielle d'une taille adaptée, il est maintenant possible de proposer plusieurs URLs pour différentes tailles et formats. La balise img peut maintenant avoir un attribut srcset, qui contient une ou plusieurs URLs séparées par des virgules et avec des indications de la qualité (par exemple <img srcset="img1.png 1x, img2.png 2x" />). Il y a également la balise picture qui peut contenir une ou plusieurs balises source qui peuvent avoir un attribut src ou srcset (//html/body/picture/source@srcset a la même syntaxe que //html/body/img@src).

    La naïveté peut laisser penser que les liens sont triviaux à gérer, c'est presque le cas. Les liens commençant par http:// et https:// sont les plus courants et il faut les "proxifier", mais il y a d'autres cas. Tout d'abord, il n'y a pas que HTTP et HTTPS, il y a d'autres protocoles dont il peut y avoir des références sur le Web et qui ne sont pas gérés par mon proxy, le plus courant étant probablement l'historique FTP (File Transfer Protocol). De plus, il y a des liens sans protocoles pour l'attribut href. En effet, il y a des liens d'actions (qui ne doivent pas être "proxifiés"), pour le courriel avec mailto:, pour le téléphone avec tel: (défini dans la RFC 3966), pour le JavaScript avec javascript: (malgré qu'il y ait l'attribut facultatif onclick et un événement associé en DOM 2), et pour une ressource d'un réseau pair-à-pair avec "magnet:". Il y a également des liens avec un protocole implicite ! Ils commencent par // et les clients web les remplacent par https:// ou http:// ou essayent l'un puis l'autre, il faut donc les "proxifier".

    Rediriger une page web peut se faire via HTTP, mais aussi en HTML. L'intérêt de la méthode en HTML est de pouvoir rediriger après un certain temps (en secondes) et potentiellement uniquement s'il n'y a pas de support JavaScript (en utilisant la balise noscript pour faire cette condition). Cela se fait avec une balise meta dans //html/head (et sans autre parent) en indiquant un temps et potentiellement une URL (par exemple <meta http-equiv="refresh" content="5" /> ou <meta http-equiv="refresh" content="0; url=https://example.net/" />). Il faut donc chercher ce genre de balise (par exemple avec /html/head/meta[lower-case(@http-equiv)='refresh' and contains(lower-case(@content), 'url=')] en XPath 2.0), puis extraire l'URL, ensuite la "proxifier", et enfin changer la valeur de l'attribut tout en conservant le temps.

    Pour utiliser du CSS dans du HTML, il y a plusieurs possibilités. La méthode la plus utilisée et recommandée est de faire référence à un ou plusieurs fichiers via une balise meta avec un attribut rel avec la valeur stylesheet en indiquant l'URL comme valeur de l'attribut href. On peut également vouloir inclure du CSS dans le HTML, ce qui est une mauvaise pratique, mais elle est toujours permise par les navigateurs web. Il y a 2 moyens pour cela : la balise style (/html//style[not(@type) or lower-case(@type)='text/css'] en XPath 2.0) et l'attribut style (/html/body[string(@style)] | /html/body//*[string(@style)]). Il faut donc récupérer le CSS puis le "proxifier" et ensuite mettre la version "proxifiée" dans la balise.

    La gestion du CSS

    Je n'y avais pas pensé au début, mais il peut y avoir des URLs dans du CSS. Elles peuvent par exemple servir pour définir un fond avec une image, inclure un autre fichier CSS, ou importer une police d'écriture
    (depuis CSS3 avec @font-face). Puisque le CSS sert pour la mise en page, il n'est pas négligeable, et a donc du être géré.

    J'ai identifié 2 situations où des URLs sont utilisées dans du CSS. La première et la plus courante est avec la "fonction" url en tant que valeur d'une propriété (par exemple background-image: url(image.png);) Le paramètre peut contenir des espaces avant et après. De plus, il peut être entouré d'un séparateur (soit un guillemet simple soit un double guillemet, heureusement que les formes valides en ASCII sont prises en compte). Le deuxième cas est avec l'instruction @import. Elle peut prendre directement une URL (avec les mêmes séparateurs que la "fonction" url) (par exemple @import "style.css";) ou via la "fonction" url (par exemple @import url(style1.css);).

    Même avec la version 7 de PHP (une version récente d'un langage de programmation orienté web), il n'y a pas de manipulateur lexical pour CSS dans la bibliothèque standard. Plutôt que d'ajouter une dépendance potentiellement non maintenue sur le long terme, j'ai écrit du code pour mon cas particulier. Cela a été motivé par le fait que CSS continue d'évoluer et qu'une avancée de ce dernier pourrait casser le fonctionnement d'un analyseur lexical. Néanmoins mon code souffre d'une limitation : il analyse le CSS ligne par ligne, or la valeur d'une propriété peut être définie sur plusieurs lignes (mais c'est peu courant notamment avec l'usage de programmes pour réduire la taille d'un fichier CSS comme clean-css et YUI Compressor). De plus, mon code ne "proxifie" pas toutes les URLs sur certaines lignes longues pour une raison inconnue. Un analyseur syntaxique de CSS pourrait être utilisé pour "proxifier" toutes les URLs (puisque mon code ne gère pas tous les cas), comme PHP-CSS-Parser de sabberworm, cssparser de Intekhab Rizvi, ou celui de Hord (pour lequel Debian a un paquet). Une option pourrait être ajoutée pour désactiver l'analyseur syntaxique au profit de mon code s'il venait à émettre une erreur fatale à cause d'un cas non géré (potentiellement nouveau) de CSS ou d'une approche moins laxiste que les navigateurs web (qui ont tendance à vouloir gérer à tout prix du code même non valide).

    La gestion du HTTP

    Hormis la ressource demandée par une requête HTTP, il peut y avoir au moins une URL pertinente à "proxifier" (mais cette fois à la réception d'une requête et pas en modifiant préalablement les éléments pouvant en engendrer). Un cas a été identifié : l'en-tête Location. Elle permet d'indiquer une nouvelle URL pour une ressource, expliqué autrement elle sert pour faire une redirection. C'est trivial à gérer si on a déjà le nécessaire pour "proxifier" une URL. En effet, chaque champ d'une requête a un intitulé et une valeur séparée par ":" et sur une seule ligne. C'est donc très simple à analyser et par extension de créer une structure de données pour le HTTP.

    La gestion du HTTP ne s'arrête néanmoins pas là. En effet, un serveur web répond à des requêtes HTTP, or le but de mon stage (et du projet qui en découle) est de rejouer une session web. Il faut donc à minima enregistrer les URLs demandées en extrayant chacune du paramètre GET correspondant. De plus, un serveur web ou une application peuvent répondre différemment en fonction des en-têtes HTTP (heureusement sinon aucun logiciel ne les utiliserait et elles seraient donc inutiles). Il y a donc un intérêt potentiel à les stocker (pour pouvoir reproduire exactement une session web) et en enlever certaines (que l'on peut juger superflues). Il a donc été fait en sorte de les enregistrer et des options ont été faites pour en enlever certaines.

    Gérer les formulaires Web

    Les formulaires web représentent un cas spécial. On pourrait naïvement penser que ce n'est qu'une question de HTML. Mais c'est légèrement plus compliqué que cela.

    Pour les formulaires qui utilisent (implicitement ou explicitement) la méthode HTTP GET (/html/body//form[not(@action) or (string(@action) and lower-case('@method')='get') or not(@method))] en XPath 2.0), il s'agit purement de HTML. Les paramètres GET potentiellement présents dans l'URL de l'attribut form@action (qui définit à quelle URL envoyer les données du formulaire) sont ignorés, en effet ce sont les champs du formulaire qui sont passés en paramètres GET. Il faut donc créer un champ dans le formulaire (avec la balise input) pour l'URL "proxifiée" et le cacher (ce qui se fait en créant un attribut type et lui attribuant la valeur hidden).

    Pour les formulaires utilisant la méthode HTTP POST (c'est l'unique autre possibilité), il faut "proxifier" l'URL de l'attribut action s'il y en a un. Une fois la requête POST reçu sur mon proxy, il faut détecter que c'est une méthode POST pour : la renvoyer en méthode POST au service "proxifié" (par défaut c'est la méthode GET qui est utilisée), ne pas essayer de "proxifier" le contenu, et ne pas renvoyer l'en-tête HTTP Content-Length (défini dans la section 14.13 de la RFC 2616) (ce qui peut faire échouer l'appel PHP à curl, probablement dans le cas où PHP ait encodé différemment le contenu et donc potentiellement changé la taille). Bien entendu, il faut aussi penser à enregistrer ces paramètres POST.

    La gestion du JavaScript

    Je n'y avais pas pensé au début (alors que c'est évident quand on fait du web en 2017), mais le JavaScript peut être source de requêtes web. Il faut "proxifier" les URLs de ces requêtes, bien entendu avant qu'elles n'aient lieu. La première idée qui pourrait venir à l'esprit serait d'utiliser un analyseur syntaxique de JavaScript, ce qui serait très lourd et il en existe à priori qu'en C et C++ (comme V8 de Google qui est libre) (mais il est possible d'appeler des binaires issus de ces langages avec PHP). Heureusement il n'y a pas de moyen de faire des requêtes avec le langage uniquement (c'est-à-dire avec des mots-clés de ce dernier), il faut en effet utiliser la bibliothèque standard du JavaScript. En JavaScript, une fonction peut être redéfinie sans erreur, y compris celles de la bibliothèque standard, c'est considéré comme dangereux (à juste titre) par certains, mais cela peut être fort utile dans de rares cas, comme celui présentement décrit.

    2 cas de fonctions à surcharger pour "proxifier" des URLs ont été identifiés et gérés. Dans chaque cas, il faut garder en mémoire la fonction actuelle (peut être qu'un autre script a déjà changé le comportement de base de la fonction), puis créer une nouvelle fonction qui "proxifie" le ou les arguments contenant potentiellement une ou plusieurs URLs, et enfin appeler la fonction à "proxifier" avec les arguments potentiellement modifiés, tout en retournant son résultat si elle en retourne un. Il ne reste ensuite plus qu'à surcharger, en donnant le même nom pour une fonction ou en modifiant le prototype de la classe pour une méthode d'instance (en effet le JavaScript a un système de classe par prototype qui diffère du modèle traditionnel présent par exemple en PHP et Java). Le terme "fonction" doit ici être compris comme une fonction en C ou en PHP, ce qui ne doit pas être confondu avec la notion de fonction en JavaScript, car celle-ci est bien plus large (les constructeurs et les méthodes sont aussi des fonctions et d'ailleurs défini avec le même mot-clé function).

    Le premier cas est facile à deviner, il s'agit de la fonction à laquelle on passe une URL pour une requête AJAX. C'est l'abréviation de "Asynchronous JavaScript and XML" et désigne un moyen de faire des requêtes synchrones ou asynchrones avec le langage JavaScript. Pour cela, il faut créer un objet de classe XMLHttpRequest (on passe ici sous silence partiel le cas de veilles versions d'Internet Explorer de Microsoft), ensuite définir un comportement (sous forme de fonction) pour le changement d'état (envoyé, reçu, etc.) puis utiliser sa méthode open, et enfin envoyer la requête avec la méthode send. Il suffit de "proxifier" le deuxième argument de la méthode open (le premier étant pour la méthode HTTP).

    Le second cas est moins commun et je ne soupçonnais pas son existence. Il s'agit de l'inclusion dynamique (en JavaScript) de balise script avec un attribut src existant et avec une valeur non nulle. Cela déclenche la récupération du script (grâce à son URL issue de l'attribut src), puis l'exécute (ce qui permet d'éviter la fonction eval). Un élément DOM a une méthode setAttribute, il faut donc la "proxifier" quand elle est appelée sur une balise script et ne "proxifier" le second argument (qui correspond à la valeur de l'attribut) que quand le premier argument vaut (en étant insensible à la casse) src (puisque cette balise peut avoir d'autres attributs comme type).

    La configuration

    Un certain nombre de choses est configurable. Il y a 4 catégories : le proxy pour faire des requêtes (une URL et un numéro de port), la capture de session (enregistrer ou pas, en-têtes HTTP à garder, etc.), le journal d'erreurs et d'avertissements (emplacement en tant que fichier, est-il publique ou non, etc.), et l'interface graphique (montrer des aides au débogage ou pas, afficher certains éléments facultatifs ou pas, etc.).

    La configuration se fait via plusieurs sources et sous forme de cascade. En effet, une source peut avoir une valeur indéfinie, mais une source de moindre priorité peut avoir une valeur définie. De plus, certaines sources ne doivent pas pouvoir définir des valeurs pour certaines propriétés. Par exemple, une source venant du client web ne doit pas être en mesure de définir le chemin d'enregistrement du fichier journal (puisqu'il pourrait s'en servir pour écrire un fichier utilisé par une autre application). Pour configurer au niveau du serveur, il faut utiliser un ou plusieurs fichiers INI.

    Les différentes sources de la plus prioritaire à celle qui l'est le moins est :

    • les paramètres GET dans l'URL
    • les cookies HTTP
    • la session PHP
    • un fichier INI spécifique à une catégorie dans le dossier de l'application
    • un fichier INI général pour toutes les catégories dans le dossier de l'application
    • un fichier INI général pour toutes les catégories dans un dossier système
    • les valeurs par défaut (qui sont codées en dur)
    Exemple de configuration (au format INI)
    # Une ligne commençant par un croisillon "#" est un commentaire.
    # Le dièse "♯" ne marche pas.
    
    # Une section aurait pu être utilisée.
    proxy-url=https://proxy
    proxy-port=80
    
    [session-captured]
    save-session=true
    save-cookies=false

    Enregistrement des données

    À chaque fois qu'une ressource est récupérée par le proxy, celui-ci doit pouvoir enregistrer la demande. L'enregistrement se fait dans le format XML, pour sa manipulation aisée (notamment via DOM, XPath, et XSLT), les nombreuses bibliothèques le gérant, le fait qu'il soit standardisé, et qu'il ne demande pas un serveur de gestion de bases de données. Néanmoins, l'enregistrement en XML est "isolé", de sorte qu'il soit facile (en ajoutant le code nécessaire) d'enregistrer dans un autre format (comme le JSON) ou avec un système de base de données (qui ajouterait une dépendance et une lourdeur) et d'ajouter une option pour choisir le format.

    Un client web peut faire plusieurs requêtes simultanées (notamment pour réduire la latence avec HTTP 1). Or cela peut provoquer une écriture simultanée de nouveaux enregistrements, ce qui est presque certain de résulter en un fichier incorrect. Il a donc fallu mettre en place un verrou pour qu'un fichier d'enregistrement ne puisse être utilisé que pour un enregistrement à la fois. Cela a été fait avec la fonction flock (qui se base sur la fonction C du même nom). La mise en place et la gestion du verrou est dans une classe abstraite qui pourrait être réutilisée pour un autre format de fichier.

    Le proxy était à la base mono-utilisateur. En effet, toutes les données enregistrées étaient nécessairement dans un seul et même fichier. Pour que chaque utilisateur/utilisatrice n'ait pas à installer le proxy, il fallait qu'il soit mutualisable et donc capable de gérer plusieurs personnes. Plutôt qu'un processus de création d'un compte (qui aurait été lourd à utiliser et implémenter), un système d'identifiant de session a été mis en place. Concrètement une personne qui demande à créer une session d'enregistrement se voit retourner un identifiant textuel sous forme de cookie HTTP. Cet identifiant est un nombre pseudo-aléatoire (puisqu'il n'y a pas de réel aléatoire en informatique) obtenu avec une fonction réputée sûre pour la cryptographie (donc imprédictible) (dans mon cas la fonction random_bytes de PHP), ce qui permet de s'assurer que l'on ne puisse pas prédire l'identifiant des autres utilisateurs et utilisatrices. L'identifiant est utilisé comme une partie du nom de fichier, or le nom du fichier aurait été très grand avec la valeur en décimale et illisible avec la valeur en ASCII ou unicode, il est donc le résultat d'une fonction qui prend en entrée le nombre aléatoire et retourne une valeur en hexadécimale. La fonction de hashage SHA-512 a été utilisée, car elle a l'intérêt de créer très peu de collisions (2 valeurs d'entrée ayant la même valeur de sortie) et peut compliquer une attaque s'il venait à être découvert que la fonction n'est pas cryptographiquement sûr (puisqu'une fonction de hashage est censée ne pas avoir de fonction inverse).

    À tout cela, il manquait un élément clé. En effet, les données sont enregistrées pour rejouer un "session web", ce qui nécessite d'enregistrer des éléments techniques, mais également la temporalité de ceux-ci. Pour ce faire un timestamp POSIX (c'est-à-dire le nombre de secondes depuis le premier janvier 1970) est enregistré pour chaque requête. Ce format a l'avantage d'être simple et d'être très courant. Néanmoins la seconde (au format entier) n'est pas une unité très précise, puisqu'un client web sur un ordinateur moderne met moins d'une seconde pour demander différents éléments d'une page web, donc une fonction qui renvoie un timestamp avec les micro-secondes a été utilisée (il s'agit en l'occurrence de la fonction microtime).

    Conversion des données

    Les données sont enregistrées dans un format de données en XML. J'ai moi-même inventé ce format qui est simple et reflète la manière dont les données sont manipulées par le proxy. Cependant les données ne sont pas enregistrées pour un usage interne au proxy, mais pour être données en entrée d'un programme de test de performance. Puisque mon tuteur travaille sur CLIF, c'est pour cet outil qu'il était nécessaire (dans le cadre du stage) de proposer un moyen de faire une conversion. Cependant il n'y aurait aucun problème technique à convertir aussi pour d'autres outils similaires.

    CLIF peut jouer un scénario de test avec du code Java (un langage de programmation très répandu) ou avec des données en XML pour ISAC (qui est un jeu de mot recursif : ISAC is a Scenario Architecture for CLIF). Un moyen de convertir pour le format d'ISAC est de loin ce qui est le plus simple et ne pose aucun problème de limitation dans ce cas (il est possible de coder des comportements plus complexes en Java). C'est donc ce format qui a été choisi.

    Convertir un XML en un autre XML est une volonté courante. La structuration de ce format permet d'envisager facilement de répondre à cette volonté, et un langage est même dédié à cela : XSLT. La conversion est presque entièrement faite en XSLT (en moins de 300 lignes de codes), malgré des différences non négligeables (notamment la manière d'enregistrer les en-têtes HTTP). Cela a été fait en utilisant la version 1.0 du langage XSLT, car la version 2.0 apporte très peu et n'est à priori gérée que par 2 implémentations libres (Saxon-B XSLT et Saxon-HE XSLT).

    Le seul élément que je n'ai pas réussi à convertir avec XSLT est le temps. En effet, mon proxy enregistre le timestamp de chaque requête alors qu'ISAC a besoin du temps entre chaque requête. Il faut donc vérifier pour chaque requête qu'il y a en une suivante (ou précédente), puis faire la soustraction des timestamp, pour ensuite ajouter un élément entre les 2 indiquant le temps qui les sépare. Il a donc fallu faire un script, à appeler avant la conversion XSLT, pour ajouter cette pause.

    L'exécution du script et l'appel de la conversion XSLT sont faits en JavaScript sur le client web. L'opération est presque instantanée avec un ordinateur moderne, néanmoins c'est très dépendant de l'ampleur des données à convertir. L'avantage que ce soit le client web qui fasse l'opération est que le serveur ne nécessite pas les ressources pour cela.

    Exemple de données enregistrées par mon proxy
    <?xml version="1.0" encoding="UTF-8"?>
    <session>
      <resource>
        <url value="https://www.w3.org/XML/" />
      </resource>
    
      <pause value="5003.14" unit="ms" />
    
      <resource>
        <url value="http://clif.ow2.org/" />
        <method value="GET" />
        <timeRequest  value="1497965627.5526"
                      unit="ms" type="unix-timestamp" />
        <timeResponse value="1497965627.6498"
                      unit="ms" type="unix-timestamp" />
        <headers from="client">
          <header key="User-Agent"
                  value="Mozilla/5.0 (X11; i686) Firefox/45" />
          <header key="Accept-Language" value="en-us"/>
          <header key="Connection" value="keep-alive" />
          <header key="If-Modified-Since"
                  value="Wed, 28 Oct 2015 15:47:33 GMT" />
          <header key="Cache-Control" value="max-age=0" />
        </headers>
        <proxy url="https://proxy" port="80" />
      </resource>
    </session>
    Exemple de données converties pour ISAC de CLIF
    <?xml version="1.0" encoding="utf-8"?>
    <scenario>
      <behaviors>
        <plugins>
          <use id="replayHttp" name="HttpInjector" />
          <use id="replayTimer" name="ConstantTimer" />
        </plugins>
    
        <behavior id="session">
          <sample use="replayHttp">
            <params>
              <param name="uri"
                     value="https://www.w3.org/XML/" />
            </params>
          </sample>
    
          <timer use="replayTimer" name="sleep">
            <params>
              <param name="duration_arg" value="5003" />
            </params>
          </timer>
    
          <sample use="replayHttp" name="get">
            <params>
              <param name="uri"
                     value="http://clif.ow2.org/" />
              <param name="headers" value="header=User-Agent|value=Mozilla/5.0 (X11\; i686) Firefox/45|;header=Accept-Language|value=en-us|;header=Connection|value=keep-alive|;header=If-Modified-Since|value=Wed, 28 Oct 2015 15:47:33 GMT|;header=Cache-Control|value=max-age=0|;" />
              <param name="proxyhost" value="https://proxy" />
              <param name="proxyport" value="80" />
            </params>
          </sample>
        </behavior>
      </behaviors>
    </scenario>

    L’API Web

    Une API (Application Programming Interface) web basique a été faite. Elle ne s'appuie ni sur XML ni sur JSON (qui sont beaucoup utilisés pour faire une API web). En effet, elle utilise les paramètres GET (en entrée uniquement), les cookies HTTP (en entrée et en sortie), et le contenu HTTP (en sortie uniquement). Elle permet de "proxifier" une ressource, gérer une session (créer, détruire, et en recréer une qui écrase l'actuelle), obtenir les données de la session dans mon format, et d'obtenir la configuration au format HTML (il pourrait être utile de faire de même en JSON et/ou XML). Elle est utilisée par l'application, mais elle pourrait être utilisée par une application tierce. Elle est plus amplement documentée dans un fichier qui est converti en page web et accessible depuis le menu du proxy.

    L’interface graphique

    L'interface graphique est visuellement rudimentaire, mais elle est facile à utiliser et est adaptée à un écran de mobile. La page d'accueil permet de gérer une session (en utilisant l'API web qui peut rediriger vers la page précédente), d'être envoyé sur le formulaire pour "proxifier", de télécharger les données de la session (s'il y en a), et de gérer la configuration.

    Il est possible de télécharger les données de la session telles qu'elles sont enregistées par mon proxy. Il est également possible de télécharger les données converties. La conversion est pour l'instant possible uniquement pour CLIF, mais il serait facile d'ajouter le nécessaire dans l'interface graphique pour d'autres outils similaires. Pour récupérer les données converties, il y a un formulaire pré-rempli avec les données de mon proxy (récupérées via l'API grâce à une requête AJAX) qui fait la conversion dans le format sélectionné au moindre changement dans les données d'entrée dans le client web (pour éviter que le serveur ait à faire ce traitement) et en utilisant "uniquement" du JavaScript (mais le JavaScript peut utiliser du XSLT).

    La configuration se fait via des formulaires. Actuellement, ils sont gérés uniquement en JavaScript, mais il serait possible d'ajouter une gestion sans JavaScript. L'avantage de passer par JavaScript est de pouvoir afficher la nouvelle configuration effective sans recharger la page et sans soumettre le formulaire pour les cases à cocher (en positionnant des cookies dans ce langage et en utilisant des requêtes AJAX avec l'API web pour la configuration).

    L’installation facile

    Il n'y avait aucune certitude que quelqu'un continue régulièrement de développer l'outil, il fallait donc considérer par précaution qu'il n'y aurait que moi qui en aurait une bonne connaissance technique. Il faut donc que l'installation soit facile, même sans moi, pour éviter que ce que j'ai créé tombe dans l'oubli.

    La partie cliente nécessite un navigateur web avec JavaScript, comme Mozilla Firefox ou Chromium, ce qui est très simple à installer et très courant. La partie serveur est faite en PHP (dans sa version 7), qui est très courant pour faire un site web ou une application web. C'est un langage de script sans compilation, il suffit donc d'appeler un script PHP avec un interpréteur adéquat (ainsi que la bibliothèque standard) pour l'exécuter avec succès. Pour appeler automatiquement les scripts via le web, il faut un serveur web gérant CGI (Common Gateway Interface). Il y a pour cela Apache qui est libre (sous licence Apache 2.0), fonctionne sur les principaux systèmes utilisés pour faire serveur (GNU/Linux, les BSD, Microsoft Windows, et Apple macOS), packagé par les principales distributions GNU/Linux (notamment Debian, RHEL/CentOS, et Ubuntu) et est le logiciel faisant serveur web le plus utilisé au monde. Cela n'a pas été testé, mais il ne devrait pas y avoir de problème avec nginx qui est le principal concurrent libre. Les pré-requis pour l'installation et l'usage sont donc, aussi bien au niveau client que serveur, simples et courants, tout en ne nécessitant pas du logiciel privateur.

    Ce que j'ai créé ne s'appuie sur rien de spécifique à un système d'exploitation (y compris pour écrire de potentielles données de sessions et de potentiels journaux d'erreurs ou avertissements) et n'a besoin que de la bibliothèque standard de PHP, déposer le code source à un endroit où un serveur web va chercher des ressources et potentiellement exécuter du code PHP (en version 7) suffit pour installer et faire fonctionner la partie serveur. Cette méthode est simple et ne nécessite que d'avoir des droits d'écriture dans un dossier qu'un serveur web utilise.

    Le paquet Debian

    Il y a de fortes probabilités pour que mon outil soit utilisé sur un système Debian ou un dérivé (comme Ubuntu, Mint, et Trisquel GNU/Linux). La manière propre et usuelle pour installer un élément sur un de ces systèmes est de passer par un ou des paquets Debian (qui sont des archives organisées d'une certaine manière et ont usuellement deb comme extension). Un paquet Debian a des avantages (par rapport à une installation par copier/coller), tels que pouvoir être facilement mis à disposition via un dépôt de paquets, contenir des méta-données (comme la version, un journal des modifications synthétique, et la licence de chaque fichier du paquet source), permettre l'installation automatique des dépendances (avec APT ou un outillage similaire), et il peut être vérifié qu'il suit les bonnes pratiques. Il a donc été décidé de faire un paquet Debian, ou plutôt un moyen automatique et aisé d'en faire un.

    Le plus gros du travail est fait par dh_make, qui est un programme libre qui automatise de nombreuses parties de la construction d'un paquet Debian propre. Hormis le fichier control (qui contient une partie importante des méta-données) et le fichier copyright (qui indique des informations vis-à-vis des auteurs/autrices et des licences), il a essentiellement fallu faire une règle install et une autre uninstall dans le makefile (qui permettent respectivement, par logique élémentaire et convention, d'installer et de désinstaller un projet utilisable) (en utilisant le paramètre facultatif DESTDIR, qui permet par exemple de faire une installation à un emplacement où il n'y a pas besoin de privilèges d'écriture de SuperUser/root) que dh_make utilise automatiquement, comme la règle test (quand elle existe) qui lui permet de tester que les tests passent avant une potentielle construction du paquet.

    La construction est faite avec debuild qui appelle le programme Lintian. Celui-ci fait des tests sur les paquets et signale des erreurs pour les problèmes graves (qui ne sont pas tolérés pour un paquet dans l'archive Debian officiel) ainsi que des avertissements pour les problèmes non significatifs (mais dont l'évaluation pourrait changer à l'avenir) (comme des fichiers sans licence ou l'inclusion de jQuery alors que cette bibliothèque JavaScript est déjà packagée dans libjs-jquery et ne devrait pas être installée plusieurs fois). Toutes les erreurs et avertissements ont été corrigés, mais il y aurait probablement des petites choses à améliorer. La création automatique du paquet en génère donc un de qualité, bien qu'il ne soit pas parfait.

    Possibilités pour améliorer les performances

    • Réécrire le logiciel en langage Go : c'est un langage avec 2 implémentations libres (l'officielle et gccgo), qui peut se compiler en code natif (contrairement à PHP) et est adapté pour le Web (ce dont on peut se douter quand on connait son auteur, à savoir Google)
    • Réécrire les parties nécessitant une puissance de calcul non négligeable en C ou C++ et les appeler en PHP (le C peut aussi être appelé en Go)
    • Actuellement, il y a une classe par cas à gérer (lien, image, formulaire, script, etc.), ce qui permet de décomposer au maximum. Pour les documents HTML, chaque classe fait une requête XPath. Il serait possible d'en faire moins avec une classe qui aurait plus de responsabilités, au détriment de la qualité et maintenabilité du code source.
    • Manipuler le HTML en JavaScript sur le client : cela déchargerait notablement le serveur, mais cela nécessiterait la gestion du JavaScript sur le client et il faudrait arriver à faire les changements d'URL avant que le client web ne les utilise pour obtenir les ressources correspondantes.
    • Mon proxy récupère toutes les ressources demandées, mais il n'a aucun mécanisme de cache, ce qui peut le conduire à demander inutilement une même ressource plusieurs fois. Une solution serait d'implémenter un mécanisme de cache dans mon proxy, cela demanderait du temps mais aurait l'avantage que ce soit intégré et donc installé automatiquement. Une autre solution est de le faire utiliser un proxy web (comme Squid, Polipo, ou Varnish HTTP Cache), ce qui est facile et permet de ne pas recréer la roue, ainsi que d'être optimisé et déjà testé. Cette possibilité d'ajouter un cache n'a d'intérêt que s'il y a plusieurs utilisateurs/utilisatrices, si plusieurs clients web ne partageant pas un cache commun sont utilisés, ou si au moins un des clients web utilisés n'a pas de cache.

    Et après ?

    Il reste des cas non gérés ou mal gérés, comme la "proxification" des URLs dans le CSS, l'attribut pour l'intégrité en HTML, et un problème d'encodage sur de rares sites web. De plus, l'interface graphique est fonctionnelle et simple, mais a une apparence graphique très sobre, ce qui pourrait être changé par exemple avec un style CSS pré-existant comme KNACSS (qui est sous licence WTFPL), Milligram ou Twitter Bootstrap (qui sont sous la licence libre "MIT"). Il y a donc des choses à faire pour améliorer l'existant.

    On peut aussi vouloir aller au-delà. Il pourrait par exemple être intéressant de faire un moyen d'exporter les données pour Apache JMeter et Tsung, qui sont 2 outils libres qui peuvent prendre du XML en entrée et qui sont packagés par la majorité des distributions GNU/Linux. Les flux de syndication (au format Atom et RSS) ne sont pas gérés, or certains navigateurs web les gèrent. De plus, on pourrait imaginer une séparation de l'API web et de l'interface graphique en 2 services différents (mais dont l'un dépend de l'autre), ce qui faciliterait la contribution à une seule des 2 parties et simplifierait la maintenance de chacune.

    Il y a de nombreux tests unitaires, du moins pour PHP (qui représente la vaste majorité du code). Ainsi pour environ 15 000 lignes de codes PHP utilisés dans l'application, il y a environ 10 000 lignes de tests unitaires en PHP (chiffres obtenus respectivement avec wc -l src/include/php/class/* et wc -l tests/php/*, ce qui inclut les commentaires dont les en-têtes pour spécifier la licence de chaque fichier, les lignes vides, etc.). Il y a également d'autres tests automatiques et pas uniquement sur le code PHP. Il y a donc un filet de sécurité si l'on veut contribuer sans casser le fonctionnement et écrire le code en respectant certaines règles (pour qu'il garde une certaine homogénéité et soit donc plus facile à lire que s'il n'en avait pas). Puisque les 2 langages de programmation utilisés sont PHP et JavaScript (on fait ici exception du XSLT qui représente environ 300 lignes de code, ainsi que de HTML et CSS que tout développeur/développeuse web connait), il est facile de trouver une personne compétente pour modifier le code, car ce sont des langages courants et qui ne disparaitront pas avant de nombreuses années.

    Pourquoi ce nom ?

    Le nom originel est CLIF Web Proxy (d'où le logo qui n'a pas été modifié par la suite). C'était trivial et ça reflétait bien le projet, un proxy web pour le logiciel CLIF pour celles et ceux qui auraient directement sauté à cette partie (ou presque). Puisque le logiciel que j'ai produit peut être utilisé comme simple proxy web et qu'il pourrait servir pour d'autres logiciels de test de charge que CLIF, j'ai décidé de lui donner un nom plus général.

    Continuant dans mon imagination prodigieuse, je l'ai nommé RyDroid Web Proxy. Cela permet de rendre hommage au Créateur Suprême. En effet, RyDroid est un pseudonyme qu'il utilise couramment sur Internet. Certains racontent que c'est un mégalomane, tandis que d'autres prétendent qu'il avait bien peu d'imagination (au moins à ce moment là), je vous laisse vous faire votre avis. Après tant d'explications techniques, vous me ou lui (c'est qu'on se perd !) pardonnerez un moment de déconne et ça peut permettre de faire émerger un sourire avant la conclusion (quel sens de la transition !).

    Conclusion

    J'ai réalisé un proxy pour enregistrer une session web et la sauvegarder dans un format pour un outil de test de charge (en l'occurrence CLIF). Il est utilisable en l'état, mais il y a des manques qui peuvent être dérangeants dans certaines situations, et des fonctionnalités additionnelles qui pourraient être plaisantes. 2 moyens simples d'installation sont proposés, ce qui facilite l'utilisation de ma réalisation technique.

    Celle-ci a été publiée via Internet sous une licence libre, ce qui en fait un bien commun. De plus, il ne dépend que de technologies libres, ce qui permet d'avoir un contrôle total sur ce qu'il fait, mais aussi sur son évolution future, à laquelle un ou plusieurs autres contribueront potentiellement. Grâce au copyleft, les personnes distribuant des versions modifiées ont l'obligation légale de mettre leurs apports dans le pot commun, et ainsi créer un cercle vertueux qui ne soit pas basé sur l'exclusivité.

    Bonnes captures Web et vive le logiciel libre !

    Commentaires : voir le flux atom ouvrir dans le navigateur

  • Sortie de Firefox 59 (Dépêches LinuxFR)

    La version 59 de Firefox est sortie le 13 mars. Elle apporte son lot de nouveautés, ses améliorations de performances (notamment pour les utilisateurs de macOS) et un souci toujours accru de protéger la vie privée de ses utilisateurs (versions bureau et mobile).

    Logo Firefox

    Nouveautés communes aux versions bureau et Android

    La navigation en mode privé n’enverra plus le chemin dans l’en‐tête Referer pour éviter le traçage entre sites.

    Nouveautés pour le bureau

    La page d’accueil a été améliorée : elle se charge plus rapidement, il est possible de faire du glisser‐déposer pour réarranger les sites les plus vus et de nouvelles possibilités vous sont offertes pour personnaliser la page.

    Mozilla croit en la décentralisation d’Internet et a ajouté la possibilité pour les extensions de pouvoir attraper les liens dat://, ipfs:// et ssb://, trois protocoles en vue.

    Dans les préférences, une partie sur les permissions (localisation, caméra, microphone, notifications, etc.) a été ajoutée afin de voir quelles sont les autorisations et blocages effectués. Il est également possible de bloquer totalement les demandes, mais Mozilla prévient que cela risque d’empêcher le bon fonctionnement de quelques sites Web.

    Les WebExtensions ont également eu leur lot de nouveautés comme, par exemple, la possibilité d’enregistrer des scripts de contenus de manière dynamique.

    Off‐Main Thread Painting continue d’être proposé à de nouveaux utilisateurs. Dans la version 58 de Firefox, c’était activé par défaut pour Windows. C’est maintenant aux utilisateurs de macOS d’avoir la fonctionnalité par défaut avec la version 59. Et GNU/Linux pour la prochaine version ?

    Les captures d’écran de Firefox peuvent maintenant être éditées (recadrage, annotations).

    La prise en charge des protocoles de communication en temps réel (RTC) a été améliorée. Et la spécification Pointer Events a été implémentée, permettant de mieux gérer les souris, écrans tactiles et autres mécanismes de saisie avec un pointeur.

    Enfin, notons que le moteur de recherche Qwant est dans la liste des moteurs de recherche par défaut pour les utilisateurs de la version française de Firefox 59.

    Nouveautés pour Android

    La compatibilité avec les sites de diffusion vidéo a été améliorée grâce à la prise en charge du protocole HLS (HTTP Live Streaming). Le travail sur les performances continue en tâche de fond.

    Et pour le futur ?

    F-droid

    Firefox pourrait faire son apparition sur F-Droid avec la version 60. En effet, un drapeau --without-google-play-services a été ajouté pour se passer des services Google Play à la compilation de Firefox, ce qui est un prérequis pour rejoindre le marché d’applications F-Droid.

    Blocage des fenêtres modales

    Firefox a été l’un des premiers navigateurs à bloquer les fameuses « pop‐ups ». Depuis, les fenêtres modales en JavaScript sont devenues un moyen populaire, mais tout aussi désagréable, de fournir la même (anti)fonctionnalité. La question de bloquer ces fenêtres modales est à l’étude. Si vous voulez aider, vous pouvez installer l’extension In‐Page Pop‐up Reporter qui va fournir des informations à Mozilla à ce sujet.

    Et du côté des extensions

    Ghostery

    L’extension Ghostery est (finalement) passée sous licence libre MPL 2.0 (mais, personnellement, je continue de préférer uBlock Origin comme bloqueur de publicités).

    Grammalecte

    Grammalecte a sorti une nouvelle version, la 0.6.2. Elle apporte des nouveautés, mais certains utilisateurs ont été surpris par la nouvelle permission demandée, à savoir sur l’API « downloads ». Comme son auteur l’explique, Grammalecte ne s’en sert pas pour espionner les fichiers que vous avez téléchargés, mais juste pour permettre d’exporter certaines données depuis Grammalecte (c’est la seule façon que les extensions ont pour écrire sur le disque dur).

    Commentaires : voir le flux atom ouvrir dans le navigateur

  • Écrire des diagrammes de séquences (Dépêches LinuxFR)

    Les diagrammes de séquences sont très utiles pour représenter le déroulement d’événements au fil du temps. Ils sont par exemple très utilisés pour décrire des protocoles de communication, où les paquets d’information se croisent, se perdent, passent du temps dans les tuyaux.

    Dans la seconde partie de la dépêche, après avoir expliqué leur principe de ces diagrammes, quelques logiciels existants seront listés et un nouveau venu sera présenté.

    Les diagrammes de séquences sont très utiles pour représenter le déroulement d’événements au fil du temps. Ils sont par exemple très utilisés pour décrire des protocoles de communication, où les paquets d’information se croisent, se perdent, passent du temps dans les tuyaux.

    Ces diagrammes comportent :

    • des acteurs, avec leur ligne de vie (un acteur peut représenter une personne, une machine, un processus, un fil d’exécution…). La spécification UML utilise le terme de « participant » ;
    • des messages échangés entre acteurs.

    On fait ces dessins au tableau, puis on les efface, mais parfois on voudrait les inclure dans une page d’un document, ou les envoyer par courriel.

    Logiciels existants

    Des outils logiciels existent, pour générer de tels diagrammes :

    • éditeur de texte (ASCII art) ;
    • Mscgen (http://www.mcternan.me.uk/mscgen) ;
    • éditeurs dits UML ;
    • éditeurs SDL (Specification and Description Language) ;
    • éditeurs de diagrammes : Dia, LibreOffice, Microsoft Visio, etc. ;
    • outils d’ingénierie système (Capella…).

    Mais pour le moment, je ne suis pas satisfait de ceux que j’ai utilisés. Je voudrais les possibilités suivantes :

    • créer un acteur ou le détruire au cours du temps ;
    • croiser les échanges de messages ;
    • perdre un message ;
    • indiquer l’expiration d’un temps imparti (timeout) ;
    • faire une mise en page du dessin sans dessiner (j’entends par là que je ne veux pas passer trop de temps à déplacer à la souris les éléments pour les aligner ou les relier, et puis tout décaler un par un parce que j’ai inséré un nouvel acteur en plein milieu…) ;
    • avoir un logiciel libre et gratuit.

    Si quelqu’un connaît un tel logiciel, je suis preneur.

    Et alors ?

    En attendant, j’ai fait un prototype d’un tel logiciel, que j’appelle pour le moment meseq sur le principe de mscgen :

    • on écrit un fichier texte décrivant le scénario ;
    • meseq génère une image PNG à partir de ce fichier.

    L’avantage de cette approche est la simplicité et la rapidité de développement de l’outil, mais l’inconvénient est que c’est moins ergonomique qu’un éditeur avec rendu WYSIWYG.

    J’ai mis au point une syntaxe rudimentaire pour le fichier d’entrée. Je sais déjà que je vais la modifier pour la rendre plus évolutive.
    Voici un exemple pour illustrer cette syntaxe (fichier .msq) :

    [init]
    actors w3client proxy "" w3server
    
    [scenario]
    
    w3client   ->   proxy   CONNECT
    w3client   <-   proxy   OK
    w3client   ->   proxy   bytes
    proxy      ->   w3server bytes
    :
    w3client  <->   w3server "TLS Handshake\nwhat follows is ciphered"
    :
    :
    w3client   ->    proxy   "GET /index.html"
    proxy      ->   w3server "GET /index.html"
    proxy      <-   w3server "200, index.html"
    w3client   <-    proxy   "200, index.html"
    

    Et voici l’image générée par meseq (plus complète que l’exemple ci‐dessus) :

    example_web.msq.png

    Autre exemple, avec flèches qui se croisent, etc. :

    example_piggyback.msq.png

    Show me the prototype

    Ce prototype est là pour étudier la faisabilité, présenter mes idées et expérimenter.
    Bon, il est codé vite et mal : non documenté, bogué, mal structuré… Bref, un vrai code de goret.

    Ce prototype et les exemples sont sur Github : https://github.com/goeb/meseq.

    On utilise les bibliothèques Cairo et Pango pour dessiner, écrire le texte, puis générer l’image. Elles sont relativement simples à utiliser.

    Il existe d’autres bibliothèques pour dessiner, que je n’ai pas étudiées (et je ne suis pas sûr qu’il existe un moyen simple de les utiliser en Python) :

    • libgd, utilisée par mscgen ;
    • les bibliothèques sous‐jacentes de Graphviz (dont le rendu est agréable).

    Pour la suite

    Les améliorations à faire sont :

    • améliorer le rendu (diagramme plus compact verticalement, réduire les conflits de textes qui se superposent…) ;
    • ajouter des visuels (bloc de commentaire, couleurs…) ;
    • augmenter la qualité de code ;
    • choisir une licence libre.

    Par la suite, je porterai peut‐être ce programme en C ou C++, afin qu’il soit plus facile d’accès pour les personnes ne disposant pas de Python sur leur poste (je pense aux personnes lambda sur système d’exploitation Windows).

    Afin d’orienter les choix qui restent à faire, je serais intéressé par les avis éclairés des lecteurs de LinuxFr.org :

    • utilisez‐vous les diagrammes de séquences ?
    • quels éléments visuels trouvez‐vous indispensables, et pour représenter quoi ?
    • faut‐il rester en Python ou passer en C ou C++ ?

    N. D. M. : voici une liste des liens apparus dans les commentaires du journal :

    Lire les commentaires

  • pydic, une suite d'outil python pour réaliser de la corrélation d'image locale (Journaux LinuxFR)

    Cher journal,
    Je t'écris aujourd'hui pour t'annoncer la venue de pydic. pydic, disponible sous licence GPLv3, est une suite d'outil Python permettant de faire de la corrélation d'image locale. Cette suite d'outil, disponible sous la forme d'un unique module pydic.py, s'adresse plus particulièrement aux mécaniciens expérimentateurs qui souhaitent cartographier les déformations au cours d'un essai mécanique comme un essai de flexion, un essai de traction ou que sais-je encore.

    Bien qu'en anglais, l'image suivante résume bien ce que fait pydic: à partir d'une suite d'image prise au cours d'un essai mécanique, pydic permet de retrouver le champ de déplacement de la zone d'intérêt (définit par l'utilisateur) puis de calculer le champ de déformation associé à ces déplacements. Attention, à ce jour pydic n'est disponible que en anglais, une traduction française viendra peut-être ultérieurement.
    Titre de l'image

    L'un des problèmes récurrents avec la corrélation d'image locale est le "bruit" de corrélation qui affecte très fortement le calcul du champ de déformation. Pour minimiser ce problème, pydic encapsule plusieurs algorithmes de lissage qui permettent de réduire efficacement ce bruit de mesure.

    L'animation suivante montre le résultat obtenu durant un essai de flexion 4 points sur le champ de déplacement. Pour que ces déplacements soient bien visibles, ils sont amplifiés d'un facteur x25 sur l'animation suivante.
    Titre de l'image

    Les résultats des calculs effectués par pydic sont disponibles sous formes de suites d'image (qui ont permis de réaliser l'animation ci-dessus) et sous la forme de fichiers csv qui favorisent l'interopérabilité entre divers logiciels de post-traitement.

    Pour prendre en main facilement pydic, celui-ci est livré avec deux exemples : un essai de traction et un essai de flexion. En plus de cartographier les déformations, ces exemples montrent comment utiliser pydic pour calculer les constantes d'élasticités des matériaux comme le module de Young et le coefficient de Poisson qui sont des constantes d'un tout premier intérêt pour le mécanicien des matériaux.

    Au niveau des dépendances, pydic dépend de matplotlib, numpy, scipy et de opencv2. Vous trouverez certainement les 3 premiers dans les packages de votre GNU/Linux préféré. Par contre, il vous faudra très certainement compiler à la main opencv2 pour pouvoir utiliser pydic.

    Bonne corrélation ! omc.

    Lire les commentaires

  • Partager l'écran de son téléphone avec un PC (Journaux LinuxFR)

    Dans le cadre d'une présentation que je dois faire la semaine prochaine à l'occasion de la célébration des 20 ans de l'April à Brest, j'ai souhaité trouver un moyen de partager un téléphone android avec un PC, en m'imposant les contraintes suivantes :

    • cela doit fonctionner avec n'importe quel téléphone android (pas besoin d'être root ou d'avoir une application quelconque installée)
    • cela doit fonctionner avec un PC équipé de debian Gnu/Linux (parce que c'est ce qui équipe les ordinateurs cibles)
    • n'utiliser que des logiciels libres

    J'ai trouvé un paquet d'outils abandonnés ou ne respectant pas un des critères ci-dessus, finalement je m'en suis sorti avec AndroidScreencast, mais pas en suivant la documentation officielle qui ne m'a pas permis de faire fonctionner l'outil. Je fais donc un journal pour indiquer comment j'ai procédé, ça me permettra de le retrouver quand j'en aurai besoin la semaine prochaine, et ça peut servir à d'autres…

    Préparation du téléphone

    Il faut activer le debug USB sur le téléphone, pour cela :

    • aller dans les propriétés du téléphone
    • appuyer plusieurs fois sur « Numéro de version » ou « build number » jusqu'à que s'affiche un message indiquant que le mode développeur est activé
    • aller dans les options de développement (le menu a dû apparaître dans les propriétés)
    • cocher la case qui va bien

    Connexion du téléphone au PC

    Installer le SDK android :

    sudo apt-get install android-sdk maven git

    Brancher le téléphone au PC avec un câble laissant passer les données, et vérifier que le téléphone est bien vu avec la commande « adb devices » :

        $ adb devices
        List of devices attached
        9d5ac4af    device

    Générer AndroidScreencast

    Installer maven et git si besoin :

    sudo apt-get install android-sdk maven git

    Récupérer les sources de AndroidScreencast :

    git clone https://github.com/xSAVIKx/AndroidScreencast.git

    Générer les cibles :

    cd AndroidScreencast/
    mvn install

    Le répertoire taget/ contient maintenant un fichier androidscreencast--linux.tar.gz : c'est tout ce dont on a besoin

    voir le résultat

    Décompresser l'archive générée où on peut, puis lancer l'application :

    java -jar androidscreencast-0.0.8s-executable.jar

    Résultat du partage d'écran

    Et hop, mieux qu'un simple partage d'écran, on peut carrément contrôler le téléphone depuis son PC !

    Lire les commentaires

  • Les sites de question / réponse (Journaux LinuxFR)

    On ne peut plus nier que l'humanité est prête à fabriquer de manière collaborative une encyclopédie regroupant le savoir de notre univers : Wikipedia. Le mouvement du libre a dépassé l'univers des geeks et des gus dans leur garage depuis de nombreuses années. Les états et les grandes entreprises commencent à s'y mettre, notamment à travers leur démarche d'Open Data.

    Mais cette encyclopédie est loin de répondre à cette grande soif d'apprentissage et de connaissance qui se croise sur la toile. Il suffit de voir le nombre de posts sur les forums, de tickets sur les bugtrackers ou d'email dans les mailing listes pour s'en rendre compte.

    On voit d'ailleurs assez vite les défauts des moyens actuels. Les questions se perdent, les fils de discussions deviennent assez vite fouillis ou sujet à digressions/trolls ou autre cascade de merci ou moi aussi. Sans compter qu'on ne comprend jamais trop ceux qui répondent à ces questions, et notamment les raisons qui les poussent à répondre. Les systèmes de commentaire qui sont actuellement disponible sur les sites de média sont de très bon représentants de ces défauts. On y trouve souvent une kyrielle de propos qui n'ont absolument rien à voir avec le sujet.

    Ce que Jeff Atwood et Joel Spolsky ont développé répond à cette problématique d'une manière qui me semble révolutionnaire. La technologie qu'ils ont développé, qu'on retrouve sur leur cascade de site stackexchange.com, vise très clairement à augmenter significativement le niveau des questions et des réponses que l'on est susceptible de trouver sur un domaine en particulier.

    En complément à Wikimedia qui a créé une communauté et des outils de publications de connaissance de haute qualité, leur site permet d'élever considérablement le niveau des discussions que l'on peut avoir sur un domaine de connaissance. Ils ont mis en place un système très élaboré de méritocratie et d'auto-contrôle par les utilisateurs, qui donnent la part belle à la théorie de l'engagement. Leur système inclut tout un procédé de reconnaissance de ceux qui posent les meilleures questions ou les meilleures réponses.
    Leur système fonctionne un peu comme un jeu vidéo. Il y a des badges, un indice de réputation, des droits d'action sur le site que l'ont peut obtenir après une certaine réputation, etc, etc. Ce sont les membres du sites qui indiquent s'ils pensent que cette question ou cette réponse est une bonne question ou une bonne réponse.

    Il en résulte des sites extrêmement efficace, tant dans la pertinence des questions posées que dans la lisibilité et la qualité des réponses obtenues. Ils publient de manière ouverte leur statistiques sur cette page. On y voit un taux très élevé consultation (3 millions de visites / jour pour le site de programmation), un taux très élevé de réponse (entre 80 et 100% (!)) et un très bon rapport entre le nombre de visiteur et le nombre d'inscrit (1/3).

    AMHA, Ils ont réussi à créer un nouveau moyen d'expression et de partage de la connaissance. Il y a plus d'un membre de ces communautés qui pense, que dans de quelques années, un score élevé de réputation sur l'un de ces sites aura autant de valeurs que 5 ans d'expériences dans le domaine de ce site.

    Leur succès a inspiré David Cuadrado qui a créé une alternative libre en AGPL. On peut l'installer chez soi et le spécialiser sur le domaine de son choix. Elle semble un peu moins élaborée, mais vu que les sources sont disponibles, rien n'empêche de l'adapter à ses besoins :).

    Lire les commentaires

  • Résolution du jeu d'échecs : patience, ça arrive... (Journaux LinuxFR)

    Bonjour,

    un petit journal pour faire la pub d'un article dont je suis co-auteur concernant la résolution éventuelle du jeu d'échecs, et susceptible d'intéresser 1 quelques lecteurs. Par "résolution", on veut dire déterminer, en supposant que les deux joueurs jouent parfaitement, si la partie se termine par une victoire de Blanc, de Noir, ou un match nul.

    Il ne s'agit évidemment pas de mener à bien une telle résolution par des moyens manuels, le jeu est trop complexe pour cela, mais d'évaluer la faisabilité de la chose si l'on recourt à l'assistance des ordinateurs2. L'idée peut être perturbante pour certains joueurs d'échecs : déjà que les ordinateurs ont dépassé les meilleurs joueurs humains, si en plus il existait un programme absolument imbattable, le jeu ne perdrait-il pas de sa saveur ?

    Heureusement pour eux, Claude Shannon avait écrit, en 1950, un fameux article à même de les rassurer : la complexité du jeu d'échecs est telle que même l'utilisation des ordinateurs ne permettra jamais de résoudre le jeu, c'est tout du moins l'idée la plus répandue chez les spécialistes depuis lors. Shannon avait en effet évalué à 10120 le nombre de parties différentes, et à 1043 le nombre de positions différentes3, deux nombres effrayants et hors de portée de nos machines (que ce soit en temps ou en espace) pour un bon bout de temps.

    Or, dans cet article, on explique que le bon nombre à considérer pour évaluer si la résolution d'un jeu est à notre portée n'est pas le nombre de positions différentes, mais plutôt la racine carrée de ce nombre. Dans le cas des échecs, ça donne un nombre de l'ordre de 1020 , dont nous ne sommes plus si loin : en 2007, le jeu des dames anglaises a été résolu avec une quantité de calculs de l'ordre de 1014 . Aussi, plutôt que "si on pourra un jour résoudre le jeu d'échecs", on peut se demander "quand le jeu d'échecs sera résolu". Dans l'article, on donne l'estimation d'une vingtaine d'années encore nécessaires… mais il est possible que ce soit moins.

    L'article est téléchargeable à cette adresse sous licence CC BY-ND. Il explique les rudiments des techniques utilisées pour résoudre informatiquement les jeux combinatoires, et ne contient pas de calculs trop compliqués, aussi il est accessible au plus grand nombre, n'hésitez pas à le lire si le sujet vous intéresse.

    Lire les commentaires

  • L’écriture neutre (Journaux LinuxFR)

    Les problèmes de l’écriture dite « inclusive »

    C’est laide

    Très.

    Cela n’inclut pas toute la monde

    Très bien, ça donne de la visibilité aux femmes. Dans quelques années toutes les « non-binaires » et autres « agenres » risquent de venir râler parce qu’elles se sentent exclues, et on va se retrouver à faire comme les gens sur tumblr avec des pronoms idiotes telles que « xir, fær, … », qu’il faudra réussir à intégrer dans l’écriture « inclusive ».

    L’accessibilité

    C’est très complexe à lire et à écrire (par exemple, sous Windows, à part en installant manuellement la disposition bépo ou quelque chose de similaire, on ne peut pas faire la caractère « · »)

    Ça ne résout aucune problème à l’oral (comment prononcer « agriculteur·ice·s » ?)

    La point (.) possède déjà une sens (la fin d’une phrase), lui en ajouter une nouvelle est donc plutôt gênante.

    L’écriture neutre

    J’ai donc décidé de vous proposer la réforme suivante, que j’appelle « écriture neutre ».

    Les règles sont simples : les genres disparaissent.

    Je pars de la constat suivante : la genre n’a quasiment jamais d’intérêt:

    • pour toutes les objets inanimées, ça ne sert strictement à rien (quelle est l’intérêt de savoir qu’on dit « une chaise » mais « un tabouret » ?)
    • il est inutile de préciser la sexe d’une personne dans 99% des phrases que l’on faite.

    Il est donc possible de n’utiliser qu’une seule « genre », que l’on appellera « neutre ». Cette genre est extrêmement simple à apprendre puisqu’elle est composée exactement comme la genre féminine dans l’écriture « traditionnelle ».
    Ainsi, comme vous avez pu la remarquer jusqu’à maintenant en lisant cette journal, on ne dira plus « Je lis mon gros journal en regardant la télé en attendant que l’avocat m’appelle » mais « Je lis ma grosse journal en regardant la télé en attendant que l’avocate m’appelle ». Les mots comme « un », « le », « mon », « il » disparaissent complètement.

    Dans l’exemple précédente, il est à noter qu’on n’a aucune idée de la sexe (ou la genre) de la dite avocate. Cela peut très bien être une femme ou une homme, mais de toute façon on s’en fiche.

    Si vraiment on a besoin de signaler la sexe de quelqu’une, il suffit alors de la préciser à l’aide d’autres mots par exemple « la personne de sexe féminine », ou « la singe mâle est en colère » voire même « cette homme est grande ».

    Quelques notes supplémentaires

    La mot « monsieur » disparait : lorsqu’on salue une personne, elle est inutile de signaler sa sexe présumée (c’est encore une fois inutile, et de plus certaines personnes peuvent se vexer si l’on se trompe, ce qui peut créer de nombreuses problèmes). On utilisera donc uniquement « madame ». « Monsieur et Madame Dupond » deviendra donc « Mesdames Dupond ».

    Cette règles à de très nombreuses avantages :

    • Malgré une petite période d’adaptation, ça devrait être assez simple à apprendre. C’est simplement une réflexe à acquérir, et non pas une toute nouvelle orthographe.
    • toutes les personnes sont, cette fois, incluses (vu qu’elle n’est aucunement question de genre ou de sexe, même les non-binaires seront ravies)
    • ça passe très bien à l’oral
    • pas besoin de trouver une nouvelle caractère sur nos claviers, et toutes les lecteurs pour aveugles et autres s’en sortiront très bien
    • ça facilite grandement l’apprentissage de la langue pour les étrangers. À l’instar de l’anglais, plus besoin d’apprendre les genres de chaque mots (et Jane Birkin n’aura plus d’excuse pour faire semblant d’inverser la genre des mots alors qu’elle pratique la français depuis des dizaines d’années)

    Vous vous demandez sûrement pourquoi j’ai choisi de baser cette genre neutre sur la genre féminine (de l’écriture traditionnelle) : tout simplement pour éviter toutes les remarques des pseudo-féministes qui vont venir râler parce que « si on ne garde que le masculin, c’est encore pire » ou « ça invisibilise les femmes, olala ». Personnellement, je trouve que se baser sur la genre masculine aurait été plus simple, vu qu’elle faisait déjà office de neutre dans l’écriture « traditionnelle ». Ceci étant dit, je ne suis absolument pas fixée, et on peut très bien choisir l’une ou l’autre, les deux me conviennent.

    Lire les commentaires

  • KDE : Bureaux virtuels et Activités (Journaux LinuxFR)

    Sommaire

    Bonjour !

    Un petit post pour éclaircir un point qui m'a semble difficile à comprendre sur KDE 4 : Les bureaux virtuel et les activités.

    Probablement que la plupart d'entre vous êtent au courant de la différence entre les deux et utilisent au mieux les possibilités liées à ceci, mais je partage mon expérience pour les autres !

    Les plus anciens auront reconnu un article déjà mis en avant sur Linux-fr : kde-43-est-sorti
    Et même revu et amélioré ensuite : kde-46-est-sorti
    Et oui, je vous parle d'une fonctionnalité sortie en 2009 ! Mais assez peu expliquée / détaillée.

    Les bureaux virtuels :

    Ces bureaux virtuels sont, je pense, connus du plus grands nombre car présents dans la plupart ou toutes les distributions et une petite animation connue permet de les faire défiler sous forme de cube ou de cercle. Sous gnome, nous utilisions COMPIZ pour cet effet graphique bienvenu, sous kde 4 cet effet est géré directement par KDE, mais pas toujours activé par défaut.

    Mise en place :

    Par défaut vous avez un, deux ou quatre bureaux préparés d'avance. Pour gérer ceux-ci, leur nombre et leur disposition, nom animation de passage… un simple clic droit sur leur icône dans la barre des tâches, puis configurer : gestionnaire de bureaux.

    Application :

    Ces bureaux virtuels sont censés vous permettre de gérer au mieux l'espace de bureau disponible. Pourquoi censé ? Parce que sur ma distribution, en lançant une application différente par bureau, le simple fait de l’appeler par la barre des tâches la fait apparaître dans le bureau ouvert, au lieu de me changer de bureau…
    Pour régler ce soucis, il faut activer l'option présente dans le gestionnaire de bureau décrit ci-dessus :

    • Composants graphiques différents pour chaque bureau

    On peut alors avoir une ou plusieurs applications dans un bureau virtuel, et basculer entre elles à partir de [alt]+[tab].
    Le basculement d'un bureau à l'autre peut se faire de différentes manière :

    • Cliquer sur le bureau concerné dans la barre des tâches
    • Roulement de la mollette sur un coin de bureau libre
    • Combinaison des touche [ctrl] + {F1, F2, Fn}

    Si toutes les applications sont en plein écran, il n'y a alors que peu ou pas d’intérêt à utiliser cette méthode : Toutes les applications sont disponible sur la barre des tâches. Par contre, le changement à partir de [alt]+[tab] ne se fait qu’entre applications du même bureau. Intéressant, si on souhaite mettre à part son client mail et son lecteur de musique (inutile de transiter par eux entre notre document word, Internet et pourquoi pas l'applet de surveillance de système).
    En fait, une organisation peut être mise en place avec les tâches de fond dans un bureau (musique, client mail), les activités temporaires de fonds (téléchargement, conversion de fichier ou surveillance système), l'activité principale en cours sur un unique bureau…
    Il est bien sûr possible d'afficher l’icône de l'application en cours d'utilisation au sein de chaque bureau ! Cela permet de voir en un coup d’œil sur quel bureau nous souhaitons partir.

    Les Activités :

    Avec tous ces bureaux virtuels ouverts, vous vous dites certainement qu'il n'est pas nécessaire d'en ouvrir d'autres… Oui mais voilà, vous avez toutes vos applications ouverte dans votre barre des tâches, cela deviens un fouillis… et en plus vous avez perdu un temps plus ou moins important à ouvrir toutes ces applications. Vous pourriez les lancer au démarrage, cela ne serait certes pas difficile pour la plupart d'entre vous, mais vous ne souhaitez pas toujours ouvrir toutes ces applications au lancement ? Perte de temps et d'espace. Les activités sont là pour vous.

    Mise en place:

    Pour créer une activité, dans la barre des tâches, le gestionnaire d'activité vous permet de créer une nouvelle activité et de rajouter des widgets spécifique à l'activité en cours. Dans cette nouvelle activité, vous bénéficiez du même nombre de bureau virtuels que précédemment.

    Application:

    • Vous souhaitez faire de la retouche d'image ? Pourquoi ne pas créer une petite activité avec Gwenview, Gimp et votre logiciel d'importation / exportation préféré (Shotwell?).
    • Vous êtes plutôt dirigé vers la musique ? Idem.

    Il est même possible de créer une seconde activité "vierge" dans le but de démarrer une seconde activité non usuelle pour laquelle il serait contre productif de préparer à l'avance une "activité" particulière… nommons la alors activité 2 ou activité parallèle…

    Le basculement entre deux activité peut se faire soit :

    • En sélectionnant l'activité dans la barre des tâches par l'intermédiaire du gestionnaire d'activité
    • En utilisant la combinaison de touches [SUPER] + [TAB]

    Conclusion

    Cette vision des activité reste en cours d'évolution, avec des propositions récentes visant à réunir tous les bureaux ensemble et concevoir les activité comme un focus sur une partie du bureau global
    http://forum.kde.org/viewtopic.php?f=83&t=98076&start=15

    KDE reste à l'écoute de ses utilisateurs. Le but de ces activités et de ce journal est de permettre d'améliorer le flux de travail… J'espère que ce journal aura permis à ceux qui, comme moi, ne connaissaient pas trop le concept d'activité de comprendre le fonctionnement et l’intérêt.

    Lire les commentaires

  • Comment réfuter (Dépêches LinuxFR)

    Dernièrement, quelques commentaires exprimaient leur mécontentement quant à l'atmosphère et aux propos tenus dans les commentaires sur ce site [référence nécessaire].
    J'ai pensé qu'un texte de Paul Graham, intitulé « How to Disagree » serait un bon point. Je le traduis en deuxième partie. Vous pouvez trouver l'original en ligne (si vous voulez lire les deux).

    À la suite du journal des commentaires ont suggéré le livre d'Arthur Schopenhauer L'Art d'avoir toujours raison — aussi appelé La Dialectique éristique) — en complément de lecture. Voir ou revoir le film de Sam Peckinpah La Horde Sauvage peut aussi faire réfléchir sur la nature humaine, méchante ou non. Enfin, la discussion courtoise et rigolote qui a suivi illustre assez bien les niveaux de désagrément.

    Sommaire

    Le web est en train de changer l'écrit en conversation. Il y a vingt ans, les écrivains écrivaient, les lecteurs lisaient. Le web laisse aux lecteurs la possibilité de répondre, et ils le font de plus en plus — dans les fils des commentaires, sur les forums, et sur leurs blogues personnels.

    Nombreux sont ceux qui répondent à quelque chose avec lequel ils ne sont pas d'accord. Ce n'est pas surprenant. Être d'accord ne tend pas à motiver les foules autant que quand on n'est pas d'accord. En outre, il y a moins matière à tergiverser. On pourrait s'étaler sur quelque chose que l'auteur a dit, mais il a probablement déjà exploré les implications les plus intéressantes. Quand on n'est pas d'accord, on entre dans un territoire non exploré par l'auteur.

    Le résultat c'est qu'il y a bien plus de controverse. Ça ne signifie pas que les gens sont plus en colère. Le changement structurel dans la manière dont nous communiquons est suffisant pour en expliquer le tout. Mais même si ce n'est pas la colère qui anime la controverse, il y a un danger que son augmentation puisse rendre les gens plus énervés. En ligne, en particulier, où il est aisé de dire des choses que l'on ne dirait pas en face à face.

    Si nous allons exprimer notre avis contraire de plus en plus, nous devrions le faire correctement et avec tact. Que cela signifie-t-il ? La plupart des lecteurs est capable de faire la différence entre une attaque personnelle, et une réfutation raisonnée et bien construite, mais je pense qu'il peut être bénéfique de mettre des noms sur chaque étape, alors voici un essai de hiérarchie d'expression d'un avis contraire (DH pour Disagreement Hierachy).

    DH0. Attaque directe

    Ceci est la plus basse forme de controverse, et probablement la plus commune. On a tous vu des commentaires tel que celui-ci :

    T'es qu'un con !!!!!!!

    Mais il est important de se rendre compte qu'une attaque directe plus élaborée n'a pas plus de poids. Ainsi, le commentaire

    L'auteur n'est qu'un dilettante dont le nombril est l'unique centre d'intérêt.

    n'est vraiment qu'une version prétentieuse du précédent.

    DH1 Ad Hominem

    Un attaque dite « ad hominem » n'est pas aussi faible qu'une attaque directe. Il se peut qu'elle ait un certain poids. Par exemple, si un sénateur écrit un article explicitant les raisons d'augmenter les salaires des sénateurs, quelqu'un pourrait répondre :

    Bien entendu qu'il a de bonnes raisons. Il est lui-même sénateur.

    Cela ne réfuterait pas du tout l'argument de l'auteur, mais ça aurait du sens d'après le contexte. Néanmoins, ça reste très faible, et s'il y a quelque chose qui cloche avec le raisonnement du sénateur, vous devriez dire ce que c'est ; dans le cas contraire, qu'est-ce que ça change qu'il soit un sénateur ?

    Dire que l'auteur manque d'autorité pour écrire à propos d'un sujet est un variante d'ad hominem — et elle est particulièrement inutile, puisque les bonnes idées proviennent souvent de champs qui n'ont rien à voir. La question à traiter est si l'auteur a vue juste ou non. Si son manque d'autorité l'a poussée à commettre des erreurs, faites donc la lumière sur celles-ci. Dans le cas contraire, il n'y a pas vraiment de problèmes.

    DH2. Réponse à l'intonation

    À ce niveau, on commence à voir des réponses en relation avec l'écrit plutôt qu'avec l'auteur. La plus basse forme étant de s'attaquer à l'intonation que l'auteur a utilisée. Par exemple :

    Je n'arrive pas à croire que l'auteur mette de côté le dessein intelligent d'une manière si cavalière.

    Bien que ce soit mieux que d'attaquer l'auteur, ça reste bien bas. Il est bien plus important que l'auteur ait raison ou pas, que de savoir si la manière dont il l'a dite est plaisante. Et plus particulièrement parce que l'intonation d'un texte écrit est difficile à juger. Quelqu'un d'aigri à propos d'un sujet pourrait se sentir offensé par une intonation que d'autres lecteurs trouveraient neutre.

    Ainsi, si la pire chose que vous pouvez dire à propos de quelque chose c'est son intonation, alors vous ne dites pas grand chose. L'auteur est désinvolte, mais il a raison ? C'est toujours mieux que s'il était grave, mais fourvoyé. S'il s'est trompé, il suffit de dire où.

    DH3. Contradiction

    À ce niveau, on a enfin des réponses concernant le contenu lui-même, plutôt que l'auteur ou la manière dont il s'est exprimé. Le plus simple étant d'exposer l'opposé de ce que dit l'auteur, sans, ou avec peu d'arguments convaincants.

    C'est souvent combiné avec DH2, tel que :

    Je n'arrive pas à croire que l'auteur mette de côté le dessein intelligent d'une manière si cavalière. Le dessein intelligent est une théorie scientifique légitime.

    Une contradiction a parfois du poids, et il arrive que l'exprimer clairement suffise à voir que c'est exact, mais il est habituellement nécessaire d'argumenter correctement.

    DH4. Contre argument

    Au niveau 4, on atteint la première forme de controverse convaincante : le contre argument. Les niveaux précédents peuvent souvent être ignorés, puisqu'ils n'apportent presque rien. Un contre argument peut apporter quelque chose, mais le problème est souvent de comprendre quoi.

    Un contre argument est une contradiction servie avec un raisonnement ou une preuve. Quand il est honnêtement ciblé contre l'argument originel, il peut être convaincant. Malheureusement, il est courant de voir des contre arguments ciblant quelque chose de légèrement différent. Bien souvent, deux personnes se querellant à propos de quelque chose, parlent, en fait, de choses différentes. Il arrive même qu'elles soient tout à fait d'accord, mais elles sont entraînées dans leur chamaillerie et ne s'en rendent pas compte.

    Néanmoins, il est parfois des moments où il est tout à fait légitime de discuter d'un point légèrement différent : quand on sent que le cœur du sujet à été manqué. Mais alors, il faut le dire explicitement.

    DH5. Réfutation

    La forme la plus convaincante est la réfutation. C'est également la plus rare, car elle demande le plus de travail. En effet, la présente hiérarchie forme une sorte de pyramide, dans le sens où plus on monte, et moins souvent on le rencontre.

    Pour réfuter quelqu'un, vous devez probablement le citer. Il vous faut trouver un passage qui vous semble erroné, et expliquer en quoi c'est le cas. Si vous n'arrivez pas à trouver un passage spécifique qui vous semble louche, il se peut que vous ayez à faire à un argument spécieux.

    Généralement, bien que réfuter quelque chose implique une citation, l'inverse n'est pas nécessairement vrai. Certaines personnes citent des parties avec lesquelles elles ne sont pas d'accord, puis se rabaissent à un niveau 3 ou même 0.

    DH6. Réfuter le point central

    La force d'une réfutation dépend de son objet. La plus puissante étant celle dont l'objet est le point central d'un écrit.

    Il arrive que, même à un niveau 5, on voit de la malhonnêteté délibérée, tel que quand quelqu'un réfute des points mineurs d'une argumentation. Parfois, la manière dont son tournées les choses les rends plus proche d'un ad hominem que d'une vraie réfutation. Par exemple, corriger la grammaire ou des erreurs mineures de chiffres ou de noms. Sauf si la crédibilité de l'argumentation dépend de la valeur réelle de ces points, le seul but de les corriger est de discréditer l'auteur.

    Réellement réfuter quelque chose demande d'en réfuter le point central, ou au moins l'un d'entre eux. Cela veut dire que l'on doit s'activer à expliciter le point central que l'on veut réfuter. Une bonne manière de le faire pourrait être la suivante :

    Le point central de l'auteur semble être x, puisqu'il dit :

    « citation »

    Mais ce n'est pas vrai à cause des raisons suivantes :…

    La citation doit réellement représenter le point central de l'auteur. Il est suffisant de réfuter quelque chose dont ce point central dépend.

    Ce que cela signifie

    Nous avons maintenant une manière de classifier les formes de réfutation. À quoi ça peut bien servir ? Une chose que cela ne donne pas, c'est une manière de tirer un gagnant. Les niveaux précédents décrivent à peine la forme d'un écrit, mais non son exactitude. Une réponse de niveau 6 peut tout à fait s'avérer erronée.

    Malgré tout, cela permet de trier. Un argument de niveau 6 peut ne pas être convaincant, mais une réponse de niveau égal ou inférieur à 2 ne l'est jamais.

    L'avantage évident d'une telle classification est de permettre aux gens d'évaluer ce qu'ils lisent. En particulier, cela les aidera à déterrer les arguments malhonnêtes. Quelqu'un d'éloquent peut donner l'impression de vaincre son opposant en utilisant des mots percutants. En fait, c'est probablement la qualité qui définie un démagogue. En donnant des noms aux différents niveaux de réfutations, nous donnons aux lecteurs critiques une épingle pour faire éclater de tels ballons.

    Cela peut également aider les auteurs. La majeure partie de la malhonnêteté intellectuelle n'est pas intentionnelle. Quelqu'un qui s'évertue à s'attaquer au ton dont est présenté un propos peut très bien croire qu'il dit vraiment quelque chose. Se poser, et déterminer le niveau correspondant de l'argumentation peut nous inspirer à dire quelque chose de mieux tel qu'un contre argument, ou une réfutation.

    Mais le plus grand bénéfice de bien réfuter n'est pas de rendre les conversations meilleures, mais c'est de rendre les personnes les tenant plus heureuses. Si vous étudiez ces niveaux, vous trouverez qu'il y a beaucoup plus de méchanceté au niveau 1 qu'au niveau 6. Vous n'avez pas besoin d'être méchant quand vous avez un réel argument à apporter. Même, vous ne voulez pas l'être. Si vous avez quelque chose à apporter, être méchant n'est qu'un encombrement.

    Si augmenter le niveau rend les gens moins méchants, cela les rendra plus heureux. La plupart d'entre eux n'aiment pas spécialement être méchants ; ils le font car ils n'y peuvent rien.

    Lire les commentaires

  • Nouvelle version de développement de GIMP: 2.9.4 (Journaux LinuxFR)

    Sommaire

    Bonjour à tous!

    Nous venons de sortir une seconde version de développement de GIMP: 2.9.4. Pour rappel, la série 2.9.x est la version de développement de ce qui deviendra la série stable GIMP 2.10.x. Il s'agit de la seconde version de développement annonçant 2.10, la précédente étant 2.9.2, sortie il y a 6+ mois.

    Je ne vais pas détailler ce qui est déjà dans la news officielle, notamment car je viens de passer plusieurs heures à corriger, compléter, ajouter des captures d'écran et retravailler celle-ci. Et j'ai la flemme de refaire tout ce travail en français. Donc je vous laisse lire la news. Désolé pour les anglophobes, je sais que vous préféreriez une belle news en français! C'est ma version de journal-marque page.

    Bon pour donner envie, je passe quelques screenshots des fonctionnalités les plus visuelles:

    Les nouveaux thèmes et icones

    Thèmes et Icônes officiels de GIMP

    La prévisualisation des effets

    Pour ceux qui se souviennent, les "effets" sont remplacés dans GIMP 2.9/10 par des opérations GEGL, le nouveau moteur de GIMP où tout traitement d'image est un graphe.
    L'un des premiers effets visibles est la prévisualisation sur le canevas en direct, permettant de tester les paramètres avant de valider, et depuis 2.9.4, la prévisualisation peut être découpée comme un "rideau", soit horizontal, soit vertical, pour voir une partie de son image avec, et sans l'effet. Voici en capture d'écran ce que ça fait (l'image dedans est d'Aryeom Han, la réalisatrice de ZeMarmot).

    Rideau de prévisualisation GEGL

    Peinture symétrique

    Vous vous en souvenez peut-être, j'avais aussi travaillé sur la peinture symétrique, ce qui est maintenant disponible dans GIMP, en 3 modes: miroir (symétrie axiale et centrale), tuile (symétrie de translation) et mandala (symétrie de rotation). Voici un petit gribouillis fait en moins d'une minute par Aryeom Han, encore, pour montrer ce qu'on peut faire avec:

    Peinture symétrique

    Notamment cela rend le dessin de tuiles continus bien plus simple, puisqu'il y a rendu immédiat de l'effet. Cela ne remplace pas totalement les méthodes classiques, quand on part d'une image existante notamment, mais peut être très utile quand on souhaite dessiner ses tuiles à partir de rien, ou pour créer des motifs à répétition sympathiques. :-)

    Autres

    Sinon y a quelques cools fonctionnalités, notamment pour la sélection (le remplissage de trous est vraiment cool. Je suis sûr qu'on a tous eu ces sélections "magiques" qui ont plein de trous), ou le traitement par batch d'images en ligne de commande, mais aussi et surtout un support très avancé de la gestion des couleurs au cœur de GIMP (cela existait déjà, mais sous forme de module et avec énormément moins de fonctionnalités).
    Il y a aussi une meilleure prise en charge des méthodes d'entrée de texte (pour écrire en languages non-occidentaux, en général avec Ibus sous GNU/Linux par exemple) dans l'outil texte, qui laissait vraiment à désirer.
    Entrée de texte

    Voilà. Je vous laisse jeter un œil aux liens pour les détails et pour avoir une liste plus exhaustives des changements car je passe exprès sur le détail. Ce journal n'est pas une release note. :-)
    Par contre, je sais, c'est chiant: nous n'avons pas de binaires pour Linux. Vous devrez soit espérer que votre distribution fasse un paquet (mais c'est une version de dév alors les chances sont maigres), soit trouver une méthode alternative (y a un PPA pour Ubuntu, mais on ne le gère pas!), soit compiler. Windows et OSX auront des installeurs, probablement d'ici quelques jours.
    C'est la vie. Je suis le premier à en être triste et j'aimerais bien un Flatpak (anciennement xdg-app) pour nos versions de sorties (et pas seulement nos nightly).

    Pour ceux qui veulent compiler, le code est dispo en téléchargement.

    Est-ce utilisable en "production"?

    Alors c'est une version taguée "instable" donc je ne vous dirai jamais de remplacer et que tout ira parfaitement. Cela reste à vos risques et périls et si vous perdez des images ou des heures de travail, ou que sais-je encore, ce n'est pas de ma faute! :P

    Mais soyons clair, pour le film ZeMarmot, depuis bien un an, nous n'utilisons que la version de développement. Je parle d'utilisation intensive, plusieurs heures par jour, tous les jours de l'année. Donc pour moi, oui c'est stable, et y a aucune chance de me voir retourner sous GIMP 2.8. GIMP 2.9 est tellement 1000x plus confortable d'utilisation. Et je fais une de mes priorités d'exterminer les crashs. Par contre même si je corrige des bugs Windows de temps en temps, la stabilité est moins garantie sous Windows. On recherche toujours des développeurs Windows, car c'est vraiment la pénurie (chez nous, ils sont — laissez moi compter — 0?). C'est pas énormément mieux pour OSX d'ailleurs.
    Pour ceux qui se rappellent mon outil de cross-compilation Crossroad, j'ai d'ailleurs récemment fait un petit article pour cross-compiler GIMP pour Windows avec crossroad. Si des gens sont intéressés, nous accueillons les bras grands ouverts les dévs Windows (mais bon, on est sur linuxfr, donc les chances sont minces).

    ZeMarmot comme projet contributeur

    Et pour finir, un peu d'auto-promotion de projet! Vous le savez, je "travaille" sur le projet ZeMarmot, un film d'animation fait avec GIMP, et sous licence Creative Commons by-sa.
    Toutes mes contributions à GIMP (192 commits depuis la sortie de 2.9.2 soit en environ 6 mois, c'est à dire un peu plus de 14% des commits de l'intervalle) sont parce que je fais partie du projet ZeMarmot, plus ou moins directement (même si des fois, je corrige juste un bug "comme ça", cela reste parce que nous utilisons cet outil quotidiennement). Dans les nouvelles fonctionnalités, je suis le développeur de la peinture en symétrie, gros contributeur sur l'intégration des brosses MyPaint, le développeur de la bonne prise en charge des méthodes d'entrées dans l'outil texte (Aryeom est coréenne, alors forcément, pouvoir écrire en coréen dans l'outil texte était important!), celui qui a fait revivre le plugin email, mais aussi l'instigateur du renouveau des thèmes/icônes, donc en charge de gérer les contributions de nouveaux thèmes et d'icônes, mais aussi revieweur de nombreux patchs, mainteneurs de certains morceaux de code, etc.

    Pourquoi je dis ça? Parce que nous avons des difficultés à financer notre projet de film, qui, bien qu'associatif, souhaite rémunérer tous les contributeurs dans une optique d'un art libre professionnel (de même que pour le logiciel libre). Nous avons réussi un premier financement, vous vous en souvenez sûrement, mais les sommes récoltés ne vont pas très loin et nous cherchons donc des financements complémentaires.
    Donc si vous aimez ce que je fais pour GIMP, ou si vous aimez GIMP même et appréciez qu'il évolue plus vite, ou simplement vous aimez le projet ZeMarmot, alors ce serait vraiment cool si des gens contribuaient à notre financement mensuel. Nous sommes pour cela sur la plateforme Tipeee, où vous pouvez vous inscrire, même pour juste quelques euros par mois.
    ZeMarmot sur Tipeee
    Si des gens préfèrent payer en dollar US, nous sommes aussi sur la plateforme Patreon.
    ZeMarmot sur Patreon

    Si vous souscrivez à ZeMarmot pour quelques euros ou dollars par mois, non seulement ça nous ferait plaisir d'avoir plus de soutiens, mais en plus, cela renforce notre position vis-à-vis de plus gros financeurs (fondations, organismes de financements…), et finalement vous financez du logiciel ET de l'art libre! :-)

    Dans tous les cas, j'espère que vous apprécierez cette nouvelle version de dév de GIMP pour laquelle nous avons mis beaucoup de cœur à l'ouvrage. Et désolé pour la page pub! ;-)

    Lire les commentaires

  • Auto-hébergement : ma page d'accueil (Journaux LinuxFR)

    J'héberge beaucoup de services sur mon serveur : Roundcube, ownCloud, Tiny Tiny RSS, Munin, phpMyAdmin, mon générateur de mots de passe, …

    Je souhaitais un moyen facile et rapide de passer d'une application à l'autre par une barre de menu. Je vous présente donc mon projet de la semaine : une barre de navigation entre services auto-hébergés.

    Il s'agit d'une iframe en pleine page qui est pilotée par une barre de liens à gauche. Du javascript ajoute quelques fonctionnalités agréables (synchro du titre et de la favicon, création d'URL uniques utilisables en marque page), mais la navigation fonctionne sans.

    Screenshot

    Quelques contraintes cependant :

    • Tous les services doivent être hébergés sur le même domaine (protection contre le cross-site scripting)
    • Quelques applications (ownCloud, phpMyAdmin, …) interdisent par défaut l'intégration dans une iframe. Il faut désactiver cette protection

    J'espère que cela pourra être utile à d'autres geeks, et suis ouvert à toute proposition d'amélioration.

    Page Github du projet

    Lire les commentaires

  • Pâtes à l'huile d'olive ou au beurre ? (Journaux LinuxFR)

    En cette merveilleuse journée de mai, une question me traverse l'esprit. Est-ce que le lectorat de linuxfr préfère les pâtes à l'huile d'olive ou au beurre ?

    En effet, il semblerait que certaines personnes préfèrent les pâtes au beurre, ce qui est choquant, et j'aimerais savoir si ces personnes sont nombreuses.

    Évidemment, quand je parle d'huile d'olive, il s'agit de véritable huile d'olive, et pas quelque chose de coupé acheté en promotion dans une grande surface.

    Ce journal est à mettre en rapport avec le journal demandant si il fallait mettre de l'huile dans l'eau des pâtes. (La réponse est négative).

    Et pour finir, une nimage en rapport.

    Lire les commentaires

  • Un fstab bien configuré pour un ordinateur « de bureau » (Journaux LinuxFR)

    Sommaire

    Bonjour journal de Linuxfr,

    Ça fait quelque temps que je te lis mais c'est la première fois que je t'écris.
    Je suis un auto-didacte avec Linux depuis quelques années mais pas un expert, aussi sois indulgent avec mon niveau technique, modeste.

    Pour un premier journal, je voudrais me pencher sur le fichier fstab (et ce qui en est lié : partitionnement, systèmes de fichier, etc). Ce fichier joue sur le disque dur qui est l'élément le plus lent de l'ordinateur, alors une configuration expliquée et rationnelle pourrait apporter, ne serait-ce qu'un peu, plus de performance et de sécurité à cet organe électronique (et une meilleure compréhension du système pour moi).

    D'abord je vais lister les trucs et astuces utiles que j'ai glané sur le Web, après je te posterai mon fichier fstab et quelques détails sur ma configuration matérielle pour que tu puisses m'aider, si tu le veux, à affiner le paramétrage de ce fichier.

    Les trucs utiles

    Aligner les partitions sur des cylindres du disque dur

    C'est une astuce, dont j'ai perdu la source, mais qui améliore(rait) un peu les performance du disque dur. Je partitionne mon disque dur en utilisant GParted (car il peut créer une partition en les alignant sur un cylindre a contrario de la plupart des installateurs de nos distributions) sur un système Live avant l'installation (où je n'ai qu'à réutiliser les partitions pré-découpées).

    Créer des partitions distinctes

    Pour des raisons de sécurité et de sûreté des données, il est préférable de créer des partitions pour /boot, /var, /tmp et /home (voire /opt pour ceux qui compilent des trucs pour leur système) distinctes de la partition racine /.

    Utiliser un système de fichier optimisé pour les différents usages

    Le système de fichier a une incidence sur les performances du disque dur.
    J'ai trouvé que ReiserFS est préférable pour la partition /var (très performant pour l'écriture des petits fichiers).
    XFS est préférable pour la partition /home, mais on est loin des avantages qu'offre ext4, donc ce dernier resterait préférable.
    Tmpfs est une bonne option pour les dossiers temporaires (/tmp, /var/tmp).

    Y'a-t-il d'autres systèmes de fichier à conseiller pour un usage précis dans le cadre de mon usage ?

    L'option "noatime"

    Cette option désactive la mise à jour des dates d'accès et de modification de tous les fichiers sur la partition concernée par l'option. C'est une option utile pour un serveur mais pas pour nos ordinateurs « de bureau », donc on peut l'ajouter à toutes les partitions dans le cas présent.

    http://tldp.org/LDP/solrhe/Securing-Optimizing-Linux-RH-Edition-v1.3/chap6sec73.html

    Les options "discard" et "data=ordered" (pour SSD uniquement)

    Ces options nécessitent un formatage de la partition en ext4 mais permettent l'activation de ce qu'on appelle communément le TRIM. Ce qui est nécessaire pour contenir l'usure prématurée du SSD.

    https://wiki.archlinux.org/index.php/Solid_State_Drives#Mount_Flags
    http://www.debian-fr.org/ssd-trim-discard-n-est-pas-pris-en-compte-t37357.html

    Mettre /tmp et /var/tmp en RAM

    Pour ce faire, il faut rajouter les deux dernières lignes de mon fstab ci-après.
    La taille allouée à chaque dossier est modifiable par l'option size=*m.

    Ça a pour avantage :
    1. d'accélérer le système car la RAM étant plus rapide que le disque dur.
    2. de réduire l'usure du disque dur (qui n'est plus sollicité car étant remplacé par la RAM).

    Les options "nosuid", "noexec" et "nodev"

    Ces options permettent une réduction - du moins une limitation - des privilèges avec les options de mount. Je passe sur ce que font ces options, il y a le man pour ça.

    1. Ajouter l'option noexec pour toutes les partitions sur le disque dur sauf la partition racine (/), la partition /var° et la partition /home°°.

    2. Ajouter l'option nodev pour toutes les partitions sauf la partition racine (/) et d'éventuelles partitions chroot.

    3. Ajouter l'option nosuid pour toutes les partitions sauf la partition racine (/).

    Je te confesse n'avoir que recopié les conseils donnés dans la source ci-dessous (page 15)
    http://people.redhat.com/sgrubb/files/hardening-rhel5.pdf

    ° : surtout avec Debian et dérivés, Aptitude en souffrirait beaucoup.
    °° : Car cela empêche l'exécution de tout script dans le dossier de l'utilisateur, je trouve cette option pratique pour les ordinateurs des personnes lambda (feu Mme Michu). Prenons l'exemple de cette personne qui utilise son ordinateur pour consulter des méls et télécharger tout et n'importe quoi comme par exemple clique-ici-pour-savoir-qui-consulte-ton-profil-Facebook.sh … Un petit truc silencieux au but obscur qui s'installe en douce dans un dossier caché, à l'insu de l'utilisateur, sans qu'un bon mot de passe ou un système bien à jour puisse y faire quelque chose.

    Exemple personnel

    Ma configuration

    J'utilise un ordinateur « de bureau » comportant un SSD (de récupération) installé en parallèle d'un disque dur. La faible taille du SSD fait que je ne peux me permettre d'y installer l'intégralité du système. Aussi, ai-je décidé de n'installer que les partitions / et /boot sur ce périphérique, plaçant les autres sur le disque dur. J'ai également séparé la partition /var (qui, comme tu le sais, contient entre autre les journaux d'activité) de la partition racine et l'ai placée sur le disque dur (dans le souci de prévenir toute usure prématurée des cellules mémoire de mon disque électronique par des écritures trop fréquentes).

    Fichier fstab

    UUID=XXX       /               ext4        defaults,noatime,discard,data=ordered                                   1 1
    UUID=XXX       /boot           ext4        defaults,noatime,nosuid,noexec,nodev,discard,data=ordered               1 2
    UUID=XXX       /home           ext4        defaults,noatime,nosuid,noexec,nodev                                    1 2
    UUID=XXX       /var            ReiserFS    defaults,noatime,nosuid,nodev                                           1 2
    UUID=XXX       swap            swap        defaults                                                                0 0
    
    tmpfs          /dev/shm        tmpfs       defaults,noatime,nosuid,noexec,nodev                                    0 0
    tmpfs          /tmp            tmpfs       defaults,noatime,nosuid,noexec,nodev,mode=1777,size=768m                0 0
    tmpfs          /var/tmp        tmpfs       defaults,noatime,nosuid,noexec,nodev,mode=1777,size=256m                0 0
    
    

    Et maintenant ?

    Dis-moi, que penses-tu des informations données ci dessus ? Qu'y a-t-il à corriger ? Que pourrais-je rajouter ?
    À propos de la ligne /dev/shm, est-elle vraiment utile ? Je ne sais quoi en penser.

    Merci de ton aide !

    PS : Je n'ai pas tout compris à cette histoire karma et c'est la première fois que j'écris, j'espère que tu jugeras ce journal avec indulgence.

    Lire les commentaires

  • Présentation d'iPXE, un chargeur d'amorçage en PXE (Dépêches LinuxFR)

    Il est parfois nécessaire de faire démarrer une machine sur le réseau (par exemple, une machine sans disque dur) : la technologie la plus courante utilisée sur x86 s'appelle PXE et permet l'amorçage depuis un serveur TFTP. La plupart des cartes réseau modernes intègrent une implémentation de PXE, cependant la spécification ne décrit que le protocole susnommé dont les limitations se font vite sentir sur des configurations un peu complexes.

    Heureusement pour nous, il existe depuis 1995 un projet libre qui a pour but le développement d'un firmware de carte réseau bien plus flexible que ce que l'on peut trouver actuellement, il s'agit d'iPXE.

    Dans la suite de cette dépêche, vous trouverez une explicitation détaillée de l'étape d'amorçage d'une machine ainsi qu'une présentation des possibilités offertes par iPXE.

    Merci à Nÿco, Sébastien Koechlin, ZeroHeure, Xavier Teyssier, Nils Ratusznik, tankey, Xavier Claude, oinkoink_daotter et Benoît pour avoir participé à la rédaction de cette dépêche.

    Sommaire

    Rappels historiques

    Lors de l'apparition des machines sans disque, un certain nombre de protocoles, parfois propriétaires, ont dû être développés pour permettre l'assignation d’adresses à celles-ci. Le premier à être normalisé par l'IETF se nomme (RARP), pour Reverse-ARP, qui ressemble beaucoup, dans sa forme, au protocole ARP. Il n'offre cependant que la possibilité d'assigner une adresse à une machine et ne permet pas de communiquer d'autres informations essentielles comme la localisation d'une image à charger. Pour pallier ces limitations, le protocole BootP a ensuite été mis au point, il a finalement été rendu obsolète par l'apparition de DHCP, qui est beaucoup plus flexible.

    En 1999, Intel et SystemSoft mettent au point Wired for Management (WFM), un système permettant la gestion de machines sans système d'exploitation, WFM décrit également une technique d'amorçage par le réseau, qui est alors nommée Preboot Execution Environment (PXE), et qui permet de télécharger un chargeur d'amorçage et d'offrir à celui-ci une API pour qu'il puisse charger facilement un noyau via le réseau. De nombreux constructeurs de cartes réseau se sont mis à embarquer des ROM d'extensions sur leurs cartes pour permettre l'amorçage par le réseau.

    Bien que six architectures matérielles soient décrites par la spécification, à ce jour seule x86 possède une couverture complète. Cependant, les stations sans disque dur étant un concept assez ancien, on retrouve des solutions rendant un service similaire sur de nombreuses architectures et pour de nombreux systèmes. À noter aussi que l'Unix Libre NetBSD fournit et documente des solutions pour un grand nombre d'architectures. Enfin, SUN Solaris propose un service similaire dans son OpenROM pour son service Jumpstart.

    L'amorçage d'une machine

    L'amorçage d'une machine de type PC à base de processeur x86/x86-64 se fait généralement en plusieurs étapes, chacune ayant pour but de récupérer un exécutable de plus en plus évolué pour enfin arriver à charger le noyau d'un système d'exploitation.

    Amorcer depuis un disque dur

    Pour bien comprendre comment l'amorçage par le réseau fonctionne, il convient de savoir comment se passe l'amorçage « classique », c'est à dire depuis un disque dur.

    Lors de l'initialisation de la machine, le BIOS détecte les périphériques amorçables (disque dur, disquette, CD-ROM…) et tente de les démarrer l'un après l'autre selon l'ordre configuré. Pour cela il charge en mémoire le premier secteur du périphérique (soit ses 512 premiers octets), et vérifie que les deux derniers octets correspondent bien aux valeurs hexadécimales AA 55. Si ce n'est pas le cas, il considère que les données chargées ne sont pas destinées à être exécutées et passe au périphérique suivant.
    Une fois qu'un programme valide est chargé en mémoire, un certain nombre de valeurs sont placées dans les registres du processeur, comme le numéro du périphérique courant par exemple. Enfin, la première instruction du programme est exécutée.

    Dans le cas d'un système Linux, le programme en question est généralement un stage1 de GRUB dont le but va être de lire le contenu de la partition /boot pour en extraire un stage2, qui est un programme bien plus évolué. Il ne faut pas oublier que le stage1 est limité à 510 octets (512 moins les deux derniers octets), ce qui est vraiment peu pour faire quoi que ce soit d'un tant soit peu avancé, d'où la nécessité d'aller chercher un stage2. Heureusement, pour faciliter la vie des concepteurs de chargeurs de démarrage, le BIOS fournit une fonction pour charger un ou plusieurs secteurs d'un périphérique en mémoire. Cette méthode est basée sur une interruption logicielle et le passage des paramètres se fait en utilisant les registres du processeur, la plupart des chargeurs d'amorçage étant écrit en assembleur, ce type d'opération est très facile à réaliser et permet de ne pas avoir à écrire un pilote pour disque-dur, ce qui est très appréciable quand on est limité en taille.

    Le stage2 est alors lancé. Celui-ci peut configurer plus largement la machine (disposition de la mémoire, mode de fonctionnement du processeur, clavier, écran…). Il peut présenter un menu pour permettre de choisir certaines options; et finalement il va récupérer les éléments de l'étape suivante: le noyau d'un système d'exploitation et un éventuel initramfs pour leur passer la main. (Note: Dans le cas de Grub, celui-ci dispose d'une étape intermédiaire, le stage1.5 qui permet de charger des drivers pour les différents systèmes de fichiers et évite d'avoir à réinstaller GRUB à chaque modification de la configuration)

    Amorcer depuis le réseau

    Pour amorcer la machine depuis le réseau, le principe général reste le même, mais, le BIOS n'ayant pas été conçu pour démarrer depuis une carte réseau, il est un peu détourné. La carte va embarquer une ROM d’extension qui sera mise à disposition du BIOS à une certaine adresse. Lors de l'étape du Power-On Self-Test, le BIOS va reconnaitre une séquence d'octets spécifiques indiquant la présence de l'extension. Cette extension de la carte réseau va s'enregistrer comme périphérique amorçable auprès du BIOS qui sera alors capable de démarrer dessus.

    Cette ROM contient un micrologiciel qui est divisé en plusieurs modules :

    • le premier est une pile PXE qui implémente une partie de la spécification PXE et dont le comportement sera détaillé plus bas;
    • le second est une série de fonctions respectant l'API UNDI pour Universal Network Device Interface permettant d'utiliser la carte réseau sans avoir à fournir un pilote. Ces fonctions pourront être utilisées par la pile PXE et par le programme que celle-ci chargera.

    Reprenons le processus de démarrage avec l'exécution de la pile PXE. Son objectif est de récupérer sur le réseau un Network Bootstrap Program (NBP) pour l'exécuter. Pour cela, il faut obtenir une adresse IP afin de pouvoir communiquer sur le réseau, puis localiser, récupérer et exécuter ce NBP. La spécification PXE adresse ces questions en faisant d'une pierre deux coups : le protocole DHCP est utilisé avec deux options particulières : next-server et filename. DHCP est en effet un protocole flexible qui permet de spécifier de nombreux paramètres personnalisés, aussi bien dans la requête que dans la réponse. La norme PXE demande que dans la réponse, le serveur DHCP spécifie dans le paramètre next-server l'adresse IP d'un serveur TFTP et dans le paramètre filename le chemin du fichier NBP sur ce serveur. UNDI proposant dans son API un client TFTP, la pile PXE n'a plus grand-chose à faire, elle va charger le NBP en mémoire puis l'exécuter à son tour.

    Ici les choses varient en fonction du NBP choisi par l'utilisateur. Très souvent il s'agit de PXELINUX, qui fait partie du projet SYSLINUX et qui est en quelque sorte l'équivalent du stage2 de GRUB. Il est capable de chercher à son tour sur le serveur TFTP un fichier de configuration, puis un noyau et un initramfs.

    iPXE

    Historique du projet

    Etherboot

    Le projet Etherboot vu le jour en 1995, avant l'apparition de la spécification PXE donc, il avait pour but développer un microgiciel embarquable dans une ROM d'extension pour BIOS afin de permettre l'amorçage par le réseau, le principe est alors sensiblement le même que celui qui sera retenu par PXE plus tard, la différence principale entre les deux approches étant qu'Etherboot récupérait directement un noyau tandis que PXE passe par un NBP.

    gPXE

    En 1999, Intel publie la spécification PXE, la question de savoir si Etherboot doit abandonner son approche actuelle pour implémenter une pile PXE divise alors les développeurs du projet. Trois développeurs, Marty Connor, H. Peter Anvin et Michael Brown prennent alors la décision de forker le projet, donnant naissance à gPXE. Marty Connor en profite pour créer rom-o-matic.net qui permet de générer des images gPXE facilement et qui connaît un succès rapide.

    Entre temps, le mainteneur d'Etherboot n'ayant plus de temps à y consacrer abandonne le projet qui est donc réintégré dans gPXE.

    En 2006, gPXE participe à la seconde édition du Google Summer of Code, sous l'égide de la fondation linux, à cette occasion, une pile TCP complète est implémentée par un étudiant indien. gPXE participera à tous les Google Summer of Code suivant jusqu'en 2011.

    iPXE

    En 2011, un différend oppose Marty Connor et Michael Brown conduisant à un fork du projet par ce dernier et donnant naissance à iPXE, gPXE ne donnant plus de signe de vie depuis presque un an, il est considéré comme mort à l'heure actuelle.

    En 2012, iPXE participe à la septième édition du Google Summer of Code, prenant la place de gPXE.

    Utiliser iPXE

    Il est possible, à partir des sources d'iPXE, de générer un grand nombre d'images différentes, chacune répondant à une utilisation précise du programme. Cette partie recense les utilisations les plus courantes et les images qu'il faudra utiliser.

    Chainloading

    iPXE peut être chargé depuis une implémentation de PXE existante, il faudra donc utiliser une image de type NBP, c'est le cas d'undionly.kpxe par exemple. Il est également possible de charger iPXE depuis un autre chargeur d'amorçage comme GRUB ou LILO, dans ce cas de figure, une image de type bzImage est nécessaire, il faudra donc utiliser ipxe.lkrn.

    Plus d'informations

    Démarrer sur CD-ROM, disquette ou clé USB

    Il existe également des images spécifiques chacun de ces supports, ipxe.iso, ipxe.dsk et ipxe.usb pour l'amorçage depuis, respectivement, un CD-ROM, une disquette ou une clé USB.

    Flasher la ROM de sa carte réseau

    Les plus téméraires d'entre vous pourront flasher la ROM de leur carte réseau afin de disposer d'iPXE de façon permanente. Ceci permet d'éviter le chainloading et économise donc une étape, sans parler du gain évident en sécurité si vous embarquez une clé privée dans iPXE : avoir une clé qui se balade en clair sur le réseau, ce n'est jamais une très bonne chose. Dans ce cas de figure, vous devez compiler une image de type .rom ou .mrom et il vous faudra connaître le pilote précis utilisé par votre carte réseau.

    Plus d'informations

    Fonctionnalités

    iPXE, en plus du respect de la spécification PXE, propose un grand nombre de fonctionnalités qui ne sont pas décrites par celle-ci.

    Protocoles

    Là où la spécification PXE ne se limite qu'aux protocoles TFTP et Multicast TFTP, iPXE intègre un certain nombre d'autres protocoles. Les plus utilisés étant bien sûr HTTP et FTP, mais sont également disponibles :

    • Scalable Local Area Multicast protocol (SLAM) : un protocole conçu pour être plus efficace que Multicast TFTP et qui n'est à ma connaissance implémenté que dans iPXE.
    • HTTPS : HTTP sécurisé qui offre un certain nombre de possibilités combiné avec l'intégration de certificats dans iPXE, voir la partie Cryptographie.
    • iSCSI / AoE / FCoE : permet l'amorçage depuis un SAN, voir la partie Sanboot ci-dessous.
    • NFS : implémenté cette année dans le cadre d'un Google Summer of Code par l'auteur de cette dépêche. Devrait être intégré dans la branche principale sous peu.

    Sanboot

    iPXE permet l'amorçage sur un SAN, il va procéder exactement comme le BIOS pour un amorçage sur disque classique, sauf qu'il va intercepter les interruptions utilisées pour demander la lecture de secteurs afin d'émuler un disque physiquement présent dans la machine. Le chargeur d’amorçage de la cible distante sera donc tout à fait capable de faire son travail et de charger un noyau. Pour poursuivre l'amorçage, il faudra bien évidemment que le système d'exploitation ait des pilotes chargés pour le protocole utilisé (iSCSI, AoE ou FCoE). Cette technique permet d'installer et amorcer des stations Windows sans disque.

    Cryptographie

    iPXE possède une implémentation de TLS, qui est utilisée pour le support d'HTTPS, et permet lors de la compilation d'embarquer une ou plusieurs Autorités de certification. Il est donc possible d'amorcer une machine avec des images téléchargées depuis l'Internet en toute sécurité. Si une autre solution qu'HTTPS est choisie, il est également possible de signer l'image et de demander à iPXE de ne la charger que si la signature est valide. Pour permettre l'authentification des clients, iPXE permet aussi d'embarquer un certificat et la clé correspondante.

    Plus d'informations

    Scripting

    L'une des fonctionnalités les plus appréciables d'iPXE est probablement la possibilité qui est offerte de le scripter. En effet, il embarque un petit interpréteur qui, bien que rudimentaire, offre des possibilités que ne fournissent pas les autres chargeurs d'amorçage. Ces scripts peuvent être soit embarqués dans l’exécutable à la compilation, soit exécutés comme des images classiques.

    La syntaxe ressemble beaucoup à du shell édulcoré, les boucles y sont absentes mais peuvent être construite à partir de goto, de même pas d'instruction if mais une alternative un tout petit peu moins intuitive. Ces choix s'expliquent par le fait que l’interpréteur doit rester le plus petit possible, faisant partie du cœur du programme, il n'est pas possible de le désactiver à la compilation contrairement à la plupart des autres fonctionnalités.

    Le classique hello world :

    #!ipxe
    
    echo Hello World!
    
    

    Un script qui demande à l'utilisateur d'entrer une valeur et envoie cette valeur ainsi que son adresse MAC à un serveur HTTP, ce script a été utilisé par l'auteur de cette dépêche à plusieurs reprises pour s’épargner le relevé fastidieux des adresses MAC d'une centaine de machines :

    #!ipxe
    
    # Effectue une requête dhcp
    dhcp
    
    # Affiche "Nom de la machine : " et attends une entrée de l'utilisateur pour continuer, la valeur saisie est placée dans la variable 'name'.
    echo -n Nom de la machine : && read name
    
    # Exécute l'image renvoyée par le serveur HTTP tout en lui transmettant la saisie de l'utilisateur et l'adresse MAC de la machine. 
    chain http://${next-server}/?name=${name}&mac=${mac}
    
    

    Une boucle qui effectue une requête dhcp tant qu'une réponse n'a pas été reçue :

    #!ipxe
    
    # Déclare le label 'retry_dhcp'
    :retry_dhcp
    
    # Effectue une requête DHCP puis 'isset' teste si la variable 'filename' contient une valeur, ce qui est le cas quand une réponse DHCP valide à été reçue.
    # Si 'isset' renvoie faux, le goto nous renvoie au début du script.
    dhcp && isset ${filename} || goto retry_dhcp
    
    # La commande 'chain' télécharge l'image dont l'URI est passé en paramètre et l’exécute.
    chain ${filename}
    
    

    iPXE embarque aussi un shell où toutes ces commandes, à l'exception de goto, sont disponibles.

    Plus d'informations

    Menu graphique

    Si PXELINUX et GRUB offrent la possibilité d'afficher des menus depuis longtemps, l'implémentation de cette fonctionnalité dans iPXE date seulement de quelques mois. Contrairement à ce que l'on peut trouver ailleurs, il n'y a pas de fichier de configuration pour décrire le menu, il faut utiliser le langage de script intégré à iPXE et en particulier les commandes menu, item et choose.

    Un exemple simple :

    #!ipxe
    
    menu
    item linux    Boot Linux
    item shell    Enter iPXE shell
    item exit     Exit to BIOS
    
    # Affiche le menu à l'utilisateur et place le nom de l'élément choisi dans la variable 'target'
    choose --default exit --timeout 3000 target && goto ${target}
    
    :linux
    # Amorce sur Linux
    chain ftp://${server}/bzImage
    
    :shell
    # Propose un shell iPXE à l'utilisateur
    shell
    
    :exit
    # Termine la session iPXE
    exit
    
    

    L'affichage d'un menu plus complet, avec des séparateurs :

    menu

    DNS

    Contrairement à une implémentation classique de PXE, iPXE est capable de comprendre des URI passé par l'option DHCP filename, dans cet URI, la cible peut être un nom de domaine. Afin de pouvoir les résoudre, iPXE intègre un petit client DNS. Ceci ouvre un certain nombre de possibilités, comme la répartition de charge par round-robin DNS qui est particulièrement utile quand on veut amorcer un très grand nombre de machines.

    VLAN

    Enfin, iPXE est capable de configurer une interface comme un VLAN trunk c'est à dire qu'il peut générer des interfaces virtuelles, une pour chaque VLAN, qui se retrouveront sur des segments Ethernet différents. Pour que ceci fonctionne, il faut bien sûr que la machine soit reliée à un commutateur capable de comprendre le protocole IEEE 802.1Q.

    Plus d'informations

    Alternatives à iPXE

    Je ne connais pas d'alternative libre à iPXE en tant que microgiciel embarquable, en revanche il existe d'autres chargeurs d'amorçage qui peuvent être utilisés comme NBP :

    • PXELINUX du projet SYSLINUX
    • pxegrub du projet GRUB

    Lire les commentaires

  • Firefox : Looking Glass (Journaux LinuxFR)

    Ce soir j'ai voulu rajouter l'addon vim-vixen sur mon Firefox et je découvre une extension que je n'ai jamais installée : "Looking Glass". Qu'est-ce !? La description n'aide pas :

    By PUG Experience Group
    MY REALITY IS JUST DIFFERENT THAN YOURS.

    WTF!? Il y a une extension dont j'ignore totalement l'objectif qui s'est installée toute seule dans mon navigateur. Gardons notre calme, Google est mon ami moteur de recherche, voyons si qqun a rencontré le même soucis. La seule mention qui colle est sur Reddit : https://www.reddit.com/r/firefox/comments/7jh9rv/what_is_looking_glass/
    L'OP est exactement dans la même situation que moi mais les commentaires pointent vers une manip de Mozilla :

    It's apparently a new shield study (pug.experience@shield.mozilla.org). Seems to just make some page modifications and send an extra header to partner websites if a particular pref is true (it was false for me).

    On retrouve également une référence sur github et la clé mentionnée est bien présente dans mon about:config : extensions.pug.lookingglass

    Maintenant Twitter est en mode complot et tout le monde se pose les même questions :
    Twitter Looking Glass

    Mais finalement la réponse se trouve dans le paramètres "Allow Firefox to install and run studies" et sur la page "about:studies" :

    What's this? Firefox may install and run studies from time to time.

    Après le succès du lancement de Quantum, ils devraient faire gaffe à ce genre de détails. Choisir une description plus claire et moins "bizarre" par exemple, ça éviterait les théories complotistes. Surtout que ce paramètre est activé par défaut donc les utilisateurs peuvent ne pas être au courant. Sur Reddit certains ont carrément préféré désinstaller FF…

    Lire les commentaires

  • En route vers GIMP 2.10 (Dépêches LinuxFR)

    La prochaine version majeure de GIMP se rapproche à grands pas. Le projet a déjà connu quatre sorties de développement : 2.9.2 fin 2015, 2.9.4 mi‐2016, 2.9.6 en août 2017 et 2.9.8 cette semaine.

    Puisque nous prévoyons de sortir la version stable 2.10 très prochainement, les versions de développement s’accélèrent et nous devrions sortir bientôt des release candidates. C’est donc un moment où les remontées de rapports de bogues et les tests sont primordiaux.

    Dans cet article, nous évoquerons certaines des évolutions majeures de la prochaine version de GIMP sans nécessairement rentrer dans le détail.

    Enfin, nous listerons les moyens d’aider le projet GIMP, aussi bien en listant les moyens de donations (périodes de fin d’année propices à cela !) que les moyens de contribuer du temps : code, design, connaissances…

    NdM : le projet ZeMarmot permet de faire beaucoup évoluer GIMP. Il est important de le soutenir !

    Sommaire

    Note : les descriptions ci‐dessous sont un résumé très rapide de chaque sortie de développement qui ne reflète qu’une infime partie des nouveautés de chaque version. Pour en savoir un peu plus, il est conseillé de lire les articles de sorties officiels (liens plus haut ; en outre, les articles officiels ont des vidéos que l’on ne peut intégrer ici), qui eux‐même ne sont que partiels. Pour une meilleure idée des nombreux changements, je ne peux que vous conseiller de vous référer au fichier NEWS, qui — bien que cette liste ne soit pas exhaustive non plus (vous voudrez lire le git log pour cela) — est la source la plus complète tout en restant simple à lire.

    Nouveautés de la 2.9.2

    Cette première version de développement fut très importante puisqu’il s’agit de la première version depuis le portage du moteur graphique. GEGL est en effet le changement majeur entre GIMP 2.8 et 2.10. Nous en avions d’ailleurs déjà parlé sur LinuxFr.org.
    En deux mots, cela apporte les images à haute précision des couleurs, la prévisualisation des filtres sur le canevas, l’accélération matérielle et à multiples fils d’exécution (multi‐thread), etc. Et, bien entendu, toute la logique interne de GIMP a été revue, ce qui fut un gros travail, sans pour autant être si visible. En particulier avec GEGL, tout traitement d’image est un graphe, ce qui annonce le futur de GIMP pour l’édition non destructrice.

    Haute précision de couleurs

    En outre, de nouveaux outils ont fait leur apparition, notamment en résultats de plusieurs Google Summer of Code, tels que :

    • outil de transformation unifiée (toutes les transformations en un outil : rotation, mise à l’échelle, perspective, déplacement et inclinaison) ;
    • outil warp, qui remplace le filtre iWarp et permet des effets similaires de manière bien plus intuitive : GIMP warp tool, dessin d’Aryeom

    La gestion des couleurs est devenue un citoyen de première classe en étant intégrée dans le cœur de GIMP, la gestion avancée des métadonnées fait son entrée et la peinture numérique n’est pas en reste avec la rotation et l’inversion du canevas.
    Rotation du canevas

    De nouvelles prises en charge de formats ont aussi été implémentées : OpenEXR et WebP. Et plusieurs autres prises en charge de formats sont corrigées ou améliorées.

    On peut aussi noter le portage de la gestion des fichiers vers GIO dans tout le code de GIMP, ce qui permet notamment l’accès aux fichiers distants de manière générique et fiable.

    Nouveautés de la 2.9.4

    Neuf mois plus tard, l’interface graphique de GIMP fait son petit défilé de mode avec l’arrivée de nouveaux thèmes et d’icônes symboliques, et surtout vectorielles, projet que je mène en gérant des contributeurs pour donner un renouveau à l’interface.
    Nouveaux thèmes

    Outre l’aspect esthétique, le travail continue fort avec une gestion des couleurs de plus en plus poussée (dont notamment l’ajout de l’épreuvage numérique, ou soft‐proofing), ainsi qu’une amélioration constante de GEGL. Les filtres sont aussi progressivement portés comme opérations GEGL, et la prévisualisation de filtres peut désormais même se faire en comparaison avec l’image actuelle en manipulant un « rideau » de prévisualisation.
    Prévisualisation en comparaison sur canevas, dessin d’Aryeom

    En outre, nous travaillons étroitement avec des développeurs de darktable et commençons ainsi une collaboration pour que les images brutes RAW s’ouvrent automatiquement dans ce développeur d’images RAW avant d’être automatiquement renvoyées dans GIMP ; en d’autres termes, si darktable est installé, il devient notre nouveau « greffon » pour la prise en charge des RAW, avec communication bilatérale. Vous pouvez, par exemple, voir cela fonctionner sur cette vidéo en lien (notons que certains en commentaires ne comprennent pas et croient que celui qui présente va trop vite ; mais non, c’est juste qu’il n’y a rien à voir : l’association entre GIMP et darktable marche simplement sans rien faire).

    Nous travaillons aussi avec les développeurs de MyPaint et avons ainsi intégré leurs brosses dans GIMP (en plus des formats de brosses existants) grâce à la bibliothèque libmypaint sur laquelle je me suis mis à contribuer (au point d’obtenir les droits d’écriture sur le dépôt).
    Ce n’est d’ailleurs pas le seul ajout intéressant pour les peintres numériques dans cette version, puisque j’y ai codé notamment la peinture en miroir, mandala et tuile après un financement participatif.

    Peinture en miroir, mandala et tuile, dessin test d’Aryeom

    » Compte‐rendu de la contribution du projet ZeMarmot pour GIMP 2.9.4 «

    Nouveautés de la 2.9.6

    Cette version, sortie il y a quelques mois, accélère les optimisations pour les performances de GIMP, en particulier via l’optimisation de GEGL même et notamment en travaillant beaucoup sur l’exécution en parallèle (multi‐threading) des opérations.

    Préférences système

    Parallèlement je travaille sur la prise en charge des écrans à haute densité de pixels (HiDPI), ce qui était une des grosses raisons pour laquelle j’avais poussé à l’utilisation d’icônes vectorielles. De plus en plus de personnes se plaignaient que les icônes étaient vraiment trop petites sur leur super écran QHD ou 4K, nous avons donc pris les devants. Cela tombe bien, car nous avons nous‐mêmes acquis une tablette‐PC QHD le mois dernier ! À partir de la 2.9.6, la taille des icônes est désormais configurable depuis les préférences (avec auto‐détection de la densité de pixels par défaut), totalement indépendamment du thème choisi.
    Configuration des icônes

    En parallèle, d’autres contributeurs travaillent sur la manipulation des filtres avec des poignées directement sur le canevas (pour une édition intuitive).
    Manipulation sur canevas de l’opération « Spirale »

    Plus important, GIMP se met à différencier davantage les espaces de couleurs linéaires et perceptuels (notamment dans les modes de calques), tout en séparant également les concepts de composition (compositing) et de mixage (blending) pour les utilisateurs avancés.

    Le mode traversant (pass‐through) applicable à des groupes de calques (pour que ceux‐ci puissent ne servir que pour l’organisation) fait son apparition, ainsi que les étiquettes en couleurs pour organiser ses calques.

    Continuant dans notre collaboration avec les autres projets, RawTherapee rejoint notre concept de greffon RAW. Dorénavant si RawTherapee est installé, il sera aussi utilisable comme intermédiaire. Et si darktable et RawTherapee sont tous deux présents sur votre machine, il sera possible de sélectionner le développeur RAW de votre choix dans les préférences de GIMP.

    On notera que nous aimons collaborer avec d’autres projets. C’est, je pense, une des marques de fabrique de GIMP, qui a toujours collaboré avec les logiciels tiers et les a incité à s’améliorer. Et, surtout, nous poussons pour un écosystème logiciel amical. Pourquoi faire mal (avec un petit greffon et quelques curseurs mal pensés) ce que des logiciels libres spécialisés font déjà très bien, en l’occurrence ici du développement de RAW ? Certains peuvent y voir une logique de « suite créative du Libre » tout en gardant l’indépendance de chaque acteur.

    Côté formats, il est désormais possible d’exporter des fichiers PDF multi‐pages, de nouvelles variantes du format PCX sont prises en charges, le format PSD (et d’autres) bénéficient aussi de nombreuses corrections de bogues. Les fonctionnalités avancées du format WebP, implémenté basiquement dans la 2.9.2, sont dorénavant prises en charge, en particulier l’animation, ce qui en fait un super remplaçant à GIF, si toutefois Firefox en ajoutait la prise en charge (plus performant, plus petits fichiers et meilleure qualité d’image, avec notamment une vraie gestion de la transparence et des couleurs 24 bits).

    Ce n’est pas tout ! le projet ZeMarmot fut un des contributeurs majeurs et je vous recommande la lecture du compte‐rendu de la contribution du projet ZeMarmot pour GIMP 2.9.6

    Nouveautés de la 2.9.8

    Les nouveautés ralentissent car nous commençons à nous concentrer sur les corrections de bogues et quatre mois seulement se sont écoulés depuis la version précédente.
    Notons que nous désactivons dorénavant OpenCL par défaut. En effet, les versions parallélisées (multi‐threaded) des algorithmes sont souvent plus rapides que les versions accélérées par le processeur graphique (notamment avec le pilote beignet pour les cartes Intel), et certains pilotes graphiques provoquent des bogues de rendu (en particulier les pilotes NVIDIA).

    Une nouveauté en particulier fait cependant sa petite sensation : l’édition des dégradés directement sur le canevas avec l’outil de dégradé. Cela fait suite au travail d’interaction dynamique avec les filtres sur le canevas entamé dans la version 2.9.4 (mais utilisé jusque‐là uniquement sur deux filtres mineurs comme base de test, à savoir Spirale et Supernova).
    L’article officiel contient aussi une vidéo plus explicite qu’une description textuelle !

    En dehors de cela :

    • un nouveau filtre d’affichage pour mettre en valeur les zones sous‐exposées et surexposées d’une image fait son apparition ;
    • la gestion des couleurs migre progressivement vers l’utilisation de babl seulement (en remplacement de LittleCMS) quand cela est possible, permettant un gain de performance assez important ;
    • le portage pour Wayland continue son chemin, notamment avec l’implémentation des captures d’écran (KDE et GNOME) ainsi que de pixels uniques (KDE seulement pour l’instant, GNOME n’ayant pas encore l’API) ;
    • la fonctionnalité de « coller sur place » apparaît, permettant de coller d’une image à l’autre en gardant les mêmes coordonnées ;
    • les boutons curseurs (spin buttons) de GIMP ont été améliorés, car beaucoup de gens ne réalisaient pas que les zones haute et basse permettaient un glissement respectivement instantané et relatif. Les deux zones sont désormais illuminées au survol de la souris pour marquer la différence : Spin Button de GIMP
    • les informations de rotation et d’inversion de canevas sont désormais affichées dans la barre d’état et permettent de revenir à l’état initial d’un clic : Statut de canevas
    • il est désormais possible de choisir le langage de l’aide contextuelle, indépendamment de la langue de l’interface : Préférences du manuel de GIMP
    • la prise en charge des fichiers PSD est encore améliorée ;
    • les fichiers PDF avec mot de passe sont désormais importables ;
    • le format HGT de la Shuttle Radar Topography Mission (NASA et autres organismes spatiaux) est désormais pris en charge et permet de créer des cartes de relief à partir de données d’élévation de cette mission (voir mon article expliquant ce format et son utilisation) : Fichier HGT importé dans GIMP
    • et bien plus !

    Note : Le projet ZeMarmot n’a pas encore préparé son compte‐rendu sur son implication (importante encore) dans la sortie de cette version toute fraîche.

    Ce qu’il reste à faire avant 2.10

    Il reste au jour de l’écriture du présent article 49 bogues marqués pour 2.10, bien que ce nombre ne cesse d’osciller depuis des mois (fin mars, nous annoncions passer sous la barre des 50 bogues !).

    Néanmoins, j’ai récemment repriorisé les bogues en marquant en bloqueurs les bogues que nous devons corriger en priorité (soit parce qu’ils concernent des fonctionnalités importantes et beaucoup usitées, soit parce qu’ils sont critiques, de type « plantage » ou gel du logiciel, soit pour des rapports avec correctif proche de la complétion qu’il serait dommage de reporter, etc.). Ce sont les bogues en rouge dans la liste donnée en lien plus haut. Ainsi, on peut considérer qu’il ne reste en fait que 18 bogues bloquant la prochaine version majeure de GIMP !
    Bien sûr, cette liste elle‐même doit être pondérée, car nous nous attendons à de nouveaux bogues rapportés après les sorties de développement et nous avons aussi quelques tâches que nous savons avoir à faire sans pour autant avoir créé de rapports de bogue.

    Nous sommes ainsi en train de considérer le gel des fonctionnalités et des chaînes de caractères (en particulier, les textes visibles de l’interface), pour ainsi rentrer dans une phase de sortie des versions release candidates qui préparent la sortie finale de GIMP 2.10.

    Quoi qu’il en soit, nous sommes très proches d’une sortie. C’est donc une période très excitante !

    Comment aider GIMP à passer les dernières étapes avant stabilisation ?

    La première chose à faire, la plus évidente, est de tester cette nouvelle version de développement et de rapporter les bogues. Malheureusement, nous ne fournissons pas de construction (build) de développement pour GNU/Linux à ce jour (nous proposons désormais un build Flatpak officiel sur Flathub, mais il ne concerne que la version stable).
    Vous devrez donc vous procurer un des constructions tierces (il existe un PPA non officiel et certaines distributions proposent des paquetages de la version de développement, semble‐t‐il) ou le compiler vous‐même.

    Bien entendu, pour ceux qui codent et ont envie de se faire les dents, il est possible de jeter un œil à notre liste de bogues pour la version 2.10. Cependant les bogues bloqueurs restants sont pour la plupart peu recommandables à de nouveaux contributeurs, mais nous acceptons bien sûr des corrections sur d’autres bogues aussi.
    La liste des bogues « newcomers » peut aussi être d’intérêt.

    On peut aussi noter que nous avons quelques hésitations au sujet des nouveaux thèmes apparus dans la version 2.9.4. En particulier parce que le contributeur qui les a commencés semble s’en être désintéressé alors qu’ils ont divers problèmes, notamment des contrastes faibles ici et là, mais aussi parce qu’ils sont livrés avec beaucoup trop d’images pour l’interface alors qu’un thème devrait être le plus léger possible (juste des règles de style, pas d’images). Certains parlent même d’abandonner ces thèmes.
    Nous accueillons donc à bras ouvert les gens qui veulent soit corriger et maintenir les thèmes existants, voire carrément en proposer de nouveaux plus maintenables.

    Financement du développement

    GIMP, c’est quoi ? C’est qui ?

    GIMP a été entièrement développé en bénévolat jusqu’à très récemment. Et, notamment, il n’existe même pas d’entité légale GIMP, ce qui explique qu’il ne peut y avoir de développement payé par le projet. L’argent du projet (par donation) est géré par la fondation GNOME qui sert d’organisme « chapeau » à GIMP (notons bien que GIMP n’est pas un projet GNOME, il s’agit d’un accord mutuellement bénéfique) et ne sert que pour les activités bénévoles. Par exemple, tous les ans, il permet de faire venir les développeurs et autres personnes importantes de la communauté du graphisme libre au Libre Graphics Meeting (LGM) et cette année même à la Wilber Week. Nous nous en servons aussi régulièrement pour financer certains évènements (dont notamment plusieurs LGM justement, qui a commencé historiquement comme une extension de la réunion GIMP si j’ai bien compris).

    Le projet a gardé cet esprit très social et bénévole que j’apprécie énormément.

    Et pour financer du développement ?

    Dernièrement, certains développeurs tentent de vivre de leurs contributions de code par financements participatifs. Il s’agit de pippin et moi‐même. Ces financements sont faits en nos noms propres (dans mon cas, plutôt au nom du projet ZeMarmot, dont il est régulièrement question sur LinuxFr.org), mais le projet GIMP nous soutient (nos campagnes respectives sont ainsi citées sur la page de donation de GIMP).

    Øyvind Kolås, alias pippin (il tient à la minuscule sur son pseudo), est le mainteneur actuel de GEGL, le moteur graphique de GIMP. Il a commencé le financement participatif mensuel de son travail en début 2017 sur la plate‐forme Patreon et a ainsi récemment fait le bilan de sa première année assez positive.

    De notre côté, le bilan est moins positif (même si les perspectives se sont un peu améliorées en fin d’année après avoir partagé un peu de nos problèmes financiers), notamment car nous sommes deux personnes sur le projet ZeMarmot.
    Il semblerait que le problème principal soit le côté symbiotique art+code de notre projet. Certaines personnes nous ont ainsi dit explicitement qu’elles ne veulent pas nous financer car elles s’intéressent à GIMP mais pas à un film d’animation (apparemment, si je faisais un financement pour le développement seulement, j’aurais plus, ce qui m’attriste !). Pourtant, c’est l’un des cœurs de notre projet et nous ne souhaitons pas changer cela. Sans ce projet artistique, je ne coderais pas GIMP ; et sans mes corrections, Aryeom ne travaillerait pas sur ce film non plus. Comme je le disais, c’est symbiotique, mais c’est aussi symbolique !
    Surtout que je ne pense pas affirmer vainement que GIMP profite énormément de l’usage que nous en faisons car nous l’utilisons de nombreuses heures au quotidien. Nous sommes ainsi les premiers à tomber sur beaucoup de bogues, ce qui permet des corrections très rapides.
    Quoi qu’il en soit, tant qu’on arrive à tenir, je reste l’un des développeurs principaux du logiciel GIMP avec 306 commits en 2017 (sur 1 710 en tout, soit plus de 17 % des commits de l’année) et je rêve de pouvoir, un jour, financer suffisamment nos projets libres pour pouvoir affirmer en vivre.

    En conclusion, comme la page officielle de donation de GIMP l’indique, il y a trois cibles de donation pour aider GIMP :

    • donner au projet GIMP : cet argent sera utilisé pour les activités communautaires uniquement ;
    • donner à pippin pour le développement de GEGL, sur Patreon ou Liberapay ;
    • donner à ZeMarmot, ce qui se transformera en salaire pour moi pour le développement de GIMP, sur Liberapay, Tipeee, ou Patreon (Liberapay est a priori la plate‐forme avec le moins de frais, et l’on peut donner en euros et dollars états‐uniens).

    Vous pouvez aussi donner directement à l’association LILA, association de loi 1901 française qui gère le projet ZeMarmot, par exemple en virement permanent (souvent sans frais en zone euro avec IBAN, bien que cela reste fonction des banques).

    En cette fin d’année 2017, période de dons aux associations, j’espère donc que vous considérerez un petit don à LILA/ZeMarmot/GIMP !
    Et j’espère aussi que vous appréciez les évolutions de GIMP.
    Marmotte heureuse

    Lire les commentaires

  • Cinelerra, openshot video et kdenlive, le duel (Journaux LinuxFR)

    'lut les gens,

    Moi les vacances de noël ça me déprime, tout cet étalage de bouffe, de guirlandes et de bons sentiments ce n'est décidément pas mon truc, du coup je me réfugie devant mon ordinateur, ça me vide la tête. Et quoi de mieux que de mettre en concurrence les dernières versions des logiciels libres de montage vidéo sous GNU/linux, à savoir kdenlive 17.12.0, openshot video 2.4.1 et cinelerra 7 qui viennent de sortir récemment.

    Commençons par kdenlive, à y regarder de plus près, pas de grosses évolutions, c'est essentiellement une version dite de maintenance avec le changelog qu'on peut découvrir par là https://kdenlive.org/2017/12/kdenlive-17-12-0-released. On nous promet par contre une version majeure 18.04 pour la nouvelle année avec une timeline retravaillée et des fonctionnalités nouvelles. Wait and see, mais j'espère toujours retrouver la fluidité de travail que j'avais quand kdenlive n'était pas encore passé à KF5. La force de kdenlive reste la richesse de ses fonctionnalités et de ses effets, on peut regretter que ce soit aussi mal documenté, il faut vraiment passer du temps pour tirer toute la quintessence du logiciel, fort heureusement on peut trouver pas mal de docs sur le net dès lors qu'on s'y donne la peine (et qu'on maîtrise un tant soit peu l'anglais !)
    Titre de l'image

    Passons à OpenShot Video Editor, bien qu'on soit passé d'une version majeure en passant de la 1.4 à la 2.4.1, l'évolution au niveau interface n'est pas très sensible, il faut reconnaitre toutefois que c'est maintenant bien plus stable et pleinement fonctionnel. Au niveau des fonctionnalités c'est quand même très en retrait par rapport à kdenlive, notamment au niveau des effets, des images clés et d'un tas d'autres fonctions (stabilisation des images, recadrage et autres zooms), mais c'est très largement suffisant pour un montage simple. La force d'Openshot c'est son interfaçage avec inkscape et blender pour les titres animés ainsi que ses transitions au point que je passe souvent d'openshot vers kdenlive pour certains bouts de séquences. Par ailleurs contrairement à kdenlive on arrive à monter et à jouer sur les effets en restant en HD, avec kdenlive je suis obligé de passer en clips intermédiaires en dégradant les rushs pour faire le montage, malgré mon i7 avec 16Go de RAM.
    Titre de l'image

    Terminons par cinelerra, la dernière version 7 apporte une meilleure prise en compte des vidéos de haute définition et du codec HEVC/x265, ainsi que la prise en compte des caméras sphériques, il y a une vidéo de démonstration par ici https://www.youtube.com/watch?v=zEQ4Cve3_-M . Bon à part ça, c'est toujours vraiment une galère pour le compiler. Une fois qu'on a passé cette difficile étape, à l'utilisation l'interface reste tout aussi brouillonne, vieillotte ça rappelle le X11/Motif dont beaucoup ici n'ont jamais entendu parlé, c'est un peu usine à gaz et ça ne donne vraiment, mais vraiment pas envie de s'y mettre d'autant que maintenant kdenlive l'a largement rattrapé en terme de fonctionnalités et de stabilité tout en offrant une interface bien plus conviviale.
    Titre de l'image

    J'ai quand même noté qu'il existait un fork d'une version Community Version par là https://cinelerra-cv.org/index.php je n'ai pas pris le temps de la tester. Je devrais, car l'interface semble plus sympathique et ça pourrait être un concurrent sérieux.

    Pour résumer, nous avons Openshot Video plutôt destiné aux débutants qui ont juste besoin de mettre quelques séquences bout à bout, kdenlive pour les plus expérimentés qui prennent le temps de monter et de faire des vidéos plus complexes et travaillées et cinelerra pour les masochistes :-). Bref un constat qui est loin d'être un scoop mais qui m'a permis un temps d'oublier la bûche, le sapin de noël et l'ambiance gnangnan qui va avec.

    Lire les commentaires

  • Je crée mon jeu vidéo E14 : formats de données (Dépêches LinuxFR)

    «Je crée mon jeu vidéo» est une série d'articles sur la création d'un jeu vidéo, depuis la feuille blanche jusqu'au résultat final. On y parlera de tout : de la technique, du contenu, de la joie de voir bouger des sprites, de la lassitude du développement solitaire, etc. Vous pourrez suivre cette série grâce au tag gamedev.

    Dans l'épisode 13, on a fait le bilan d'une année de développement. Un des constats était que le temps manquait, et au vu de la durée entre cet épisode-là et celui-ci, on peut dire que c'est toujours le cas. Dans ce nouvel épisode, on va discuter non seulement de formats de données, mais aussi de compilation croisée.

    Sommaire

    Formats de données

    État des lieux

    Actuellement, dans Akagoria, trois formats de données sont gérés directement ou indirectement : XML, Protobuf et YAML. Le terme format de sérialisation de données serait probablement plus approprié, puisque pour chacun de ces formats, il peut y avoir plusieurs dialectes.

    Concrètement :

    • XML est utilisé pour la carte à travers le dialecte TMX, défini par Tiled. J'utilise ma propre bibliothèque, libtmx, pour avoir une vue de la carte indépendante du XML. La bibliothèque utilise elle-même TinyXML-2.
    • Protocol Buffers est utilisé par le format Nanim de devnewton. Dans les dernières versions, Nanimstudio peut exporter les données en JSON plutôt qu'en Protocol Buffers. Actuellement, j'utilise protobuf couplée avec l'analyseur lexical généré depuis nanim.proto.
    • YAML est utilisé pour les autres données du jeu, dans des formats que j'ai défini moi-même. J'utilise yaml-cpp qui est relativement simple à utiliser. Je l'avais déjà utilisé dans MapMaker avec satisfaction et je préfère ce format à XML car moins verbeux.

    Et pour le futur, il y aura sans doute d'autres données à gérer. Par exemple, les dialogues. Dans Andor's Trail, ils sont gérés en JSON. Comme on peut le voir sur un exemple, le format gère aussi les récompenses et l'enchaînement des quêtes. On peut aussi penser au format des sauvegardes, au format de la configuration du joueur, etc.

    Solution

    La solution serait de n'avoir qu'un seul format de sérialisation, ce qui réduirait le nombre de bilbiothèques utilisées à une seule. Et on voit bien le problème :

    • soit il faut choisir XML puisque c'est celui utilisé par Tiled, ce qui veut dire qu'il faut transformer les autres données en XML. J'imagine déjà la tête de devnewton si je lui dis qu'il me faut un export XML dans NanimStudio.
    • soit il faut coder un convertisseur depuis les différents formats vers celui choisi, mettons YAML. Dans cette deuxième hypothèse, pour Nanim, on peut utiliser l'export JSON qui est à peu près un sous-ensemble de YAML.

    La deuxième hypothèse a d'énormes avantages : pas de dépendance forte à un format externe, facilité de lecture puisque tout se ressemble. Mais elle a aussi quelques inconvénients notables : obligation de redéfinir des dialectes dans le format unique, obligation de réécrire des analyseurs sémantiques pour ces dialectes. Ces inconvénients sont une variante de la réinvention de roue.

    Quelle réponse au problème global ?

    En fait, il y a une question à laquelle nous n'avons pas répondu : pourquoi s'emmerder avec des formats de fichiers ? Pourquoi ne pas tout coder en dur ? Bonne question. La réponse usuelle est que des données à part permettent de faire des changements sans avoir à recompiler le jeu. En particulier, les données dans des fichiers permettent à des non-informaticiens de pouvoir les manipuler assez facilement. Bon, ça c'est quand on développe un jeu avec des non-informaticiens. Quand on développe un jeu à peu près tout seul, la non-recompilation est un avantage en soi.

    Mais surtout quand on fait du libre, on aime les formats ouverts, mais aussi les formats standardisés, parce qu'ils permettent par la suite de créer des outils génériques pour les manipuler. Et ce qui manque le plus dans les jeux libres, ce sont ces formats standardisés. Au final, chacun refait la même chose dans son coin et on n'avance pas. On ne peut pas capitaliser sur un ensemble de formats communs. Et surtout, on n'a aucun outil pour les manipuler.

    L'exemple de Tiled est parlant. Le format TMX est à peu près le seul format sur lequel tout le monde s'appuie dans pas mal de jeux libres. Certes il n'est pas parfait, mais son système de propriétés fait qu'on peut lui ajouter des fonctionnalités à peu de frais, tout en restant compatible avec le seul éditeur du format connu jusqu'à présent. Mais est-ce bien suffisant ? La communauté du libre a toujours trouvé les ressources pour pallier ce genre de problème mais dans le cas des jeux vidéos, elle reste assez inerte.

    Les grands studios ne développent pas que des jeux, ils développent aussi beaucoup d'outils. Certains moteurs libres de jeux proposent également des éditeurs, mais le problème des formats est toujours posé. Choisir un moteur de jeu, c'est choisir les formats qui vont avec et donc se lier à une technologie en particulier. Ce que je dis sonne un peu comme un yakafokon, parce que standardiser des formats de ce genre relève du parcours du combattant et nécessite une expérience que je suis sans doute très loin d'avoir.

    En attendant une solution globale, je peux au moins éliminer Protobuf et utiliser l'export JSON de NanimStudio.

    Compilation croisée pour Windows

    Après des premiers essais infructueux dûs à des bugs dans les outils de compilation, j'avais mis de côté cet aspect des choses, à savoir fournir un binaire pour Windows. Mais il y a eu des mises à jour, notamment de Ming, et j'ai retenté. J'utilise l'excellent crossroad qui a été présenté ici-même il y a quelques temps (et qui a changé un peu donc lisez la doc si vous l'utilisez).

    Première chose à dire, il faut vraiment s'armer de patience quand on tente ce genre de compilation. Parce qu'on tombe sur des erreurs de compilation qu'on ne trouve pas ailleurs. Alors bon, des fois, c'est tellement cryptique que la seule solution, c'est petit patch en mode « la Rache ». Et dans d'autres cas, c'est tout à fait légitime. Par exemple, le compilateur a l'air plus strict sur les standards. Saviez-vous qu'il n'y avait pas les constantes genre M_PI dans <cmath> ? En fait, elles sont dans les spécifications Unix et du coup, quand on les utilise et qu'on veut compiler pour un système non-Unix, ça provoque une erreur de compilation parce que la constante n'existe pas.

    Autre chose à prendre en compte, on compile beaucoup de choses. Parce que même s'il y a déjà des paquets disponibles (grâce à OpenSuse), il manque beaucoup de choses. Pour cet essai, j'ai dû recompiler SFML, Box2D, protobuf, tinyxml2 et yaml-cpp. Sans compter mes propres bibliothèques. Il faut faire attention à plein de choses, il faut compiler le strict minimum pour que ça se passe au mieux. Et surtout, on a plein d'avertissements sur des pages et des pages ! Bref, on serre les fesses à chaque commande.

    Au final, on se retrouve avec un joli zip de 40 Mio qui contient tous les binaires et les fichiers de développement. Et… Kaboum ! Ça ne marche toujours pas. Bon ben, faute de temps, je retenterai une prochaine fois. Mais je suis assez content de crossroad. Il fait exactement ce qu'on attend de lui et il aide juste ce qu'il faut pour la compilation croisée.

    D'ici à la prochaine fois

    N'oubliez pas que le week-end du 23 au 25 janvier 2015 a lieu la Global Game Jam. C'est un exercice amusant, et il y a de plus en plus de sites partout en France, n'hésitez pas à y faire un tour. Personnellement, je serai à Besançon, avec mes étudiants qui organisent le site.

    Lire les commentaires