vendredi 9 janvier 2026

Compter les lignes d'un projet git

Ceci est un blog-note, il serait donc dommage de ne pas en profiter pour... Prendre des notes !

J'ai récemment voulu voir où j'en étais quant à la quantité de code produite pour un projet. Simple curiosité, pour me rendre compte.
Comment faire ? Comme ceci :

git ls-file | xargs wc-l

Bien sûr, si vous voulez plus de détail, comme le nombre de lignes des fichiers php, vous pouvez rajouter un grep.

git ls-file | grep '.php' | xargs wc -l

C'est tout.

Edit du 17 janvier 2026 : On me souffle dans l'oreillette que Tokei fait aussi très bien le boulot ! Merci à Ollivier Robert pour la découverte.

mercredi 7 janvier 2026

A worker was found in a dead state

Nouvelle joie de MacOS... Oui je sais, j'ai qu'à installer Linux. Mais non.

Je bossais tranquillement sur un playbook Ansible ce matin quand, tout à coup, le drame !

[ERROR]: A worker was found in a dead state

Mais que vais-je faire ? Comment vais-je survivre ? Quel avenir vais-je laisser à mes enfants ?
Et bien figure-toi, encore une fois : ça n'arrive pas sur Linux et c'est visiblement récurrent sur MacOS. Mais on aune solution !

Il suffit de lancer son playbook avec la variable d'environnement OBJC_DISABLE_INITIALIZE_FORK_SAFETY à yes :

OBJC_DISABLE_INITIALIZE_FORK_SAFETY=yes ansible-playbook ...

En gros, si j'ai bien compris (rien de sûr), c'est dû à l'utilisation de la méthode python fork() qui permet de créer un nouveau processus. Sauf que sur MacOS, si la bibliothèque utilisée n'est pas "fork-safe", alors l'OS t'envoie balader avec un plantage ou un deadlock.

Voilà, enjoy, même si c'est pas optimal.

jeudi 5 juin 2025

Comprendre les RegExp - Exemple d'un feed BlueSky

Les RegExp ont tendance à faire peur à toute personne qui n'est pas familiarisée avec celles-ci. Pourtant, lorsqu'on connaît quelques points précis, on peut déjà aller assez loin.
Ainsi, sans avoir la prétention de couvrir tout l'usage des expressions régulières (loin s'en faut), je pense que celle qui illustre ce billet est une bonne entrée en matière.

Celle-ci est celle qui construit le feed TND(FR) que je décris dans ce billet. Prenons un peu de temps pour la décortiquer.

L'expression est donc la suivante :

(^|\s|\b|#)(ritaline|concerta|tda(h)?|tsa|autisme|
autistique(s)?|bipolaire(s)?|autiste(s)?|tnd
neurodéveloppement(aux)?|synesthésie|méthylphénidate|
hyperactivité|hyperacti(f|ve)(s)?|asperger|trouble de l'attention|
trouble déficit de l'attention)($|\s|\b)

Note : Elle diffère en effet de celle de l'illustration, puisque je me suis rendu compte d'erreurs et l'ai corrigée.

On peut ici la séparer en trois éléments distincts, chacun entre parenthèses (pour prioriser et regrouper, comme en mathématiques). Le premier est (^|\s|\b|#). Il correspond au début de l'expression recherchée, et contient plusieurs éléments intéressants.

  • ^ indique qu'il s'agit d'un début de ligne
  • \s indique un espace ou une tabulation
  • \b indique la position de début ou de fin de mot
  • # n'est ici que le caractère # lui-même, utilisé pour les hashtags sur la plupart des réseaux sociaux (coucou Threads)
  • | est quant à lui un simple OU qui sépare deux éléments

Ce bloc peut donc être lu comme : Un début de ligne OU un espace ou une tabulation OU un début ou une fin de mot OU le caractère #. Et c'est exactement ce que nous recherchons. Nous voulons que l'expression qui sera détectée commence (étant donné que c'est le premier bloc) par un début de ligne OU un espace ou une tabulation OU un début ou une fin de mot OU le caractère #.
Ceci empêche par exemple de chercher le mot vent sans variation, et d'avoir en retour éventuel qui contient bien vent mais n'est pas l'expression souhaitée, puisqu'il ne commence pas par vent.

Le second bloc est le plus long : (ritaline|concerta|tda(h)?|tsa|autisme|autistique(s)?|bipolaire(s)?|autiste(s)?|tnd|neurodéveloppement(aux)?|synesthésie|méthylphénidate|hyperactivité|hyperacti(f|ve)(s)?|asperger|trouble de l'attention|trouble déficit de l'attention)

On définit ici l'ensemble des termes que nous voulons sélectionner avec notre expression régulière, tous séparés par un | qui veut dire OU. Nous voulons donc retenir les termes ritaline OU concerta OU autisme OU tsa, etc.
Une spécificité ici est que certains mots sont regroupés en quelques caractères. Par exemple, pour regrouper à la fois hyperactif, hyperactive, hyperactifs et hyperactives, j'ai utilisé hyperacti(f|ve)(s)?. Attardons-nous là-dessus. Nous avons ici, à nouveau, trois bloc :

  • hyperacti est le début du mot que nous cherchons, juste après les critères du premier bloc vu plus haut
  • (f|ve) indique qu'après le début du mot, nous voulons le masculin (f) OU le féminin (ve)
  • (s)? permet d'inclure le pluriel - ici le s- tout en le rendant facultatif, ce que permet le point d'interrogation

Ainsi, nous devons avoir un mot qui commence par hyperacti, suivi du masculin f ou ve. Ces points sont obligatoires. Nous pouvons aussi avoir le pluriel s à la fin, mais le mot sera retenu même s'il ne contient pas le s, et ce grâce au ?.

Enfin, le dernier bloc est à l'image du premier, et indique ce que nous devons rencontrer à la fin de notre expression recherché : ($|\s|\b)

  • $ indique une fin de ligne
  • \s indique un espace ou une tabulation
  • \b indique un début ou une fin de mot

Là encore, directement après les termes que nous voulons rechercher, nous devons avoir une fin de ligne OU un espace ou une tabulation OU un début ou une fin de mot. Pour reprendre le même exemple que pour le premier bloc, ceci empêche que soit retenu venteux alors que nous ne voulons que le mot vent.

Voilà, j'espère qu'avec ce court billet vous aurez de quoi construire quelques petites expressions régulières, et pourquoi pas construire un feed BlueSky ;) Moi je les construis avec SkyFeed

Pour une liste plus exhaustive des différents opérateurs d'expressions régulières, je ne peux que vous renvoyer à la page wikipedia correspondante.

mardi 25 février 2025

Notes en vrac #8

Huitième édition des notes en vrac. Beaucoup de retard dans mes lectures, le contenu ne sera pas forcément de toute première fraicheur.

Tech

Mails

  • DKIM, DMARC, SPF, ... Pourquoi ? Comment ? Johan explique tout dans son billet.

Clap de fin

Sécurité et fuites

Mises à jour

  • Les versions 4.1.23, 4.2.17 et 4.3.4 de Mastodon sont disponibles.

Vie privée


TDAH

  • Résultats de l'enquête sur l'arrêt du traitement pour le TDAH, sur le site TDAH à l'âge adulte.

jeudi 25 avril 2024

Operation not permitted

Il existe plusieurs façons d'envoyer des fichiers vers un conteneur sur un hyperviseur Proxmox. Mais toutes ne sont pas toujours sans embuches. Le cas que j'ai rencontré aujourd'hui m'a un peu fait me casser les dents. Pour pas grand chose, au final. Pour refaire rapidement le parcours, j'ai voulu déposer les fichiers statiques du site ZdX sur le conteneur qui le sert. J'ai donc envoyé mes fichiers sur mon user via scp, monté le système de fichiers du conteneur grâce à pct mount, puis j'ai fait un banal mv. Et c'est là que ça se corse.


J'ai donc commencé par envoyer mes fichiers de façon classique avec sftp, dans le home de mon utilisateur xakan. J'ai monté le système de fichier du conteneur avec pct mount <id du conteneur>, et simplement déplacé les fichiers avec mv <mondossier> /var/lib/lxc/<id>/rootfs/var/www/zdx. Un petit lxc-attach <id du conteneur> plus tard, me voici dans le dossier /var/www/ à vérifier les droits sur les fichiers avec ls -al :

drwxr-xr-x 11 nobody   nogroup  4096 Apr 24 19:20 zdx

Qu'à cela ne tienne, toujours depuis le conteneur, on met www-data:www-data comme propriétaires du dossier :

chown -R www-data: zdx
chown: changing ownership of 'zdx/terms/index.html': Operation not permitted

Ah. C'est même pas un accès refusé, c'est une opération non autorisée. lsattr m'indique que l'attribut i n'est pas présent, ce n'est donc pas le problème. En réalité, cela vient du fait que mon conteneur est un conteneur sans privilèges, sans correspondance entre l'utilisateur xakan et les utilisateurs du conteneur. Le dossier est donc assigné à nobody et nogroup.

La solution consiste donc à aller chercher le pid du processus init tel que vu par l'hôte. Il est bien entendu à 1 du côté du conteneur.

lxc-info -p 200
PID:            1204

Du côté de l'hôte, le processus init de mon conteneur est donc 1024. Je peux à partir de là aller chercher l'uid de l'utilisateur qui exécute ce processus, toujours tel que vu depuis l'hôte :

cat /proc/1204/uid_map
         0     100000      65536

De retour sur le conteneur après un nouvel lxc-attach 200, je vérifie l'id de l'utilisateur www-data qui doit posséder le dossier :

id -u www-data
33

D'un point de vue hôte, l'utilisateur qui doit être propriétaire du dossier zdx a donc pour id 100000 + 33 (id de l'utilisateur depuis le conteneur). Il n'y a donc plus qu'à définir les droits depuis l'hôte, en passant par le montage du système de fichier :

chown -R 100033:100033 /var/lib/lxc/200/rootfs/var/www/public

On démonte le système de fichier du conteneur :

pct unmount 200

Et on va sur le conteneur vérifier que les droits sont bons, toujours avec ls -al :

drwxr-xr-x 11 www-data www-data 4096 Apr 24 19:20 zdx

That's it!

mardi 9 avril 2024

Mastodon, maintenance et 2FA

Nous avons récemment, avec Xala, migré les différents services de ZdX pour aller vers une infrastructure plus puissante et surtout plus facile à faire évoluer. Et le dernier service à avoir été migré est Mastodon qui a toujours le don de réserver des surprises.

À la fin de cette migration donc, nous avons rencontré des difficultés avec PostgreSQL, et avons pu observer de nombreuses entrées dupliquées dans la base de Mastodon.

Qu'à cela ne tienne, Mastodon propose tootctl, un outil d'administration qui permet également de corriger les entrées dupliquées. Allons-y :

mastodon@zdx-mastodon:~/live/bin$ ./tootctl maintenance fix-duplicates
This task will take a long time to run and is potentially destructive.
Please make sure to stop Mastodon and have a backup.
Continue? (Yes/No) Yes
Deduplicating user records…
Restoring users indexes…
Removing duplicate account domain blocks…
Restoring account domain blocks indexes…
Removing duplicate account identity proofs…
Restoring announcement_reactions indexes…
Deduplicating conversations…
Restoring conversations indexes…
Deduplicating custom_emojis…
Restoring custom_emojis indexes…
Deduplicating custom_emoji_categories…
Restoring custom_emoji_categories indexes…
Deduplicating domain_allows…
Restoring domain_allows indexes…
Deduplicating domain_allows…
Restoring domain_blocks indexes…
Deduplicating unavailable_domains…
Restoring domain_allows indexes…
Deduplicating email_domain_blocks…
Restoring email_domain_blocks indexes…
Deduplicating media_attachments…
Restoring media_attachments indexes…
Deduplicating preview_cards…
Restoring preview_cards indexes…
Deduplicating statuses…
Restoring statuses indexes…
Deduplicating accounts… for local accounts, you will be asked to chose which account to keep unchanged.
Restoring index_accounts_on_username_and_domain_lower…
Reindexing textual indexes on accounts…
Deduplicating tags…
Restoring tags indexes…
Deduplicating webauthn_credentials…
Restoring webauthn_credentials indexes…
Deduplicating webhooks…
Restoring webhooks indexes…
Finished!

Trop facile !

Sauf que, suite à cela... Plus de 2FA sur l'instance ZdX. Impossible de se connecter si le 2FA est activé, le code généré est systématiquement refusé.

Me voilà obligé de désactiver le 2FA, et impossible de le remettre. Peu importe le compte. Je n'ai pas creusé, mais c'est dommage.

x.x.x.x - - [09/Apr/2024:12:00:47 +0000] "POST /settings/two_factor_authentication/confirmation HTTP/1.1" 500 894 "https://social.zdx.fr/settings/two_factor_authentication/confirmation/new" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15"

vendredi 2 février 2024

Changer la version de Ruby

À chaque fois que la version minimale de Ruby évolue dans les prérequis de Mastodon, je me retrouve à chercher comment la mettre à jour. C'est l'occasion pour moi de poser ça ici pour retrouver mes petits plus facilement.

Voici donc les quelques commandes qui me sont toujours utiles. Attention, j'utilise ici rbenv.

Connaître la version de Ruby :

$ rbenv version

Lister les versions disponibles :

$ rbenv install --list

Si la version voulue n'est pas disponible :

$ git -C /home/mastodon/.rbenv/plugins/ruby-build pull

Installation de la version voulue :

$ rbenv install <version>

Application de la nouvelle version :

$ rbenv local <version>

mercredi 13 décembre 2023

Notes en vrac #2

Régulièrement, j'essaie de poster ici quelques notes en vrac. Voici la deuxième édition. Rapide et datée pour certains liens. Je m'appliquerai mieux la prochaine fois.

Santé mentale et TND

  • Découverte du rôle d'un régulateur cérébral impliqué dans les maladies psychiatriques, par le CNRS et handicap.fr

Tech

  • Canonical a sorti Dqlite, un outil permettant de faire de la haute-disponibilité avec SQLite. Je suis perplexe.
  • GitHub supporte enfin le multi-compte.

Sécurité

Liens en vrac

  • Où trouver des ressources légales pour de bonnes lectures numériques (payantes et gratuites) : Outrelivres

lundi 28 août 2023

Notes en vrac #1

Voilà plusieurs semaines que je prends des notes dans le but de sortir ce billet. Voilà une belle occasion de se lancer, et d'essayer ensuite de s'y tenir.


Personnel

  • Voilà maintenant deux mois que bébé tout neuf a agrandi notre famille. Ça reste des moments difficiles à passer, notamment au niveau du sommeil et de notre disponibilité. Mais notre famille est maintenant complète et magnifique.
  • J'ai pris un peu de recul au niveau associatif. Moins d'engagement. J'avais besoin de me libérer du temps, de faire des choses qui me paraissaient plus abordables, dans lesquelles je pourrais m'engager sans problème. Ce n'est pas encore parfait, mais je me suis sorti des promesses que je ne pouvais pas tenir.
  • J'essaie de m'améliorer au niveau familial en retrouvant peu à peu de la sérénité. Ça semble fonctionner.

Professionnel

  • La v18 de Dolibarr est sortie. Je vois quelques uns de mes développements être intégrés et présents dans le changelog. C'est peu, mais c'est toujours plaisant.
  • J'ai enfin trouvé mon équilibre, et me sens moins sous pression (que je me mettais seul). Retrouver une certaine sérénité ici aussi. Ce n'est pas déplaisant.
  • Je me suis aussi débarrassé de cette prestation qui traînait depuis beaucoup trop longtemps avec mon activité d'auto-entrepreneur.
  • Je me dégage un peu de temps pour faire des tests concernant l'infrastructure et découvre de nouveaux outils.

Réseaux sociaux

  • J'ai posé mes valises sur Bluesky depuis 16 jours maintenant. Je m'y plais, je retrouve autre chose. Il suffit d'attendre que le réseau s'étoffe un peu. Mais le concept de feeds ne me déplaît pas. C'est original et ça change un peu pour découvrir du contenu.
  • Les tempêtes de m**de continuent sur Mastodon, toujours pour les mêmes raisons : l'idéologie prend le dessus sur les aspects légaux. Le dialogue reste relativement bloqué, et on voit encore des guerres de chefaillons qui pensent détenir une vérité absolue et se permettent de bloquer à vue ce qui ne leur plaît pas, privant leurs utilisatrices et utilisateurs d'une partie de la fédération. Mais ces gros acteurs restent importants et centralisent du fait de leur visibilité.

Des liens en vrac

Tech

Climat et météo

Divers

Neuro/Santé mentale