Coin web de Frédéric Péters

fpeters@0d.be

Terminaux parallèles

17 juin 2021, 20:44

Enrico Zini est développeur Debian et il vient de commencer une série de billets sur le développement d’un nouvel outil de déploiement, dans l’esprit d’Ansible, ou en tout cas partant de ses usages d’Ansible et des problèmes qu’il peut avoir avec, c'est son premier billet : My gripes with Ansible.

Dans le mauvais d’Ansible il pointe un problème majeur, Ansible est lent, il pose même l’emphase, Ansible est lent. Et de là il part donc écrire son outil, qu’il appelle Transilience.

Ici j’ai déjà noté (par exemple dans intégration continue maison) comment je déployais au maximum via des paquets .deb, c’est-à-dire via l’exécution répétées de apt update && apt ugprade sur les serveurs. C’est aussi la vieille école suivie au boulot et j’ai parfois tendance à mélanger, mais tant qu’à développer, autant que ça marche au boulot comme à la maison.

On lance donc beaucoup de apt update && apt upgrade et ça avait été automatisé via Ansible et c’était effroyablement lent, genre plusieurs minutes pour passer sur l’ensemble des serveurs; en partie c’est parce qu’il y avait zéro parallélisme, de mémoire c’est quelque chose qui avait pu exister mais avait été retiré dans un refactoring et jamais revenu, mais ça n’expliquait pas tout.

Je n’aime pas traiter les serveurs comme du bétail, j’aime pouvoir jeter un œil sur ce qui se passe, pouvoir prendre la main sur les opérations si nécessaire, et ça se joue facilement en exécutant des commandes les unes après les autres mais gérer l’exécution parallèle complique les choses. Heureusement il existe déjà un outil parfait pour exécuter dans un même terminal plusieurs commandes, c’est tmux, multiplexeur de terminaux, et l’idée a donc été de l’exploiter ici : s’il y a apt update && apt upgrade à exécuter sur les serveurs alpha, beta et gamma, il suffit de démarrer tmux et dans une fenêtre lancer la commande sur alpha, dans une deuxième sur beta, dans une troisième sur gamma, elles seront indépendantes, il sera possible d’aller regarder chacune, s'il y a une interruption il y aura possibilité de prendre la main, le plan est parfait.

Et le plan fonctionne, d’abord côté performances, lucky me j'avais enregistré les résultats dans le commentaire du commit initial. La situation était :

 $ time eotasks -g ext_test apt.upgrade
real    6m9,956s
user    3m32,096s
sys     0m2,322s

et avec le nouvel outil, on passait de 6 minutes à 24 secondes :

 $ time eoptasks -k ext/test apt.upgrade
real    0m24,249s
user    0m0,140s
sys     0m0,025s

Un autre sujet je pensais avoir écrit dessus déjà (mais on dirait que non (en fait un très court moment en parlant de procmail)) c’est passion profiter de l’unicode dans ces interfaces en terminal. Et parce qu’il fallait bien un processus pour démarrer les commandes vers les différents serveurs, autant colorer celui-ci,

On en est resté là assez longtemps mais récemment il y a eu confrontation avec des systèmes de « bastion ssh » primitifs, qui ne gèrent pas d’authentification par clé; c’est quand même assez nul de devoir copier·coller des mots de passe depuis des postits mais nouveau bénéfice à utiliser tmux ici, on a un terminal dont on peut facilement interroger le contenu, et dans lequel facilement envoyer des touches, comme si quelqu’un tapait vraiment dans le terminal.

Il y a quelques bizarreries, genre tmux send_keys qui envoie un espace d'abord, l’idée étant ici que si c'est une commande envoyée dans un shell elle ne sera pas enregistrée dans l'historique (cf la doc sur send_keys), ce qui est quand même très particulier comme situation. Mais passé cela ça marche bien et en terminant de coder ça je me dis que ça peut être pas mal de passer un peu de temps à valider les termes expect et send que j’avais décidé d’utiliser et comme j'en ai le vieux souvenir je vais voir la documentation d'expect, « langage » dont ce type d’automatisation était le cœur de métier. Ça commence mal avec presque plus de liens valides sur https://core.tcl-lang.org/expect/ mais heureusement il y a la page de Wikipedia sur Expect avec des exemples et pile dedans, les deux entrées utilisées (expect/send) que l'on retrouve dans la documentation sont celles que j'ai codées, sorties d’une vieille mémoire d’il y a vingt ans…

Avec ça il devient donc possible d’ajouter dans la configuration des lignes comme

[server:les-boulets]
expect = password:
send = un mot de passe copié du postit

Et au revoir bastion pénible.

Comme quoi, une décision initiale, déléguer le parallélisme à tmux, se trouve encore bien plus tard donner des bénéfices absolument pas anticipés. Comme quoi aussi sortir un peu de la hype (ansible était un peu hype, quand même) pour reculer d’un pas, monter sur les épaules de géants bien solides, et réécrire un peu, ça peut être totalement bénef.

(pour le coup c’est du code encore empreint de particularismes, mais il est dispo dans le dépôt eoptasks du boulot).