PROJET AUTOBLOG


Le blog de Seboss666

Site original : Le blog de Seboss666

⇐ retour index

Planifier une action via cron dans un container Docker

mardi 26 décembre 2017 à 18:30

Lors de la transformation de l’installation de ma forge personnelle pour la passer sous Docker Swarm, j’ai développé un petit script python pour gérer la mise à jour du sous-domaine de connexion SSH. Mon besoin était simple, donc l’exécution régulière est directement gérée dans le script, mais cette solution pratique manque cruellement de souplesse quand on veut passer à quelque chose de plus fin et complexe. Voyons comment faire plus puissant, sans que ça ne soit horriblement compliqué.

Dans le monde traditionnel de l’informatique, on imagine sans mal aussi bien sous Windows (tâches planifiées) que Linux (cron mon amour), les solutions pour planifier l’exécution de tâches à intervalles plus ou moins régulier (du style, du lundi au vendredi entre 8h et 18h). Mais quand votre service tourne sous Docker, à fortiori sous Docker Swarm, c’est fini, et l’exécution doit passer par d’autres moyens.

Rapide, simple, limité : inclus dans le service

Mon service consiste en un script Python unique, qui tourne en boucle infinie, avec une pause d’une minute à chaque fois. C’est bien, mais pour appliquer la plage d’horaire d’exécution que j’ai mis en exemple juste au dessus, c’est violent à écrire en Python et ne se résume plus dès lors à un sleep(60).

Mais techniquement, vous pouvez appliquer cette méthode à tous les langages qui vous permettent de faire des boucles, donc ça reste valable selon moi pour un besoin très basique.

Cron, mais pas avec la méthode habituelle

Je remercie à Djerfy d’avoir utilisé cette astuce qui a piqué ma curiosité. Pour un bot qui nous envoie régulièrement des citations du site Chuck Norris Facts, c’est via cron que le script qui concerne la connexion à l’API et l’envoi de la citation sur le channel Telegram est exécuté. Cela demande un peu plus de boulot par contre. Il faut plusieurs informations et commandes dans plusieurs fichiers, à commencer par la définition de la stack :

environment:
            - "CRON_SCHEDULE=30 09 * * *"

On retrouve le format habituel des tâches cron (minutes, heures, jour, mois, jour de la semaine), ce qui nous donnera des possibilités bien plus nombreuses. Le Dockerfile rajoute ensuite deux fichiers au lieu d’un seul :

RUN chmod +x /app/chucknorris.py && \
    chmod +x /app/init.sh

CMD ["/app/init.sh"]

Ce n’est donc plus le fichier python qui est appelé directement, mais init.sh. Que contient ce fichier ? Plusieurs choses, mais pour ce qui nous intéresse, voici les morceaux de choix :

if [ -z "${CRON_SCHEDULE}" ]; then
    echo -ne "Empty CRON_SCHEDULE variable\n"
    exit 1
fi

# variables crond
STDOUT_LOC=${STDOUT_LOC:-/proc/1/fd/1}
STDERR_LOC=${STDERR_LOC:-/proc/1/fd/2}

# settings crond
echo -ne "# custom script for sending jokes\n${CRON_SCHEDULE} /app/chucknorris.py > ${STDOUT_LOC} 2> ${STDERR_LOC}\n" | crontab -

# run cron
su -c "/usr/sbin/crond -f"

Mais qu’est-ce que ça fait ce morceau de code ? Pour rappel, contrairement à un système Linux classique, le processus avec le PID 1 dans un conteneur Docker est le processus lancé par la dernière commande CMD du Dockerfile, ici init.sh du coup. Dans ce script, au delà d’une vérification de base, les deux premières lignes intéressantes concernent la définition de variables concernant les descripteurs de fichier pour le fameux processus 1; en gros, on peut rediriger les sorties standards et d’erreurs vers ces descripteurs, ce qui permet de visualiser les messages de notre application réelle via les commandes Docker sur l’hôte.

Ensuite, on définit un nouveau fichier de crontab avec les informations de l’environnement (c’est ce que fait le  echo |crontab -), et enfin on lance crond. Mais que fait donc le -f ? Au début, en fouillant « bêtement » le manuel de crond, je ne trouve pas trace du -f en question, mais c’est le cas dans le manuel de cron. Le switch -f indique à cron de rester en premier plan (foreground, pour les anglophiles qui se poseraient la question), et non de passer en mode démon, ce qui est une condition sine qua non sur le PID 1 pour qu’un container Docker reste en vie.

La puissance de Cron, avec ses faiblesses

J’imagine qu’il faudra un peu plus de boulot si vous devez intégrer plusieurs tâches planifiées dans le même container. On sera probablement plus avisé de séparer les tâches dans des containers séparés si ça concerne des scripts différents.

Cron n’est pas non plus la solution la plus parfaite, et j’ai déjà buté ou été obligé de bricoler (parfois dans le script lancé lui-même), pour obtenir le résultat que voulait le client. En gros, ça ne fait rien de plus ni de moins qu’un service cron sur un OS classique, mais ça permet déjà bien plus de possibilités que d’écrire et de conditionner en dur les exécutions de votre tâche.

Quelques astuces diverses, dixième

vendredi 22 décembre 2017 à 18:30

Il serait criminel de terminer l’année sans vous filer une dernière tournée d’astuces à coller sous le sapin numérique que vous avez certainement quelque part 🙂 Comme toujours, à garder dans un coin de votre mémoire ou de votre wiki personnel (ou un simple marque-pages Firefox, ça fonctionne aussi mais c’est moins facile à chercher).

Convertir une vidéo en série d’images

Un petit défi trouvé je ne sais plus où : retrouver une image précise, dans une vidéo où celles-ci défilent très vite. Plutôt que de m’emmerder à lire au ralenti, à repasser 50 fois en espérant voir quelque chose, il « suffit » de convertir et de générer un fichier image par image de vidéo. Pour ça, il faut extraire le nombre de fps de la vidéo en question, et réutiliser ce paramètre pour qu’ffmpeg fasse le boulot :

ffmpeg -i DMdLcMPW4AUQV9t.mp4 -vf fps=27.5 out%d.png

On a ensuite autant de fichiers images qu’il y a d’images dans la vidéo, et celle qu’on recherche va forcément apparaître.

L’optimisation d’image rapide pour les pressés

Pour économiser quelques précieux mégaoctets quand on travaille sur un site qui manipule beaucoup d’images, sauf à vouloir faire le traitement au moment de l’upload, on peut le faire après coup :

find . -iname "*.png" -exec optipng -o5 -strip all {} \;

find . -iname "*.jpg" -exec jpegoptim -m90 --strip-all {} \;

Les deux logiciels sont à installer et sont disponibles dans la plupart des distributions. Petit test rapide sur le dossier wordpress d’un client, passé de 416 à 322Mo. Après, il faut regarder la qualité finale des fichiers pour les jpg qui seront recompressés…

Yaourt : utiliser la puissance du multicœurs pour la compression

J’ai déjà parlé d’AUR et de la puissance de ce système de gestions de paquets (et de ses risques aussi). En voulant réinstaller MARP, j’ai découvert, au delà de la taille aberrante liée à Electron, que la compression du paquet construit se limitait à un seul cœur, et que c’était en particulier la compression qui était en cause. Pour utiliser tous les cœurs disponibles, c’est dans le fichier /etc/yaourtrc qu’il faut se rendre :

COMPRESSXZ=(xz -c -z - --threads=0)
#Si gzip, installer pigz puis
COMPRESSGZ=(pigz -c -f -n)

A la prochaine installation/mise à jour de paquet, ça devrait être bien plus rapide. Sauf quand votre connexion est merdique…

Asciiart

Je cherche à créer un message sympa pour la connexion SSH à mes serveurs, mais et pour ça, rien de tel qu’un peu d’ascii art. Pour afficher du texte décoré, il y a figlet qui permet de faire quelques trucs sympa.

[seboss666@seboss666-ltp ~ ]$ figlet -f smslant Seboss666
   ____    __                ____ ____ ____
  / __/__ / /  ___  ___ ___ / __// __// __/
 _\ \/ -_) _ \/ _ \(_-<(_-</ _ \/ _ \/ _ \ 
/___/\__/_.__/\___/___/___/\___/\___/\___/

Vous pouvez vous intéresser à la commande figlist pour avoir une idée des « polices » possibles et faire vos propres tests 🙂

PS : figlet est à installer auparavant évidemment.

REGEX : filtrer only alphanum,_ and –

Celle-là, je la dois en grande partie à Djerfy. Sur le coup, on a pas trouvé mieux, mais ça fonctionne. Je cherchais à filtrer dans un script bash le nom de l’utilisateur saisi pour m’assurer qu’il respecte le format que je voulais, à savoir alphanumérique, underscore et tiret. On a abouti à cette routine :

ISVALID=$(echo ${NEWUSER} | sed "s/[a-zA-Z0-9-]//g;s/_//g")
if [ "x" != "x${ISVALID}" ]; then
	echo -ne "error"
fi

Si une brutasse a une meilleure méthode, en sachant que sur la partie sed si on essaie de le faire en une seule fois ça merde, je veux bien un petit partage en commentaire 🙂

Docker : changer la plage d’IP du bridge par défaut

J’ai rencontré un souci après l’installation de Docker sur ma VM Linux au boulot, je n’accédais plus au dépot SVN privé sur lequel nous publions notamment nos clés SSH à déployer sur les milliers de serveurs Linux que nous avons sous notre responsabilité. Il s’avère que c’est l’adresse par défaut du bridge docker0 et surtout la route associée qui n’était pas la bonne. Pour corriger ça, j’ai créé le fichier /etc/docker/daemon.json avec le contenu suivant :

{
"fixed-cidr": "192.168.5.0/24"
}

On redémarre ensuite le démon Docker, le bridge a changé d’adresse et de route, joie dans la demeure, les serveurs auront ma nouvelle clé dans la journée 🙂

Remplir un fichier known_hosts pour son service Gogs

Si vous avez lu mon article sur la mise sous Docker de mon service gogs, il ne vous aura pas échappé que le hook du miroir GitHub a un peu été contrarié par le fait que la première fois l’utilisateur git n’a pas enregistré l’identité des serveurs SSH distants. Si j’ai copié un fichier existant, il est également possible, depuis l’hôte Docker, d’utiliser ssh-keyscan :

ssh-keyscan -t rsa github.com >> /home/docker/gogs/git/.ssh/known_hosts

À répéter deux/trois fois pour choper les trois serveurs. Et c’est valable pour tous les services sur lesquels votre forge doit se connecter.

Gagner quelques secondes en modifiant légèrement votre Dockerfile

Ça révolutionnera pas votre utilisation de Docker, mais en limitant le nombre de commandes RUN, vous limitez la génération d’images intermédiaires et donc gagnez un peu de temps, toujours appréciable si vous enchaînez les « compilations ». Voici ce que je faisais au départ :

RUN apk update
RUN add docker
RUN pip install --no-cache-dir ovh

On peut tout regrouper en une seule « étape » :

RUN apk add -U --no-cache docker &&\
pip install --no-cache-dir ovh

Ça ne change absolument rien à la taille potentiellement délirante de votre image évidemment. Pour ça, je vais essayer d’utiliser j’ai utilisé le module Docker, mais la documentation est affreuse (comme trop souvent).

La météo dans son terminal

Très rapide, en couleur en plus, Et si vous avez besoin d’un peu de précision (genre ça vous répond le mauvais Pays), vous pouvez ajouter un ~ devant le nom de la ville pour qu’il tente une localisation :

[seboss666@seboss666-ltp ~ ]$ curl wttr.in/Melun
Weather report: Melun, France

               Overcast
      .--.     0-4 °C         
   .-(    ).   ↘ 17 km/h      
  (___.__)__)  10 km          
               0.0 mm         
                                                       ┌─────────────┐                                                       
┌──────────────────────────────┬───────────────────────┤  Sat 16 Dec ├───────────────────────┬──────────────────────────────┐
│            Morning           │             Noon      └──────┬──────┘     Evening           │             Night            │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│    \  /       Partly cloudy  │               Cloudy         │  _`/"".-.     Light rain sho…│  _`/"".-.     Patchy rain po…│
│  _ /"".-.     -1-3 °C        │      .--.     1-5 °C         │   ,\_(   ).   1-4 °C         │   ,\_(   ).   1-4 °C         │
│    \_(   ).   → 12-20 km/h   │   .-(    ).   → 15-22 km/h   │    /(___(__)  ↗ 13-21 km/h   │    /(___(__)  ↗ 11-19 km/h   │
│    /(___(__)  19 km          │  (___.__)__)  18 km          │      ‘ ‘ ‘ ‘  14 km          │      ‘ ‘ ‘ ‘  18 km          │
│               0.0 mm | 0%    │               0.0 mm | 0%    │     ‘ ‘ ‘ ‘   0.3 mm | 58%   │     ‘ ‘ ‘ ‘   0.1 mm | 19%   │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
                                                       ┌─────────────┐                                                       
┌──────────────────────────────┬───────────────────────┤  Sun 17 Dec ├───────────────────────┬──────────────────────────────┐
│            Morning           │             Noon      └──────┬──────┘     Evening           │             Night            │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│      .-.      Light drizzle  │      .-.      Light drizzle  │      .-.      Light drizzle  │      .-.      Light rain     │
│     (   ).    0-4 °C         │     (   ).    2-5 °C         │     (   ).    4-6 °C         │     (   ).    2 °C           │
│    (___(__)   ↗ 17-26 km/h   │    (___(__)   ↗ 19-28 km/h   │    (___(__)   ↑ 23-36 km/h   │    (___(__)   ↑ 23-35 km/h   │
│     ‘ ‘ ‘ ‘   20 km          │     ‘ ‘ ‘ ‘   20 km          │     ‘ ‘ ‘ ‘   19 km          │     ‘ ‘ ‘ ‘   20 km          │
│    ‘ ‘ ‘ ‘    0.6 mm | 69%   │    ‘ ‘ ‘ ‘    1.2 mm | 59%   │    ‘ ‘ ‘ ‘    1.4 mm | 75%   │    ‘ ‘ ‘ ‘    1.7 mm | 88%   │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
                                                       ┌─────────────┐                                                       
┌──────────────────────────────┬───────────────────────┤  Mon 18 Dec ├───────────────────────┬──────────────────────────────┐
│            Morning           │             Noon      └──────┬──────┘     Evening           │             Night            │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│      .-.      Light rain     │      .-.      Light drizzle  │    \  /       Partly cloudy  │    \  /       Partly cloudy  │
│     (   ).    3-6 °C         │     (   ).    2-6 °C         │  _ /"".-.     1-5 °C         │  _ /"".-.     0-3 °C         │
│    (___(__)   ↘ 19-27 km/h   │    (___(__)   ↓ 24-32 km/h   │    \_(   ).   ↘ 14-23 km/h   │    \_(   ).   ↘ 13-21 km/h   │
│     ‘ ‘ ‘ ‘   20 km          │     ‘ ‘ ‘ ‘   20 km          │    /(___(__)  17 km          │    /(___(__)  17 km          │
│    ‘ ‘ ‘ ‘    0.7 mm | 79%   │    ‘ ‘ ‘ ‘    0.2 mm | 69%   │               0.0 mm | 0%    │               0.0 mm | 0%    │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘

Cartographie dans un terminal

Oui, encore un autre service qu’on s’attendait pas à trouver, et pourtant, c’est un truc de dingue :

telnet mapscii.me

Ensuite, on utilise a/z pour zoomer/dézoomer, et les flèches pour se déplacer. Bluffant.

Tribute to Star Wars

Fin d’année oblige, on termine avec quelques petites bricoles en bash qui demandent un écran d’une certaine taille en hauteur, et dans le premier cas l’installation d’ack et de lolcat (dispos dans vos dépôts préférés au moins dans Debian depuis Wheezy). On a donc la première commande :

clear ; while : ; do ack --bar | lolcat --force ; sleep 0.05 ; printf "\e[0;0H" ; done

Les développeurs doivent s’ennuyer parfois pour cacher ça dans leur code 🙂

Et le bouquet final, la plus délire de ce que j’ai pu voir je pense (après le générique via les reverse IP), raison pour laquelle je vous la donne en dernier, l’épisode 4 en ascii art à portée de telnet :

telnet towel.blinkenlights.nl

C’est un boulot de malade !

On se donne rendez-vous l’année prochaine 😉

Supprimer GRUB, sans tuer la table de partitions

mardi 19 décembre 2017 à 18:30

Ça fait un bout de temps que je gardais cette bidouille dans les cartons. Avant d’installer mon micro serveur et d’investir dans un NAS, à mon arrivée dans mon appartement j’avais recyclé mon vieux laptop Acer, précédemment libéré sous Manjaro, en serveur perso, sur lequel j’avais branché un disque dur externe pour disposer d’un stockage un peu plus conséquent. Et à l’occasion d’un reboot à distance, ce disque dur m’a posé quelques problèmes.

MBR mon amour

Le disque dur externe n’était en fait rien de plus qu’un ancien disque dur, le dernier en date que j’avais monté dans mon laptop HP (avant le Acer donc), qui a eu l’occasion d’accueillir ArchLinux quelques temps avant la reconversion. Ce disque dur avait donc vu son MBR accueillir GRUB. Lors des formatages qui ont suivi en tant que disque dur externe, ce MBR n’a jamais été réinitialisé.

Hors, lors d’un redémarrage suite à une série de mises à jour, le laptop a tenté de démarrer sur ce disque USB. Il a identifié GRUB, qui s’est alors mis à chercher, d’après ses paramètres, une partition qui n’existe pas, et donc le serveur échoue à démarrer.

De l’art de supprimer les bons blocs

Attention : Ce MBR n’a de sens qu’avec l’ancien modèle de partitions dit « msdos ». Les disques récents, en particulier les plus volumineux, utilisent le format GPT décrit évidemment de manière différente. Les manipulations que je présente ici concernent uniquement le format « msdos ».

Donc, le MBR et la table de partitions sont décrits dans les 512 premiers blocs octets du disque. Ici, c’est grâce à dd qu’on va opérer sur le disque. Après avoir branché votre disque, et identifié son nom (/dev/hdX dans mon cas, le disque étant un IDE), on commence par sauvegarder ces fameux 512 premiers blocs octets en cas de besoin :

dd if=/dev/sdX of=/tmp/hdXmbr.img bs=512 count=1

Ensuite, on a plusieurs choix. Soit on souhaite repartir complètement de zéro, et on supprime le contenu des 512 blocs octets en question :

dd if=/dev/zero of=/dev/hdX bs=512 count=1

Il faudra ensuite un outil tiers (cfdisk, parted…) pour recréer une table de partitions et ensuite les partitions recherchées; soit on veut conserver la table de partitions, et là, il faut soit tout supprimer et restaurer uniquement les blocs octets nécessaires, à savoir les 64 blocs qui la décrive :

dd if=hdXmbr.img of=/dev/hdX bs=1 count=64 skip=446 seek=446

Soit ne supprimer que les 446 premiers blocs octets :

dd if=/dev/zero of=/dev/hdX bs=446 count=1

Et normalement, ça devrait cuire. Si jamais vous avez un souci et que ne voyez plus vos partitions, vous pouvez toujours restaurer l’image entière, ce qui permettra dans un premier temps de récupérer les infos et d’analyser plus posément ce qui a déconné.

Et pour les nouvelles technos ?

Il serait intéressant également de s’attarder sur les disques plus récents qui utilisent des blocs de 4ko au lieu de 512 et qui exploitent le format GPT. Avis aux bonnes volontés 🙂

Le dépôt pour le service gogs sur Docker Swarm est en ligne

samedi 16 décembre 2017 à 10:30

Voilà, après plusieurs soirées et matinées à pleurer pour maîtriser les modules et mettre en forme potable les fichiers et le code liés à l’histoire de ma première expérience de Docker Swarm, j’ai décidé de publier le tout sur GitHub, qui est, vous vous en doutez, un miroir du dépôt gogs privé. Je pense qu’il va aussi être intéressant de détailler les raisons du décalage dans la publication.

En soi la partie Gogs est ultra simple et c’est surtout la partie maison, la mise à jour de DNS, qui m’a pris le plus de temps à mettre au propre. Je vous donne tout de suite l’adresse du dépôt, si vous souhaitez consulter son historique pour suivre cet article au cas où ça ne serait pas assez parlant.

Une image initiale beaucoup trop grosse (et c’était pas le seul problème)

Mes choix de départs étaient fonctionnels, mais vraiment pas optimisés. Pour les plus curieux qui fouilleront les logs git, vous verrez à quel point c’était dégueulasse. En soi la partie gestion de l’API OVH n’était pas affreuse, mais pour récupérer l’hôte sur lequel le service tourne, je passais par subprocess et lançais la commande docker directement. Ce qui impliquait de l’installer en même temps que les autres morceaux dont j’avais besoin.

Moralité, l’image de base pesait 157Mo, pour exécuter un script Python d’une trentaine de lignes. Pire encore, si j’ai dès le départ pris le pli d’exporter la configuration des credentials pour l’API, tout le reste était géré en dur dans le code : nom du service, zone DNS, sous-domaine, et même la liste des membres du cluster avec leur IP. Non vraiment y’a pas grand chose à sauver de ce script.

Le Dockerfile lui-même n’était pas le plus optimisé du monde, avec trois commandes RUN successives pour :

Sachant que pour chaque RUN il crée une image intermédiaire sur laquelle il s’appuie pour le RUN suivant. Ouais c’est pas dingue, mais c’est mon premier Dockerfile en même temps. Vous comprendrez que j’avais envie de faire les choses un peu plus proprement, autant pour vous que pour moi d’ailleurs.

Des choix un peu plus pertinents, mais qui demandent plus de maîtrise

Donc, mon premier réflexe a été de m’interroger sur le poids de cette fameuse image, un problème que j’avais déjà formulé lors de mon premier cas d’usage personnel de Docker avec wpscan (d’ailleurs un commentateur éclairé avait présenté les choses différemment et améliorait grandement le dossier). En cherchant, il s’avère qu’il existe un module Docker pour Python, et un test rapide de construction montre une taille de seulement 63,4Mo une fois les choses réglées. Une sacrée amélioration, qu’il sera compliqué de pousser plus loin.

Restait à savoir s’en servir. Et ça a été une purge croyez-moi, j’ai souffert, je sais que ça ne sera probablement pas la dernière fois, d’autant plus que la documentation est particulièrement peu accessible pour un débutant. Là où on peut directement sélectionner et récupérer les infos d’un service avec la cli docker en une seule commande, il aura fallu pas mal d’itérations et d’échecs successifs pour arriver à un résultat fonctionnel, qui vous le conviendrez, n’est pas des plus esthétiques et pourrait peut-être mériter un peu plus de lisibilité de ma part.

Il y aurait je pense encore pas mal de boulot pour faire quelque chose de définitivement carré. Dans l’immédiat, c’est déjà je pense suffisamment organisé et généralisé pour que vous l’adaptiez un peu facilement à votre cas d’usage.

Enfin, pour le Dockerfile, il ne reste plus que les installations de modules Python, qui se fait en un seul RUN. On gagne donc deux étapes, ce qui permet de gagner du temps et des images intermédiaires. Toujours pratique quand on voit que même sur une connexion locale, le temps de génération et d’upload sur un registry privé peut s’avérer d’une lenteur que je n’explique toujours pas.

Vous n’aurez pas forcément L’Alsace et la Lorraine tous les dépôts

J’ai décidé de publier celui-ci car la part de « créativité » le justifiait à mes yeux. Mais certains dépôts qui vont contenir les descriptions d’autres services qui tourneront sur le cluster ne seront que des légères adaptations de ce qu’on pourrait trouver à portée d’une recherche sur n’importe quel moteur, alors ne vous attendez pas non plus à une profusion de partages.

Mais évidemment, si la « valeur ajoutée » se justifie sur un autre de mes projets, je n’en parlerai certes peut-être pas sur le blog, mais surveillez GitHub, on sait jamais. J’ai également un compte sur Framagit (créé à l’occasion d’une légère implication sur lufi), un jour qui ne sera pas fait comme un autre j’ajouterai peut-être une ligne sur mes hooks pour rebalancer les infos là-bas aussi, histoire d’avoir une deuxième version publique de ce que je décide de partager.

Un bon petit casque Bluetooth confortable, endurant, et utilisable sous Linux

mercredi 13 décembre 2017 à 18:30

J’ai expliqué récemment que j’utilisais déjà un casque Bluetooth avec mon téléphone, mais c’est un casque très peu cher (sub 15€), qui tient à peine 3h, en intra-auriculaire (faut se le plugger dans l’oreille pour entendre quelque chose). Le black friday étant tombé le jour de mon opération, j’ai malgré tout réussi à profiter d’une offre pour me payer un casque un peu plus conséquent, et surtout plus endurant.

C’est donc pendant que je récupérais graduellement l’usage de mes jambes après l’anesthésie que j’ai pu tomber sur ce casque EP-B52 de marque AUKEY, à seulement 36€ pendant le Black Friday, contre 50€ actuellement. Je n’avais pas d’autres gros besoins immédiats, contrairement à l’année dernière où j’ai rééquipé la famille en smartphones potables, et je peste déjà assez souvent contre mon casque actuel, qui n’a d’autonomie que le nom théorique, pour me laisser convaincre. Au passage, j’ai commandé sur le site web d’Amazon depuis Firefox Android. C’est possible, Amazon a pensé le responsive jusqu’au bout, pas besoin d’une application intrusive qui va s’occuper de scanner vos SMS, contacts, fichiers sans raison.

En plus j’ai découvert la marque AUKEY cette année, d’abord avec une batterie externe de 16000mah, commandée un peu avant la Nuit du Hack, dont je suis également très content, la qualité de fabrication semble être là, et un positionnement sur l’emballage tout à fait honnête (carton recyclable voir même recyclé, à l’impression minimaliste). Les gammes de produits qu’ils fournissent sont variées, je vous laisse parcourir le site officiel. Un mot d’ordre semble régner sur leurs produits : une prestation plus qu’honnête pour le prix proposé. En contrepartie, ne vous attendez pas à une foultitude d’additions bienvenues : ma batterie n’est fournie qu’avec un petit câble qui peut servir dans les deux sens (recharger un appareil et recharger la batterie elle-même), et la notice en plusieurs langues. Le casque est fourni avec un câble de recharge micro-USB, un câble jack TRRS avec commande (j’y reviendrai), et la notice, avec en plus une pochette rigide pour le transport. Sur les deux produits la qualité de traduction de la notice est très bonne, on sent que ce n’est pas une moulinette chinois-anglais-français automatisée avec un Google Translate du pauvre qui est inutilisable. En résumé, on va a l’essentiel, et pour ma part c’est tout ce que je demande.

L’emballage qui va à l’essentiel

Mais bref, concentrons-nous donc sur le casque. Il est repliable, adaptable à plusieurs tailles de tête. Les charnières et les glissières semblent solides, et sont en métal. Les coussinets sont en simili-cuir qui aura probablement un peu de mal à durer plusieurs années, mais ils ne sont ni trop durs, ni trop mous, c’est confortable. Je n’avais pas vérifié avant, mais leur taille est parfaite, ils entourent tout juste mes pavillons. Le casque n’est pas trop lourd, même si je suis plutôt peu sensible à ce point (en tout cas pour moi il n’est absolument pas gênant). Il est tout de noir mat vêtu, et ça me plaît. Il n’y a que trois boutons : un « + », un « -« , et un « phone », mais tous ont plusieurs fonctions : par des appuis courts, les « + » et « – » contrôlent le volume du casque, qui est indépendant du volume du dispositif de lecture, des appuis longs envoient une commande précédent/suivant à l’application de lecture (VLC sur mon téléphone, comme sur PC). Le bouton « phone » est encore plus polyvalent, il sert à allumer/éteindre le casque, à le basculer en mode « recherche », à décrocher le téléphone (y’a un micro intégré), à faire pause dans l’application musique, bref, rien de transcendant ou d’original, mais ça répond bien, les pressions doivent être prononcées ce qui évite les « clics » accidentels.

Le casque est à la norme Bluetooth 4.1, il est donc préférable d’avoir sous la main un appareil qui supporte au minimum cette norme. Cela permet un débit certes faible mais plus facilement atteint qu’avec les versions précédentes de la norme, une qualité audio moins dégradée, une portée plutôt confortable, et une consommation énergétique très faible. L’appairage avec aussi bien mon téléphone que mon ordinateur s’est effectué du premier coup sans accroc, ce qui encore en 2017 n’est pas toujours garanti. En fonction des évènements (allumage, association, extinction, batterie faible) le casque émet un son un peu étrange qu’il faudra que j’identifie un peu mieux; même mon casque pourri m’annonce la couleur en anglais, c’est un peu dommage que ce ne soit pas le cas ici. Le câble TRRS qui est fourni avec désactive le Bluetooth quand on le branche. Cette bascule filaire, que je dois encore tester dans le cadre d’une batterie à plat pour confirmer le bon fonctionnement, est en tout cas bienvenue. La « télécommande » du câble contient un micro qui sera plus exploitable que celui qui est posé sur l’une des oreillettes du casque, qui arrose tellement large pour réussir à capter votre bouche que votre interlocuteur profite certainement de tout votre voisinage. Cette même télécommande déporte aussi le bouton multifonctions pour décrocher/raccrocher/mettre en pause/lancer la lecture.

Pour la qualité d’écoute… Comme je le pensais, pas de miracle. J’aurai même tendance à pondérer la description d’Amazon sur la profondeur du son et la solidité des basses. Certes il est possible de raffiner un peu en jouant avec l’égaliseur de VLC, mais malgré tout en Bluetooth, on sent la compression, en particulier sur certains types de musique comme celle des Daft Punk (j’ai remis la main sur le live de 2007), et les basses manquent cruellement, ceci dit il ne manque pas grand chose du reste du son. C’est d’autant plus flagrant quand on compare avec le câble Jack : les basses sont beaucoup plus présentes, et sans être « waouh », le son est bien plus agréable à réglages identiques.

Et l’appairage Bluetooth sous Linux… J’ai un module Intel 7260 qui fait Wifi+Bluetooth, parfaitement reconnu par le noyau 4.9 que j’utilise actuellement, et c’est Blueman sur Manjaro XFCE qui assure la partie gestion des périphériques. La découverte et l’appairage sont immédiats, juste une petite surprise, à la première connexion c’est l’ordi qui fait la connexion, donc ça fonctionne direct, lorsque j’ai rallumé la deuxième fois il a fallu répondre à une boite de dialogue qui me demandait d’autoriser l’association, temporaire ou permanente, du casque à l’ordinateur. Il y a plusieurs profils présents (casque, micro, etc), j’ai sélectionné casque puisque c’est l’usage principal que je compte en faire. Là, le premier test fait mal : le son est dégueulasse au possible, à la limite du compréhensible. Le coupable est tout vite trouvé : par défaut, pulseaudio ne sélectionne pas le profil AD2P. Un coup de pavucontrol plus tard, en basculant au passage le casque comme périphérique prioritaire, le son est de la même qualité qu’avec le téléphone, et on constate la même perte de données sur les basses en comparant avec le jack. Quand je compare à quelques années auparavant avec mon laptop Acer, mon adaptateur Bluetooth USB et l’état de l’art des logiciels de l’époque, le progrès est monstrueux. À une ou deux étapes de configuration simples près, ça « juste marche ».

Et concernant l’autonomie, au moment où je démarre l’écriture de l’article j’en suis à plus de 9h d’écoute sans signe de fatigue. Maintenant que je finalise le tout (relecture/corrections), j’en suis à plus de 15h, et il ne râle pas encore. Souvent l’autonomie annoncée est loin d’être une réalité, mais là on en est pas loin, ce qui est une très bonne surprise.

Finalement, la question qu’on pourrait se poser, c’est : vaut-il les 50€ qu’il coûte habituellement ? J’aurais presque envie de dire oui, mais c’est en comparaison de mes expériences passées. Pour les mélomanes exigeants, il sera clairement insuffisant, notamment sur les basses, mais pour ma part ça me convient, en plus si j’ai envie d’un peu plus de fidélité j’ai le câble pour aller avec, en jack standard ça passe partout. La promesse tenue de l’autonomie annoncée est également plaisante. Son design n’est certes pas dingue, mais c’est loin d’être moche, le mat donne même une impression de qualité qui n’est de toute manière pas absente du produit, bien au contraire. Bref, Pour moi c’est un choix à ne pas exclure sur cette gamme de budget.