Gestion de configuration : introduction
Fri, 31 July, 2015 (1300 Words)Cela doit faire au moins 2 ans que je souhaite partager la façon dont je gère mes configurations (en anglais dotfiles). Comme j'ai longtemps repoussé l'échéance, probablement de peur d'avoir un roman à écrire, je vais en faire une série de petits billets de blog dont celui-ci est l'introduction. Nous y aborderons donc mon besoin, et mes choix.
Besoin(s)
En bon geek que je suis, je suis fan des dotfiles. Les dotfiles — fichiers de configurations — sont de petits fichiers, habituellement dans notre dossier personnel (votre $HOME), qui nous permettent de paramétrer et personnaliser nos outils de tous les jours. C'est principalement vrai pour des outils en ligne de commande — et ça tombe bien, j'adore — mais pas uniquement limité à ces derniers.
Je vais faire un très petit aparté sur le pourquoi de cette personnalisation :
- C'est fun à faire et c'est relativement important de mon point de vue.
- C'est éducatif ou formateur ; on lit les documentations de nos outils, leurs fonctionnalités un peu cachées. On va souvent découvrir un peu la philosophie dans laquelle l'outil a été créé. C'est en mettant les mains dans le cambouis et en foutant un gros bordel que j'ai le plus appris (ça va du langage shell et d'autres langages de scripts, de POSIX, au noyau linux ou encore au LISP avec GNU/Emacs).
- Cela fait gagner du temps et de manière non négligeable. Je suis
né courageux mais terriblement fainéant (et oui c'est possible
:-P
), j'aime pas trop me répéter quand ça devient un peu compliqué / chiant (e.g.docker run monimage args
ça va,docker run
avec-v /tmp:/tmp -v /var/run/docker.socket:/var/run/docker.socket […]
etrun monimage arg1 arg2 arg3 […]
moins déjà).
Mais revenons à nos moutons et faisons une petite liste de mes besoins, un peu en vrac :
- J'ai plusieurs ordinateurs (laptop/desktop/serveurs) et je souhaite avoir mes configurations synchronisées entre ceux-ci — et ce de manière simple, c'est à dire une commande à exécuter.
- C'est lié au point précédent mais, je ne peux pas vivre sans
outil de gestion de version, comme git. Il me faut donc un outil
ou ensemble d'outil qui sache utiliser des outils de gestion de
version du marché.
- En fonction de mes ordinateurs, mes besoins de configuration
changent. Il me faut donc un outil flexible qui me permette de dire
par exemple : sur ce PC j'ai un serveur
Xorg
donc j'ai besoin de mes configuration xorg, de celle de mon window manager, etc. — et inversement sur ce serveur j'ai besoin de python et haskell mais pas de xorg.. - Je ne souhaites pas avoir à faire des liens symboliques, ou de scripts d'installation. Je trouves que ça rends les choses plus compliquées. Du coup il faut que je puisse avoir plusieurs dépôts de configuration (repository) qui pointent au même endroit, sans que ce soit le bordel.
- Le partage est important pour moi. Il en découle deux choses :
- Il faut que je puisse documenter un peu mon repository, avec un
bon vieux
README
; sans que chaqueREADME
se marche dessus. - Il y a quelques informations qui sont personnelles, comme par
exemple les clés ssh. Il me faut donc être capable d'avoir des
dépôts publiques et des dépôts privés. C'est grandement facilité
par l'aspect flexibilité
:-)
.
- Il faut que je puisse documenter un peu mon repository, avec un
bon vieux
- Un bonus que je souhaite, est de pouvoir disposer de hooks, un peu
à la manière de git (voir ici). L'idée est de pouvoir générer un
fichier de configuration à partir d'un ensemble de fichiers qui
viendraient de différents dépôts. Le meilleur exemple que je peux
donner c'est
~/.ssh/config
dans lequel je vais y mettre des bouts publiques que je souhaites partager (comme leHost *
avec des trucs cool commeControlPersist
, on en parlera plus tard) et des bouts privés (mes hosts privés, avec mes configurations de rebonds, etc..).
Cette liste a mis un certain temps à se former dans ma tête, mais une fois qu'elle était formée, j'ai pu assez facilement faire des choix.
Choix
Deux outils et un peu d'organisation permettent de répondre à mes
besoins. Les deux outils sont vcsh
et myrepos
(anciennement appelé
mr
), fait par respectivement Richard Hartmann et Joey Hess (tout
deux assez impliqué dans la communauté Debian).
vcsh
En un mot, vcsh permet de maintenir plusieurs repository git dans
un seul dossier. Par défaut tous les repository git maintenus par
vcsh
pointent vers le dossier $HOME
, mais il est possible
d'utiliser un autre dossier.
L'idée est de pouvoir disposer de plusieurs repository par famille
d'application, par exemple vim
, ssh
, emacs
, zsh
, etc. Cela
permet ainsi d'avoir différents ensemble de configurations sur
différentes machines et pour différents utilisateurs. Cela apporte
une très grande flexibilité et facilite le partage de configuration
(au sein d'une entreprise ou d'un projet par exemple) tout en
laissant la place à la définition de configuration(s)
personnalisé(s).
En bonus, vcsh
supporte un système de hook, permettant d'exécuter
des commandes à différents moments du workflow — c'est la seule
partie qui manquant à vcsh
de mon point de vue alors j'y ai
apporté ma petit pierre.
vcsh
est la clé de voûte de ma gestion de configuration. Sans le
travail formidable de Richard Hartmann, je ne sais pas comment je
ferais..
myrepos
En un mot, myrepos est un outil permettant de gérer plusieurs
repository (git, subversion, mercurial, …) avec une seule
commande : mr
. C'est simple et efficace :
mr u
(oumr update
) pour récupérer les dernières modifications (git pull
,svn up
, …).mr -d $HOME/.config u
pour récupérer les dernières modifications des repository qui sont dans$HOME/.config
.mr -j 6 u
pour paralléliser la récupération (ici 6 jobs en parallèle).mr p
pour pousser des modifications (git push
, …).mr run
pour lancer un commande (j'utilise ça tous les jours).
Il est également possible de personnaliser les commandes à lancer lors d'un update ou autre (toutes les commandes), et même en définir des nouvelles. Cela se présente comme suit :
[foo] checkout = git@github.com:joeyh/foo.git update = git pull --rebase [bar] # This repository has an upstream, which I've forked; # set up a remote on checkout. checkout = git clone git@github.com:joeyh/bar.git cd bar git remote add upstream git@github.com:barbar/bar.git # make `mr zap` integrate from upstream zap = git pull upstream git merge upstream/master git push origin master [mystuff] checkout = git@github.com:joeyh/foo.git # Skip if the current user is not joey skip = test `whoami` != joey [DEFAULT] # Teach mr how to `mr gc` in git repos. git_gc = git gc "$@"
Une autre fonctionnalité qui m'est totalement indispensable est ce
qu'on appel les fixup(s)
. Il est en effet possible d'exécuter une ou
plusieurs commandes (shell) après un update
(ou via la commande
fixup
). C'est grâce à ce système la que je génère mes fichiers de
configuration en provenance de plusieurs repository (comme
$HOME/.ssh/config
ou encore $HOME/.gitconfig
).
myrepos
est l'exemple de l'outil simple et efficace qui fait une
chose et le fait très bien, et dont je n'arrive pas à me passer
:-D
. Je l'utilise également dans plein d'autres cas, comme par
exemple pour mettre à jour mes forks de projets open-source.
Conclusion
Et voilà, c'est tout pour cette introduction ;-)
. La prochaine
partie se penchera sur la structure que j'utilise ainsi que le
repository principal qui est vcsh-home. Dans les parties suivantes
on parlera des autres repository et donc des configurations
spécifiques pour les différents outils (comme sh-config,
emacs-config ou encore go-config). On parlera aussi probablement de
git-annex
dans le futur.