Planet Asrall

July 18, 2020

Alexandre Bailly

Déploiement terminé du nouveau blog

La mise en place de la nouvelle version du blog est terminée.

Ancienne version du blog

L'ancienne version du blog est toujours accessible à cette adresse : https://blog.chibi-nah.fr/oldblog/ Les commentaires sont bien entendu désactivés.

Nouvelle version du blog

Bien entendu, le déploiement de la nouvelle version ne s'est pas produite sans erreur :

remote: rsync: open "blog/deploiement-termine.html" failed: Permission denied (13)
remote: rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1207) [sender=3.1.3]
To blog: blog.chibi-nah.fr.git
   da63214..4194076  master -> master

Là, c'est bon, c'est corrigé.

Il ne me reste "plus" qu'à écrire de nouveaux articles… mais ça, c'est une autre histoire.

Flux RSS/Atom

"Normalement", ça devrait être bon avec de la réécriture d'URL (RewriteRule) et une redirection 302 vers la nouvelle adresse du flux RSS (il n'y a plus de flux par catégorie).

by alex at July 18, 2020 10:00 PM

July 04, 2020

Alexandre Bailly

Nouveau blog (2020)

Le nouveau blog est maintenant en place. À la place de PluXML, c'est maintenant au tour de Pelican de gérer le contenu.

Changements

Au niveau changement, le plus visible est probablement le changement du thème. Cependant, le procédé pour la rédaction des articles est complètement différent.

Les articles sont désormais stockés au format Markdown (pour ceux écrits par le passé), au format reStructuredText pour les nouveaux articles, et cette fois, tout est versionné et géré avec git.

Par exemple, pour écrire cet article, je tape présentement dans Visual Studio Code, sur mon PC, dans un fichier texte au format rst. Pour la publication, c'est Pelican qui s'en charge automatiquement dès que j'ajoute l'article dans git (git hook). Simple, rapide, et avec peu de contraintes.

Anciens articles

Pour les anciens articles, le script d'import a pu convertir le contenu des articles, mais pas les métadonnées (date de publication, url). J'ai du repasser sur tous les articles pour ajouter ces informations, de manière à ne pas casser les liens existants vers les articles du blog. Cependant, certaines pages avaient du contenu supplémentaire, sous forme de son ou de vidéo, le script ne les a pas importés. Il me faudra donc repasser sur chacune de ces pages et ajouter le code supplémentaire pour gérer ces médias.

Commentaires

Concernant la gestion des commentaires, ça va être très simple : je ne vais plus m'embêter avec. Les anciens commentaires n'ont pas été repris, et je n'ai pas l'intention ; dans un premier temps, en tout cas ; de les reprendre.

Pour tout commentaire, le plus simple sera de passer par le Fediverse (vous savez comment me joindre).

Conclusion

En n'ayant plus de grosses contraintes au niveau écriture me permettra d'écrire plus d'articles de blog dans les prochains mois ? Je ne m'avancerai pas trop dessus, mon emploi du temps (professionnel) étant bien chargé jusqu'à février 2021.

by alex at July 04, 2020 10:00 PM

June 28, 2020

Luc Didry

Γνῶθι σεαυτόν, mais avec des logi­ciels libres

Γνῶθι σεαυτόν, Gnothi seau­ton, « Connais-toi toi-même » en français (hop, lien Wiki­pé­dia).

Les grecs ne pensaient sans doute pas au quan­ti­fied self (mesure de soi), mais moi, oui.

Je ne suis pas un foufou de la mesure de soi, mais ces derniers temps… disons que j’ai des raisons de m’y inté­res­ser.
Le problème, récur­rent de nos jours, est que quand on a un truc qui prend des mesures, on doit géné­ra­le­ment les refi­ler (les mesures) à une appli­ca­tion ou un site, bref, on s’en dépos­sède allè­gre­ment.

Mais nous avons de la chance, il existe des logi­ciels libres qui nous permettent de garder nos mesures pour nous.

Petit tour des logi­ciels et appli­ca­tions libres que j’uti­li­se…

Gadget­bridge

Il y a de cela plusieurs années, j’ai souhaité une montre connec­tée pour comp­ter mon nombre de pas quoti­diens : ayant un mode de vie très séden­taire, je souhai­tais m’as­su­rer que je me bougeais suffi­sam­ment les fesses.

J’ai acheté un brace­let Angel sensor car il était open source. Je vous la fais courte : j’ai eu le machin (cher pour ce que c’était), une appli­ca­tion de test (vrai­ment pas utile, c’était pour montrer les possi­bi­li­tés du SDK) et peu de temps après, la boîte a cessé tout déve­lop­pe­ment et toute commu­ni­ca­tion. Bref, c’est tombé à l’eau.
Cepen­dant, ce projet m’a fait connaître Gadget­bridge, une appli­ca­tion Android libre qui commu­nique avec de nombreux brace­lets connec­tés.

J’ai jeté mon dévolu sur un Xiaomi MiBand 2 : petit, pas cher (± 20€), basique, avec les fonc­tion­na­li­tés qui m’in­té­res­saient mais guère plus.

Ça a très bien fonc­tionné : Gadget­bridge me permet de modi­fier la confi­gu­ra­tion du MiBand, d’y mettre des alarmes, de choi­sir si je veux être averti quand je suis statique trop long­temps (le but : faire quelques exer­cices après être resté trop long­temps sur l’ordi), de récu­pé­rer le nombre de pas, l’ac­ti­vité détec­tée et le rythme cardiaque. Tout ça en gardant les données sur le télé­phone et non en les envoyant aux serveurs de Xiaomi. Et si je gardais le blue­tooth allumé sur le télé­phone, les noti­fi­ca­tions du télé­phone sont trans­mises au brace­let (ça peut être pratique).

Bref, ça fonc­tion­ne… sauf pour l’as­pect « ça va m’ai­der à me bouger », je n’ai pas réussi à me moti­ver bien long­temps 😅

Slee­pyHead

En octobre dernier, j’ai eu de très gros problèmes de sommeil, je ne dormais au mieux que 3 heures par nuit, sauf excep­tions, et ça a duré des mois 🙁

J’ai passé un examen du sommeil en mars (ouaip, pas top les délais de prise de rendez-vous) et il s’avère que je fais des hypo­pnées. Mais genre bien : 50 à 55 par heure, c’est très violent. La page Wiki­pé­dia de l’Index Apnées Hypo­pnées indique « les sujets ayant un IAH supé­rieur à 30 sont extrê­me­ment rares ». C’est violent au point qu’il m’est décon­seillé de conduire (parce qu’in­ci­dem­ment, je suis moins alerte et plus sujet aux endor­mis­se­ments que norma­le­ment).

Le remède est assez simple : un appa­reil à pres­sion posi­tive conti­nue (PPC) pendant la nuit. Un machin qui m’en­voie de l’air sous pres­sion dans le nez et/ou la bouche.

Apparté, si on vous équipe d’un machin comme ça :

  • deman­dez direc­te­ment qu’on vous donne le module qui humi­di­fie l’air, ça vous évitera d’avoir les muqueuses dessé­chées et de vous réveiller à cause de dès que l’air ambiant devient sec ;
  • si vous avez l’im­pres­sion que l’air que vous expi­rez reste dans le masque (et donc que vous respi­rez votre CO₂), resse­rez les sangles du masque. Ma barbe qui repous­sait (je l’avais rasée pour l’exa­men) faisait des mini-fuites non détec­tées par l’ap­pa­reil, m’em­pê­chant de souf­fler suffi­sam­ment fort pour ouvrir les clapets d’ex­pi­ra­tion.

L’en­tre­prise médi­cale qui m’a four­nit l’ap­pa­reil peut le confi­gu­rer et récu­pé­rer les mesures à distance. Par contre, rien n’est prévu pour que je puisse accé­der à celles-ci : les utili­sa­teurs les contac­taient dès que le résul­tat de la nuit n’était pas le même que celui de la veille alors ils ont arrêté de permettre aux utili­sa­teurs de voir leurs données. Bon, OK, mais moi je ne suis pas comme ça, et je veux pouvoir consul­ter mes données : être capable de voir si je dors plus ou moins long­temps (parce que bon, si je me contente de regar­der l’heure de réveil, je vais vite oublier), voir si j’ai eu plus d’hy­po­pnées les nuits où je dors peu, etc. Et puis tant qu’à produire des données, il me paraît natu­rel de pouvoir y accé­der.

Il existe un logi­ciel fait pour accé­der aux données des appa­reils à PPC : Slee­pyHead. Le projet est malheu­reu­se­ment à l’aban­don car le déve­lop­peur a lâché l’af­faire face aux casse-pieds. Je n’ai pas les détails, mais c’est malheu­reux de réus­sir à dégoû­ter un déve­lop­peur d’un tel logi­ciel libre.

Heureu­se­ment, il est encore possible de télé­char­ger Slee­pyHead. La version GNU/Linux propo­sée étant pour Ubuntu 15.04 (une distri­bu­tion d’il y a 5 ans, donc), j’ai préféré compi­ler le logi­ciel depuis les sources. Je n’ai pas eu trop de soucis (à savoir, instal­ler des dépen­dances au fur et à mesure des plan­tages de la compi­la­tion), le README étant clair et les instruc­tions simples.

Next­cloud et GpxPod

Je dors bien mieux depuis que j’ai mon appa­reil à PPC mais depuis à peu près un mois, quelque soit l’heure à laquelle je me couche, je me réveille tôt. Très tôt. Trop tôt : entre 4 et 5 heures du matin.

Ça m’est arrivé l’an­née dernière, pendant l’été (sans doute à cause de la chaleur) et j’en avais profité pour marcher tous les matins. Comme c’est plutôt une bonne chose de faire de l’exer­cice et que j’ai (encore) pris du poids, je me suis (re)mis à marcher tous les matins.

Afin de voir combien de kilo­mètres je faisais, en combien de temps, et si c’était à un rythme régu­lier, j’ai souhaité utili­ser mon smart­phone et Next­cloud avec l’ap­pli­ca­tion PhoneT­rack.
Pour le smart­phone, j’ai essayé l’ap­pli­ca­tion conseillée : PhoneT­rack. Zéro pointé : sur près d’un km, ça loguait à peine deux points (par contre, ça les envoyait direc­te­ment au serveur Next­cloud, c’était bien pratique). Je ne sais pas si c’était un mauvais réglage de ma part, mais c’était déce­vant.
J’ai ensuite essayé l’ap­pli­ca­tion OpenT­racks : bien meilleur suivi ! Par contre il fallait expor­ter les trajets vers le serveur Next­cloud (j’avais mis une synchro­ni­sa­tion du dossier d’ex­port vers le serveur) et impor­ter les trajets dans PhoneT­rack. Il y avait encore un souci : le suivi n’était pas très précis. En regar­dant le trajet, on avait l’im­pres­sion de suivre un homme ivre au dernier degré.

C’est à ce moment que l’en­vie d’une montre GPS m’a titillé. Pour la préci­sion et aussi pour un appa­reil moins encom­brant.
Entre prix élevés et coûts envi­ron­ne­men­taux des appa­reils neufs, je me suis tourné vers l’oc­ca­sion et j’ai trouvé une montre Garmin Fore­run­ner 110 à 30€. Pas cher, je lui offre une deuxième vie et en plus non connec­tée. Bingo !
L’as­pect « non connec­tée » est inté­res­sant car il y a moins de chances de se retrou­ver obligé de la connec­ter à une appli­ca­tion parti­cu­lière pour récu­pé­rer les données. J’avais véri­fié le modèle avant l’achat : elle est détec­tée comme clé USB sur un ordi­na­teur… Parfait, donc 🙂
Et bonus : la montre vient avec un moni­teur de fréquence cardiaque.

Petit point à noter, toute­fois : les Garmin crachent des fichiers .fit là où le stan­dard pour les traces GPS est le .gpx. Une petite recherche plus tard et je décou­vrais gpsbabel qui permet de conver­tir les .fit en .gpx (et je peux même ajou­ter au fichier .gpx les rele­vés de fréquence cardiaque).

Il me fallait récu­pé­rer les fichiers de la montre, les conver­tir avec gpsbabel, les envoyer au serveur Next­cloud et les impor­ter dans PhoneT­rack. Pas très pratique. J’ai commencé à écrire un script pour auto­ma­ti­ser tout ça avec Next­cloud work­flow : il m’au­rait alors suffi de dépo­ser les fichiers sur Next­cloud. Mais le pilo­tage d’ap­pli­ca­tions n’est pas simple depuis un script…

J’ai regardé les autres appli­ca­tions Next­cloud pour le suivi GPS dans l’es­poir d’en trou­ver une qui ne néces­si­te­rait pas d’im­por­ter manuel­le­ment les fichiers .gpx et j’ai trouvé GpxPod, du même déve­lop­peur que PhoneT­rack. Non seule­ment, cette appli­ca­tion peut lire les fichiers .gpx d’un dossier mais en plus elle peut conver­tir elle-même les fichiers .fit en .gpx (pour peu que gpsbabel soit installé sur le serveur) et permet de compa­rer les diffé­rentes traces !
Bref, tout bénéf : je monte la clé, je dépose les fichiers sur Next­cloud et c’est tout bon, pas besoin de faire un script 😊

Je vais quand même faire un script pour Next­cloud work­flow pour extraire la fréquence cardiaque des traces .gpx et utili­ser ces données avec l’ap­pli­ca­tion Analy­tics, histoire de voir s’il y a des chan­ge­ments avec l’ha­bi­tude.

OpenS­cale

Je l’ai dit : j’ai pris du poids. Encore (la dernière fois, c’était en septembre).

Ce n’est pas que je cède aux sirènes du « Sois mince pour être beau » ou que je n’aime pas mon corps, mais :

  • j’ai­me­rais beau­coup ne pas devoir rache­ter des fringues, ça me gonfle d’avoir plein de fringues dans mon armoire que je ne peux plus mettre ;
  • le poids influe sur mon sommeil (si je suis moins lourd, je ronfle moins, donc je pense que ça peut influer sur mes hypo­pnées).

Donc je veux surveiller mon poids (et tant qu’à faire, en perdre). Là-dessus, l’ap­pli­ca­tion openS­cale est nickel : elle me permet de noter mon poids, mais aussi le tour de taille et d’autres mesures, et calcule des trucs toute seule (comme l’IMC).

Elle fonc­tionne parfai­te­ment bien toute seule mais peut commu­niquer avec des balances connec­tées.

Depuis près de 3 semaines que je marche 8 kilo­mètres au petit matin et à jeun, je ne vois guère de résul­tat (et sans augmen­ter ma consom­ma­tion de nour­ri­ture, je précise). Souhai­tant savoir si je prenais de la masse muscu­laire ou si, à tout le moins, je perdais de la masse grais­seuse, j’ai acheté une balance impé­dan­ce­mètre suppor­tée par openS­cale : une Sani­tas SBF70 (je n’ai pas trouvé d’oc­ca­sion quand je l’ai ache­tée mais j’en ai trouvé une à l’ins­tant sur ebay (donc on peut en trou­ver d’oc­ca­sion, pour ceux que ça inté­resse)).

Ça fonc­tionne très bien : je me pèse, et de temps en temps, alors que la balance est encore active, je lance l’ap­pli­ca­tion qui va aller cher­cher l’his­to­rique des pesées.

Ça ne fait que 3 jours que j’ai la balance, donc je ne sais pas encore s’il y a des varia­tions (les varia­tions que je constate sont minimes, je pense qu’il n’y a rien à en tirer pour l’ins­tant).

Et si je souhaite exploi­ter les données d’openS­cale, je peux faire une sauve­garde des données et utili­ser la base de données SQLite qui en résulte comme bon me semble 🙂

Aver­tis­se­ment

Bien évidem­ment, je n’ai été payé par aucune des marques citées dans cet article. Je les ai citées parce qu’il est impor­tant de connaître les marques et modèles exact·es qui fonc­tionnent avec les logi­ciels libres : autant, au niveau ordi­na­teur, ça va plutôt bien main­te­nant, peu de compo­sants posent problème, autant les bidules connec­tés, il y en a beau­coup (la très grande majo­rité) qui sont verrouillés de partout et inex­ploi­tables par des logi­ciels libres.

Crédit : Photo par Theme Inn sur Unsplash

by Luc at June 28, 2020 11:18 AM

April 26, 2020

Luc Didry

J’ai retrouvé mon flow de déve­lop­peur

Le flow, c’est quand vous êtes à fond sur une tâche. Neil Jomunsi l’ex­plique fort bien dans son article Une méthode simple pour écrire vite et bien : le « flow » de l’écri­vain :

Concept popu­la­risé par le psycho­logue Mihály Csíks­zent­mihá­lyi, le flow est cet état d’in­tense concen­tra­tion qui permet à n’im­porte quel spor­tif, artiste, joueur, moine boud­dhiste, etc de rester foca­lisé sur l’ins­tant présent et d’ou­blier le monde qui l’en­toure pour ne se consa­crer qu’à une chose : l’ac­com­plis­se­ment de sa tâche. Quand on atteint l’état de flow, on s’ou­blie soi-même et on ne fait plus qu’un avec ce que l’on est en train de faire. Les barrières entre la personne et l’ac­tion s’ef­facent, les deux s’im­briquent pour ne plus faire qu’un.

Cela fait plusieurs mois, voire plus d’un an que j’ai perdu ma capa­cité à entrer dans un flow de déve­lop­peur. Si je pouvais toujours coder, c’était plutôt par petites touches, un bugfix par ci, une petite amélio­ra­tion par là… mais rien de consé­quent, alors qu’il m’ar­ri­vait fréquem­ment par le passé de coder comme un dément.

Or cela fait main­te­nant plusieurs semaines qu’elle est reve­nue 🙂
Elle est reve­nue lorsque j’ai décou­vert Alpi­neJS et que j’ai décidé de l’uti­li­ser pour réécrire WemaWema (la réécri­ture n’est pas encore termi­née). Cette semaine, il s’est mani­festé lorsque j’ai codé le support du stockage objet Swift dans Lufi pour les besoins de Frama­soft1 et hier quand j’ai ajouté de l’in­té­gra­tion conti­nue à Lufi-cli pour construire et publier des paquets binaires de Lufi-cli.

Concrè­te­ment, ça fait de très grosses jour­nées de travail, dans un état quasi second. Une transe. Et quand on sort du flow, on se sent épuisé, vidé, mais heureux (je pense qu’il doit y avoir une sacrée pous­sée d’endor­phine qui rentre en jeu)… et ça fait du bien au moral de façon géné­rale ! 🤗

Bref : I’m back in the game, baby!

Crédit : Photo par Enrique Ortega sur Unsplash


  1. D’ailleurs s’il y en a qui veulent tester cette fonc­tion­na­lité, je suis preneur de retours 

by Luc at April 26, 2020 07:32 AM

April 24, 2020

Pierre Boesch

FreeBSD : pkg: PRE-INSTALL script failed

Lors d'un pkg upgrade, j'ai eu cette erreur :

# pkg upgrade
[...]
===> Creating groups.
Using existing group '_tss'.
===> Creating users
Creating user '_tss' with uid '601'.
pw: user '_tss' disappeared during update
pkg: PRE-INSTALL script failed

D'après ce thread, l'erreur pkg: PRE-INSTALL script failed survient lorsque la db password n'est plus synchronisée. Pour corriger cela, il faut re-générer la db avec pwd_mkdb :

pwd_mkdb -p /etc/master.passwd

Puis on peut relancer pkg :

# pkg upgrade
[...]
[1/39] Installing tpm-emulator-0.7.4_2...
===> Creating groups.
Using existing group '_tss'.
===> Creating users
Using existing user '_tss'.
[1/39] Extracting tpm-emulator-0.7.4_2: 100%
[2/39] Installing libtasn1-4.15.0...

by Pierre Boesch at April 24, 2020 10:00 PM

April 19, 2020

Luc Didry

March 27, 2020

Luc Didry

« Le confi­ne­ment ? Ça va pas te chan­ger grand chose ! Ha ha ! »

Cette formule, je l’ai pas mal enten­due ces derniers jours. Pour être honnête, j’ai blagué dessus aussi. Au début.

Ça fait main­te­nant presque deux semaines que nous sommes confi­nés. Et main­te­nant, cette blague me gonfle.

Alors oui, c’est vrai que je bosse en télé­tra­vail depuis plus de 4 ans. Et c’est vrai que ma tenue de travail est un pyjama et une robe de chambre. De même, il est vrai qu’il m’ar­rive de ne pas sortir de chez moi plusieurs jours d’af­fi­lée.

Donc oui, je suis peut-être mieux préparé au confi­ne­ment que la plupart des gens. Mais dire que ça ne me pèse pas serait mentir.

Déjà parce que, bossant de chez moi, j’ap­pré­cie les sorties hors de ma tanière. Comme j’ha­bite à deux pas d’un super-marché, je ne fais pas de grandes courses : y aller ache­ter deux ou trois trucs tous les deux jours, ça me fait une coupure, une sortie, un bol d’air. J’ai aussi la chance d’avoir une média­thèque toute aussi proche, où je vais régu­liè­re­ment. Et le marché bio/local du vendredi. Et le marché du dimanche. Il y a aussi les cours hebdo­ma­daires de langue japo­naise, les cours mensuels de cuisine japo­naise. Et aller boire des coups avec les amis. Et aller en ville pour passer à la librai­rie. Bref les occa­sions de sortir, que ce soit pour 5 minutes ou plusieures heures ne manquent pas.

Ensuite, il y a une immense diffé­rence entre rester chez soi par choix (ou flemme) et ne pas pouvoir le faire libre­ment.

Il y a aussi le fait que mon fils n’ha­bite chez moi qu’une semaine sur deux. Ça veut dire être seul une semaine sur deux. Et actuel­le­ment, quasi­ment sans sortir.

J’ai la chance d’avoir un balcon, et quand je me fais un café (plusieurs fois par jour donc), je commence par en boire quelques gorgées accoudé à la rambarde. Le calme du quar­tier (dû au confi­ne­ment et à sa consé­quence sur la circu­la­tion) et, cette semaine, le soleil qui revient et les oiseaux qui gazouillent rendent encore plus dur le fait de ne pas pouvoir sortir pour en profi­ter. Je ne peux que regar­der du haut de ma tour de béton.

Donc, si, le confi­ne­ment, ça change beau­coup de choses pour moi aussi.

Crédit : Photo par Erda Estre­mera sur Unsplash

by Luc at March 27, 2020 06:24 PM

March 07, 2020

Alexandre Bailly

Nouvelles du blog

Ça fait un moment que j'hésitais à lâcher PluXML. Non pas parce que j'aime pas ce CMS (bien au contraire), mais à cause de certains détails agaçant.

Je l'utilise depuis 2010 (quasiment une décennie), mais depuis, ma procédure de rédaction des articles a pas mal évolué.

Mes derniers articles sont rédigés en ReStructuredText (rst), un langage de balisage léger, dans le même style que Markdown ou Textile, via ReText, suivi d'un export au format html, et enfin copier-coller dans l'éditeur html de PluXML.

Cela fait donc plusieurs étapes entre la rédaction et l'aperçu dans le blog, avec la répétition de toute la procédure si je veux éditer ou corriger un truc.

À noter : j'utilise la même procédure pour nv, qui tourne aussi sous PluXML.

Par exemple, la dernière fiction du mercredi a été rédigée en reStructuredText, à partir d'une idée tenant sur une ligne, puis exportée en html, etc.

https://nouvelles.chibi-nah.fr/controle-z-d

Par contre, pour mes pages de docs, j'utilise une procédure totalement différente. Là, je passe par Sphinx-doc, git, et quelques hooks.

Pour la rédaction, j'utilise aussi bien ReText, Geany ou Visual Studio Code (pas de troll, merci).

Je génère les pages en local pour contrôler le contenu. Le suivi des révisions étant géré par git, cela signifie donc que je peux aussi bien bosser avec Ryoko comme avec Yue. Et pour la publication ? Un simple git push, et c'est tout. Les pages sont générées sur le serveur puis copiés vers le répertoire de destination. Pas de copie via ftp ou scp. Pas de prise de tête.

Un processus totalement différent par rapport au blog.

Mon occupation actuelle est de reprendre tous les articles du blog (un peu moins d'une centaine), que j'ai converti en Markdown, via un script python, dont David Revoy a parlé récemment.

https://www.davidrevoy.com/article756/moving-to-markdown

https://github.com/KillianKemps/Pluxml-to-Markdown

Cependant, le contenu du blog étant essentiellement statique (les commentaires étant modérés, voire carrément désactivés), l'intérêt d'un CMS générant dynamiquement les pages est discutable. Je pense m'orienter vers un générateur statique. Pas Sphinx-doc, qui ne correspond pas à mes prérequis pour un blog (pour de la documentation, c'est juste génial). Plutôt Pelican (que je teste en ce moment).

Cela nécessite pas mal de travail. Notamment insérer toutes les métadonnées dans chacune des pages (date de publication, auteur, tags). Et chose importante : essayer de garder les mêmes URL que celles générées avec PluXML.

La migration du blog s'effectuera dans les prochaines semaines, une fois les articles corrigés et le thème mis en place.

by alex at March 07, 2020 11:00 PM

January 16, 2020

Luc Didry

La tech en grève

C’est un fait marquant dans l’his­toire du secteur infor­ma­tique français : des « tech » râlent et appellent à la grève (il y a eu un autre appel mais je ne le retrouve pas).

TL; DR: on bosse dans l’info, on aime auto­ma­ti­ser des trucs, mais c’est pas pour foutre des gens au chômage. Non, c’est pour libé­rer du temps de loisir, bosser moins, mieux vivre.

L’au­to­ma­ti­sa­tion peut et doit servir l’hu­ma­nité. Elle permet­trait de travailler moins, de partir en retraite plus tôt, et dans d’ex­cel­lentes condi­tions de vie, de déga­ger à tous du temps libre pour étudier, expé­ri­men­ter, pratiquer les sports, les arts, passer du temps en famille ou entre amis ; de vivre.

Bref, je me retrouve beau­coup dans cet appel, que j’ai signé.

Il y a sur https://onestla.tech/ des ressources graphiques pour des affiches, des bannières. Géné­ra­le­ment à base de l’émoji « poing levé » : ✊

Je ne trou­vais pas cet émoji assez vindi­ca­tif à mon goût, donc j’ai été cher­ché un poing levé sur https://freesvg.org/ (lien vers celui que j’ai choisi). Étant une quiche1 en graphisme, j’ai lancé un petit appel sur Masto­don et JCFrog a bien voulu mettre des câbles RJ45 dans le poing levé.

Après ça, un peu d’inks­cape pour mettre de la couleur et du texte, et hop :


Affiche rouge au format portrait avec, en noir, un poing levé tenant des câbles RJ45, le texte « La tech en grève » et l'adresse https://onestla.tech Affiche rouge au format paysage avec, en noir, un poing levé tenant des câbles RJ45, le texte « La tech en grève » et l'adresse https://onestla.tech


Cliquez ici pour une archive conte­nant les fichiers PNG et SVG des affiches.

Édouard Lafon en a fait une version bannière.

Et parce qu’une pancarte en carton, ça s’abîme vite, j’ai peint l’af­fiche sur une toile avec des marqueurs pein­ture et je n’au­rais plus qu’à l’ac­cro­cher à un manche à balai pour en faire une pancarte 🙂


Tableau rouge avec, en noir, un poing levé tenant des câbles RJ45, le texte « La tech en grève » et l'adresse https://onestla.tech

On se retrouve à la manif’ tout à l’heure, cama­rades ?


  1. lorraine, what else? 

by Luc at January 16, 2020 06:30 AM

December 21, 2019

Pierre Boesch

Zabbix Server et Proxy dans une jail FreeBSD

Situation

J'ai récemment débuté un mini projet pour superviser mes serveurs et services avec Zabbix sur FreeBSD, le tout dans des jails. Un serveur chez kimsufi sera le Zabbix Server (dans un jail) et sur mon serveur principal chez OneProvider, j'ai mis en place un Zabbix Proxy (toujours dans une jail). J'ai rencontré deux problèmes bloquants avec la partie serveur et proxy : l'impossibilité de démarrer le serveur et d'importer le schéma de db pour le proxy.

Zabbix Server

Jail : cannot allocate shared memory

Dans une jail FreeBSD, j'ai donc installé le serveur Zabbix. Après avoir configuré la db, et crée le fichier de configuration du serveur (/usr/local/etc/zabbix42/zabbix_server.conf) lorsque je lançais le service, il ne démarrait simplement pas :

# /usr/local/etc/rc.d/zabbix_server start
# /usr/local/etc/rc.d/zabbix_server status
zabbix_server is not running.

Un coup d'œil dans les logs Zabbix : zabbix_server [2691]: cannot create locks: cannot allocate shared memory for locks

Après une recherche, je tombe sur une page du wiki de Zabbix qui explique qu'il faut augmenter des paramètres du kernel (shmall et shmmax) qui sont par défauts trop bas. Rapidement, je m'aperçois que leur documentation est trop vieille : les valeurs qu'ils conseillent d'appliquer sont plus bas que celles appliquées par défaut sur FreeBSD 12. Pour la pérennité, les valeurs par défaut :

# ipcs -M
shminfo:
    shmmax:    536870912    (max shared memory segment size)
    shmmin:            1    (min shared memory segment size)
    shmmni:          192    (max number of shared memory identifiers)
    shmseg:          128    (max shared memory segments per process)
    shmall:       131072    (max amount of shared memory in pages)

Celles conseillées par le how to :

 kern.ipc.shmall=2097152
 kern.ipc.shmmax=134217728

On voit clairement, comme dit plus haut, que les paramètres en place ont une valeurs bien plus élevés.

SYSV IPC

En continuant mes recherches, j'arrive par hasard sur la documentation PostgreSQL fait état des mêmes remarques que celle de Zabbix à un détail près : un paramètre spécifique à appliquer sur une jail dont je ne connaissais pas l'existence :

En cas d'exécution dans une cage FreeBSD en activant security.jail.sysvipc_allowed de sysctl, les postmaster exécutés dans différentes cages devront être exécutés par différents utilisateurs du système d'exploitation

Je tente en activant le paramètre allow.sysvipc dans la jail zabbix :

# vim /usr/local/etc/ezjail/zabbix
-export jail_zabbix_parameters="allow.raw_sockets=1"
+export jail_zabbix_parameters="allow.raw_sockets=1 allow.sysvipc=1"
# ezjail-admin restart zabbix

Et le service zabbix_server s'est lancé sans erreur :

# /usr/local/etc/rc.d/zabbix_server status
zabbix_server is running as pid 5815.

Après lecture d'un blogpost très intéressant SYSV IPC correpond au Shared Memory, Semaphores and Message Queue. Les jails se partageant le même kernel, quand elles ont besoin de SYSV IPC elles doivent demander l'autorisation de l'utiliser. Avant FreeBSD 11, on pouvait soit accorder les droits complets soit les refuser totalement via le paramètre que l'on a vu précédemment allow.sysvipc. Si deux jails ont ce partage de ressources, si l'une d'elle est comprise, elle peut compromettre l'autre également. Depuis FreeBSD 11 donc, on peut utiliser les paramètres sysvshm et sysvsem avec la valeur new (créer un nouveau namespace SYSV pour la jail). J'ai modifié la configuration de ma jail de cette façon :

# vim /usr/local/etc/ezjail/zabbix
-export jail_zabbix_parameters="allow.raw_sockets=1 allow.sysvipc=1"
+export jail_zabbix_parameters="allow.raw_sockets=1 sysvshm=new sysvsem=new"
# ezjail-admin restart zabbix

Le service démarre toujours et avec de la sécurité :).

Zabbix Proxy

Import SQL Row size too large (> 8126)

Une fois le paquet installé et la db crée, il faut importer les données sql du fichier schema.sql. Pas de bol une nouvelle fois :

# mysql -h 192.168.0.4 -uzabbix zabbix_proxy < /usr/local/share/zabbix42/proxy/database/mysql/schema.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1118 (42000) at line 1284: Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

Ce problème est connu : MariaDB ne calcule pas correctement la taille des lignes pendant l'exécution. Les calculs sont censés être corrigés entre autre en 10.4.7, j'ai pourtant la 10.4.11… :

# pkg info | grep mariadb
mariadb104-client-10.4.11      Multithreaded SQL database (client)
mariadb104-server-10.4.11      Multithreaded SQL database (server)

Le lien ci-dessus renvoie vers le bugreport MDEV-19292 où, mis à part désactiver innodb_strict_mode=OFF, passer la taille des varchar à 255 de la table host_inventory serait la solution :

Keep InnoDB strict mode enabled, but change some of those varchar(N) columns to varchar(N >= 256 bytes). If the table's default character set is utf8mb4, then that means that N would have to be 64 or more. i.e. this also succeeds in MariaDB 10.2.26.

Un coup de sed dans schema.sql :

$ cd /usr/local/share/zabbix42/proxy/database/mysql/schema.sql
$ sed -i.bak '/CREATE TABLE `host_inventory`/,/PRIMARY KEY/s/varchar([0-9]\{1,\})/varchar(255)/' schema.sql

Et effectivement l'import fonctionne sans faute !

by Pierre Boesch at December 21, 2019 11:00 PM

December 06, 2019

Pierre Boesch

Thinkpad fixer le mapping des touches de luminosité

Sur archlinux après une mise à jour du kernel, à priori depuis la 5.3, les touches de réglages de la luminosité de mon Thinkpad X200 ne fonctionnaient plus.

xev (permet d'afficher les évênements de X), me confirme que les touches ne sont plus reconnues :

$ xev
MappingNotify event, serial 32, synthetic NO, window 0x0,
    request MappingKeyboard, first_keycode 8, count 248

MappingNotify event, serial 32, synthetic NO, window 0x0,
    request MappingKeyboard, first_keycode 8, count 248

Le wiki d'archlinux donne plusieurs solutions dont celle d'ajouter une section Device de x11 pour utiliser l'option intel-backlight du driver intel (sur certains modèles il faudra charger acpi_backlight).

$ cat /etc/X11/xorg.conf.d/10-intel-backlight.conf
Section "Device"
    Identifier "Card0"
    Driver "intel"
    Option "Backlight" "intel_backlight"
EndSection

Après un reboot, les touches de luminosités fonctionnent de nouveau et sont effectivement reconnues par xev :

KeyRelease event, serial 41, synthetic NO, window 0xc00001,
    root 0xc4, subw 0x0, time 50185961, (-160,432), root:(484,469),
    state 0x10, keycode 232 (keysym 0x1008ff03, XF86MonBrightnessDown), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False

Pour information, avant la solution précédente, rajouter l'option --release des bindings XF86MonBrightnessUp/Down dans ma configuration i3 a fonctionné également :

-bindsym XF86MonBrightnessUp exec --no-startup-id xbacklight -inc 5
+bindsym --release XF86MonBrightnessDown exec --no-startup-id xbacklight -dec 5

by Pierre Boesch at December 06, 2019 11:00 PM

November 21, 2019

Pierre Boesch

Pacman 5.2 breaks dependency required by yay

Récemment lorsque j'ai tenté de mettre à jour ArchLinux avec yay je me suis retrouvé bloqué sur des dépendances cassées avec pacman :

$ yay
:: Synchronizing package databases...
 core is up to date
 extra is up to date
 community is up to date
 multilib is up to date
:: Starting full system upgrade...
resolving dependencies...
looking for conflicting packages...
error: failed to prepare transaction (could not satisfy dependencies)
:: installing pacman (5.2.1-1) breaks dependency 'pacman<=5.1.3' required by yay

Donc impossible de mettre à jour pacman en 5.2 parce que yay est dépendant de la version 5.1. La solution rapide pour résoudre ce problème de dépendance entre yay et pacman est de supprimer yay, de mettre à jour son système avec pacman et réinstaller yay.

$ sudo pacman -R yay
$ sudo pacman -Syu
$ sudo pacman -S yay

yay fonctionne à nouveau :

$ yay
:: Synchronizing package databases...
 core is up to date                                                            135,6 KiB  2,50 MiB/s 00:00 [----------------------------------------------------------------]
 extra is up to date                                                          1645,9 KiB  2,79 MiB/s 00:01 [----------------------------------------------------------------]
 community is up to date                                                         4,7 MiB  2,46 MiB/s 00:02 [----------------------------------------------------------------]
 multilib is up to date
:: Starting full system upgrade...
resolving dependencies...
looking for conflicting packages...
Packages (183) […]

by Pierre Boesch at November 21, 2019 11:00 PM

October 24, 2019

Simon Florentin

Fermeture du blog

Salut, Petit message de service pour annoncer la fermeture du blog. En effet, je n’y poste plus rien. Je vais

Read more »

by Simon at October 24, 2019 08:07 AM

October 21, 2019

Luc Didry

Pous­ser ses filtres SIEVE en ligne de commande et sans mot de passe (avec Kwal­let)

Les filtres Sieve sont des régles de filtrage de mails exécu­tées par le serveur de messa­ge­rie (NB : tous ne le proposent pas). C’est à mon sens l’op­tion la plus propre pour filtrer ses mails : quelque soit mon logi­ciel de consul­ta­tion de mes mails (webmail, client graphique ou textuel sur ordi­na­teur, client sur smart­phone…), le filtrage sera toujours le même, sans avoir besoin de reco­pier les règles.

Pour éditer ces règles, il y a plusieurs solu­tions. La solu­tion de group­ware Blue­mind, que j’uti­lise à titre person­nel et profes­sion­nel four­nit un éditeur graphique sur le webmail, mais il est trop limité pour mon usage : je ne peux que cumu­ler des règles et non pas les mixer, créer des sous règles, etc. Un exemple de sous-règle : si je souhaite que les mails prove­nant de l’adresse foo@example.org soit rangés dans un dossier foo, et que si, parmi ces mails, le sujet contient bar, le mail soit marqué comme lu, je peux écrire en Sieve :

if allof ( address :contains "from" ["foo@example.org"] ) {
    if allof ( header :contains "Subject" "bar" ) {
        setflag "\\Seen";
    }
    fileinto "foo";
    stop;
}

Mais Blue­mind ne permet pas cela, les règles seront plus basiques (ah, les limi­ta­tions des inter­faces graphiques !). Thun­der­bird peut utili­ser une exten­sion, Sieve pour gérer les filtres Sieve, mais je ne sais plus trop ce que ça vaut, ça fait long­temps que je n’uti­lise plus Thun­der­bird. Kmail, le client de messa­ge­rie de KDE et que j’uti­lise, permet de gérer (nati­ve­ment) les filtres Sieve de façon graphique mais pous­sée ou… de les écrire direc­te­ment. Voilà qui est top ! Ah mais… c’est pas ouvert dans Vim. Dommage, j’ai mes petites habi­tudes et j’ai horreur d’uti­li­ser un autre éditeur de texte.

La ligne de commande : sieve-connect

Donc, person­nel­le­ment, j’uti­lise Vim pour écrire mes scripts Sieve et sieve-connect pour les envoyer à mon serveur de messa­ge­rie. Exemple :

sieve-connect -s serveur.example.org -p 2000 -u luc@example.org \
 --localsieve /home/luc/filter.siv --upload --remotesieve mes_regles.sieve

Expli­ca­tion des options :

  • -s serveur.example.org : l’adresse du serveur ;
  • -p 2000 : le port utilisé par le serveur pour l’in­ter­face de gestion des filtres Sieve ;
  • -u luc@example.org : mon login ;
  • --localsieve /home/luc/filter.siv : l’adresse du fichier à pous­ser ;
  • --upload : l’ac­tion à entre­prendre, donc l’en­voi au serveur ;
  • --remotesieve mes_regles.sieve : le nom du fichier distant dans lequel je vais pous­ser mes règles. On peut effec­ti­ve­ment avoir plusieurs fichiers de règles, mais un seul sera actif. Pratique pour avoir des règles spéciales pour les vacances : il n’y a qu’à acti­ver le fichier qui les contient et zou 🙂

Là-dessus, sieve-connect va me deman­der mon mot de passe et hop, c’est poussé !

Sieve-connect permet d’en­voyer des règles, de les récu­pé­rer, de lister les fichiers de règles, d’ac­ti­ver l’un ou l’autre. Bien pratique donc !

Et le mot de passe ?

Pour ne pas avoir à donner mon mot de passe à chaque fois sans pour autant le mettre dans un script, je vais profi­ter de KWal­let, le gestion­naire de mot de passe de KDE contient déjà le mot de passe de mon compte mail, puisque j’uti­lise Kmail. Donc autant le lui deman­der !

Je peux deman­der l’ac­cès au porte­feuille de mot de passe via D-Bus :

qdbus org.kde.kwalletd5 /modules/kwalletd5 open kdewallet imap "Sieve push"

La chaîne "Sieve push" est le nom que je déclare pour mon « appli­ca­tion ». Kwal­let me deman­dera si j’au­to­rise l’ap­pli­ca­tion « Sieve push » à accé­der au porte­feuille. Cette commande va me retour­ner un handle que je vais utili­ser dans mes demandes ulté­rieures. En allant voir dans l’ap­pli­ca­tion graphique de gestion Kwal­let, KWal­letMa­na­ger, je vois que le mot de passe de mon compte de messa­ge­rie est akonadi_imap_resource_1rc du dossier imap. Donc pour en deman­der le mot de passe, je fais :

qdbus org.kde.kwalletd5 /modules/kwalletd5 readPassword le_handle_obtenu_avant \
 imap akonadi_imap_resource_1rc "Sieve push"

NB : on notera que je répète le nom de mon appli­ca­tion, "Sieve push", dans la commande. C’est néces­saire.

Plus qu’à donner le mot de passe à sieve-connect. Pour simpli­fier, je combine tout ça dans une fonc­tion que je vais mettre dans mon ~/.zshrc :

sievepush() {
    ID=$(qdbus org.kde.kwalletd5 /modules/kwalletd5 open kdewallet imap "Sieve push")
    echo $(qdbus org.kde.kwalletd5 /modules/kwalletd5 readPassword $ID imap akonadi_imap_resource_1rc "Sieve push") | sieve-connect -s serveur.example.org -p 2000 -u luc@example.org --localsieve /home/luc/filter.siv --upload --remotesieve mes_regles.sieve
}

Et voilà ! Plus qu’à lancer sievepush depuis mon termi­nal et ça enverra mon fichier de filtres à mon serveur de messa­ge­rie. Si mon porte­feuille KWal­let est ouvert, ça partira direct, sinon, ça me deman­dera le mot de passe du porte­feuille.

Crédit : Photo par Tyler Nix sur Unsplash

by Luc at October 21, 2019 02:34 PM

October 12, 2019

Luc Didry

Scan­ner et impor­ter faci­le­ment ses livres sur Inven­taire.io

J’ai des livres. Plein. Peut-être trop. On s’en fout. Le truc, c’est qu’une belle collec­tion comme ça, c’est mieux quand elle est cata­lo­guée.

D’où mon inté­rêt pour inven­taire.io : c’est un plate-forme (libre !) sur laquelle on peut impor­ter ses livres, les marquer comme dispo­nibles au don ou au prêt, se connec­ter avec des gens, regar­der les inven­taires des uns et des autres, faire une demande de prêt…

C’est très simple d’em­ploi et si on four­nit l’ISBN d’un livre, la plate-forme va essayer de récu­pé­rer les données (auteur, couver­ture, synop­sis, etc) toute seule via wiki­data et d’autres sources de données. Très pratique donc. Le site propose même un scan­ner de code-barres ! Pile-poil avec un smart­phone, mais ça devrait même aussi fonc­tion­ner avec une webcam. On peut aussi utili­ser une appli­ca­tion de scan­ner de code-barres, on n’est pas obligé d’uti­li­ser celui du site.

Par contre, si scan­ner des codes-barres avec un télé­phone est pratique, véri­fier et vali­der les livres qui résultent du scan­nage sur le télé­pho­ne… c’est un peu bof. Surtout si comme moi vous scan­nez les livres par paquets de 50. L’idéal est donc de scan­ner avec son télé­phone et de vali­der sur l’or­di­na­teur…

KDECon­nect pour la liai­son télé­phone — ordi­na­teur

KDECon­nect est un outil très pratique pour contrô­ler son ordi­na­teur depuis son télé­phone : y envoyer des fichiers, gérer le lecteur multi­mé­dia… Et dans l’autre sens, on peut accé­der à l’es­pace disque de son télé­phone depuis son ordi­na­teur. Mais surtout, la killer feature, pour moi, c’est le partage du presse-papier : je copie un truc sur le télé­phone ou sur l’ordi et son contenu se retrouve dans le presse-papier de l’autre appa­reil.

Pour utili­ser KDECon­nect, il faut l’ap­pli­ca­tion KDECon­nect (dispo­nible sur F-Droid, je ne sais pas si elle est sur le play store) et sur l’or­di­na­teur, il faut instal­ler le paquet kdeconnect et lancer les appli­ca­tions (/usr/lib/x86_64-linux-gnu/libexec/kdeconnectd pour lancer la version ordi­na­teur depuis la ligne de commande pour une Debian). Il y a aussi une version pour Gnome : gscon­nect.

Ensuite, il faut que les deux appa­reils soient dans le même réseau. Après, il n’y a plus qu’à appa­reiller les appa­reils.

Barcode scan­ner sur le télé­phone

Instal­lez Barcode scan­ner (dispo­nible sur F-Droid) sur votre télé­phone et confi­gu­rez-le pour qu’il copie ce qu’il scanne dans le presse-papier.

On y est presque : avec ces deux outils, l’or­di­na­teur peut d’ores et déjà rece­voir dans son presse-papier les codes-barres que vous allez scan­ner.

Surveiller le presse-papier avec Clip­no­tify

J’ai trouvé un projet, Clip­no­tify qui permet de surveiller le contenu du presse-papier. Télé­char­gez la dernière version sur https://github.com/cdown/clip­no­tify/releases.

Enre­gis­trer les codes-barres dans un fichier

Vous aurez aussi besoin de xsel pour accé­der au contenu du presse-papier (Clip­no­tify ne donne pas le contenu de celui-ci, il se contente de regar­der s’il change), ainsi que de tee.

Ensuite vous n’au­rez plus qu’à lancer cette petite commande :

while clipnotify
do
    ISBN=$(xsel)
    echo $ISBN | tee -a /tmp/clip.log
done

Faites Ctrl+C pour arrê­ter.

NB: Je ne pipe pas direc­te­ment xsel vers tee car xsel ne fait pas de retour à la ligne. Notez aussi que vous pouvez vous passer de tee en faisant echo $ISBN >> /tmp/clip.log, mais j’aime bien voir direc­te­ment sur le termi­nal ce qui écrit dans /tmp/clip.log.

Pour une raison que j’ignore, chaque contenu de press-papier se retrouve écrit plusieurs fois dans le fichier /tmp/clip.log. Corri­ger le fichier n’est pas diffi­cile :

uniq /tmp/clip.log  | grep "^97"

Ou (au cas où on scanne le même livre deux fois par inad­ver­tance) :

sort -u /tmp/clip.log  | grep "^97"

Le grep est là pour se déba­ras­ser des codes-barres mal scan­nés : un ISBN comment toujours par 978 ou 979. Pensez à regar­der le numéro que vous indique avoir scanné Barcode scan­ner !

Voilà. Vous avez main­te­nant une belle liste d’ISBN qu’il nous suffit désor­mais de coller sur https://inven­taire.io/add/import 🙂

Et si vous voulez voir ce que j’ai dans ma biblio­thèque, vous pouvez aller voir sur https://inven­taire.io/inven­tory/framasky (mais je suis encore en train d’im­por­ter mes bouquins, j’ai pas fini de tout scan­ner).

EDIT (12/10/2019) : ajout du grep pour enle­ver les codes-barres mal scan­nés.

Crédit : Photo par Eli Fran­cis sur Unsplash

by Luc at October 12, 2019 03:06 PM

October 11, 2019

Alexandre Bailly

Visual Studio, clavier TypeMatrix™ bépo et underscore

Ou comment se prendre la tête pour pouvoir taper le caractère _

Lors de la migration vers les nouvelles versions des outils en environnement professionnel, on peut rencontrer des problèmes complètement inattendus, et non documentés. D’autant plus s’il s’agit de produits Microsoft, où le support est absolument incapable de trouver l’origine du problème. Je ne parlerai pas des “experts” certifiés MSVP¹, pour qui le problème vient du clavier.

Là où c'est amusant, c’est que la touche fonctionne dans le champ de recherche mais pas dans l'éditeur.

J’avais rencontré ce problème avec Microsoft SQL Server Management Studio pour SQL Server 2017 (basé sur vs2015), et mon contournement était de taper l’underscore dans le bloc-note, puis de faire un copier-coller à chaque fois que j’en avais besoin, c’est-à-dire en permanence.

L’utilisant nettement moins souvent dans Visual Studio et ayant également Visual Studio Code (j’utilise plus ce dernier que la solution ultra lourde, d’ailleurs, et la touche underscore fonctionne, elle, sur VS Code), et les recherches de la solution s'avérant infructueuses, j’allais abandonner, jusqu’au moment, où au détour d’un message sur Stack Overflow, quelqu’un en Allemagne semblait avoir un problème similaire, mais avec un autre caractère ; sauf que là, une piste était donnée.

Les raccourcis claviers

Certes, très utiles (enlevez-moi mon Ctrl + B et je pète un câble), mais parfois problématiques.

Après quelques tests stupides que je ne détaillerai pas, il s’avère que VS (depuis 2012 ? 2015 ?) détermine d’abord la séquence de touches, exécute le raccourci-clavier si celui-ci correspond, sinon insère le caractère pouvant correspondre à la même séquence.

Sur un TypeMatrix™ bépo, le caractère underscore _ s'obtient via Alt gr + espace. Sauf que Alt gr sous Windows, c’est un raccourci pour Ctrl + Alt. Donc, le caractère underscore _ correspond donc à Ctrl + Alt + Espace. Vous voyez venir la blague ?

Cette séquence de touches est attribuée à un raccourci clavier dans le mode éditeur. Et donc, prend le pas sur l’insertion du caractère tant désiré. Les raccourcis clavier ne s’appliquant pas dans le champ de recherche, cela explique pourquoi le _ peut être saisi sans aucun problème.

On a maintenant l’explication, du coup, corrigeons le problème.

Les captures d’écrans proviennent de Visual Studio 2017, mais c’est la même démarche dans MS SQL Server Management Studio.

Aller dans le menu « Outils », puis cliquer sur « Options… ».

Dans la fenêtre, cliquer sur « Clavier » sur la gauche.

La liste des raccourcis clavier s’affiche. Comme celle-ci est trop longue, on ne va pas les vérifier un par un.

Cliquer dans le champ texte sous « Appuyer sur les touches de raccourci : » puis appuyer les touches Alt gr + Espace. Cela insère bien le raccourci clavier Ctrl + Alt + Espace, ici en 1 sur la capture d’écran.

Le nom de la commande utilisant ce raccourci clavier apparaît alors sous « Raccourci actuellement utilisé par : », ici en 2 sur la capture d’écran.

Cliquer dans le champ texte sous « Afficher les commandes contenant : ».

Taper ensuite le nom de la commande (même partiellement) pour filtrer l’affichage.

Cliquer ensuite sur le nom de la commande, ici, la sélection en bleu sur la capture d’écran.

Cliquer sur le bouton « Supprimer », ici en 1 sur la capture d’écran.

Vérifier que le raccourci est bien supprimé, ici en 2 sur la capture d’écran.

Cliquer sur « OK », ici en 3 sur la capture d’écran pour valider et fermer la fenêtre.

Essayez de taper le caractère underscore. Cela devrait fonctionner.

Normalement, il y a un seul raccourci clavier avec cette séquence de touches. Si la touche n’est toujours pas reconnue, recommencer les manipulations pour trouver les autres commandes utilisant également cette séquence de touches.

---

¹ : Il suffit d’apprendre par cœur les annales et de réciter le tout par cœur² pour avoir la certification. Des gamins de 12 ans sont tout à fait capables (et certain·e·s l’ont obtenu).

² : La raison pour laquelle je n’ai pas ces certifications. Celles et ceux me connaissant IRL savent pourquoi.

by alex at October 11, 2019 10:00 PM

August 19, 2019

Luc Didry

Instal­ler l’ex­ten­sion Netflix sur Kodi

Bon… j’aime pas Netflix parce que ça utilise des DRM et que ça pue du cul mais la mère de mon gamin a pris un abon­ne­ment (à deux écrans, pour elle et lui) et comme j’ai pas envie qu’il s’use les yeux à regar­der Netflix sur son télé­phone quand il est chez moi… j’ai installé l’ex­ten­sion Netflix sur le Kodi du rasp­berry pi du salon, qui est relié à un vidéo-projec­teur.

J’ai utilisé ce tuto­riel : https://kwar­tix.word­press.com/2019/05/13/netflix-rasp­berry-et-kodi/. Bien fait, mais j’ai rencon­tré des diffi­cul­tés, donc je refais un article avec tout ce que j’au­rais voulu savoir.

Pré-requis

  1. avoir Kodi en version 18 mini­mum. Ça ne m’a pas posé de problème puisque c’était déjà le cas pour moi, mais c’est bon à savoir ;
  2. avoir au moins 2Gio d’es­pace libre : pour choper le bazar de DRM qui va bien, l’ex­ten­sion va télé­char­ger une image Chrome OS, et c’est volu­mi­neux.

Ce qui va nickel dans le tuto

On installe des dépen­dances :

sudo apt install python-pip python-crypto build-essential \
  python-all-dev python-setuptools python-wheel \
  python-crypto-dbg python-crypto-doc python-pip-whl
pip install pycryptodomex
sudo ln -s /usr/lib/python2.7/dist-packages/Crypto /usr/lib/python2.7/dist-packages/Cryptodome

NB : j’ai fait le pip en root, vu que quand j’ai plusieurs commandes sudo à taper, je m’em­bête pas et je me mets en root. Je ne sais pas si ça peut faire une diffé­rence quel­conque.

Une petite typo

Ça, je l’ai dit en commen­taire de l’ar­ticle : une URL n’est pas bonne. Ça arrive.

wget https://raw.githubusercontent.com/sonpero/Netflix/master/repository.castagnait-1.0.0.zip

L’URL de l’ar­ticle pointe sur la page github du fichier et non sur le fichier lui-même.

Après cela, on installe ce fichier dans Kodi comme une exten­sion via l’ins­tal­la­tion par fichier zip. Ce n’est cepen­dant pas une exten­sion : c’est un dépôt d’ex­ten­sion qu’on installe là.

Les problèmes commencent

Il est tout à fait possible que l’au­teur de l’ar­ticle origi­nel n’ait pas rencon­tré les soucis suivants, mais moi si, ce qui justi­fie cet article.

  1. au moment d’ins­tal­ler l’ex­ten­sion Netflix via le nouveau dépôt, j’ai eu droit, comme sous Android, à un message indiquant que l’ins­tal­la­tion d’ex­ten­sion via des sources incon­nues n’était pas auto­risé. Un petit tour dans les para­mètres (le message a la bonne idée d’in­clure un bouton pour s’y rendre direc­te­ment) et c’est réglé ;
  2. une fois l’ex­ten­sion instal­lée et les iden­ti­fiants rentrés, impos­sible de lire une vidéo : il me manquait l’ex­ten­sion InputS­tream Adap­tive, et impos­sible de la trou­ver dans les dépôts. En fait, ayant installé Kodi à partir des dépôts Deb Multi­me­dia, il me fallait l’ins­tal­ler depuis les paquets Debian (et j’en ai installé un autre avec, il me semble qu’ils sont rela­ti­ve­ment liés) :

    apt install kodi-inputstream-adaptive kodi-inputstream-rtmp

    Puis un petit redé­mar­rage de Kodi pour qu’il voit ces nouvelles exten­sions ;

  3. Après, au lance­ment (enfin !) d’une première vidéo, l’ex­ten­sion m’a proposé l’ins­tal­la­tion de wide­vine… et c’est là que j’ai été averti qu’il fallait 2Gio d’es­pace libre. J’ai du faire un peu de place ;
  4. La place faite, Kodi se plai­gnait du fait qu’il fallait fdisk ou parted sur la machine pour pouvoir extraire wide­vine. Deux outils pour­tant bien instal­lés. J’ai lancé Kodi avec l’uti­li­sa­teur root après avoir fait ln -s /home/kodi/.kodi /root/.kodi (oui, j’ai un utili­sa­teur dédié) et j’ai enfin pu termi­ner l’ins­tal­la­tion de wide­vine ;
  5. Les vidéos ne se lançaient pas pour autant, pour des problèmes de permis­sions d’après les messages d’er­reur. L’ins­tal­la­tion de wide­vine via l’uti­li­sa­teur root mais son utili­sa­tion par l’uti­li­sa­teur kodi avait laissé des traces, en l’oc­cu­rence un lien symbo­lique dont la cible était dans /root/. Pour y remé­dier :
    cd /home/kodi/.kodi/cdm
    rm libwidevinecdm.so;
    ln -s /home/kodi/.kodi/userdata/addon_data/script.module.inputstreamhelper/cdm/libwidevinecdm.so

Et voilà, après ça, ça fonc­tionne 🙂

Bonus

Je suis chez un FAI asso­cia­tif (LDN, pour ne pas le nommer) via un VPN. Ce qui veut dire que :

  1. j’ai un pres­ta­taire qui me permet de monter le VPN, en l’oc­cu­rence Orange ;
  2. si je pompe trop de bande passante, c’est mon FAI qui est péna­lisé.

Enfin mon Turris Omnia, qui monte le VPN et redis­tri­bue Inter­net chez moi, n’a pas un proces­seur de folie : le chif­fre­ment/déchif­fre­ment du trafic VPN ne me permet pas de profi­ter de la pleine puis­sance de la connexion fibre Orange (ça reste plus que correct quand même hein !).

Du coup, pour éviter de péna­li­ser mon FAI et de bour­ri­ner mon Turris, je route direc­te­ment le trafic Netflix via la box Orange avec un simple :

ip route add 45.57.49.131 via 192.168.2.1 dev eth1

La première IP est celle d’un serveur Netflix, la deuxième est celle de la box Orange et eth1 est l’in­ter­face du Turris connec­tée à la box.

Bien sûr, il y a plus d’une adresse IP à router ainsi. J’ai fait une compi­la­tion de ce que j’ai trouvé sur un snip­pet Frama­git : https://frama­git.org/snip­pets/3739.

EDIT : On a porté à ma connais­sance la commande bgpq3 -J AS-NFLX, qui permet de connaître les adresses IPv4 de l’AS de Netflix. Je ne sais pas s’il faut toutes les dévier vers la box orange (j’ai eu des soucis sur certaines adresses que j’avais détec­tées) mais en tout cas ça va simpli­fier le boulot ! Pour les IPv6, il faut utili­ser bgpq3 -6 -J AS-NFLX.

Crédit : Photo par Alex Litvin sur Unsplash

by Luc at August 19, 2019 05:12 PM

August 07, 2019

Luc Didry

Un nouvel article sur le wiki : Borg­ma­tic !

🎶 Baaaa­ckup ! Ton univers impi­toyaaaable ! 🎶
sur l’air du géné­rique de la série Dallas

Les sauve­gardes, c’est compliqué, mais c’est indis­pen­sable. Il y a un logi­ciel bien sympa qui monte depuis quelques années : Borg. Si vous voulez en savoir plus, je vous invite à aller voir sa page dédiée sur mon wiki, qui date déjà un peu mais dont je n’avais pas parlé. Elle est tirée d’un petit cours que j’avais fait dessus pour la licence ASRALL.

Non, je viens plutôt vous parler ici de Borg­ma­tic, qui simpli­fie énor­mé­ment l’uti­li­sa­tion de Borg. Car Borg est un peu comme Dupli­city : puis­sant mais casse-pieds à mettre en place.
Il faut écrire des scripts et des scripts pour l’uti­li­ser, rete­nir des commandes à rallonge, etc. Grmpf.

Borg­ma­tic permet de rendre l’uti­li­sa­tion de Borg d’une simpli­cité enfan­tine. Bref : allez faire un tour sur https://wiki.fiat-tux.fr/admin:systeme:borg­ma­tic 🙂

Crédits : Photo d’un Borg1 de Star Trek par Marcin Wichary en CC-BY


  1. vous plai­gnez pas, j’ai failli prendre une photo de Björn Borg pour illus­trer l’ar­ticle 😛 

by Luc at August 07, 2019 03:11 PM

August 05, 2019

Luc Didry

Lufi 0.04 est sorti !

Cette fois-ci, il se sera écoulé moins d’un an entre deux versions majeu­res… bon, ok, il s’est passé 9 mois… bon, ok, la liste des modi­fi­ca­tions n’est pas énor­me… 😅

Et pour­tant ! Et pour­tant, c’est une version rela­ti­ve­ment impor­tante.

En effet, il est main­te­nant possible de faire zipper par Lufi vos fichiers avant de les envoyer. Cela veut dire que plutôt que de four­nir 10 liens diffé­rents à vos corres­pon­dants, il est possible de n’en four­nir qu’un seul. Voyez plutôt :

(télé­char­ger la vidéo)

La deuxième modi­fi­ca­tion concerne plutôt les entre­prises et autres struc­tures utili­sant l’au­then­ti­fi­ca­tion LDAP : un utili­sa­teur connecté pourra invi­ter une personne n’ayant pas de compte LDAP à venir dépo­ser des fichiers sur Lufi pour les lui trans­mettre.
Cette fonc­tion­na­lité a été finan­cée par la société TECH’ad­van­tage 😘

Je vous laisse avec cette varia­tion en rouge de l’artwork que j’avais commandé à Soniop l’an­née dernière, toujours en CC-BY-SA, (fichier source Photo­shop).

Cliquez pour avoir l’image originelle (en grande taille)

NB : il est à noter que cette nouvelle version béné­fi­cie des correc­tions de bugs récentes que j’ai pu appor­ter à Lufi ces derniers jours : voir les listes de modi­fi­ca­tions des versions 0.03.6 et 0.03.7.

Liens :

by Luc at August 05, 2019 08:28 PM

July 27, 2019

Luc Didry

J’aime Kresus d’amour tendre et vrai ❤️

J’aime bien avoir un logi­ciel pour faire mes comptes et caté­go­ri­ser mes dépenses, histoire de voir combien je dépense en tel ou tel truc.

J’en ai testé plusieurs, à chaque fois en logi­ciel à instal­ler sur son PC comme [Grisbi](J’aime bien avoir un logi­ciel pour faire mes comptes et caté­go­ri­ser mes dépenses, histoire de voir combien je dépense en tel ou tel truc.

J’en ai testé plusieurs, à chaque fois en logi­ciel à instal­ler sur son PC comme Grisbi ou KMyMo­ney mais je les aban­don­nais plus ou moins rapi­de­ment à cause d’un souci : la flemme. Oui, la flemme de rentrer chaque dépense à la main dans le logi­ciel. Et une fois qu’on a laissé traî­ner ses comptes pendant trop long­temps, le retard est impos­sible à rattrapé.

Heureu­se­ment, j’ai décou­vert Kresus ! Déve­loppé par Benja­min Bouvier en nodejs, au départ comme une appli­ca­tion Cozy Cloud, Kresus va cher­cher lui-même les données de vos comptes sur le site de votre banque grâce à Weboob.

Ceci n’est pas un tuto­riel d’ins­tal­la­tion, pour ça, y a déjà la doc kiva­bien sur le site du projet. Non, je vais plutôt dire ce que j’aime à propos de Kresus (et que je n’avais pas sur les autres logi­ciels que j’ai utilisé) :

  • tout d’abord : ça va cher­cher les mouve­ments bancaires tout seul ! Y a plus qu’à les caté­go­ri­ser 🙂
  • les alertes ! J’ai confi­guré Kresus pour qu’il m’en­voie un mail à chaque mouve­ment bancaire : je suis direc­te­ment informé, tous les matins dans ma boîte mail, de ce qu’il s’est passé sur mes comptes pendant la nuit. Les alertes sont confi­gu­rables par seuil de montant, donc vous pouvez choi­sir de n’être informé que des mouve­ments supé­rieurs ou infé­rieurs au montant que vous souhai­tez.
  • les alertes1 ! En effet, ma banque aussi m’en­voie des mails mais… un ou deux jours après les alertes de Kresus 😏
  • c’est un logi­ciel web : je peux donc l’uti­li­ser sur mon télé­phone, ce qui, de nos jours, est quand même bien pratique

Parmi les trucs que les autres logi­ciels propo­saient aussi :

  • la caté­go­ri­sa­tion (mais ça, c’est un peu le but de ce genre de logi­ciel)
  • des graphiques
  • gestion de budget (vous défi­nis­sez un budget pour tel poste de dépense/rentrée et ça vous dit si vous êtes au-dessus/en-dessous/à l’équi­libre)

Y peut-être d’autres fonc­tion­na­li­tés mais je ne dois pas les utili­ser 😉

Par contre, atten­tion :

  • c’est mono-utili­sa­teur et ça ne gère pas l’au­then­ti­fi­ca­tion, il faut utili­ser une authen­ti­fi­ca­tion HTTP pour en sécu­ri­ser l’ac­cès. Il y a un ticket en cours mais ça risque de mettre du temps (ça se fera peut-être plus vite une fois que Kresus utili­sera une base de données SQL ?)
  • les données de connexion à votre banque sont stockées en clair dans la base de données (CouchDB pour l’ins­tant. En gros, ce sont des fichiers plats sur votre système). Si vous choi­sis­sez de four­nir un Kresus à quelqu’un d’autre, il faut qu’elle vous fasse confiance pour ne pas aller voir et bien sécu­ri­ser votre serveur. Moi je préfère ne pas le propo­ser.
  • les banques modi­fient parfois leurs pages d’au­then­ti­fi­ca­tion (et parfois de façon imper­cep­tible), rendant weboob inca­pable d’y accé­der et de récu­pé­rer les infor­ma­tions. Dans ce genre de cas, il faut aller sur https://git.weboob.org pour :
    • ouvrir un ticket si personne ne l’a déjà fait
    • regar­der si personne n’a proposé de solu­tion ou si personne n’a déjà patché les fichiers du module bancaire de votre banque. Si oui, il faut mettre à jour votre module bancaire (il suffit géné­ra­le­ment de faire un wget des fichiers en écra­sant les anciens)

Voilà, Kresus, c’est un super logi­ciel et je l’aime vrai­ment beau­coup ❤️
Si vous voulez faire un don aux déve­lop­peurs, il y a une orga­ni­sa­tion Libe­ra­pay.

Crédits : photo par Fabian Blank sur Unsplash


  1. non, j’suis pas sénile, c’est juste que j’ai encore un truc à dire sur les alertes. 

by Luc at July 27, 2019 12:02 PM

July 07, 2019

Luc Didry

Mise à jour du firm­ware d’un Rasp­berry Pi 4

J’aime bien mon Rasp­berry Pi 4, mais il a une fâcheuse tendance à chauf­fer. Heureu­se­ment, il y a une mise à jour du firm­ware qui fait gagner quelques degrés et augmente les perfor­mances 🙂

Comme c’est désor­mais la règle pour mes tutos, j’ai publié comment faire sur mon wiki : https://wiki.fiat-tux.fr/admin:systeme:maj-firm­ware-rasp­ber­ry­pi4.

Crédits : Photo par Laura MacNeil sur Unsplash

by Luc at July 07, 2019 07:17 AM

July 04, 2019

Luc Didry

Fédé­rez votre Word­press !

TL; DR: vous pouvez suivre et commen­ter ce blog via @luc@­fiat-tux.fr via la fédé­ra­tion Acti­vi­tyPub, appe­lée aussi Fedi­verse.

Le (ou la, c’est pas vrai­ment bien défini) fédi­verse, qu’est-ce que c’est ? C’est l’en­semble des services web qui causent entre eux via le voca­bu­laire Acti­vi­tyPub. Cela permet de faire commu­niquer deux serveurs de micro-blog­ging comme Masto­don et Pleroma ensemble. Mais encore mieux, cela permet de commen­ter une vidéo PeerTube depuis Masto­don.

Il existe déjà des moteurs de blog fédé­rés comme Plume et j’es­père bien­tôt Diffu mais quit­ter le Word­press sur lequel j’ai mes archives, mes habi­tudes, mes exten­sions confi­gu­rées aux petits oignons… c’est diffi­cile, surtout quand il n’y a rien pour impor­ter un export Word­press.

Qu’à cela ne tienne ! Il existe des exten­sions Word­press pour fédé­rer votre blog : Acti­vi­tyPub et Ptero­type. Ne me deman­dez pas la diffé­rence entre les deux, je vous laisse lire ce qu’en dit le déve­lop­peur de l’ex­ten­sion Acti­vi­tyPub.

J’ai donc installé Acti­vi­tyPub et ça fonc­tionne nickel sans rien faire. La preuve ? J’ai installé l’ex­ten­sion avant de publier mon précé­dent article, je me suis abonné à @luc@­fiat-tux.fr avec mon compte Frama­piaf et j’ai pu voir appa­raître l’ar­ticle dans ma time­line. J’ai commenté depuis Frama­piaf et ça fonc­tionne comme par magie 😁

À part le fait que l’image d’en-tête de l’ar­ticle a été dupliquée, c’est juste parfait, je vous encou­rage à essayer cette exten­sion ! 🙂


EDIT : Appa­rem­ment, le fait de confi­gu­rer le plugin pour ne publier qu’un extrait de l’ar­ticle fout en l’air la mise en page. Quant aux adresses comme @luc@­fiat-tux.fr, elles ne semblent pas être trans­for­mées en lien vers le profil fédéré. C’est dommage.

Crédits : Photo par Alina Grub­nyak sur Unsplash

by Luc at July 04, 2019 08:15 PM

Nouveau thème pour le blog !

Ça fait un bout de temps que je n’ai pas touché au thème de ce blog (depuis 2013, 6 ans quand même !) et je me suis dit que je chan­ge­rais bien.

J’avais deux besoins :

  • un thème sombre (parce que j’aime bien les thèmes sombres, telle­ment que j’uti­lise l’ex­ten­sion Dark Reader sur mon navi­ga­teur, qui permet de donner un thème sombre à quasi­ment n’im­porte quelle page web avec un résul­tat bluf­fant) ;
  • un thème léger : à l’heure des pages web obèses (coucou lemonde.fr et tes 2Mio, dont ±1,7Mio de javas­cript et de trackers (sans décon­ner, faites le test avec uMatrix ou en désac­ti­vant le javas­cript)).

Je suis vite tombé sur le thème Gene­ra­teP­ress qui est vrai­ment sympa : il y a pas mal d’op­tion de person­na­li­sa­tion et la possi­bi­lité d’ajou­ter des règles CSS person­na­li­sées. Donc j’ai basé mon nouveau thème dessus.

J’ai souhaité en faire un thème enfant pour chan­ger le footer qui contient la licence du blog (CC-0 🙂) mais je n’ar­ri­vais pas à voir mon thème enfant dans les thèmes instal­lés donc tant pis, j’ai modi­fié le thème direc­te­ment, à la barbare. Faudra juste que je remette mes modifs à chaque mise à jour.

J’ai aussi installé l’ex­ten­sion Autop­ti­mize qui permet de conca­té­ner et compres­ser fichiers CSS et javas­cript.

J’ai pu consta­ter, sur la page d’ac­cueil, un passage d’un poids — hors images — de près de 700Kio à envi­ron 200Kio, ce qui nous fait un gain de près de 70% 😁


Tiens, tant qu’à parler de blog, je vous encou­rage à aller voir la campagne de finan­ce­ment du logi­ciel Diffu sur Ulule : https://fr.ulule.com/diffu/. Diffu est un moteur de blog qui sera fédéré (donc ça causera avec Plume, Masto­don, tous­sa…) qui sera instal­lable sur des héber­ge­ments mutua­li­sés donc acces­sible au plus grand nombre. Il y a un mockup sur https://mockup.diffu.social/.

Crédits : Photo par Taelynn Chris­to­pher sur Unsplash

by Luc at July 04, 2019 06:50 PM

June 21, 2019

Luc Didry

Migra­tion d’une version majeure de Post­greSQL à une autre (pour Debian Buster)

Aver­tis­se­ment Ceci est une réac­tua­li­sa­tion d’un [précé­dent article][1]. J’en avais marre de devoir chan­ger les numé­ros de version dans mes copier/coller (quoi, vous ne croyez quand même pas que je me souviens de ces commandes par cœur ?), donc je réac­tua­lise l’ar­ticle, ce sera plus confor­table pour tout le monde.

Avec la sortie de Buster, c’est Post­greSQL 11 qui est proposé. Mais comment faire pour migrer les bases de données du clus­ter 9.6 (qui ne rece­vra plus trop d’up­dates) vers le 11 ? Ce n’est pas très compliqué.

Aver­tis­se­ment Cet article est main­te­nant dispo­nible sur mon wiki à l’adresse https://wiki.fiat-tux.fr/admin:bdd:pgsql:migra­tion-version-majeure.
Le wiki contient des infor­ma­tions impor­tantes en plus et sera mis à jour. Pour cette raison, j’ai supprimé cet article pour que personne ne fasse d’er­reur. Rendez-vous donc sur le wiki 😉

by Luc at June 21, 2019 03:09 PM

May 18, 2019

Luc Didry

Une page wiki pour Rspamd

Rspamd est un super anti­spam qui ne fait pas que ça. Je l’uti­lise sur mon serveur perso et chez Frama­soft.

Par contre la doc est assez complexe, et tout n’y est pas, ou pas forcé­ment de façon simple.

J’ai donc commencé à écrire un article sur Rspamd dans mon wiki : https://wiki.fiat-tux.fr/admin:mail:rspamd.

J’ai préféré écrire dans mon wiki plutôt qu’ici parce que c’est plus simple pour retrou­ver la page, ainsi que pour la modi­fier 🙂 (je n’avais pas arrêté de chan­ger des trucs dans mon article sur bitwar­den, c’était assez pénible)

Crédits : Photo par Samuel Zeller sur Unsplash

by Luc at May 18, 2019 09:01 AM

April 23, 2019

Romain Dessort

Carte des pistes de ski des Laurentides

Après 4 hiver à skier et cartographier les pistes de ski nordique des Laurentides, je me devais de produire une carte de tout ça. C'est maintenant chose faite avec ces 2 cartes des Laurentides :

Ce sont les premières cartes à couvrir tout le secteur des Laurentides, et à être plus complètes que les cartes locales des différents organismes, qui ne montrent pas certaines des pistes historiques.

Pour générer ces cartes, j'ai utilisé QGIS, puissant outil libre de SIG mais qui reste assez complexe à maitriser pour quelqu'un comme moi qui manque clairement de connaissance dans ce domaine.

Voici les sources du projet QGIS.

J'explique ci-après les étapes en gros que j'ai suivi pour construire la carte dans QGIS.

Fond de carte

Pour les données topographiques, j'adore le rendu de OpenTopoMap pour leur précision et leur qualité graphique. J'ai donc connecté leur serveur WMS dans QGIS pour avoir leurs tuiles en fond de carte.

Récupération des données relatives aux pistes de ski nordique

Le but ici est de récupérer les données brutes de OpenStreetMap relatives aux pistes de ski nordique afin d'avoir des données vectorielles sur lesquelles travailler.

QGIS, via le plugin QuickOSM, peut interroger directement l'API Overpass pour récupérer ce qui nous intéresse. On va donc récupérer plusieurs choses à l'aide de requêtes Overpass API :

  • tous les sentiers. Ils sont déjà rendus sur les tuiles OpenTopoMap mais ça permet de les mettre un peu plus en valeur :

    way["highway"="path"]({{bbox}});
    out geom;
    
  • les relations ayant pour tag piste:type=nordic :

    relation["piste:type"="nordic"]({{bbox}});
    out geom;
    
  • les chemins (dans le vocabulaire de OpenStreetMap) ayant pour tag piste:type=nordic :

    way["piste:type"="nordic"]({{bbox}});
    out geom;
    
  • et enfin les chemins qui ont pour tag piste:type=nordic mais n'étant dans aucune relation ayant pour tag piste:type=nordic. C'est une astuce qui va être importante pour la suite. Plus compliqué (merci les nombreux exemples de requêtes Overpass API) :

    // On récupère les chemins avec piste:type=nordic et on stocke ça dans
    // le set .all
    way({{bbox}})["piste:type"="nordic"]->.all;
    
    
    // On récupère les relations pour lequelles au moins un de leur chemin
    // membre est présent dans le set .all
    rel["piste:type"="nordic"](bw.all);
    // et pour ces relations, on récupère tout leurs chemins membres dans
    // .members
    way(r)->.members;
    
    
    // Il ne reste plus qu'à faire la différence des 2 sets
    ( .all; - .members; );
    
    
    out geom;
    

QuickOSM stocke le résultat de chaque requête dans des calques séparés. On voit déjà que des mêmes données se retrouvent dans plusieurs calques (la 3ème requête inclue forcement les données de la 4ème et beaucoup de chemins avec piste:type=nordic ont aussi le tag highway=path. Idéalement j'aurai rajouté des exclusions dans les requêtes, mais je suis allé au plus simple, pourquoi s'embêter avec des requêtes Overpass quand il suffit de changer l'ordre d'affichage des calques.

J'ai donc dans l'ordre (du plus bas au plus haut) :

  • le calque de fond de carte OpenTopoMap
  • le calque avec les chemins avec highway=path
  • le calque avec les relations avec piste:type=nordic
  • le calque avec les chemins avec piste:type=nordic qui ne font parti d'aucune relation (mais dont le tracé est masqué, voir la suite)
  • le calque avec les chemins avec piste:type=nordic

Maintenant il s'agit d'ajouter des styles à tout ça

Pour reprendre ce qui se fait de plus commun au Québec, les pistes de ski de fond tracées seront en trait plein et avec le code de couleur représentant leur niveau de difficulté (vert/bleu/noir). Les pistes de ski nordique (communément appelé « hors-piste ») seront en rouge et en tirets. Les autres sentiers seront noir en tirets avec une épaisseur légèrement moindre que les autres (ils sont moins importants). Les relations quant a elles ont une couleur rouge pale. Ça ne se verra pas dans la plupart des cas car par dessus il y a la couleur de la piste de ski (appliquée sur les calques des chemins, sauf dans le cas où la piste que représente la relation traverse un lac ou suit une route : dans ce cas il n'y a pas de chemin avec piste:type=nordic. Ça permet de bien différencier là où il y a une vraie piste des parties qui ne sont pas forcement skiables (routes) ou qu'il n'y a pas de tracé définit (lacs).

Pour les 2 premiers calques (de l'ordre évoqué précédemment), c'est simple on joue avec les options de style de QGIS. Pour le 3ème, on ne veut pas les afficher donc on les mets en transparence totale ou largeur de 0 px (c'est toujours à cause de la fameuse astuce, j'y reviens, j'y reviens !).

Et enfin pour le 4ème calque, pour définir le style en fonction du type de piste et du niveau de difficulté (pour les pistes tracées), on va dire à QGIS de gérer le style suivant 5 règles, que voici :

"piste:grooming" =  'backcountry'
("piste:grooming" like '%classic%' or "piste:grooming" like '%skating%') and "piste:difficulty" = 'easy'
("piste:grooming" like '%classic%' or "piste:grooming" like '%skating%') and "piste:difficulty" = 'intermediate'
("piste:grooming" like '%classic%' or "piste:grooming" like '%skating%') and ("piste:difficulty" = 'advanced' or "piste:difficulty" = 'expert')
"piste:grooming" = 'scooter'

Puisqu'on a accès à tous les attributs OSM dans les données vectorielles importées, c'est relativement simple.

Nom et référence des pistes

Ensuite vient la partie où il faut placer le nom et/ou la référence (en fonction de qu'est ce qui est présent dans les attributs OpenStreetMap) sur les pistes. C'est là que j'ai bloqué pendant longtemps car, au niveau de OpenStreetMap, c'est un peu le bordel : une piste peut être créée par une relation qui assemble plusieurs chemins. Dans ce cas le nom et la référence (numéro ou lettre identifiant la piste en pratique) de la piste sont portés par les attributs name et ref de la relation. Une piste peut aussi ne pas avoir de relation, et être constituée d'un ou plusieurs chemin indépendants. Dans ce cas le nom et la référence peuvent être portés par les attributs name et ref des chemins où, si ces attributs existent déjà et qu'ils ne reflètent pas les bonnes valeurs, par les attributs piste:name et piste:ref (c'est le cas par exemple si la piste de ski emprunte un sentier de vélo ou de marche qui est nommé différemment).

Mon problème sur lequel j'ai luté pendant un moment était pour savoir si un chemin faisait parti d'une relation ou nom via le langage de requête de QGIS. En effet, une fois les données OSM importées, on perd leur structuration. La solution qu'on m'avait proposée sur StackOverflow consistait à utiliser des fonctions géométriques pour voir si le chemin donné se superposait à la relation donnée, mais je ne pouvais pas faire ça simplement pour chacune des relations à tester. D'où l'idée que j'ai eu de récupérer ce fameux calque supplémentaire : les chemins qui ne font partie d'aucune relation. Ainsi au niveau de QGIS c'est bien plus simple : j'affiche les noms pour le calque des relations ainsi que pour le calque des chemins n'ayant pas de relations. Le calque qui contient tous les chemins, lui, je ne lui fait afficher aucun nom.

Pour chacun des 2 calques, Il reste quand même à savoir quels attributs afficher parmi name, ref, piste:name et piste:ref mais ça se fait simplement avec le langage de QGIS.

Pour les relations :

case
    when name <> '' and ref <> '' then
        name || ' (' || ref || ')' 

    when ref <> '' then
        ref

    when name <> '' then
        name

end

Pour les chemins :

case
    when ("name" <> '' or "piste:name" <> '') and ("ref" <> '' or "piste:ref" <> '') then
        if("piste:name" <> '', "piste:name", "name") || ' (' || if("piste:ref" <> '', "piste:ref", "ref") || ')' 

    when "ref" <> '' or "piste:ref" <> ''then
        if("piste:ref" <> '', "piste:ref", "ref")

    when "name" <> '' or "piste:name" <> '' then
        if("piste:name" <> '', "piste:name","name")

end

On a maintenant les noms et/ou les référence des pistes qui s'affichent, et sans conflit. J'ai du jouer beaucoup sur les options d'affichage de QGIS car par défaut si la ligne est trop courbe dans tous les sens ou qu'il y a déjà trop d'information à un endroit, le moteur de QGIS n'affiche pas le nom. Pour plus de lisibilité, mais du coup je me retrouvais avec beaucoup de piste qui n'étaient pas identifiées.

Composition des cartes

Enfin c'est le moment de générer l'aperçu de la carte, via le module de composition de QGIS. Je définis la zone géographique que je veux imprimer, fixe une échelle, y ajoute des objets de texte pour le titre, les sources de données utilisées, une barre d'échelle, etc… QGIS permet de générer automatiquement une légende en fonction des règles de style qu'on a définit précédemment, ce qui est très pratique !

J'ai décidé de générer 2 cartes (secteur nord et secteur sud) pour économiser de la place sur le papier, car il n'y a pas beaucoup de pistes entre les 2.

J'aurai aimé pouvoir imprimer cette carte sur du grand papier pour pouvoir la donner à des collègues de ski. Pour avoir une échelle de 1:50 000, ça m'aurait pris environ une surface de papier de 1 m × 1 m. Mais après quelques devis, les prix sont vraiment chers et je ne suis pas non plus 100 % satisfait du rendu graphique (ni certain du résultat une fois imprimé !) donc j'ai plutôt décidé de découper ça en feuille A4 avec posterazor.

Améliorations

Il y en a beaucoup !

Déjà construire cette carte a permis de détecter pas mal de petites erreurs dans OpenStreetMap sur les données utilisées, je n'ai clairement pas tout corrigé, au delà du fait qu'il y a toujours des pistes incomplètes à aller explorer.

Je ne suis pas non plus très satisfait du placement automatique des noms des pistes par QGIS, bien que j'ai pas mal bidouillé ses réglages. La solution serait probablement de placer le nom des pistes à la main pour chacune d'elles, pour ainsi les mettre à l'endroit qui me semble le plus naturel.

Mais surtout je ne peux malheureusement pas considérer mes cartes générées comme de réelles cartes topographiques car j'ai du faire plusieurs approximations :

  • la projection utilisée est la pseudo-mercator, projection utilisée par OpenTopoMap sur lequel je me base et typiquement utilisé pour le rendu des cartes sur le web. Cette projection fait que l'échelle varie en fonction de la latitude et donc pas adaptée pour une carte topographique. Je devrais plutôt utilisé la projection UTM (zone 18 N pour la région qui m'intéresse ici), qui n'introduit pas de distorsion d'échelle et est utilisé comme projection officielle au Canada. Cependant ça aurait voulu dire regénérer toutes les tuiles avec le style OpenTopoMap avec la bonne projection, donc beaucoup de travail
  • la deuxième approximation est beaucoup plus classique et est au niveau de la sortie en PDF st du fait que je découpe le gros fichier en plusieurs A4, je n'arrive pas à garantir que l'échelle est correctement conservée entre le moment où je produits le PDF dans QGIS et où j'imprime les feuilles A4.

Mis à part ces problématiques, j'espère que cette carte pourra servir aux autres skieurs pour découvrir des nouvelles pistes dans les Laurentides !

April 23, 2019 09:22 PM

April 21, 2019

Romain Dessort

Using molecule with GitLab CI

This article follows this one where I talk about verifying and testing your Ansible roles with molecule.

As I wrote in this first article, I also configured GitLab CI to automatically run molecule tests after each push to the repository. A good documentation to start with is the official GitLab CI/CD documentation.

Here is our .gitlab-ci.yml (latest version) used on our ansible repository hosting all our roles:

---
image: quay.io/ansible/molecule:latest
services:
  - docker:dind

stages:
  - tests

before_script:
  - docker -v
  - python -V
  - ansible --version
  - molecule --version

molecule-role-common:
  stage: tests
  tags:
    - docker
  variables:
    DOCKER_HOST: "tcp://docker:2375"
    PY_COLORS: 1
  script:
    - cd roles/common/
    - molecule test
  only:
    changes:
      - roles/common/**/*

molecule-role-monitoring-tools:
  stage: tests
  tags:
    - docker
  variables:
    DOCKER_HOST: "tcp://docker:2375"
    PY_COLORS: 1
  script:
    - cd roles/monitoring-tools/
    - molecule test
  only:
    changes:
      - roles/monitoring-tools/**/*
[‌]

Our repository is hosted on gitlab.com and even if we can connect our own GitLab Runners to gitlab.com instance, we decided to use the provided gitlab.com's shared runners to get started quickly.

Those use Docker to run the jobs. So we instantiate the official molecule image (from Red Hat's registry):

image: quay.io/ansible/molecule:latest

And since molecule also needs to spawn Docker containers, we need to start another container: docker:dind (Docker in Docker). This is done with:

services:
  - docker:dind

And by exporting the DOCKER_HOST variable to the jobs, so that molecule will be able to connect to the Docker daemon to manage its containers:

variables:
  DOCKER_HOST: "tcp://docker:2375"

Then we define one stage, called tests:

stages:
  - tests

Each jobs related to this stage will have the stage: tests key in their definition.

The before_script block is here for debugging purpose (if the molecule tests succeed locally bt fail on the runners, it may be because the tests are run with a different version of molecule).

Last, we define as many jobs as we have roles to test with molecule. Here, tags is important since it is used by GitLab CI to select the runner the job will be executed on. We need a runner with Docker, thus:

tags:
  - docker

With script keyword we specify each command the runner should run. Pretty self-explanatory:

script:
  - cd roles/monitoring-tools/
  - molecule test

And only adds kind of a condition to the job. We don't want to run all jobs if, for instance, someone updates the README file. The job should run only if a commit introduces a change to a file in the role itself. So we restrict the execution to a change under the role's hierarchy only with:

only:
  changes:
    - roles/monitoring-tools/**/*

For instance, this pipeline, triggered by the commit afe5929c, has spawned only one job, the molecule-role-firewall test, since only the firewall role was modified. Whereas this commit (which impacted multiple roles) triggered 7 jobs (and yes, one has failed).

If a job fails, the commiter will receive a notification by e-mail with the commit and job ID. We can check the job's output on GitLab, to see why it has failed.

As an ending note, to test your .gitlab-ci.yml without pushing, you can install the gitlab-runner package and run it on your repository (you still need to commit your changes since `gitlab-runner will checkout the repository):

$ gitlab-runner exec docker <your job name>

April 21, 2019 01:40 AM

April 20, 2019

Romain Dessort

Containerize ZNC with systemd-nspawn

On my previous server, I had an IRC client (weechat) running in a screen session. I recently migrated this setup to a ZNC bouncer running on my server + weechat running on my laptop, mainly to avoid network lags through SSH and to have a better desktop integration (notifications, etc.).

My server hosts my e-mails, important and confidential documents (among other things) and I always thought that running an always connected IRC client on the same machine was a bad idea.

So in the same time I got rid of my weechat+screen to migrate to ZNC, I had a look at systemd-nspawn, also known as systemd containers. It's actually pretty much like LXC containers, but managed with the systemd logic in mind.

Here is a quick tutorial of how I containerized ZNC into a systemd container on a Debian stretch system:

  1. First, install systemd-container and debootstrap packages:

    # apt install systemd-container debootstrap
    
  2. Create directories used by systemd-container (which aren't create on install):

    # mkdir /var/lib/machines/ /etc/systemd/nspawn/
    

    /var/lib/machines/ will host the containers' hierarchy and containers unit files will be stored into /etc/systemd/nspawn/.

  3. Install a Debian system + znc package using debootstrap into /var/lib/machines/znc/:

    # cd /var/lib/machines/
    # debootstrap --include znc stretch znc
    
  4. To make the container start on boot, you have to enable the corresponding systemd-nspawn instance and the machines target (which will start all enabled instances of systemd-nspawn unit:

    # systemctl enable systemd-nspawn@znc machines.target
    
  5. At this stage, your container is ready. You can start your container (run its init process) with:

    # systemd-nspawn -D /var/lib/machines/znc/
    

    Or execute a command in the container:

    # systemd-nspawn -D /var/lib/machines/znc/ hostname
    

    systemd-nspawn comes with the machinectl command which allows you to easily manage your containers:

    # machinectl [list|list-images|start|stop|status|…]
    

    See its man page for all supported sub-commands and options.

  6. Now, let's configure some few extra stuff to run ZNC. Create a dedicated user in the container:

    # systemd-nspawn -D /var/lib/machines/znc/ useradd -u 1002 -g 1002 -m znc
    
  7. And customize the container's options by putting a config file into /etc/systemd/nspawn/:

    [Exec]
    # Don't start the init process inside the container, instead execute
    # `znc`
    Boot=off
    Parameters=/usr/bin/znc --foreground
    
    
    # Drop all default capabilities: the container will run with no
    # capabilities, ZNC doesn't need any
    DropCapability=CAP_CHOWN CAP_DAC_OVERRIDE CAP_DAC_READ_SEARCH CAP_FOWNER CAP_FSETID CAP_IPC_OWNER CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE CAP_NET_BIND_SERVICE CAP_NET_BROADCAST CAP_NET_RAW CAP_SETGID CAP_SETFCAP CAP_SETPCAP CAP_SETUID CAP_SYS_ADMIN CAP_SYS_CHROOT CAP_SYS_NICE CAP_SYS_PTRACE CAP_SYS_TTY_CONFIG CAP_SYS_RESOURCE CAP_SYS_BOOT CAP_AUDIT_WRITE CAP_AUDIT_CONTROL
    
    
    # Start `znc` as znc
    User=znc
    
    
    # Those 2 options aren't supported by the version of systemd shiped
    # with Debian stretch. Ephemeral=on makes the container discard on
    # shutdown any modification made during its runtime (Docker style) and
    # NoNewPrivileges ensures that the code executed inside the container
    # won't be able to gain greater privileges (with setuid bit for instance)
    #Ephemeral=on
    #NoNewPrivileges=on
    
    
    # Use private user namespace (equivalent to LXC's unprivilegied mode)
    PrivateUsers=on
    
    
    [Files] 
    # Mount my .znc configuration directory onto the container (with write
    # access) and the znc.pem containing the private key, certificates
    # chain and DH param (read-only)
    Bind=/home/romain/.znc/:/home/znc/.znc/
    BindReadOnly=/var/lib/acme/live/irc.univers-libre.net/combined:/home/znc/.znc/znc.pem
    
    
    [Network]
    # Use the same network stack as the host
    VirtualEthernet=no
    

    This file will automatically be read by systemd-nspawn before starting the container. All these options can be specified as commandline parameters to systemd-nspawn as well.

Resources:

April 20, 2019 04:03 AM

April 16, 2019

Romain Dessort

Ancien réseau de ski à Saint-Donat

Bien qu'assez éloigné des autres pistes nordiques de la vallée de la Rivière du Nord, on peut retrouver aussi des vielles pistes abandonnées aussi loin que Saint-Donat. Le massif de montagne entre le lac Ouareau, Saint-Donat et l'Interval hébergeait visiblement beaucoup de pistes de ski. La plus connue et celle qui a le mieux survécue à l'épreuve du temps est la Kaaikop qui monte au Mont Kaaikop depuis la 329 en passant par l'auberge de l'Interval. Un petit réseau de pistes toujours entretenues existe aussi autour de cette auberge mais je ne le connais pas vraiment.

Mais plus au nord-est, j'avais découvert en y allant l'été plusieurs sentiers bien envahis mais assez larges pour être des pistes de ski (lui, lui et lui notamment. Sur certains, il restait même quelques panneaux avec le numéro de la piste, des « attention pente raide » et des « sens unique », preuve que ça devait même être un réseau damé et tracé. Certaines balises portaient le nom La Réserve, station de ski alpin des environs, c'est donc possible qu'à une époque ce centre avait un réseau de ski nordique qu'il a ensuite complètement abandonné au profil du ski alpin…

Aujourd'hui, seules quelques pistes sont encore entretenues officiellement par le club de plein air de Saint-Donat qu'on peut voir sur leur carte.

J'y suis retourné la semaine passée, après la dernière neige de la saison avec 2 autres collègues de ski, dans le but de rejoindre le Mont Kaaikop depuis Le Grand R via une des pistes abandonnées. Je la connaissais en partie pour l'avoir faite l'été, mais je l'avais perdue à un moment donnée. En début d'hiver, j'avais repéré une intersection sur un autre sentier où c'était très probable qu'elle arrive là, je voulais donc confirmer ça. Finalement on a manqué une intersection et pas pris le sentier que je voulais… mais on en a découvert un autre ! À peu près parallèle à celui que je voulais retrouvé. J'ai aussi remarqué le départ d'un autre sentier (encore un) qui partait plein est.

Bref il reste beaucoup à explorer dans ce secteur encore, j'ai rajouté plus de fixme que complété des sentiers dans OpenStreetMap…

Par contre j'ai pu mettre la main sur un vieux plan des piste de Saint-Donat datant de 1981, édité à l'époque par le club de ski de fond des Panaches (qui n'existe plus). Le secteur dont je parle ici est celui du Lac Bouillon. Mais on voit qu'il y avait des pistes pas mal partout autour de Saint-Donat.

Certains des pistes que j'ai trouvé apparaissent effectivement sur le plan, mais d'autres non, probablement plus récentes.

April 16, 2019 06:26 PM

April 12, 2019

Romain Dessort

Yoghourt maison

Des fois il y a des trucs tellement simple à faire qu'on peut se demander pourquoi le monde ne les font plus eux-mêmes. Les yoghourts par exemple.

Un couple qui m'avait hébergé en Colombie-Britannique faisait son propre yaourt et m'avait montré comment faire. Du coup maintenant j'ai pris l'habitude de faire le mien (et d'en remanger aussi, parce que ça faisait longtemps que je n'en achetais plus).

Les avantages que je vois à faire son propre yaourt :

  • moins de déchet, surtout s'il est possible de trouver du lait en bouteille consignée (même si au Canada c'est moins pire, on ne trouve pas des pots de yoghourt individuels, seulement des pots de 0,5 ou 1 L)
  • plus économique (1 L de lait est généralement moins cher que 1 L de yoghourt)
  • le plaisir de faire son propre yoghourt
  • permet de conserver du lait plus longtemps si votre bouteille est due pour bientôt

La marche à suivre est assez simple, en fait il n'y a quasiment rien à faire. Je peux résumer ça à :

  • vider une bouteille de lait dans une casserole et le faire bouillir
  • le laisser tiédir et mélanger avec le fond de votre yoghourt précédent
  • transvaser dans des pots et les conserver au chaud le plus longtemps possible, puis mettre au frigo

Mais ça mérite quand même quelques explications de plus :

Au départ il faut trouver des bactéries lactiques actives, soit en pharmacie soit en supermarché, sous forme de « Yogourt Starter ». D'après des tests, utiliser des yaourts existants du commerce ne marche pas, même des yaourt dit contenant des ferments actifs, un bon test pour valider (ou pas) ce qui est écrit sur les pots de yaourt…

Ensuite il faut du lait (entier tant qu'à faire, mais allégé marche aussi).

Commencez par faire bouillir le lait pour le stériliser (en le surveillant car ça monte vite, prévoyez une grande casserole) et laissez le refroidir tranquillement jusqu'à ce qu'il soit tiède (trempez un doigt dedans, ça doit être chaud mais pas brulant).

Stérilisation du lait

À ce moment là ajoutez les bactéries actives et mélangez bien puis transvaser dans des pots type Mason (ou n'importe quels pots de récup en fait).

Le but maintenant est de garder les pots tièdes (normalement autour de 40 °C mais on est pas à 5 °C près) pendant 4 ou 5h minimum, le temps que les bactéries travaillent. C'est à ce moment là qu'il faut faire preuve d'un peu de créativité. Personnellement je les mets chacun systématiquement dans un gros bas de laine pour mieux garder leur chaleur. Ensuite, l'hiver je les pose sur un radiateur puis je les recouvre d'une polaire. Sinon ils vont dans le four encore chaud, derrière une vitre au soleil, sous la couverture et je dors avec (oui oui !)… Vous pouvez aussi récupérer des petites résistances chauffantes et les mettre dans un vêtement, puis les pots dedans. Bref plein de possibilités.

Yogourt prêt à fermenter dans un bas de laine

Je les laisse comme ça une nuit puis je les mets au frigo ensuite pour stopper le processus (plus les bactéries travailleront, plus le yaourt sera ferme mais acide).

Sinon il y a bien sûr des… trucs qui s'appellent des yaourtières (qui devraient être efficaces), spécialement conçus pour encombrer vos placards de cuisine, puis vos (nos) poubelles quand, tôt ou tard, ils ne marcheront plus.

Le yaourt dans les pots se conservent un ou deux mois au frigo sans problème. Un fois un pot ouvert, je peux le conserver plusieurs semaines. Probablement plus en fait, mais ça m'ait jamais arrivé d'avoir un yoghourt qui a viré mauvais.

Yogourt maison Miam !

Et enfin, pour refaire une autre batch, au lieu des bactéries sèches du départ, il suffit de prendre le fond du pot qui vous reste et le mélanger au nouveau lait tiédi (genre l'équivalent de 3 ou 4 cuillères à soupe, au pif). Au bout d'un moment, si le yoghourt a du mal à prendre, c'est que votre culture de bactéries s'épuise et il suffit de repartir avec de nouvelles.

April 12, 2019 09:40 PM