Introduction

Il y a quelques temps, j'ai décidé de quitter Github, en fermant mon compte. Depuis, j'expérimente des modes de contribution au logiciel libre de manière à peu près décentralisées.

Aujourd'hui, nous allons voir comment contribuer à un développement avec l'aide de git et du bon vieux courrier électronique via la commande git send-email !

Comment ça marche ?

Globalement le mode opératoire est asez simple:

  • Vous avez un clone du dépôt central.
  • Vous faîtes des modifications donc des commits.
  • Une fois que vous estimez que vos changements sont dignes d'êtres soumis au(x) responsable(s) du projet, vous utilisez git send-email.
  • De son côté, le responsable du projet utilise git am pour récupérer vos modifications.
  • S'il a des remarques à faire, il vous les renvoie en réponse à votre courrier électronique où finalement toute l'action de négociation se déroule (en privé par défaut).
  • Une fois que tout est ok pour le responsable projet, il intègre vos changements (ou non) et votre contribution est intégrée au projet (ou non).

Pour faire simple, git send-email propose un système proche des pull-requests de Github mais en passant par le canal complètement décentralisé du courrier électronique.

C'est plutôt une proposition intéressante car elle permet un développement immédiat avec quelques outils dont, à peu près tout le monde est équipé (git et une adresse de courrier électronique).

Quelques éléments de configuration

Avant de commencer, sachez que sous Debian, git email-send n'est pas installé par défaut avec le paquet git (ce qui est sans doute dommage). Vous pouvez l'installer via:

# apt install git-email

Ensuite, avant de pouvoir utiliser git send-email, il faut configurer git pour accéder à votre serveur de courrier électronique.

  • D'abord, vous devez savoir à quelle adresse de courrier électronique envoyer vos modifications (project@thesuperproject.example dans la suite de l'article). Cette configuration sera bien entendu différente pour chaque projet et elle doit être locale au dépôt git.
    git config --local sendemail.to project@thesuperproject.example
  • Ensuite, vous aurez besoin d'indiquer quel serveur SMTP sera utilisé pour réaliser l'envoi du courrier électronique proprement dit. Ces éléments de configuration seront sans doute indépendants du projet sur lequel vous travaillez. Vous pouvez donc les déclarer en global:
    git config --global sendemail.smtpServer smtpserver.example
    git config --global sendemail.smtpServerPort 25
    git config --global sendemail.smtpEncryption tls
    git config --global sendemail.from myaccount@smtpserver.example
    git config --global sendemail.smtpUser myaccount
  • Enfin, vous avez besoin de configurer quelques options générales de git send-email, notamment le fait d'annoter systématiquement vos patches (via annotate) ainsi que la configuration de l'encodage de vos messages:
    git config --global sendemail.verify on
    git config --global sendemail.annotate yes
    git config --global sendemail.transferEncoding 8bit

Un exemple concret

Du point de vue du contributeur externe

Ok, vous êtes un contributeur externe. Vous avez réalisé quelques commits sur la branche master et vous souhaitez les soumettre au responsable du projet. Vous avez configuré git send-email comme indiqué ci-dessus.

Dans vos changements, vous avez dépassé la référence origin/master de quelques commits. Vous avez juste à lancer la commande suivante:

$ git send-email origin/master

Votre éditeur de texte configuré dans git va s'ouvrir en vous permettant d'écrire un message au début du courrier électronique. C'est là que vous remplissez la description de votre soumission de patch.

Ensuite, après l'enregistrement, git send-email vous demande une confirmation ainsi que le mot de passe du serveur SMTP (car nous ne l'avons pas renseigné en dur dans la configuration de git pour des raisons de sécurité).

Si tout se passe bien, votre courrier électronique est envoyé ! S'il y a des problèmes dans l'authentification, vérifiez votre configuration SMTP. Par exemple, dans mon cas j'utilise STARTTLS sur mon serveur SMTP et j'ai dû configurer l'option sendemail.smtpEncryption à tls pour pouvoir faire l'authentification de manière correcte.

Si vous voulez envoyer un truc différent, vous pouvez utiliser le vocable des révisions git. Par exemple, si vous souhaitez envoyer uniquement un commit précis, vous pouvez mettre son uid:

$ git send-email 1bea5dff495173beb9b93e6e0ea7df6e2435a283

Du point de vue du développeur interne

Ok, vous êtes un développeur du projet et vous avez reçu un courrier électronique avec un patch dedans. Vous devez appliquer ce patch, le tester, faire d'éventuels réponses avec l'auteur du patch puis quelques aller-retours. Néanmoins, en dehors de l'application du patch sur le dépôt, tout ces éléments se dérouleront dans votre application de courrier électronique.

Pour appliquer le patch soumis, vous devez le sauvegarder et appliquer le patch avec git am.

Dans mon cas, je sauvegarde le message au format eml depuis Roundcube dans un fichier dédié. Ensuite, je lance la simple commande:

$ git am chemin/vers/fichier.eml

Ce qui est assez intéressant, c'est que git am reprend le sujet du courrier électronique comme sujet du commit ainsi que les commentaires globaux du patch.

Il y aura forcément des conflits, des trucs pas terribles mais, comme d'habitude dans git, vous aurez besoin de gérer les choses... ou de renvoyer à l'auteur du patch, à votre discrétion.

Conclusions

git send-email fait les choses très bien. Après avoir passé 5 minutes à le configurer correctement et compris comment ça marchait, vous avez maintenant un outil bien intégré pour faire des propositions d'évolution sur des projets externes. Et ce, sans avoir besoin d'avoir un compte sur cette plate-forme externe, ni d'utiliser votre navigateur web pour écrire des messages. C'est plutôt efficace et en plus, tout reste dans git. Pas besoin d'outil externe.

Bien entendu, votre "pull-request" n'est pas connue du grand public par défaut. Néanmoins si l'équipe de développement a mis en place une bonne vieille mailing-list des familles, votre soumission devrait être disponible dessus. Ce n'est pas mon cas sur medspx.fr car je préferre rester dans un mode plus discret et que je n'ai pas vraiment de contributeurs externes.

Pour information, j'ai trouvé trace de git send-email sur le blog de Drew Devault, le développeur principal du projet Sway.

Je vous invite aussi à lire le guide des contributions via git send-email sur la plate-forme sr.ht. Il est plein d'exemples assez intéressants...

Posted dim. 25 nov. 2018 13:09:00 Tags:

Introduction

Il y a quelques temps, j'ai décidé de quitter Github, en fermant mon compte. Après tout, ça va dans le sens de mes convictions. Pour l'instant, ça me va très bien mais je reconnais que ce n'est pas très pratique pour travailler sur des projets de logiciels libres.

L'acquisition de Github par Microsoft et le fait qu'on trouve maintenant des millions de projets de logiciels libres, tous centralisés sur Github pose clairement la question du risque de tout mettre ses yeux dans le même panier. Que se passe-t-il si Github devient trop puissant et impose ses conditions ?

Néanmoins, nous sommes en 2018 et ne pas utiliser des outils modernes pour partager du code impose de revenir en arrière et d'exclure certaines bonnes pratiques. Aussi, je me devais de trouver un système adapté à mes moyens et à mes ambitions pour partager le code source libre qu'il m'arrive de produire.

Cet article tente d'améliorer l'aspect partage des choses en présentant une installation de gitolite, un logiciel de référence pour gérer les droits d'accès à des dépôts Git.

Principes de Gitolite

Avant d'utiliser un logiciel, c'est bien de savoir comment il fonctionne, du moins dans ses grandes lignes.

  • gitolite utilise un compte UNIX standard pour opérer. De cette manière, la compromission de ce compte ne vient perturber que ce compte et pas le reste du système (du moins, de prime abord).
  • le compte gitolite utilise un répertoire dédié qui contient deux ensembles:
    • un répertoire de dépôts git (bare), c'est là qu'on mettra nos dépôts git. Ce répertoire ce nomme repositories.
    • un répertoire caché (.gitolite) qui contient la logique de gitolite avec les scripts Perl à lancer dans les hooks. Il contient également les clefs publiques SSH des utilisateurs qui ont accès aux dépôts gits.
  • Il existe un dépôt de base nommé gitolite-admin qui permet d'interagir avec la configuration de gitolite. De fait, toute la conf de gitolite se fait à l'aide de ce dépôt qui contient des hooks spécifiques. Il est même déconseillé d'utiliser une autre méthode.
  • Par défaut, gitolite permet l'accès aux dépôts git via SSH. Il est toutefois possible d'autoriser un accès via HTTP(S).
  • Les utilisateurs déclarés dans gitolite son des utilisateurs indépendants du système d'exploitation.

Installation de gitolite sous Debian

Vous devez disposer d'une clef publique SSH pour le compte "administrateur" de gitolite. Pour ma part, j'y fous ma clef publique de GNUPG au format ssh-rsa que j'obtiens avec la commande gpg (voir ci-dessous).

Ensuite, vous pouvez installer le paquer Debian gitolite3. Ce dernier vous demandera où placer le répertoire spécifique à gitolite. Pour ma part, je le place dans /var/local/gitolite.

$ gpg --export-ssh-key mon_compte_gpg > medspx.pub
$ scp medspx.pub compte@srv.example.org:/tmp/
# apt install gitolite3
  - clef SSH de l'administrateur: `/tmp/medspx.pub`
# mv /var/lib/gitolite3 /var/local/gitolite
# usermod --home /var/local/gitolite gitolite3

Voilà, c'est fait...

Après installation du paquet, debconf créé un utilisateur dédié. Il se nomme gitolite3 et a pour HOME le répertoire d'installation de gitolite que vous avez renseigné en amont.

Ce répertoire contient tout ce que j'ai expliqué dans les principes de gitolite sous la forme suivante:

  • .ssh => le répertoire de conf SSH de l'utilisateur gitolite3. On y trouve un fichier de clefs autorisées, modifié par un hook de gitolite.
  • repositories => notre répertoire de dépôts qui contient le dépôt de configuration de gitolite (gitolite-admin.git) ainsi qu'un dépôt de test (testing.git).
  • .gitolite => le répertoire "interne" de gitolite.
  • .gitolite.rc => le fichier de conf globale de gitolite (qui point vers /etc/gitolite3/gitolite.rc.
  • projects.list => un fichier pour gitweb dont on se fout (parce que je n'utilise pas gitweb).

Utiliser gitolite

Maintenant que gitolite est installé, il convient de l'utiliser et de commencer à le configurer correctement.

Tout commence par le clonage du dépôt gitolite-admin. Vous pouvez le cloner en utilisant le compte dédié gitolite (donc gitolite3 sous Debian). Comme vous avez renseigné votre clef SSH, vous avez le droit d'y avoir accès. Un simple clone via SSH donne la commande suivante:

$ git clone gitolite3@srv.example.org:gitolite-admin

Le dépôt contient deux répertoires:

  • keydir: qui contient les fichiers de clefs publiques.
  • conf: qui contient les fichiers de configuration de gitolite. Pour l'instant, il ne devrait y avoir que le fichier gitolite.conf.

Ajouter un utilisateur est assez simple: il suffit de récupérer sa clef publique dans un fichier avec le nom du compte suffixé avec l'extension .pub dans le répertoire keydir, de commiter le dépôt et de pousser la modification pour que la clef soit ajustée.

Pour gérer les droits des dépôts, il suffit de modifier le fichier de configuration: conf/gitolite.conf. Sa syntaxe est assez simple à comprendre même si elle peut se complexifier avec des includes et d'autres éléments.

Néanmoins, il y a un élément que vous devez bien noter ! Vous devez toujours utiliser le compte SSH de l'utilisateur gitolite (donc gitolite3 sous Debian). En effet, SSH n'est pas automagique: il ne va pas créer un compte utilisateur POSIX à la volée pour vous permettre de vous connecter. Au contraire, c'est l'utilisateur gitolite3 qui, avec son shell spécial (le binaire de gitolite), va s'occuper de faire la gestion des droits. C'est bien noté ?

Import de dépôts existants

Pour ma part, j'ai beaucoup de dépôts sur mon serveur et il convient de les référencer/importer sous Gitolite. La doc sur le sujet est assez bien faîte:

# cd /var/local/gitolite/repositories
# rm -r testing.git
# cp -r ../..git/*.git .
# chown -R gitolite3:gitolite3 *.git
# su gitolite3
$ gitolite compile
$ gitolite setup --hooks-only
$ gitolite trigger POST_COMPILE

Ensuite, il reste à ajouter les dépôts dans le fichier de conf et le tour est joué.

Mise en place de l'accès via HTTP

Ok, maintenant, vous avez un accès à des dépôts git via SSH, de manière sécurisée pour l'authentification et le contrôle d'accès (qui sont deux choses différentes).

Mais bon, vous êtes ambitieux et vous voulez faire cool comme github et utiliser un service en HTTPS ! Et là, c'est le drame: gitolite ne gère pas super bien l'accès HTTP. En effet, gitolite ne gère pas du tout l'authentification mais uniquement le contrôle d'accès. Dans ce que nous avons vu, c'est SSH qui gère l'authentification, gitolite s'occupe du reste.

Pour la partie HTTP, c'est donc Apache qui va s'occuper de l'authentification et transférer ce qui va bien à gitolite. Mais, nous avons un problème majeur: Apache ne sait pas authentifier avec une clef SSH. Ce n'est pas prévu pour, ce n'est pas fait pour ! Il faut donc broder et c'est que nous propose la documentation de gitolite sur le sujet. Je vous invite aussi à lire cet article que j'ai finalement utilisé.

Comme on doit broder, autant le faire intelligemment, c'est à dire en comprenant ce qu'on fait. Nous devons faire les choses suivantes:

  • Authentifier les utilisateurs depuis Apache.
  • Lancer gitolite-shell depuis un process Apache via CGI.
  • gitolite requière d'utiliser le compte gitolite3, il faut donc un mécanisme qui permette de le faire.
  • Il y a des variables d'environnement à configurer pour que gitolite retrouve ses petits.
  • Il faut un mécanisme pour que les utilisateurs puissent gérer leur mot de passe Apache.

D'un point de vue administration système, j'ai choisi d'utiliser au maximum ce qui est fourni par la distribution Debian. Ainsi, tout le système gitolite est géré par l'utilisateur gitolite3. J'aurais pu installer une version indépendante de gitolite, en plus du paquet Debian. C'est ce qui est recommendé dans la documentation sur l'accès HTTPS.

Le fait d'utiliser l'utilisateur gitolite3 via Apache implique d'utiliser le module suexec de ce dernier. Ceci n'est pas sans conséquence pour certains déploiements de sites web car pour le virtualhost, l'utilisateur qui lancera tous les scripts CGI sera maintenant gitolite3 et non www-data. Si vous utilisez cgit, vous serez impacté.

Mise en place du socle HTTP de base

Pour ma part, voici ce que j'ai fait:

  • Installer le module Apache suexec et l'activer:
    # apt install apache2-suexec-pristine
    # e2enmod suexec
  • Créer un répertoire dans /var/www:
    # mkdir /var/www/bin
    # chown gitolite3:gitolite3 bin
  • Créer un fichier de script shell qui encapsule le lancement de gitolite:
#!/bin/bash
#
# Suexec wrapper for gitolite-shell
#

export GIT_PROJECT_ROOT="/var/local/gitolite/repositories"
export GITOLITE_HTTP_HOME="/var/local/gitolite"

exec /usr/share/gitolite3/gitolite-shell
  • Modifier ses droits/appartenance
    # chown gitolite3:gitolite3 /var/www/bin/gitolite-suexec.sh
    # chmod 0700 /var/www/bin/gitolite-suexec.sh
  • Mettre la configuration suivante dans un fichier de conf d'Apache: [[!format Erreur: Format de page non reconnu apache]]

Une fois votre serveur Apache redémarré, vous devriez pouvoir accéder à vos dépôts en suivant les règles d'accès de gitolite.

Gestion des mots de passe par les utilisateurs

Dans tous les cas, retenez que vous allez devoir gérer des mots de passe Apache pour vos utilisateurs externes, en plus de leur clef SSH. Bon, je vous rassure, GitHub le fait aussi: vous créez un compte Github puis vous uploadez vos clefs SSH.

A notre niveau, gitolite est plutôt fait pour créer des comptes à partir d'une clef SSH publique. Le processus est plutôt inversé par rapport à Github. Mais pourquoi pas !

Néanmoins, une fois que vos utilisateurs ont une clef SSH référencée dans le système gitolite que vous avez mis en place, ils ont la liberté d'utiliser le binaire gitolite-shell qui fait un peu plus que de servit du git. En effet, gitolite-shell permet de lancer quelques commandes de gestion. Parmi celles-ci, il y en a une qui est très intéressante car elle se nomme htpasswd et sa fonction est de gérer un mot de passe HTTPS pour Apache. Avec un peu de configuration, on peut tout à fait permettre aux utilisateurs de lancer cette commande.

Avant de commencer, il convient de modifier le fichier de configuration globale de gitolite. Ce dernier est situé dans /etc/gitolite3/gitolite.rc.

Vous devez ajouter 'htpasswd' à la liste des commandes autorisées (ENABLED). Ensuite, définissez la variable HTPASSWD_FILE avec le bon nom de fichier associé:

    HTPASSWD_FILE => '/var/local/gitolite/gitolite-http-authuserfile',

Voilà, c'est fait.

Pour que vos utilisateurs puissent modifier leur mot de passe HTTP, il leur suffit de faire:

    $ ssh gitolite3@sr.example.org htpasswd
    Please type in your new htpasswd at the prompt.  You only have to type it once.

    NOTE THAT THE PASSWORD WILL BE ECHOED, so please make sure no one is
    shoulder-surfing, and make sure you clear your screen as well as
    scrollback history after you're done (or close your terminal instance).
    
    new htpasswd:

Et le tour est joué. Retenez bien que vous devrez maintenir deux choses:

  • Votre clef SSH
  • Votre mot de passe et compte HTTP.

Mais, c'est déjà ce que vous faîtes si vous êtes sous Github !

Accès non authentifiés via HTTP

Pour l'instant, nous n'avons fait que gérer les accès authentifiés via Apache. Il nous reste à permettre l'accès anonyme, sans authentification. Mais je ne vais pas traiter cet accès dans cet article car plein de solutions s'offrent à vous, d'un répertoire distinct pour les dépôts publics à l'utilisation d'un autre logiciel qui réalise l'accès HTTP pour vous (cgit peut le faire par exemple).

Conclusions

Pour résumer, si la mise en place de l'accès SSH via gitolite est assez simple, l'accès via HTTPS se révèle un poil plus complexe et source de compromis. Mais dans l'ensemble ça fonctionne correctement. N'oubliez seulement pas de lire régulièrement le

Le seul point négatif de gitolite, c'est le fait qu'il soit codé en Perl. Je sais par avance que jamais je ne pourrais me plonger dans le code interne de Gitolite à cause de ce facteur. En dehors de ce point qui m'oblige à faire confiance au développeur de ce logiciel, je dois dire que Gitolite est simple, plutôt robuste et qu'il ne consomme pas beaucoup de ressources.

Néanmoins, la partie HTTP est un poil complexe à gérer et je pense qu'il existe une marge de progrès dans l'application sur ce point. Après tout, l'accès par HTTPS est pratiquement un pré-requis de nos jours si on souhaite favoriser les échanges (surtout derrière des firewalls nazis).

Posted sam. 17 nov. 2018 11:06:30 Tags: