<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Univers Libre</title>
    <subtitle>Yet another sysadmin&#39;s personal blog</subtitle>
    <link rel="self" type="application/atom+xml" href="https://univers-libre.net/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://univers-libre.net"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-10-02T00:00:00+00:00</updated>
    <id>https://univers-libre.net/atom.xml</id>
    <entry xml:lang="en">
        <title>Carte des pistes de ski des Laurentides</title>
        <published>2019-04-23T00:00:00+00:00</published>
        <updated>2019-04-23T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/carte-ski-laurentides/"/>
        <id>https://univers-libre.net/posts/carte-ski-laurentides/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/carte-ski-laurentides/">&lt;p&gt;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 :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/carte-ski-laurentides/secteur-sud.pdf&quot;&gt;secteur sud&lt;/a&gt; (&lt;a href=&quot;/posts/carte-ski-laurentides/secteur-sud-posterized.pdf&quot;&gt;format A4&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/carte-ski-laurentides/secteur-nord.pdf&quot;&gt;secteur nord&lt;/a&gt; (&lt;a href=&quot;/posts/carte-ski-laurentides/secteur-nord-posterized.pdf&quot;&gt;format A4&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Pour générer ces cartes, j’ai utilisé &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.qgis.org/en/site/&quot;&gt;QGIS&lt;/a&gt;,
puissant outil libre de SIG mais qui reste assez complexe à maitriser pour quelqu’un
comme moi qui manque clairement de connaissance dans ce domaine.&lt;/p&gt;
&lt;p&gt;Voici les &lt;a href=&quot;/posts/carte-ski-laurentides/carte-ski-laurentides.tar&quot;&gt;sources&lt;/a&gt; du projet QGIS.&lt;/p&gt;
&lt;p&gt;J’explique ci-après les étapes en gros que j’ai suivi pour construire la carte
dans QGIS.&lt;/p&gt;
&lt;h2 id=&quot;fond-de-carte&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#fond-de-carte&quot; aria-label=&quot;Anchor link for: fond-de-carte&quot;&gt;Fond de carte&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pour les données topographiques, j’adore le rendu de
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://opentopomap.org/about&quot;&gt;OpenTopoMap&lt;/a&gt; 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.&lt;/p&gt;
&lt;h2 id=&quot;recuperation-des-donnees-relatives-aux-pistes-de-ski-nordique&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#recuperation-des-donnees-relatives-aux-pistes-de-ski-nordique&quot; aria-label=&quot;Anchor link for: recuperation-des-donnees-relatives-aux-pistes-de-ski-nordique&quot;&gt;Récupération des données relatives aux pistes de ski nordique&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;QGIS, via le plugin QuickOSM, peut interroger directement l’&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.openstreetmap.org/wiki/Overpass_API&quot;&gt;API Overpass&lt;/a&gt; pour récupérer ce qui nous intéresse.
On va donc récupérer plusieurs choses à l’aide de &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL&quot;&gt;requêtes Overpass API&lt;/a&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;tous les sentiers. Ils sont déjà rendus sur les tuiles OpenTopoMap mais ça permet de les mettre un peu plus en valeur :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;way[&amp;quot;highway&amp;quot;=&amp;quot;path&amp;quot;]({{bbox}});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;out geom;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;les relations ayant pour tag &lt;em&gt;piste:type=nordic&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;relation[&amp;quot;piste:type&amp;quot;=&amp;quot;nordic&amp;quot;]({{bbox}});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;out geom;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;les &lt;em&gt;chemins&lt;/em&gt; (&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.openstreetmap.org/wiki/Way&quot;&gt;dans le vocabulaire de OpenStreetMap&lt;/a&gt;) ayant pour tag &lt;em&gt;piste:type=nordic&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;way[&amp;quot;piste:type&amp;quot;=&amp;quot;nordic&amp;quot;]({{bbox}});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;out geom;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;et enfin les &lt;em&gt;chemins&lt;/em&gt; qui ont pour tag &lt;em&gt;piste:type=nordic&lt;/em&gt; mais n’étant
dans aucune relation ayant pour tag &lt;em&gt;piste:type=nordic&lt;/em&gt;. C’est une astuce
qui va être importante pour la suite. Plus compliqué (merci les &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_API_by_Example&quot;&gt;nombreux
exemples&lt;/a&gt;
de requêtes Overpass API) :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;// On récupère les chemins avec piste:type=nordic et on stocke ça dans&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;// le set .all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;way({{bbox}})[&amp;quot;piste:type&amp;quot;=&amp;quot;nordic&amp;quot;]-&amp;gt;.all;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;// On récupère les relations pour lequelles au moins un de leur chemin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;// membre est présent dans le set .all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rel[&amp;quot;piste:type&amp;quot;=&amp;quot;nordic&amp;quot;](bw.all);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;// et pour ces relations, on récupère tout leurs chemins membres dans&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;// .members&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;way(r)-&amp;gt;.members;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;// Il ne reste plus qu&amp;#39;à faire la différence des 2 sets&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;( .all; - .members; );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;out geom;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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 &lt;em&gt;chemins&lt;/em&gt; avec &lt;em&gt;piste:type=nordic&lt;/em&gt; ont aussi le tag &lt;em&gt;highway=path&lt;/em&gt;. 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.&lt;/p&gt;
&lt;p&gt;J’ai donc dans l’ordre (du plus bas au plus haut) :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le calque de fond de carte OpenTopoMap&lt;/li&gt;
&lt;li&gt;le calque avec les &lt;em&gt;chemins&lt;/em&gt; avec &lt;em&gt;highway=path&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;le calque avec les relations avec &lt;em&gt;piste:type=nordic&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;le calque avec les &lt;em&gt;chemins&lt;/em&gt; avec &lt;em&gt;piste:type=nordic&lt;/em&gt; qui ne font parti d’aucune relation (mais dont le tracé est masqué, voir la suite)&lt;/li&gt;
&lt;li&gt;le calque avec les &lt;em&gt;chemins&lt;/em&gt; avec &lt;em&gt;piste:type=nordic&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;maintenant-il-s-agit-d-ajouter-des-styles-a-tout-ca&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#maintenant-il-s-agit-d-ajouter-des-styles-a-tout-ca&quot; aria-label=&quot;Anchor link for: maintenant-il-s-agit-d-ajouter-des-styles-a-tout-ca&quot;&gt;Maintenant il s’agit d’ajouter des styles à tout ça&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;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 &lt;em&gt;chemins&lt;/em&gt;, 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 &lt;em&gt;chemin&lt;/em&gt; avec &lt;em&gt;piste:type=nordic&lt;/em&gt;. Ç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).&lt;/p&gt;
&lt;p&gt;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 !).&lt;/p&gt;
&lt;p&gt;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 :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;quot;piste:grooming&amp;quot; =  &amp;#39;backcountry&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&amp;quot;piste:grooming&amp;quot; like &amp;#39;%classic%&amp;#39; or &amp;quot;piste:grooming&amp;quot; like &amp;#39;%skating%&amp;#39;) and &amp;quot;piste:difficulty&amp;quot; = &amp;#39;easy&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&amp;quot;piste:grooming&amp;quot; like &amp;#39;%classic%&amp;#39; or &amp;quot;piste:grooming&amp;quot; like &amp;#39;%skating%&amp;#39;) and &amp;quot;piste:difficulty&amp;quot; = &amp;#39;intermediate&amp;#39;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&amp;quot;piste:grooming&amp;quot; like &amp;#39;%classic%&amp;#39; or &amp;quot;piste:grooming&amp;quot; like &amp;#39;%skating%&amp;#39;) and (&amp;quot;piste:difficulty&amp;quot; = &amp;#39;advanced&amp;#39; or &amp;quot;piste:difficulty&amp;quot; = &amp;#39;expert&amp;#39;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;quot;piste:grooming&amp;quot; = &amp;#39;scooter&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Puisqu’on a accès à tous les attributs OSM dans les données vectorielles importées, c’est relativement simple.&lt;/p&gt;
&lt;h2 id=&quot;nom-et-reference-des-pistes&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#nom-et-reference-des-pistes&quot; aria-label=&quot;Anchor link for: nom-et-reference-des-pistes&quot;&gt;Nom et référence des pistes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;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 &lt;em&gt;chemins&lt;/em&gt;. 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 &lt;em&gt;name&lt;/em&gt; et &lt;em&gt;ref&lt;/em&gt; de la relation. Une
piste peut aussi ne pas avoir de relation, et être constituée d’un ou plusieurs
&lt;em&gt;chemin&lt;/em&gt; indépendants. Dans ce cas le nom et la référence peuvent être portés par
les attributs &lt;em&gt;name&lt;/em&gt; et &lt;em&gt;ref&lt;/em&gt; des &lt;em&gt;chemins&lt;/em&gt; où, si ces attributs existent déjà
et qu’ils ne reflètent pas les bonnes valeurs, par les attributs &lt;em&gt;piste:name&lt;/em&gt;
et &lt;em&gt;piste:ref&lt;/em&gt; (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).&lt;/p&gt;
&lt;p&gt;Mon problème sur lequel j’ai luté pendant un moment était pour savoir si un
&lt;em&gt;chemin&lt;/em&gt; 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 &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://gis.stackexchange.com/questions/315581/rule-for-labeling-ways-not-being-part-of-osm-relation-in-qgis&quot;&gt;proposée&lt;/a&gt; sur StackOverflow consistait à utiliser des
fonctions géométriques pour voir si le &lt;em&gt;chemin&lt;/em&gt; 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 &lt;em&gt;chemins&lt;/em&gt; 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 &lt;em&gt;chemins&lt;/em&gt; n’ayant pas de relations. Le
calque qui contient tous les &lt;em&gt;chemins&lt;/em&gt;, lui, je ne lui fait afficher aucun nom.&lt;/p&gt;
&lt;p&gt;Pour chacun des 2 calques, Il reste quand même à savoir quels attributs afficher parmi &lt;em&gt;name&lt;/em&gt;, &lt;em&gt;ref&lt;/em&gt;, &lt;em&gt;piste:name&lt;/em&gt; et &lt;em&gt;piste:ref&lt;/em&gt; mais ça se fait simplement avec le langage de QGIS.&lt;/p&gt;
&lt;p&gt;Pour les relations :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    when name &amp;lt;&amp;gt; &amp;#39;&amp;#39; and ref &amp;lt;&amp;gt; &amp;#39;&amp;#39; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        name || &amp;#39; (&amp;#39; || ref || &amp;#39;)&amp;#39; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    when ref &amp;lt;&amp;gt; &amp;#39;&amp;#39; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ref&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    when name &amp;lt;&amp;gt; &amp;#39;&amp;#39; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        name&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pour les &lt;em&gt;chemins&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;case&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    when (&amp;quot;name&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39; or &amp;quot;piste:name&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39;) and (&amp;quot;ref&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39; or &amp;quot;piste:ref&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39;) then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if(&amp;quot;piste:name&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39;, &amp;quot;piste:name&amp;quot;, &amp;quot;name&amp;quot;) || &amp;#39; (&amp;#39; || if(&amp;quot;piste:ref&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39;, &amp;quot;piste:ref&amp;quot;, &amp;quot;ref&amp;quot;) || &amp;#39;)&amp;#39; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    when &amp;quot;ref&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39; or &amp;quot;piste:ref&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39;then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if(&amp;quot;piste:ref&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39;, &amp;quot;piste:ref&amp;quot;, &amp;quot;ref&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    when &amp;quot;name&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39; or &amp;quot;piste:name&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if(&amp;quot;piste:name&amp;quot; &amp;lt;&amp;gt; &amp;#39;&amp;#39;, &amp;quot;piste:name&amp;quot;,&amp;quot;name&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h2 id=&quot;composition-des-cartes&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#composition-des-cartes&quot; aria-label=&quot;Anchor link for: composition-des-cartes&quot;&gt;Composition des cartes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;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 !&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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 &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://sourceforge.net/projects/posterazor/&quot;&gt;posterazor&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;ameliorations&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#ameliorations&quot; aria-label=&quot;Anchor link for: ameliorations&quot;&gt;Améliorations&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Il y en a beaucoup !&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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 :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;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&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;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 !&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using molecule with GitLab CI</title>
        <published>2019-04-21T00:00:00+00:00</published>
        <updated>2019-04-21T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/ansible-molecule-gitlab-ci/"/>
        <id>https://univers-libre.net/posts/ansible-molecule-gitlab-ci/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/ansible-molecule-gitlab-ci/">&lt;p&gt;This article follows &lt;a href=&quot;/posts/ansible-molecule.html&quot;&gt;this one&lt;/a&gt; where I talk
about verifying and testing your Ansible roles with molecule.&lt;/p&gt;
&lt;p&gt;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 &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://docs.gitlab.com/ee/ci/&quot;&gt;GitLab CI/CD documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here is our &lt;em&gt;.gitlab-ci.yml&lt;/em&gt; (&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://gitlab.com/facil/ansible/blob/master/.gitlab-ci.yml&quot;&gt;latest version&lt;/a&gt;) used on our &lt;em&gt;ansible&lt;/em&gt; repository hosting all our roles:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;image: quay.io/ansible/molecule:latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;services:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - docker:dind&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stages:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - tests&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;before_script:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - docker -v&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - python -V&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - ansible --version&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - molecule --version&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;molecule-role-common:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  stage: tests&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  tags:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - docker&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  variables:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    DOCKER_HOST: &amp;quot;tcp://docker:2375&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    PY_COLORS: 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  script:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - cd roles/common/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - molecule test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  only:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    changes:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - roles/common/**/*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;molecule-role-monitoring-tools:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  stage: tests&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  tags:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - docker&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  variables:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    DOCKER_HOST: &amp;quot;tcp://docker:2375&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    PY_COLORS: 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  script:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - cd roles/monitoring-tools/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - molecule test&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  only:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    changes:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - roles/monitoring-tools/**/*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[…]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Those use Docker to run the jobs. So we instantiate the official molecule image
(from Red Hat’s registry):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;image: quay.io/ansible/molecule:latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And since molecule also needs to spawn Docker containers, we need to start
another container: &lt;em&gt;docker:dind&lt;/em&gt; (Docker in Docker). This is done with:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;services:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - docker:dind&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And by exporting the &lt;code&gt;DOCKER_HOST&lt;/code&gt; variable to the jobs, so that molecule will
be able to connect to the Docker daemon to manage its containers:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;variables:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  DOCKER_HOST: &amp;quot;tcp://docker:2375&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then we define one stage, called &lt;em&gt;tests&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;stages:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - tests&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each jobs related to this stage will have the &lt;code&gt;stage: tests&lt;/code&gt; key in their
definition.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;before_script&lt;/code&gt; 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).&lt;/p&gt;
&lt;p&gt;Last, we define as many jobs as we have roles to test with molecule. Here,
&lt;code&gt;tags&lt;/code&gt; 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:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tags:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - docker&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With &lt;code&gt;script&lt;/code&gt; keyword we specify each command the runner should run. Pretty
self-explanatory:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;script:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - cd roles/monitoring-tools/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - molecule test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And &lt;code&gt;only&lt;/code&gt; 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:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;only:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  changes:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - roles/monitoring-tools/**/*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For instance, &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://gitlab.com/facil/ansible/pipelines/54380774/builds&quot;&gt;this
pipeline&lt;/a&gt;,
triggered by the commit afe5929c, has spawned only &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://gitlab.com/facil/ansible/-/jobs/187303076&quot;&gt;one
job&lt;/a&gt;, the
&lt;em&gt;molecule-role-firewall&lt;/em&gt; test, since only the firewall role was modified.
Whereas &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://gitlab.com/facil/ansible/commit/39abe0e9785e72aa8964a193e3af066106552f6a&quot;&gt;this
commit&lt;/a&gt;
(which impacted multiple roles) triggered &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://gitlab.com/facil/ansible/pipelines/54499990/builds&quot;&gt;7
jobs&lt;/a&gt; (and yes, one
has failed).&lt;/p&gt;
&lt;p&gt;If a job fails, the commiter will receive a notification by e-mail with the
commit and job ID. We can check the &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://gitlab.com/facil/ansible/-/jobs/187667011&quot;&gt;job’s
output&lt;/a&gt; on GitLab, to see
why it has failed.&lt;/p&gt;
&lt;p&gt;As an ending note, to test your &lt;em&gt;.gitlab-ci.yml&lt;/em&gt; without pushing, you can
install the &lt;em&gt;gitlab-runner&lt;/em&gt; package and run it on your repository (you still
need to commit your changes since `gitlab-runner will checkout the repository):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ gitlab-runner exec docker &amp;lt;your job name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Containerize ZNC with systemd-nspawn</title>
        <published>2019-04-20T00:00:00+00:00</published>
        <updated>2019-04-20T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/containerize-znc-with-systemd-nspawn/"/>
        <id>https://univers-libre.net/posts/containerize-znc-with-systemd-nspawn/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/containerize-znc-with-systemd-nspawn/">&lt;p&gt;On my previous server, I had an IRC client (weechat) running in a &lt;code&gt;screen&lt;/code&gt;
session. I recently migrated this setup to a &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.znc.in/ZNC&quot;&gt;ZNC
bouncer&lt;/a&gt; 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.).&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;So in the same time I got rid of my weechat+screen to migrate to ZNC, I had a
look at &lt;code&gt;systemd-nspawn&lt;/code&gt;, also known as systemd containers. It’s actually
pretty much like LXC containers, but managed with the systemd logic in mind.&lt;/p&gt;
&lt;p&gt;Here is a quick tutorial of how I containerized ZNC into a systemd container on
a Debian stretch system:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First, install &lt;em&gt;systemd-container&lt;/em&gt; and &lt;em&gt;debootstrap&lt;/em&gt; packages:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# apt install systemd-container debootstrap&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create directories used by &lt;code&gt;systemd-container&lt;/code&gt; (which aren’t create on
install):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mkdir /var/lib/machines/ /etc/systemd/nspawn/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;/var/lib/machines/&lt;/em&gt; will host the containers’ hierarchy and containers
unit files will be stored into &lt;em&gt;/etc/systemd/nspawn/&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install a Debian system + &lt;em&gt;znc&lt;/em&gt; package using &lt;code&gt;debootstrap&lt;/code&gt; into
&lt;em&gt;/var/lib/machines/znc/&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cd /var/lib/machines/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# debootstrap --include znc stretch znc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To make the container start on boot, you have to enable the corresponding
&lt;em&gt;systemd-nspawn&lt;/em&gt; instance and the &lt;em&gt;machines&lt;/em&gt; target (which will start all
enabled instances of &lt;em&gt;systemd-nspawn&lt;/em&gt; unit:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemctl enable systemd-nspawn@znc machines.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;At this stage, your container is ready. You can start your container (run
its init process) with:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemd-nspawn -D /var/lib/machines/znc/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or execute a command in the container:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemd-nspawn -D /var/lib/machines/znc/ hostname&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;systemd-nspawn comes with the &lt;code&gt;machinectl&lt;/code&gt; command which allows you to
easily manage your containers:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# machinectl [list|list-images|start|stop|status|…]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See its man page for all supported sub-commands and options.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now, let’s configure some few extra stuff to run ZNC. Create a dedicated
user in the container:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# systemd-nspawn -D /var/lib/machines/znc/ useradd -u 1002 -g 1002 -m znc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;And customize the container’s options by putting a config file into
&lt;em&gt;/etc/systemd/nspawn/&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Exec]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Don&amp;#39;t start the init process inside the container, instead execute&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# `znc`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Boot=off&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Parameters=/usr/bin/znc --foreground&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Drop all default capabilities: the container will run with no&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# capabilities, ZNC doesn&amp;#39;t need any&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;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&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Start `znc` as znc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;User=znc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Those 2 options aren&amp;#39;t supported by the version of systemd shiped&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;with Debian stretch. Ephemeral=on makes the container discard on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;shutdown any modification made during its runtime (Docker style) and&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NoNewPrivileges ensures that the code executed inside the container&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;won&amp;#39;t be able to gain greater privileges (with setuid bit for instance)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#Ephemeral=on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#NoNewPrivileges=on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Use private user namespace (equivalent to LXC&amp;#39;s unprivilegied mode)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;PrivateUsers=on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Files] &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Mount my .znc configuration directory onto the container (with write&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;access) and the znc.pem containing the private key, certificates chain&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;and DH param (read-only)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Bind=/home/romain/.znc/:/home/znc/.znc/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BindReadOnly=/var/lib/acme/live/irc.univers-libre.net/combined:/home/znc/.znc/znc.pem&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Network]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Use the same network stack as the host&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;VirtualEthernet=no&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This file will automatically be read by &lt;code&gt;systemd-nspawn&lt;/code&gt; before starting
the container. All these options can be specified as commandline
parameters to &lt;code&gt;systemd-nspawn&lt;/code&gt; as well.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.archlinux.org/title/Systemd-nspawn&quot;&gt;https://wiki.archlinux.org/title/Systemd-nspawn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html&quot;&gt;https://www.freedesktop.org/software/systemd/man/systemd-nspawn.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html&quot;&gt;https://www.freedesktop.org/software/systemd/man/systemd.nspawn.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.freedesktop.org/software/systemd/man/machinectl.html&quot;&gt;https://www.freedesktop.org/software/systemd/man/machinectl.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Ancien réseau de ski à Saint-Donat</title>
        <published>2019-04-16T00:00:00+00:00</published>
        <updated>2019-04-16T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/ancien-reseau-saint-donat/"/>
        <id>https://univers-libre.net/posts/ancien-reseau-saint-donat/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/ancien-reseau-saint-donat/">&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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 (&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/way/660840988&quot;&gt;lui&lt;/a&gt;, &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/way/527661490&quot;&gt;lui&lt;/a&gt; et &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/way/427837098&quot;&gt;lui&lt;/a&gt; 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 &lt;em&gt;La Réserve&lt;/em&gt;, 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…&lt;/p&gt;
&lt;p&gt;Aujourd’hui, seules quelques pistes sont encore entretenues officiellement par
le club de plein air de Saint-Donat qu’on peut voir sur leur &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://fondationpleinairsaint-donat.org/images/Carte_Hivernale_des_Sentiers_de_St-Donat.jpg&quot;&gt;carte&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;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 &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/way/683408254&quot;&gt;autre&lt;/a&gt; ! À peu près parallèle à celui que je voulais retrouvé.
J’ai aussi remarqué le départ d’un &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/way/683408255&quot;&gt;autre sentier&lt;/a&gt; (encore un) qui partait plein est.&lt;/p&gt;
&lt;p&gt;Bref il reste beaucoup à explorer dans ce secteur encore, j’ai rajouté plus de
&lt;em&gt;fixme&lt;/em&gt; que complété des sentiers dans OpenStreetMap…&lt;/p&gt;
&lt;p&gt;Par contre j’ai pu mettre la main sur un vieux &lt;a href=&quot;/posts/ancien-reseau-saint-donat/saint-donat.pdf&quot;&gt;plan des piste de Saint-Donat&lt;/a&gt;
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.&lt;/p&gt;
&lt;p&gt;Certains des pistes que j’ai trouvé apparaissent effectivement sur le plan, mais d’autres non, probablement plus récentes.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Mémo pour fartage de skis de classique</title>
        <published>2019-04-12T00:00:00+00:00</published>
        <updated>2019-04-12T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/memo-fartage/"/>
        <id>https://univers-libre.net/posts/memo-fartage/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/memo-fartage/">&lt;p&gt;À chaque début de saison, j’ai toujours du mal à me rappeler de certains petits
détails et astuces pour préparer mes skis de fond de classique. Je mets donc
ici mes notes en public, chacun a ses techniques et astuces mais ça m’a bien servi au début de lire les méthodes des autres skieurs.&lt;/p&gt;
&lt;h2 id=&quot;zone-de-glisse&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#zone-de-glisse&quot; aria-label=&quot;Anchor link for: zone-de-glisse&quot;&gt;Zone de glisse&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Commencer toujours par la zone de glisse pour éviter de mettre de la poussière
de cire sur le nouveau fart de retenu.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Brosser 2 ou 3 fois la zone de glisse à la brosse de laiton pour enlever la
saleté et la vieille cire ;&lt;/li&gt;
&lt;li&gt;Crayonner la cire du jour sur la zone de glisse. Pour les cires pour
températures chaudes, très facile, pour les cires plus dures c’est bien de
les poser quelques minutes avant sur un radiateur pour les ramollir un peu
(sinon les réchauffer au fer). En mettre vraiment très peu, juste un passage
suffit ;&lt;/li&gt;
&lt;li&gt;Prendre une chaussette de laine autour d’un liège et polir énergiquement la
base ;&lt;/li&gt;
&lt;li&gt;Finir avec quelques passages à la brosse de nylon.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;De temps en temps, et si la base est vraiment salle, il peut être bien de
couler de la cire (n’importe laquelle) dessus et de gratter + brosser, soit la
méthode classique (à l’ancienne).&lt;/p&gt;
&lt;h2 id=&quot;zone-de-retenue&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#zone-de-retenue&quot; aria-label=&quot;Anchor link for: zone-de-retenue&quot;&gt;Zone de retenue&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Scraper l’ancien fart avec une raclette de métal s’il en reste. La lame de la
raclette doit être en biseau et bien aiguisée pour éviter que le fart ne
roule sur lui même. Toujours gratter des extrémités de la zone vers l’intérieur ;&lt;/li&gt;
&lt;li&gt;S’il y a du klister, faire fondre un peu de cire dessus pour faciliter le
retrait et éviter de s’en mettre de partout ;&lt;/li&gt;
&lt;li&gt;Nettoyer éventuellement au fiberlene + défartant, surtout s’il y avait du
fart plus chaud avant. Ne pas oublier les côtés du ski ;&lt;/li&gt;
&lt;li&gt;Sabler la zone de retenue au papier de verre (80-100) dans le sens inverse
de la glisse pour redresser les fibres. 2 passages suffisent ;&lt;/li&gt;
&lt;li&gt;Crayonner une couche de binder (garder le binder au congélateur pour que ce soit
plus facile à appliquer) ;&lt;/li&gt;
&lt;li&gt;Étaler le binder au fer (~120 °C) pour améliorer sa prise. Nettoyer
rapidement la rainure avant que le fart ne refroidisse s’il y en a dedans ;&lt;/li&gt;
&lt;li&gt;Laisser refroidir quelques minutes et polir au liège ;&lt;/li&gt;
&lt;li&gt;Appliquer le fart ou klister de jour. Prendre garde a bien nettoyer la
rainure entre chaque nouvelle couche. Je mets toujours 5 couches, quelque
soit la longueur de la sortie. Mieux vaut faire beaucoup de fines couches
que quelques couches épaises.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;On peut éventuellement se passer de remettre du fart de base si neige fraiche
et pour une courte sortie.&lt;/p&gt;
&lt;h2 id=&quot;divers-trucs&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#divers-trucs&quot; aria-label=&quot;Anchor link for: divers-trucs&quot;&gt;Divers trucs&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Attention, la neige artificielle est plus proche des micro-cristaux de glace
que des vrais flocons, donc très abrasive. Du fart (un peu plus chaud que la
normale) marche bien (pas besoin de klister), mais prévoir un bon fart de base,
voir une couche intermédiaire de klister entre le binder et le fart de jour si
longue sortie.&lt;/p&gt;
&lt;p&gt;Si besoin de réajuster le fartage durant la sortie, quelques trucs pour
faciliter la réapplication de fart et éviter de faire des gros motons :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sécher le mieux possible la zone de retenue ;&lt;/li&gt;
&lt;li&gt;Si il fait grand soleil, exposer la base du ski fasse au soleil et attendre
un peu pour la réchauffer. Sinon la réchauffer en faisant quelques passages
énergique de liège ;&lt;/li&gt;
&lt;li&gt;Réappliquer le fart. Si il est trop chaud pour être crayonné, le presser
légèrement sur la semelle et faire un petit twist du poignet.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Pour les conditions printanières :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cas de neige mouillée et chaude : klister seul ;&lt;/li&gt;
&lt;li&gt;cas de neige glacée et froide : ajouter une couche ou 2 de fart (typiquement bleu ou bleu spécial) par dessus, le klister a tendance à geler sinon.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La cire pour ski est tout aussi efficace sur le plancher, si vous préparez vos
skis à l’intérieur, mettre une bâche sous le banc de fartage pour récupérer
la poussière de cire, au risque de transformer votre plancher en patinoire !&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Yoghourt maison</title>
        <published>2019-04-12T00:00:00+00:00</published>
        <updated>2019-04-12T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/yoghourt-maison/"/>
        <id>https://univers-libre.net/posts/yoghourt-maison/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/yoghourt-maison/">&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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).&lt;/p&gt;
&lt;p&gt;Les avantages que je vois à faire son propre yaourt :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;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)&lt;/li&gt;
&lt;li&gt;plus économique (1 L de lait est généralement moins cher que 1 L de yoghourt)&lt;/li&gt;
&lt;li&gt;le plaisir de faire son propre yoghourt&lt;/li&gt;
&lt;li&gt;permet de conserver du lait plus longtemps si votre bouteille est due pour bientôt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La marche à suivre est assez simple, en fait il n’y a quasiment rien à faire. Je peux résumer ça à :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vider une bouteille de lait dans une casserole et le faire bouillir&lt;/li&gt;
&lt;li&gt;le laisser tiédir et mélanger avec le fond de votre yoghourt précédent&lt;/li&gt;
&lt;li&gt;transvaser dans des pots et les conserver au chaud le plus longtemps possible, puis mettre au frigo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mais ça mérite quand même quelques explications de plus :&lt;/p&gt;
&lt;p&gt;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…&lt;/p&gt;
&lt;p&gt;Ensuite il faut du lait (entier tant qu’à faire, mais allégé marche aussi).&lt;/p&gt;
&lt;p&gt;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).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/yoghourt-maison/DSC09172.JPG&quot;&gt;&lt;img src=&quot;/posts/yoghourt-maison/DSC09172.JPG&quot; alt=&quot;Stérilisation du lait&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;À 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).&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/yoghourt-maison/DSC09173.JPG&quot;&gt;&lt;img src=&quot;/posts/yoghourt-maison/DSC09173.JPG&quot; alt=&quot;Yoghourt prêt à fermenter dans un bas de laine&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;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).&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/yoghourt-maison/DSC09256.JPG&quot;&gt;&lt;img src=&quot;/posts/yoghourt-maison/DSC09256.JPG&quot; alt=&quot;Yoghourt maison&quot; /&gt;&lt;/a&gt;
Miam !&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Automatically generate a diagram of your infrastructure from Ansible inventory</title>
        <published>2019-04-05T00:00:00+00:00</published>
        <updated>2019-04-05T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/ansible-infrastructure-diagram/"/>
        <id>https://univers-libre.net/posts/ansible-infrastructure-diagram/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/ansible-infrastructure-diagram/">&lt;p&gt;Another post about Ansible. This time I will talk about generating a
representation of your infrastructure, for documentation purpose, using your
Ansible inventory and gathered facts.&lt;/p&gt;
&lt;p&gt;I had to update the infrastructure diagram of the Services FACiLes project, it
was deprecated and, inevitably, will still be in a few months because we keep
adding new containers and services. That’s a common issue in tech documentation.&lt;/p&gt;
&lt;p&gt;Moreover, manually editing a graph isn’t a thing I usually like to do,
especially when elements, relations and additional text can more easily be declared
in a text file using a definition language. I found for instance &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://github.com/otahi/network_drawer&quot;&gt;this
tool&lt;/a&gt; (not tested) which allows you to
describe what you want to graph using a YAML file and then use graphviz to draw
the resulting diagram. But, wait, I already have this kind of structured data,
it’s in my Ansible inventory file.&lt;/p&gt;
&lt;p&gt;I then thought about writing an equivalent tool to draw a diagram representing
Ansible hosts and groups declared in the inventory and their facts and
variables. Of course, someone else already had this idea, and this is called
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://github.com/willthames/ansible-inventory-grapher&quot;&gt;ansible-inventory-grapher&lt;/a&gt;.
This python tool produces graphviz code that you can directly pipe to graphviz
to generate a png or svg file.&lt;/p&gt;
&lt;p&gt;As an example, here is how the graph of our infrastructure looks like:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/ansible-infrastructure-diagram/ansible-inventory-graph.png&quot;&gt;&lt;img src=&quot;/posts/ansible-infrastructure-diagram/ansible-inventory-graph.png&quot; alt=&quot;infrastructure graph generated from Ansible inventory&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ansible-inventory-grapher doesn’t show value of variables but you can use [this
fork]((https://github.com/eking-go/ansible-inventory-grapher/tree/variables_with_value)
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://github.com/willthames/ansible-inventory-grapher/pull/39&quot;&gt;merge request
pending&lt;/a&gt;) to
have them on your graph.
You should also enable fact caching in your &lt;code&gt;ansible.cfg&lt;/code&gt; and gather your server’s facts before running ansible-inventory-grapher. Else you will only have variables declared in &lt;em&gt;host_vars/&lt;/em&gt; and &lt;em&gt;group_vars/&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The default jinja2 template used to generate the code suitable for graphviz prints all variables and facts, but I was only interested by some of them (those passed to the &lt;code&gt;--visible-vars&lt;/code&gt; actually) so I slighty modified the template as follow:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--- doc/ansible-inventory-graph.default.j2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+++ doc/ansible-inventory-graph.j2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@@ -8,7 +8,7 @@&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;lt;font face=&amp;quot;Times New Roman, Bold&amp;quot; point-size=&amp;quot;16&amp;quot;&amp;gt;{{ node.name}}&amp;lt;/font&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-{% if node.vars and showvars %}&amp;lt;hr/&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;font face=&amp;quot;Times New Roman, Bold&amp;quot; point-size=&amp;quot;14&amp;quot;&amp;gt;{% for var in node.vars|sort %}{{var}}{% if var in visible_vars %} = {{node.vars[var]}}{% endif %}&amp;lt;br/&amp;gt;{%endfor %}&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;{% endif %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+{% if node.vars and showvars %}&amp;lt;hr/&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;font face=&amp;quot;Times New Roman, Bold&amp;quot; point-size=&amp;quot;14&amp;quot;&amp;gt;{% for var in node.vars|sort %}{% if var in visible_vars %}{{var}} = {% if node.vars[var] is iterable and node.vars[var] is not string %}{{ node.vars[var]|map(attribute=&amp;#39;name&amp;#39;)|join(&amp;#39;, &amp;#39;) }}{% else %}{{node.vars[var]}}{% endif %}&amp;lt;br/&amp;gt;{% endif %}{% else %}&amp;lt;br /&amp;gt;{%endfor %}&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;{% endif %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;/table&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; {% else %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@@ -17,7 +17,7 @@&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;b&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;lt;font face=&amp;quot;Times New Roman, Bold&amp;quot; point-size=&amp;quot;16&amp;quot;&amp;gt;{{ node.name}}&amp;lt;/font&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   &amp;lt;/b&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-{% if node.vars and showvars %}&amp;lt;hr/&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;font face=&amp;quot;Times New Roman, Bold&amp;quot; point-size=&amp;quot;14&amp;quot;&amp;gt;{% for var in node.vars|sort %}{{var}}{% if var in visible_vars %} = {{node.vars[var]}}{% endif %}&amp;lt;br/&amp;gt;{%endfor %}&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;{% endif %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;+{% if node.vars and showvars %}&amp;lt;hr/&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;font face=&amp;quot;Times New Roman, Bold&amp;quot; point-size=&amp;quot;14&amp;quot;&amp;gt;{% for var in node.vars|sort %}{% if var in visible_vars %}{{var}} = {% if node.vars[var] is iterable %}{{ node.vars[var]|map(attribute=&amp;#39;name&amp;#39;)|join(&amp;#39;, &amp;#39;) }}{% else %}{{node.vars[var]}}{% endif %}&amp;lt;br/&amp;gt;{% endif %}{% else %}&amp;lt;br /&amp;gt;{% endfor %}&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;{% endif %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;/table&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; {% endif %}{% endfor %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;@@ -26,3 +26,5 @@&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   {{ edge.source|labelescape }} -&amp;gt; {{ edge.target|labelescape }};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; {% endfor %}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, I wrote a simple Makefile to easily update the graph when inventory is
updated:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Clear out default implicit rules and variables.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MAKEFLAGS += --no-builtin-rules --no-builtin-variables&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.PHONY: inventory-graph&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;inventory-graph: doc/ansible-inventory-graph.png&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;doc/ansible-inventory-graph.png: inventory/hosts $(wildcard inventory/group_vars/*.yml) $(wildcard inventory/host_vars/*.yml)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	ansible -i inventory/ -m setup all &amp;gt;/dev/null&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	~/src/ansible-inventory-grapher/bin/ansible-inventory-grapher -i inventory/ -t doc/ansible-inventory-graph.j2 -a &amp;quot;rankdir=LR;&amp;quot; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars knot_zones \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars backup_server \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars munin_master \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars icinga2_master \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars icinga2_parent \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars backup_hosts \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars icinga2_monitored_sites \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars db_type \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars hosted_by \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars libvirt_domains \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars lxc_containers \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars ansible_architecture \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars ansible_default_ipv4.address \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars ansible_default_ipv6.address \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars ansible_distribution \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars ansible_distribution_version \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars ansible_memtotal_mb \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars ansible_processor_vcpus \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars ansible_virtualization_role \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	--visible-vars ansible_virtualization_type \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	all | dot -T png &amp;gt;$@&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That way, when we add a new machine or make any change in our infra, all we
need to do is &lt;code&gt;make inventory-graph&lt;/code&gt; and commit the resulting graph. The image
file is linked in our documentation in our private wiki, thus we are ensured
that it is always up to date!&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Ansible QA and testing with molecule</title>
        <published>2019-03-31T00:00:00+00:00</published>
        <updated>2019-03-31T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/ansible-molecule/"/>
        <id>https://univers-libre.net/posts/ansible-molecule/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/ansible-molecule/">&lt;p&gt;Winter is already over in the Laurentians, and for a few weeks now ski
conditions are so horribles that it’s not fun anymore and I’m sick of applying
and cleaning klister on my skis. We will soon have rain and mud and flooding
everywhere. April is definitely the worst month in Quebec despite sunny and
longer days. But the good thing is that I suddenly have a huge amount of time
left for other things. Like system administration and coding.&lt;/p&gt;
&lt;p&gt;Thus I picked up a task from my todo list that I always wanted to do: trying
molecule over our Ansible roles and playbook at FACiL. The infrastructure
running behind the &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://facil.services/&quot;&gt;Services FACiLes&lt;/a&gt; project is setup
and maintained 100% with Ansible. All our roles and playbooks are &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://gitlab.com/facil/ansible/&quot;&gt;public and
hosted on Gitlab&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://github.com/ansible/molecule&quot;&gt;molecule&lt;/a&gt; is a Python tool
developed by the same team as Ansible and aims running different kind of tests
over your ansible roles: linting, role execution on multiple targets and
scenarios, ensure idempotence over multiple executions and running unit
tests on the target.&lt;/p&gt;
&lt;p&gt;I am not going to write a full tutorial on molecule, a lot of them already
exist on Internet, though not always up to date since molecule is still a
young project and in heavy development. The &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://molecule.readthedocs.io/en/latest/&quot;&gt;official
documentation&lt;/a&gt; is a bit rough to
get started and to understand the scope of molecule. A &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.jeffgeerling.com/blog/2018/testing-your-ansible-roles-molecule&quot;&gt;good
tutorial&lt;/a&gt;
I found for being the most up to date and accurate.&lt;/p&gt;
&lt;p&gt;Instead, in this post I’m going to explain how I use it to test our roles, with
some tips I didn’t find in the official documentation. I also played with
Gitlab CI so molecule tests are run on each git push, but it will be for
another post.&lt;/p&gt;
&lt;h2 id=&quot;molecule-s-files&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#molecule-s-files&quot; aria-label=&quot;Anchor link for: molecule-s-files&quot;&gt;molecule’s files&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We start by creating a molecule directory in our role:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ molecule init scenario --verifier-name goss --driver-name docker --role-name &amp;lt;role&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will create a directory named &lt;em&gt;molecule/&lt;/em&gt; in your role’s directory. You can
have multiple scenarios for your role, stored under &lt;em&gt;molecule/&lt;/em&gt; directory. By
default, &lt;code&gt;molecule init&lt;/code&gt; will create the scenario &lt;em&gt;default&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ tree molecule/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;molecule/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── default&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ├── Dockerfile.j2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ├── INSTALL.rst&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ├── molecule.yml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ├── playbook.yml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ├── tests&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    │   └── test_default.yml&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    └── verify.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each file above are just here to help you to get started and can be edited as you
want. Options we passed to the &lt;code&gt;molecule init&lt;/code&gt; command are just here to alter
these files. I usually prefer copying the &lt;em&gt;molecule/&lt;/em&gt; directory from an
existing role (which is totally acceptable) since I have done some extra
customization on it.&lt;/p&gt;
&lt;h3 id=&quot;molecule-yml&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#molecule-yml&quot; aria-label=&quot;Anchor link for: molecule-yml&quot;&gt;&lt;em&gt;molecule.yml&lt;/em&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;molecule.yml&lt;/em&gt; is the only molecule configuration file. Here is the
&lt;em&gt;molecule.yml&lt;/em&gt; we use in our roles :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dependency:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  name: galaxy&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;driver:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  name: docker&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lint:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  name: yamllint&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;platforms:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  - name: molecule-monitoring-tools&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    image: geerlingguy/docker-debian9-ansible:latest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    command: ${MOLECULE_DOCKER_COMMAND:-&amp;quot;&amp;quot;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    volumes:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      - /sys/fs/cgroup:/sys/fs/cgroup:ro&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    privileged: true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    pre_build_image: true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;provisioner:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  name: ansible&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  lint:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name: ansible-lint&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  options:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    skip-tags: molecule-converge-notest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  log: true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;scenario:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  name: default&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;molecule is designed to be very extensible. For instance, it uses the
galaxy dependency resolver (dependencies are defined in the &lt;em&gt;meta/main.yml&lt;/em&gt;
file of your role) and ansible as a provisioner (this is the only one
supported for now but we can imagine molecule will be able to use other
configuration management tools).&lt;/p&gt;
&lt;p&gt;We use &lt;code&gt;yamllint&lt;/code&gt; as the linter for all YAML file of the role (including
molecule’s own files!) and &lt;code&gt;ansible-lint&lt;/code&gt; for ansible files.&lt;/p&gt;
&lt;p&gt;For some reasons, we don’t want to run some Ansible tasks when testing the
role. molecule let us pass any &lt;code&gt;ansible-playbook&lt;/code&gt; option with the dict
&lt;code&gt;provisioner:options&lt;/code&gt;. Here we excluded tasks which have the
&lt;em&gt;molecule-converge-notest&lt;/em&gt; tag on them.&lt;/p&gt;
&lt;p&gt;And finally we tell molecule to run the role in a Docker container. molecule
supports a large range of drivers, including LXC containers, Vagrant VMs and
common public cloud providers. Even if we use LXC containers on production, I
choose to use the Docker driver with molecule because, first it’s more easy to
setup on a personal machine, and second because this is the only supported
option if we want to run molecule tests on Gitlab’s shared runners (using
Docker in Docker), I will talk about it later in a second post.&lt;/p&gt;
&lt;p&gt;Most of our roles don’t work inside a minimal Docker container, so we use
geerlingguy/docker-debian9-ansible Docker image. The image provides a more
complete Debian system (with systemd and common tools). It is maintained by
Jeff Geerling, who wrote a lot of Ansible roles and uses it to test his own roles.&lt;/p&gt;
&lt;p&gt;By default, molecule spawns a container named &lt;em&gt;instance&lt;/em&gt;. It’s a bad idea since
I ended up with conflicts when I tried to launch tests on multiple roles at the
same time, each of them was executed in the same container. Thus I edited
&lt;em&gt;platforms:name&lt;/em&gt; key so that it bears the role’s name.&lt;/p&gt;
&lt;h3 id=&quot;dockerfile-j2&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#dockerfile-j2&quot; aria-label=&quot;Anchor link for: dockerfile-j2&quot;&gt;&lt;em&gt;Dockerfile.j2&lt;/em&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This file is only here if you want to build your Docker container on each test.
You can use any Docker image (defined in &lt;em&gt;platforms:image&lt;/em&gt;) and this Dockerfile
will install requirements such as python, sudo, bash and ca-certificates
package to run Ansible.&lt;/p&gt;
&lt;p&gt;Since the image we use already contains those dependencies, we instruct
molecule not to build another Docker image (&lt;em&gt;platforms:pre_build_image&lt;/em&gt;).
this way, we also speed up tests.&lt;/p&gt;
&lt;h3 id=&quot;install-rst&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#install-rst&quot; aria-label=&quot;Anchor link for: install-rst&quot;&gt;&lt;em&gt;INSTALL.rst&lt;/em&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;INSTALL.rst&lt;/em&gt; is an informal file containing instructions to others
contributors and requirements to run molecule tests. For instance, we need to
have the Docker engine and docker-py installed on our machine.&lt;/p&gt;
&lt;h3 id=&quot;playbook-yml&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#playbook-yml&quot; aria-label=&quot;Anchor link for: playbook-yml&quot;&gt;&lt;em&gt;playbook.yml&lt;/em&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;After &lt;em&gt;molecule.yml&lt;/em&gt;, this is the second most important file. Once molecule has spawned the container, it will run this playbook.&lt;/p&gt;
&lt;p&gt;Here is its content:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- name: Converge&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  hosts: all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  roles:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - role: &amp;lt;role&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pretty simple, it applies &lt;code&gt;&amp;lt;role&amp;gt;&lt;/code&gt; onto the spun up container. But if your role requires some variables to be set, or dependencies that aren’t declared in your role’s &lt;em&gt;meta/main.yml&lt;/em&gt; file, you can add them here. For instance:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;- name: Converge&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  hosts: all&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  roles:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - role: &amp;lt;other role&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    - role: &amp;lt;role&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  vars:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    foo: &amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;verify-yml-and-tests-test-default-yml&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#verify-yml-and-tests-test-default-yml&quot; aria-label=&quot;Anchor link for: verify-yml-and-tests-test-default-yml&quot;&gt;&lt;em&gt;verify.yml&lt;/em&gt; and &lt;em&gt;tests/test_default.yml&lt;/em&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finally, those two files are for unit tests. &lt;em&gt;verify.yml&lt;/em&gt; installs Goss (the verifier tool) in the container and run tests it finds in the &lt;em&gt;tests/&lt;/em&gt; directory. Although it’s a very interesting subject, I didn’t dig too much into unit tests for now.&lt;/p&gt;
&lt;h2 id=&quot;running-molecule&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#running-molecule&quot; aria-label=&quot;Anchor link for: running-molecule&quot;&gt;Running molecule&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First, to enable bash completion:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ eval &amp;quot;$(_MOLECULE_COMPLETE=source molecule)&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Running &lt;code&gt;molecule&lt;/code&gt; without argument will show you the list of available sub-commands. I’m not going to explain all of them, and I don’t even sure what all these sub-commands do, I still learning about molecule.&lt;/p&gt;
&lt;p&gt;Run linting tools on your role:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ molecule lint&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Test your role into a freshly created container (by executing &lt;em&gt;playbook.yml&lt;/em&gt; on it):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ molecule converge&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;molecule converge&lt;/code&gt; will automatically lint your code prior to run it.&lt;/p&gt;
&lt;p&gt;At this time you can either login to the container to manually check what has been done:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ molecule login&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or replay &lt;code&gt;molecule converge&lt;/code&gt; if you obtained errors and have fixed them in your role.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;molecule converge&lt;/code&gt; allows us to pass almost any &lt;code&gt;ansible-playbook&lt;/code&gt; option. For instance, you may want to debug tasks with a specific tag:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ molecule converge -- -vvv --tags &amp;lt;tag&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To destroy the running container so you can start with a new one:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ molecule destroy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you just want to start a container but don’t execute anything in it (for instance if you want to known the state of a file in a brand new install):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ molecule prepare&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To run idempotence check (molecule will simply run the &lt;em&gt;playbook.yml&lt;/em&gt; a second time and check that no tasks report a &lt;em&gt;changed&lt;/em&gt; state):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ molecule idempotence&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All these previous commands are useful while you are developing a role. Once you have done or did only minors edits (you are pretty confident that you didn’t break anything), it’s handy to run all the test suite at once:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ molecule test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will lint your code, start a new container, apply &lt;em&gt;playbook.yml&lt;/em&gt;, verify idempotence, run unit tests and finally destroy the container.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>[Ansible] sudo password from your password manager or agent</title>
        <published>2019-03-29T00:00:00+00:00</published>
        <updated>2019-03-29T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/ansible-sudo-password-agent/"/>
        <id>https://univers-libre.net/posts/ansible-sudo-password-agent/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/ansible-sudo-password-agent/">&lt;p&gt;Make Ansible retrieve the sudo password from my password manager. For a long
time, I was wondering how to solve this issue. Ansible is my main tool to
manage my own servers. All the infrastructure of the &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://facil.services/&quot;&gt;Services
FACiLes&lt;/a&gt; project I contribute to (a future
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://chatons.org/&quot;&gt;CHATONS&lt;/a&gt; is built with Ansible automation in mind,
and even at my previous work, Ansible is used on a daily basis.&lt;/p&gt;
&lt;p&gt;A thing that really annoyed me was that each time I run a playbook, I have to
give Ansible my sudo password. Besides that, Ansible prompts for the password at an early
stage of execution, even before trying to include all files or running a syntax
check on them. Thus it isn’t uncommon that Ansible fails immediately after
because of a mistake I made in a playbook, and I have fix it, rerun the
command, reenter my password… and so on. Which is very frustrated.&lt;/p&gt;
&lt;p&gt;I know some workarounds exist to avoid dealing with the interactive sudo
password prompt: allowing Ansible to be executed without password on the servers (almost
equivalent to allowing any command to be executed without password…, which is
not an acceptable answer), storing your password into &lt;code&gt;ansible_sudo_pass&lt;/code&gt;
variable in a cleartext file somewhere (yes you can encrypt it with
&lt;code&gt;ansible-vault&lt;/code&gt; but then you have to give the vault password each time you run
your playbook), trying to mess with &lt;code&gt;except&lt;/code&gt;…&lt;/p&gt;
&lt;p&gt;The simple and elegant way of doing it for me would be that Ansible gets the password from an agent,
like &lt;code&gt;gpg-agent&lt;/code&gt;, or execute an arbitrary command to get it.
After a lot of research and experimentation, I found a pretty nice and clever
solution on &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://stackoverflow.com/a/53889884&quot;&gt;Stackoverflow&lt;/a&gt; (far at the
bottom, it should be upvoted more than that IMHO). The idea is to combine &lt;code&gt;--extra-var&lt;/code&gt;
ansible option (to which a file descriptor can be passed, while prefixing it with
&lt;code&gt;@&lt;/code&gt;) and &lt;code&gt;&amp;lt;()&lt;/code&gt; bash operator to convert a command’s stdout to a file virtual
file descriptor. We end up with the following command:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ansible-playbook -e@&amp;lt;(echo &amp;quot;ansible_sudo_pass: $(pass Sysadmin/xxxx)&amp;quot;) playbook.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This way my sudo password is retrieved from my &lt;code&gt;pass&lt;/code&gt;’s password manager (which uses
gpg-agent) and I’m not bothered anymore with Ansible’s interactive prompt \o/.&lt;/p&gt;
&lt;p&gt;The only drawback is that I didn’t find a way to set this into the
&lt;em&gt;ansible.cfg&lt;/em&gt; or somewhere else, except writing a bash alias or a small
wrapper.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Les pistes de Saint-Hippolyte</title>
        <published>2019-03-14T00:00:00+00:00</published>
        <updated>2019-03-14T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/saint-hippolyte/"/>
        <id>https://univers-libre.net/posts/saint-hippolyte/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/saint-hippolyte/">&lt;p&gt;Qui aurait penser qu’il y avait des anciennes pistes de ski nordique vers
Saint-Hippolyte ? C’est un coin semble-t-il assez peu connu à part par les
locaux qui fréquentent ces pistes là. En effet aucune ressource sur Internet
n’en parle et aucune carte de ce secteur qu’on peut se procurer (à ma connaissance). Mais il
y avait bel et bien un dense réseau tout autour de Prévost (Shawbridge),
puisque c’est là où habitait Herman S. Johannsen. Le secteur de Prévost,
Piedmont et Saint-Hippolyte est protégé par la &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.parcdesfalaises.ca/&quot;&gt;Réserve Naturelle du Parc des
Falaises&lt;/a&gt; contre (notamment) le développement
immobilier, ce qui est une très bonne chose. Mais c’est aussi un secteur
littéralement envahi par les raquetteurs, ce qui ne donne jamais trop envie
d’aller l’explorer à ski. Pourtant au delà d’une certaine distance des points d’accès, les sentiers deviennent moins tapés par les raquettes et on peut retrouver de la belle neige.&lt;/p&gt;
&lt;p&gt;Je m’y suis rendu pour la première fois avec des membres du
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://clubmontagnecanadien.qc.ca/&quot;&gt;CMC&lt;/a&gt; qui connaissaient un peu le coin,
puis à quelques jours près, Barclay s’y était aussi
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://skiglisse.blogspot.com/2019/01/jouer-les-indiana-jones-la-reserve.html&quot;&gt;aventuré&lt;/a&gt;
(&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://skiglisse.blogspot.com/2019/01/la-whizzard-du-sud.html&quot;&gt;en deux
fois&lt;/a&gt;).  J’y
suis donc retourné seul avec pour mission de cartographier le plus de pistes
possible.&lt;/p&gt;
&lt;p&gt;J’ai ainsi pu ajouter un bon bout de la &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/relation/9360332&quot;&gt;Fd (Flight Delight)&lt;/a&gt;, la plupart de la &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/relation/9360332&quot;&gt;6X&lt;/a&gt;, qui continuait même plus au nord en contournant le lac Desjardins, la partie centrale de la &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/relation/8018699&quot;&gt;Johannsen&lt;/a&gt; (que j’aimerai vraiment pouvoir relier au complet, j’ai en tête de partir de Mont-Rolland et d’aller jusqu’à Prévost en la suivant), et enrichie un peu la &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/relation/9360335&quot;&gt;WN&lt;/a&gt;, &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/relation/9360334&quot;&gt;Wizzard&lt;/a&gt;, la &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/relation/9360333&quot;&gt;8&lt;/a&gt; et quelques autres.&lt;/p&gt;
&lt;p&gt;Cela n’a pas été une tâche facile, surtout dans le secteur de Prévost, non pas
que les pistes ne sont plus visibles, mais au contraire, certaines pistes ont
été reroutées, donc on peut tomber sur les anciens tracés avec quelques vieilles
balises rouillées qui ont bravées l’épreuve du temps, les nouveaux sentiers qui
reprennent les mêmes noms mais qui ne correspondent plus du tout au tracé
original et les sentiers informels créés par les randonneurs eux-mêmes, sans
compter que plusieurs pistes fusionnent ensemble sur une certaine distance
avant de se reséparer. Bref, quoi cartographier dans OpenStreetMap n’a pas été
chose facile et je ne suis pas certain que chaque sentier y est correctement
nommé, mais c’est déjà beaucoup mieux qu’avant.&lt;/p&gt;
&lt;p&gt;J’ai aussi suivi la &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/relation/9360333&quot;&gt;MOC (McGill Outing
Club)&lt;/a&gt; aussi loin que possible
avant d’arriver dans un terrain privé. Elle n’a pas beaucoup d’intérêt (peu de
défis et pas très jolie, elle à l’air d’un vieux chemin de coupe) et est pas mal
envahie aussi, mais elle sert d’artère centrale aux autres pistes du secteur. Et
j’ai trouvé une piste mystère (elle aussi pas mal envahie) qui remonte de la
MOC vers le Mont Olympia, juste balisée avec des disques de plastiques jaune.&lt;/p&gt;
&lt;p&gt;C’est dans le secteur de Saint-Hippolyte que j’ai trouvé une précieuse aide dans ma tâche : 2 cartes différentes, présentes à 2 intersections :&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/saint-hippolyte/DSC09051_big.jpg&quot;&gt;&lt;img src=&quot;/posts/saint-hippolyte/DSC09051_thumb.jpg&quot; alt=&quot;Carte du Parc des Falaises, secteur Saint-Hippolyte&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/posts/saint-hippolyte/DSC09053_big.jpg&quot;&gt;&lt;img src=&quot;/posts/saint-hippolyte/DSC09053_thumb.jpg&quot; alt=&quot;Carte de la Réserve Ogilvy, Saint-Hippolyte&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La première n’est pas très intéressante car elle ne montre que quelques sentiers, l’autre est déjà plus complète et m’a bien servie pour m’aider à y voir plus clair dans ce réseau, même si elle n’est pas tout à fait complète non plus.
Ces 2 cartes ne semblent pas être trouvable sur Internet, donc à conserver précieusement !&lt;/p&gt;
&lt;p&gt;J’en profite aussi pour laisser un lien vers une &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://web.archive.org/web/20070328142543/http://www.hippopleinair.org:80/PDF/carte-sentiers_ski.pdf&quot;&gt;carte&lt;/a&gt; éditée par Plein-Air-Saint-Hippolyte, organisme qui ne semble plus exister depuis une dizaine d’année, qui montre encore d’autres sentiers de ski, cette fois au nord de Saint-Hippolyte (merci Archive.org !). Je ne suis pas du tout allé explorer ce coin là par contre.&lt;/p&gt;
&lt;p&gt;Un &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://skiglisse.blogspot.com/2019/03/objectif-6x.html&quot;&gt;autre article de
Barclay&lt;/a&gt; tout récent à
propos de ce secteur, après qu’il a vu les nouveaux sentiers cartographiés dans
OpenStreetMap (j’ai l’impression qu’on joue au chat et à la souris à chaque
fois !).&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Le nord de la Western</title>
        <published>2019-03-13T00:00:00+00:00</published>
        <updated>2019-03-13T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/western/"/>
        <id>https://univers-libre.net/posts/western/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/western/">&lt;p&gt;La Western est une autre ancienne piste de ski dans les Laurentides qui, comme son nom de laisse penser, se trouve dans la partie ouest de la région, à l’ouest de la vallée de la rivière du Nord et l’ancienne voie du CP Railway. La partie probablement la plus connue se trouve dans le réseau de Morin-Heights et apparait sur la &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://web.archive.org/web/20190325221538/http://morinheights.com/IMG/jpg/map_pistes_de_ski_2018_verso_final.jpg&quot;&gt;carte de leur réseau&lt;/a&gt; pour une dizaine de kilomètres, partant des pistes de fond tracées jusqu’au lac Théodore au Nord. C’est la seule partie présente sur une carte. Mais la Western va en fait bien au delà !&lt;/p&gt;
&lt;p&gt;Au sud, je l’ai trouvée aussi bas qu’à Sainte-Anne-des-Lacs, au niveau de la Loken, où j’ai été surpris d’y trouver une vieille balise de la Western. Je suppose qu’elle monte plein nord vers Morin-Heights, mais au vu du développement résidentiel de Saint-Sauveur qui se trouve entre les 2, je doute malheureusement qu’il en reste grand chose et, si c’est encore possible de passer, ça risque d’être beaucoup sur la route. Je ne suis pas allé explorer ce secteur.&lt;/p&gt;
&lt;h2 id=&quot;section-du-lac-theodore-a-la-fleur-de-lys&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#section-du-lac-theodore-a-la-fleur-de-lys&quot; aria-label=&quot;Anchor link for: section-du-lac-theodore-a-la-fleur-de-lys&quot;&gt;Section du lac Théodore à la Fleur-de-Lys&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Par contre beaucoup plus au nord, je l’avais encore croisée l’année passée en remontant la Fleur-de-Lys de Sainte-Adèle à Sainte-Agathe-des-Monts, peu avant que la Fleur-de-Lys connecte la Canadienne. Dernièrement je suis donc retourné à cette intersection pour suivre la Western le plus loin possible. D’abord vers le sud, jusqu’au lac Théodore. À l’endroit de l’intersection avec la Fleur-de-Lys, la Western qui part vers le sud n’est pas forcement évidente à retrouver, il faut en fait suivre un chemin privé vers le sud sur une cinquantaine de mètres. Ensuite de ça le tracé est très bien visible et balisé jusqu’au Lac Théodore, aucune difficulté particulière à le suivre. Il y a peu de dénivelé mais j’ai trouvé le sentier très joli, notamment le long du lac Normand, à travers une belle forêt de cèdre.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/western/DSC09048_big.jpg&quot;&gt;&lt;img src=&quot;/posts/western/DSC09048_thumb.jpg&quot; alt=&quot;Balises de la Western&quot; /&gt;&lt;/a&gt;
Balises de la Western&lt;/p&gt;
&lt;p&gt;On arrive au Lac Théodore en marchant/skiant un bout sur l’avenue des Pivouanes, qui débouche sur une mini-baie privée sur le lac. Pour rejoindre la Western du réseau de Morin-Heights, il suffit de mettre cap plein sud sur lac pour retomber dessus sur l’autre rive.&lt;/p&gt;
&lt;p&gt;Après avoir reviré de bord une fois rendu au lac Théodore, j’ai tenté d’explorer la section au nord de l’intersection à la Fleur-de-Lys. La piste était un peu plus envahie par les branches et moins évidente à suivre. J’ai pu la skier jusqu’à un lac sans nom au nord de la Colline Beauvais. Mais j’ai perdu son tracé après. J’ai appris par contre jusqu’où elle va : elle doit traverser le lac Paquin, traverser le chemin du 7ème Rang et arriver tout au bout du Chemin des Pins à Sainte-Agathe.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/western/DSC09047_big.jpg&quot;&gt;&lt;img src=&quot;/posts/western/DSC09047_thumb.jpg&quot; alt=&quot;Direction Sainte-Agathe&quot; /&gt;&lt;/a&gt;
On peut deviner un « Direction Sainte-Agathe »&lt;/p&gt;
&lt;h2 id=&quot;section-de-la-fleur-de-lys-a-sainte-agathe&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#section-de-la-fleur-de-lys-a-sainte-agathe&quot; aria-label=&quot;Anchor link for: section-de-la-fleur-de-lys-a-sainte-agathe&quot;&gt;Section de la Fleur-de-Lys à Sainte-Agathe&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bon, je n’ai pas eu le temps de publier cet article que je suis déjà retourné sur les traces de la Western ! Je rajoute ici ce qui devait être un second article.&lt;/p&gt;
&lt;p&gt;Comme j’ai su que la Western pouvait se prendre tout au bout du Chemin des Pins à Sainte-Agathe, je me suis rendu là lundi dernier. Le Chemin des Pins se termine dans un camp de vacances, complètement abandonné pour la saison hivernale. Après avoir tourné un peu rond dans le camp, j’ai fini par trouver la piste ; elle file assez proche de la route avant de partir plein est. Son extrémité nord se trouve en fait 500 m plus loin puisqu’elle joint directement la Fournelle, piste tracée du centre de ski de fond du Camping Sainte-Agathe.&lt;/p&gt;
&lt;p&gt;Après ça, la piste contourne la Colline aux Framboises par le sud puis file vers le sud-est en coupant les 8ème et 7ème rangs, jusqu’à arriver au lac Paquin. Un peu avant de croiser le 8ème rang, on se retrouve face à une descente toute droite assez impressionnante, digne d’une pente de ski alpin (je n’en ai jamais vu des aussi raides et longues ailleurs) ! Heureusement elle n’est pas trop étroite et comme j’ouvrais dans 40 cm de neige lourde, j’ai pu faire quelques beaux virages de telemark assez facilement (en fait un des rares moments durant cette journée où j’ai pu profiter de la glisse). Avec des conditions de neiges plus difficile par contre, je ne pense pas être capable de la descendre…&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/western/DSC09139_big.jpg&quot;&gt;&lt;img src=&quot;/posts/western/DSC09139_thumb.jpg&quot; alt=&quot;Pente de la Western&quot; /&gt;&lt;/a&gt;
La photo ne rend pas du tout de la pente.&lt;/p&gt;
&lt;p&gt;On arrive au chemin du 7ème rang par la Rue du Continental, puis il faut marcher 50 m sur le rang vers l’est avant de pouvoir embarquer sur le lac (avant de traverser la décharge du lac). Sur le lac, je n’avais pas la moindre idée d’où aller, donc j’ai longé la rive est qui offre de belle falaises et cascades de glace. Mais il faut en réalité mettre le cap plutôt vers le sud-sud-ouest pour retomber sur le chemin Gascon Est. En réalité on peut tout aussi bien marcher/skier sur le chemin du 7ème rang pour arriver sur le chemin Gascon Est, ce sera certainement plus rapide si il n’y a aucune trace sur le lac et que les chemins ne sont pas totalement déneigés pour permettre de ski dessus.&lt;/p&gt;
&lt;p&gt;La piste reprend depuis le chemin (facile à trouver, il y a une balise) et continu plein sud en passant à l’ouest d’une petite colline, jusqu’aux lignes électrique qu’il faut traverser. La piste traverse de bout-en-bout un lac sans nom, celui-là où je m’étais rendu la fois précédente. Après ça, la Western continue sud-ouest jusqu’à la Fleur-de-Lys.&lt;/p&gt;
&lt;p&gt;Globalement, cette section de la Western reste assez bien balisée même si, sans connaitre son tracé approximatif, elle reste difficile à suivre à certains endroits où le balisage est un peu plus aléatoire (érablières clairsemées, traversées de lacs et intersections avec des chemins et rangs).&lt;/p&gt;
&lt;p&gt;J’ai continué jusqu’à Sainte-Adèle en suivant la Fleur-de-Lys jusqu’au bout, très belle piste que j’aime beaucoup aussi, mais celle là je l’avais déjà cartographiée l’année passée.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/western/DSC09140_big.jpg&quot;&gt;&lt;img src=&quot;/posts/western/DSC09140_thumb.jpg&quot; alt=&quot;Fleur-de-Lys&quot; /&gt;&lt;/a&gt;
Ancienne balise de la Fleur-de-Lys.&lt;/p&gt;
&lt;p&gt;La &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.openstreetmap.org/relation/3512095&quot;&gt;Western est maintenant complète&lt;/a&gt; pour sa portion au nord de Morin-Heights dans OpenStreetMap.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Automatically backup your Android phone with udev</title>
        <published>2019-03-01T00:00:00+00:00</published>
        <updated>2019-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/android-backup/"/>
        <id>https://univers-libre.net/posts/android-backup/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/android-backup/">&lt;p&gt;I wrote a simple script and udev rule a few years ago to automatically backup
my phone (running &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://replicant.us/&quot;&gt;Replicant OS&lt;/a&gt;, a free, FSF-approved
Android distribution) to my computer when I plug it to a USB port.
I just published those scripts after some clean-up on a &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://gitlab.com/billux/android-backup&quot;&gt;git repository&lt;/a&gt; and wrote instructions on how to set it up.&lt;/p&gt;
&lt;p&gt;I know there are plenty of Android applications to backup my data and upload
them somewhere via Internet. But my phone is rarely connected, the Wi-Fi is
usually turned off and I have no data plan. Instead I do plug my phone to my
computer on a regular basis to recharge it, so it seemed obvious to
automatically trigger a backup of my phone via USB.&lt;/p&gt;
&lt;p&gt;udev can be use to detect events, like plugging-in a device, and trigger
actions based on these events. In my case, the udev rule looks like this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ACTION==&amp;quot;add&amp;quot;, SUBSYSTEMS==&amp;quot;usb&amp;quot;, ENV{ID_SERIAL_SHORT}==&amp;quot;XXXXXXXXXXXXXXXX&amp;quot;, TAG+=&amp;quot;systemd&amp;quot;, ENV{SYSTEMD_USER_WANTS}+=&amp;quot;android-backup@$env{ID_SERIAL_SHORT}.service&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Where &lt;code&gt;ID_SERIAL_SHORT&lt;/code&gt; is used to uniquely identify my phone. The rule
triggers the android-backup@.service systemd unit (in user mode, no need to run
it as root).&lt;/p&gt;
&lt;p&gt;The systemd unit is very simple, there is no need to specify an &lt;code&gt;[Install]&lt;/code&gt;
section, targets or anything like that since it is triggered directly by udev:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Type=oneshot&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ExecStart=%h/.local/bin/android-backup.sh %I&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the unit simply calls the following shell script:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!/bin/sh&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;export DISPLAY=0:0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;BACKUP_DIR=~/replicant-backup/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;RSYNC_EXCLUDE=~/.config/android-backup.exclude&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;notify-send &amp;quot;Android Backup&amp;quot; &amp;quot;Starting Android backup&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;set -e&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir -p &amp;quot;$BACKUP_DIR&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb wait-for-device 2&amp;gt;&amp;amp;1 |(grep -Ev &amp;quot;^(\* daemon not running; starting now at|* daemon started successfully$)&amp;quot; || true)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb root&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb wait-for-device&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb shell rsync --daemon --no-detach --config=/system/etc/rsyncd.conf &amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb forward tcp:6010 tcp:873&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sleep 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;rsync -av --chmod u+rwX --delete --delete-excluded --exclude-from &amp;quot;$RSYNC_EXCLUDE&amp;quot; rsync://localhost:6010/root/ $BACKUP_DIR&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb forward --remove tcp:6010&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb shell pkill rsync&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if [ $? -ne 0 ]; then&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    notify-send &amp;quot;Android Backup&amp;quot; &amp;quot;Backup terminated with errors. See journalctl --user -eu android-backup for details&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;else&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    notify-send &amp;quot;Android Backup&amp;quot; &amp;quot;Backup terminated successfully&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this script, I first start adb (as root so it can have access to the whole
system) and start a rsync daemon on the OS running on the phone and forward its
TCP port through adb. I can then start a normal rsync from my computer to fetch
all the files and directories. The destination directory (on my computer) is
included in my daily backup, thus I automatically have incremental copies of my
phone’s data.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Marathon Canadien de Ski</title>
        <published>2019-02-12T00:00:00+00:00</published>
        <updated>2019-02-12T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/marathon-canadien-de-ski/"/>
        <id>https://univers-libre.net/posts/marathon-canadien-de-ski/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/marathon-canadien-de-ski/">&lt;p&gt;Le &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://skimarathon.ca/&quot;&gt;Marathon Canadien de Ski&lt;/a&gt; (MCS) est la plus longue
épreuve de ski de fond en Amérique du Nord, 160 km (163,7 km exactement), qui
se répartissent en 2 jours soit à peu près 80 km par jour. C’est aussi la plus
ancienne épreuve en Amérique, il a été tenu pour la première fois en 1967, lors
des 100 ans du Canada.
Il s’agit plus d’un évènement populaire que d’une compétition, les skieurs ne
sont pas chronométrés et sont là plus pour le plaisir de skier et le défi
personnel que la performance. L’évènement attire en moyenne 2000 personnes,
venant principalement du Québec, de l’Ontario et du nord-est des États-Unis.&lt;/p&gt;
&lt;p&gt;La piste reliait à l’origine les villes de Gatineau et La Chute en longeant plus ou moins la
rivière des Outaouais. Montebello était le point central et l’étape
intermédiaire. À cause de l’enneigement de plus en plus incertain ces dernières
années, il part maintenant d’un peu au sud de Saint-Jovitte (Mont-Tremblant)
pour se rendre à La Chute, en faisant un crochet par Montebello, qui reste
l’étape intermédiaire. La piste est tracée une seule fois par année pour
l’évènement et passe en majorité sur des terres privées.&lt;/p&gt;
&lt;p&gt;Pourquoi j’en parle ici ? Ça me titillait depuis que j’en ai entendu parlé en
arrivant au Québec, mais cette année je m’y suis inscrit et suis très fier
d’avoir skier l’intégralité des 160 km en 2 jours ! Je fais un petit retour sur
mon expérience.&lt;/p&gt;
&lt;p&gt;Il y plusieurs catégories lors de l’inscription, on peut soit faire le
demi-marathon, le marathon entier (Coureur des Bois) ou les sections que l’on
veux (Randonneur) (le parcours est divisés en 10 sections de 16 km chacune en
moyenne). Jusqu’au dernier moment avant mon inscription, j’ai beaucoup hésité
dans quelle catégorie m’inscrire. J’étais plus partant pour faire le marathon
entier au début, puis à un moment j’ai douté beaucoup, je n’arrivais pas à
m’entrainer autant que je voulais (on a eu un décembre sans neige) et j’ai fini
par m’inscrire dans la catégorie Randonneur. Comme ça je me suis dit que si je
ne skiais pas les 10 étapes, je ne perdais pas le défi. Le prix a joué aussi,
car les frais de participation sont assez cher : 300 $ pour les Coureurs des
Bois contre 200 $ pour les Randonneurs. Puisque les Randonneurs peuvent quand
même skier l’intégralité du marathon, les 100 $ ne se retrouvent que dans la
médaille à la fin, ça ne justifiait pas la différence pour moi.  Surtout qu’à
cela, il fallait ajouter les frais d’hébergement pour vendredi et samedi (150 $
pour dormir par terre dans les salles de classe de l’école de Papineauville et
manger à la cantine de l’école) + plus la navette depuis Montréal (100 $), plus
toutes les taxes… Bref ça faisait un sacré budget et faisait cher le kilomètre
skié. Mais je dois admettre que c’était toute une organisation sur place vu le
nombre de participant et c’était assez bien rodé.&lt;/p&gt;
&lt;p&gt;La veille du marathon, j’avais encore changé d’avis et je voulais à tout pris
skier les 80 km par jour. Sauf qu’une chose que j’ai appris au dernier moment
est que les Randonneurs qui veulent skier les 10 sections sont clairement
pénalisés par rapport aux Coureurs des Bois : les Coureurs des Bois partent à
5h, le départ des Randonneurs est à 7h30 et il y a un cutoff à 15h30 pour tout
le monde au départ de la dernière section de la journée. Ça laisse beaucoup moins de temps
aux Randonneurs ! Donc au final, je me retrouve avec un défi supplémentaire,
skier les 4 premières sections de chaque jour plus vite que les Coureurs des
Bois pour arriver avant le cutoff de 15h30.&lt;/p&gt;
&lt;p&gt;Dans ma tête, c’était donc un défi de 66 km à skier en 8h, pauses comprises,
puis les 15 km de la dernière section du jour que je pouvais skier à la vitesse
d’un piéton si je serai à bout, ça n’aura plus d’importance. J’ai calculé
précisément mes heures de passages aux différents checkpoints. Je devais skier
à une vitesse minimum de 9 km/h et pouvais m’arrêter maximum 15 minutes à
chaque checkpoint pour refaire le plein d’eau, manger et refarter mes skis si
besoin. La veille, j’ai appris par cœur mes heures de passage et j’ai mémorisé
le plus de détails possible des cartes des sections (traverses de routes, de
lacs, grandes côtes, passages dans les champs) de façon à me donner des points
de repères une fois sur la piste pour situer mon avancement ; 80 km c’est long
et il est facile de se « perdre » dans les chiffres et d’avoir l’impression de
ne pas avancer si dès le départ au matin l’objectif est le 80 ème kilomètre.
Voir que j’arrive effectivement à telle place alors que j’en suis qu’au 38 km
est très motivant et rassurant à la fois. Et je me prépare ensuite à atteindre
le prochain repère, peut-être juste 10 km plus loin. En fait, je me fous
complètement du tout dernier kilomètre.&lt;/p&gt;
&lt;p&gt;De manière générale, je suis (assez involontairement mais maintenant que j’en
ai conscience ça devient moins involontaire) pessimiste concernant mes
objectifs, ce qui fait que je les surpasse bien au delà et ça devient une
source de motivation plus grande. Dans ce cas si concrètement, mes heures de
passage étaient vraiment le minimum, le cas vraiment limite (je skie plus
vite que 9 km/h), donc à chaque fois j’arrivais toujours avec 5 ou 10 minutes
d’avance sur ce que j’avais en tête. Là encore, ça me rassurait et me motivait
pour la section suivante, où je me mettais au défi de maintenir mon avance ou
faire encore mieux.&lt;/p&gt;
&lt;p&gt;Le premier jour, je suis arrivé à 1h05 avant le cutoff, 1h05 d’avance sur ce
que j’avais prévu, et 40 minutes d’avance pour le deuxième jour.
J’ai fini la première journée à 16h30 et 16h37 le lendemain, en skiant à peu
près 8h à 10,5 km/h de moyenne plus 1h de pause au total. Je skie habituellement
entre 10 et 11 km/h et avant le marathon, je doutais être capable de maintenir
ma vitesse habituelle sur une aussi grande distance. Mais en faisant des stats
par section, je ne constate aucune baisse de vitesse en fin d’épreuve (sauf la
dernière section du premier jour où je me ralentissais volontairement pour ne pas me bruler
inutilement pour le lendemain). Même, je me sentais bizarrement encore plein
d’énergie, en tout cas d’un point de vue mental et cardiaque, mes muscles eux
commençaient à fatiguer sérieusement.&lt;/p&gt;
&lt;p&gt;Autant j’ai skié plus vite que prévu, autant la durée des pauses passait très
rapidement. Le fait est que contrairement à la course à pied, c’est bien moins
facile de boire et manger en skiant, avec les bâtons, gants et dragonnes
ergonomiques, alors que mon eau est coincée quelque part contre mon ventre pour
éviter le gel au lieu d’une simple poche d’eau avec un tuyau comme en trail.
Donc je me ravitaillais essentiellement aux checkpoints qui étaient d’ailleurs
pas mal bien fourni (eau chaude miellée, soupe, chili, bananes, barres de
céréales…).&lt;/p&gt;
&lt;p&gt;L’autre chose étaient les conditions de ski assez difficiles : il y a eu
plusieurs épisodes de pluie puis du regel la semaine précédent l’évènement et
la neige était très transformée. Les 2 jours on a eu un grand beau soleil, bien
agréable mais n’améliorant pas les conditions, la température oscillait entre
-15 à -3 °C suivant l’avancement de la journée. Bref, des conditions très
printanières, la glisse était rapide mais le fartage n’était pas évidant.
Malgré une base de liant que j’avais appliqué à chaque fois la veille, le fart
de jour ne durait pas longtemps avec les conditions abrasive et je refartais
tous les 15 à 20 km en moyenne, et dépendamment de l’évolution de la
température (après coup, à des moments j’aurai vraiment du m’arrêter et prendre
5 minutes pour ajuster le fartage au lieu de me fatiguer à skier sans plus
aucun kick et me disant que sa attendra le prochain checkpoint).
Par contre une chose de vraiment bien, des exposants étaient là à chaque
checkpoints pour farter les skis ; j’arrivais, je leur laissais mes skis, je
mangeais et buvais un bout puis dès qu’ils avait fini avec mes skis je
repartais. Ça me faisait gagner pas mal de temps.&lt;/p&gt;
&lt;p&gt;Par rapport à la course à pied, c’est bien plus facile, je ne me verrai pas du
tout courir pendant 8h par exemple. Déjà il n’y a pas toute la fatigue du aux
chocs à chaque impact, c’est que de la glisse, je peux me reposer en descente
(si elles sont pas trop raides) et je peux changer de technique pour reposer
plus le haut ou le bas du corps quand l’un ou l’autre fatigue. Je faisais même
du pas de patin sur les pistes de motoneige pour varier un peu, preuve que ce
n’était pas le cardio mais plus les muscles qui fatiguaient.&lt;/p&gt;
&lt;p&gt;Au niveau des paysages traversés, c’était très varié, certaines sections
étaient très belles, d’autres moins. On a traversé des pinèdes, des érablières
et des forêts de cèdres, des terrains de golf, des champs, passé au travers de
fermes, skié le long de routes et dans des vallées, traversé des lacs et des
rivières, on a skié dans un tunnel sous l’autoroute… Par moment on était sur
des sentiers étroits dans le bois, d’autres fois sur des larges pistes de
motoneige.&lt;/p&gt;
&lt;p&gt;Finalement je ne regrette pas de m’être inscrit en tant que Randonneur, ça a
été un défi supplémentaire par rapport au temps, j’ai pu dormir plus longtemps
que les Coureurs des Bois qui se levaient à 3h pour partir à la nuit, et aussi,
comme peu de Randonneurs faisaient la première section de la journée, on était
qu’un petit groupe de 20/30 personnes à partir au lieu des centaines de
Coureurs des Bois qui, eux, partaient tous en même temps et créaient des gros
bouchons (de ce qu’on m’a raconté).&lt;/p&gt;
&lt;p&gt;D’ailleurs dans la catégorie Coureurs des Bois, il y a une catégorie spéciale
pour ceux qui dorment dehors. C’est en fait le défi ultime, skier avec tout son
matériel de camping d’hiver et dormir au camp aménagé (avec feu de camp et
balles de foin) le samedi soir. Moi personnellement, je ne regrette pas du tout
de trouver une douche et un endroit chaud et sec après 80 km de ski. Je m’étais
dis à un moment que j’essayerai le camping d’hiver au Québec, mais finalement…
ça me tente plus trop !&lt;/p&gt;
&lt;p&gt;Bref, le Marathon Canadien de Ski aura été pour moi une superbe expérience,
j’en garde plein de bon souvenir et je suis pas mal plus confiant et fier de
mes capacités en ski de fond. Presque je m’en veux un peu d’avoir douté de mes
capacités au moment de l’inscription !&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/marathon-canadien-de-ski/DSC09017_big.jpg&quot;&gt;&lt;img src=&quot;/posts/marathon-canadien-de-ski/DSC09017_thumb.jpg&quot; alt=&quot;Départ du jour 2&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/posts/marathon-canadien-de-ski/DSC09019_big.jpg&quot;&gt;&lt;img src=&quot;/posts/marathon-canadien-de-ski/DSC09019_thumb.jpg&quot; alt=&quot;Dernier checkpoint&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/posts/marathon-canadien-de-ski/DSC09021_big.jpg&quot;&gt;&lt;img src=&quot;/posts/marathon-canadien-de-ski/DSC09021_thumb.jpg&quot; alt=&quot;Médaille&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>List changed configuration files and restore the maintainer&#39;s version</title>
        <published>2019-01-24T00:00:00+00:00</published>
        <updated>2019-01-24T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/list-changed-conffiles/"/>
        <id>https://univers-libre.net/posts/list-changed-conffiles/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/list-changed-conffiles/">&lt;p&gt;Recently I had to clean one of my server (a virtual machine hosted by
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://tetaneutral.net/&quot;&gt;Tetaneutral&lt;/a&gt;) to make it as close to a fresh install
as possible, but without reinstalling it or migrate it somewhere else. It is an
old server and it has been installed by hand. Since I now use Ansible to manage
my other servers, I wanted to include it to the inventory and apply the same
configuration on it.&lt;/p&gt;
&lt;p&gt;On Archlinux, I used to use this command which list me all configuration files
(in /etc) which have diverged from the version shipped by the package:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ pacman -Qii | awk &amp;#39;/^MODIFIED/ {print $2}&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I didn’t find a simple equivalent way to do it in Debian with dpkg tools,
however I found &lt;code&gt;debsums&lt;/code&gt;, an extra package that does the job pretty well:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ debsums -se&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I then can restore the package’s version by reinstalling the corresponding
package with &lt;code&gt;--force-confask&lt;/code&gt; option:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# apt install --reinstall -o Dpkg::Options::=&amp;quot;--force-confask&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is an oneliner to automate the process (careful, it doesn’t ask for any confirmation!):&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# debsums -se 2&amp;gt;&amp;amp;1 |awk &amp;#39;{print $4}&amp;#39; |xargs -n 1 dpkg -S |awk -F: &amp;#39;{print $1}&amp;#39; |sort -u |xargs apt install --reinstall -o Dpkg::Options::=&amp;quot;--force-confask&amp;quot; -o Dpkg::Options::=&amp;quot;--force-confnew&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since &lt;code&gt;xargs&lt;/code&gt; doesn’t work well with interactive commands, I force the choice by passing both &lt;code&gt;--force-confask&lt;/code&gt; and &lt;code&gt;--force-confnew&lt;/code&gt; options.&lt;/p&gt;
&lt;p&gt;As a conclusion, keep in mind the configuration files &lt;strong&gt;added&lt;/strong&gt; in &lt;em&gt;*.d/&lt;/em&gt; directories won’t be listed nor removed, so you still have to clean these directories manually.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Safe paste in terminal</title>
        <published>2018-12-22T00:00:00+00:00</published>
        <updated>2018-12-22T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/safe-paste-in-terminals/"/>
        <id>https://univers-libre.net/posts/safe-paste-in-terminals/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/safe-paste-in-terminals/">&lt;p&gt;In my daily life of sysadmin, I copy-paste many chunk of text (commands, IP
addresses, URLs, file paths, whole scripts or file contents sometimes because it’s
easier to copy-paste them rather than to scp them). I usually copy them from
other servers or from my company’s internal documentation (trusted
sources). However, I may sometimes follow howtos or read Stackoverflow answers
and copy text and commands from those less trusted websites.&lt;/p&gt;
&lt;p&gt;I want to talk about how easy one could trick you by replacing copied text in
your clipboard or inserting terminal escape sequences so that your shell will
run additional and potentially malicious commands. And how I protecting myself
against these tricks.&lt;/p&gt;
&lt;h2 id=&quot;tricks-i-have-identified&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tricks-i-have-identified&quot; aria-label=&quot;Anchor link for: tricks-i-have-identified&quot;&gt;Tricks I have identified&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Here is a list of tricks an attacker can use to fool you and make you paste a
malicious command in your terminal.&lt;/p&gt;
&lt;h3 id=&quot;replacing-copied-text-with-javascript&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#replacing-copied-text-with-javascript&quot; aria-label=&quot;Anchor link for: replacing-copied-text-with-javascript&quot;&gt;Replacing copied text with Javascript&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Dylan Ayrey demonstrates that with a &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://github.com/dxa4481/Pastejacking&quot;&gt;few lines of
Javascript&lt;/a&gt;, a malicious website can
alter your clipboard content. The code runs on key release event (keyboard
shortcut or right click) and override clipboard content with the malicious
code the attacker wants you to execute.&lt;/p&gt;
&lt;p&gt;Obviously this attack doesn’t work if you disable Javascript on unstrusted
websites, which is by the way always a good idea.&lt;/p&gt;
&lt;h3 id=&quot;hiding-malicious-code-with-css&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#hiding-malicious-code-with-css&quot; aria-label=&quot;Anchor link for: hiding-malicious-code-with-css&quot;&gt;Hiding malicious code with CSS&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;But even with Javascript disabled it’s easy for an attacker to put hidden text
in your clipboard. The idea is to put the malicious code in the middle of the
displayed command in a &lt;code&gt;&amp;lt;span /&amp;gt;&lt;/code&gt; element and apply different
CSS properties on it, so that the malicious code isn’t visible for the user. For
instance make it float and move it away from the viewport, make it transparent,
with no height or width…&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.ush.it/team/ascii/hack-tricks_253C_CCC2008/wysinwyc/what_you_see_is_not_what_you_copy.txt&quot;&gt;Here is an interesting
article&lt;/a&gt;
about this attack. It also show how to hide the malicious code once pasted in
the victim’s terminal so that the victim can’t
even known he has been p0wned.&lt;/p&gt;
&lt;p&gt;What about disabling CSS then?&lt;/p&gt;
&lt;h3 id=&quot;inserting-non-printable-characters&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#inserting-non-printable-characters&quot; aria-label=&quot;Anchor link for: inserting-non-printable-characters&quot;&gt;Inserting non-printable characters&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;That’s no enough since you could have non-printable characters (like
backspaces) in raw text. &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://security.stackexchange.com/questions/39118/how-can-i-protect-myself-from-this-kind-of-clipboard-abuse&quot;&gt;Here is an
example&lt;/a&gt;
(the whole thread is an interesting reading by the way).
Basically, the idea is to insert extra characters and a backspace character
after each of them to make the code appear inoffensive.&lt;/p&gt;
&lt;h2 id=&quot;how-i-protect-myself&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#how-i-protect-myself&quot; aria-label=&quot;Anchor link for: how-i-protect-myself&quot;&gt;How I protect myself&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So what next? What solutions I use to protect myself against those attacks?&lt;/p&gt;
&lt;h3 id=&quot;pasting-into-a-text-editor-the-bad-idea&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#pasting-into-a-text-editor-the-bad-idea&quot; aria-label=&quot;Anchor link for: pasting-into-a-text-editor-the-bad-idea&quot;&gt;Pasting into a text editor: the bad idea&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In most shell, I can easily start &lt;code&gt;$EDITOR&lt;/code&gt; with &lt;code&gt;^X^E&lt;/code&gt; to edit the current
command. But that’s totally ineffective since the pasted text can contain
&lt;code&gt;^ESC:!&amp;lt;malicious code&amp;gt;&lt;/code&gt; which will work in vim, or simply send the right
shortcut to close the editor and get back to the shell.&lt;/p&gt;
&lt;h3 id=&quot;shell-s-bracketed-paste-mode&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#shell-s-bracketed-paste-mode&quot; aria-label=&quot;Anchor link for: shell-s-bracketed-paste-mode&quot;&gt;Shell’s bracketed paste mode&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is an elegant solution. Bash (actually readline) can configure the
terminal to enclose the pasted text between paste sequences (hence the
&lt;em&gt;bracketed paste mode&lt;/em&gt;):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;enable-bracketed-paste (Off)
When  set to On, readline will configure the terminal in a way that will enable
it to insert each paste into the editing buffer as a single string  of  charac‐
ters,  instead  of treating each character as if it had been read from the key‐
board.  This can prevent pasted characters from being  interpreted  as  editing
commands.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To enable it:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ echo &amp;quot;set enable-bracketed-paste on&amp;quot; &amp;gt;&amp;gt;~/.inputrc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you then try to paste multi-lines commands in your terminal, the commands won’t be executed unless you press enter. You have a chance to review and edit them before their execution.&lt;/p&gt;
&lt;p&gt;But it has two main drawbacks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;obviously enabling bracketed paste mode will work on your own computer only,
unless you enable it on all your remote servers as well.&lt;/li&gt;
&lt;li&gt;you may still be vulnerable to code injection if the pasted text contains the
bracketed-paste-mode end sequence, whether your terminal automatically filter
this sequence or not.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can test this &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://thejh.net/misc/website-terminal-copy-paste&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;confirm-paste-plugin-in-urxvt&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#confirm-paste-plugin-in-urxvt&quot; aria-label=&quot;Anchor link for: confirm-paste-plugin-in-urxvt&quot;&gt;confirm-paste plugin in URxvt&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;URxvt has a nice plugin called paste-confirm. It is shipped with URxvt and can be found in its plugin directory (&lt;em&gt;/usr/lib/urxvt/perl/&lt;/em&gt;). Once loaded, the plugin will detect multi-lines pastes and will ask you whether to really paste it to the shell or not.&lt;/p&gt;
&lt;p&gt;To enable it, simply add it to the plugin list in your &lt;em&gt;~/.Xdefaults&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;URxvt.perl-ext-common: […],confirm-paste&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;print-your-clipboard-content-before-you-paste&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#print-your-clipboard-content-before-you-paste&quot; aria-label=&quot;Anchor link for: print-your-clipboard-content-before-you-paste&quot;&gt;Print your clipboard content before you paste&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;It’s always a good idea to double-check your clipboard content before pasting
it somewhere. I sometimes don’t remember or I’m not sure about what was my
previous selection, and I remember pasting whole file content into my terminal
a couple of times…&lt;/p&gt;
&lt;p&gt;I now use &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://github.com/mrichar1/clipster&quot;&gt;clipster&lt;/a&gt; for my cliboard
manager with &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://github.com/gilbertw1/roficlip&quot;&gt;roficlip&lt;/a&gt;. Thus with a
simple shortcut I can quickly double-check and select the previous entries in
my clipboard.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Convert SSH keys from a format to another</title>
        <published>2017-09-06T21:46:24+00:00</published>
        <updated>2017-09-06T21:46:24+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/convert-ssh-keys/"/>
        <id>https://univers-libre.net/posts/convert-ssh-keys/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/convert-ssh-keys/">&lt;p&gt;An SSH key can be stored in multiple format. &lt;code&gt;ssh-keygen&lt;/code&gt; from OpenSSH
generates keys in its own format, but other SSH implementations can use other
formats. PuTTY for example generates keys in RFC4716 format, which looks like
this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-----BEGIN RSA PUBLIC KEY-----&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;MIIBCgK349HFUE929fXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;D1MVlcrYG6XRKfkcIFEO929JFNEJONBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-----END RSA PUBLIC KEY-----&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can’t simply copy-paste this in an &lt;em&gt;authorized_keys&lt;/em&gt; file. Hopefully you
can easily convert the public key from a format to another. This is done by
I-do-about-anything-and-everything command, aka &lt;code&gt;ssh-keygen&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ ssh-keygen -i -m &amp;lt;format&amp;gt; -f input_key.pub &amp;gt; output_key.pub&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;-m&lt;/code&gt; specify the input key format among &lt;em&gt;RFC4716&lt;/em&gt; (the format used by PuTTY, this
is the default if &lt;code&gt;-m&lt;/code&gt; isn’t specified), &lt;em&gt;PKCS8&lt;/em&gt; and &lt;em&gt;PEM&lt;/em&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Get a list of opened Firefox tabs</title>
        <published>2017-09-06T21:20:49+00:00</published>
        <updated>2017-09-06T21:20:49+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/show-firefox-tabs/"/>
        <id>https://univers-libre.net/posts/show-firefox-tabs/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/show-firefox-tabs/">&lt;p&gt;Since I usually work with 2 Firefox on 2 different computers (a personal one
and a professional one), I often need to get back some of my opened tabs from
the Firefox instance running on my second computer.&lt;/p&gt;
&lt;p&gt;Firefox store all opened tabs and windows and their history in the
sessionstore-backups/recovery.js in your profile’s directory. So as long as this
file is synchronized in some way to a remotely accessible machine (backups),
you can parse the file and get the list of all your opened tabs and windows. I
wrote a simple Python script to print tab’s title and URL of each tabs from the
recovery.js file:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!/usr/bin/env python3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Print title and URL for each tab of each window of the specified&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# Firefox profile.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;import json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;with open(&amp;quot;&amp;lt;path to your Firefox profile&amp;#39;s directory&amp;gt;/sessionstore-backups/recovery.js&amp;quot;, &amp;quot;r&amp;quot;) as f:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    jdata = json.load(f)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    for w in jdata[&amp;#39;windows&amp;#39;]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        for t in w[&amp;#39;tabs&amp;#39;]:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            i = t[&amp;#39;index&amp;#39;] - 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            print(&amp;quot;%s (%s)&amp;quot; % (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                t[&amp;#39;entries&amp;#39;][i][&amp;#39;title&amp;#39;],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                t[&amp;#39;entries&amp;#39;][i][&amp;#39;url&amp;#39;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                ))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You will get a list like this:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ show-ff-tabs.py&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[…]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;GitHub - devimust/easy-bookmark-manager: Easy and simple self-hosted bookmark / snippet management tool. (https://github.com/devimust/easy-bookmark-manager)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;GitHub - Kickball/awesome-selfhosted: This is a list of Free Software network services and web applications which can be hosted locally. Selfhosting is the process of locally hosting and managing applications instead of renting from SaaS providers. (https://github.com/Kickball/awesome-selfhosted#personal-dashboards)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;GitHub - cdevroe/unmark: An open source to do app for bookmarks. (https://github.com/cdevroe/unmark)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(you can see that I currently looking for a simple self-hosted bookmark manager :-) )&lt;/p&gt;
&lt;p&gt;More information for the structure of recovery.js file on the &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.mozilla.org/Firefox/session_restore#The_structure_of_sessionstore.js&quot;&gt;Mozilla
wiki&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rando-voyage dans les provinces maritimes du Canada</title>
        <published>2017-07-18T21:53:42+00:00</published>
        <updated>2017-07-18T21:53:42+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/voyage-provinces-maritimes-canada/"/>
        <id>https://univers-libre.net/posts/voyage-provinces-maritimes-canada/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/voyage-provinces-maritimes-canada/">&lt;p&gt;Je reviens d’un voyage-rando dans les provinces maritimes du Canada, principalement à Terre-Neuve. Comme d’habitude, les photos sont &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://photos.univers-libre.net/provinces-maritimes/&quot;&gt;ici&lt;/a&gt; mais j’ai aussi pour l’occasion fait un &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://photos.univers-libre.net/provinces-maritimes/story.html&quot;&gt;récit de mon séjour là-bas&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Ça m’a pris quelques modifications dans &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://dev.univers-libre.net/gallepy/&quot;&gt;gallepy&lt;/a&gt; (mon générateur de galeries photos statique), pour pouvoir ajouter un onglet &lt;em&gt;Récit&lt;/em&gt; si un story.mdwn est présent dans le répertoire de la galerie, mais je suis plutôt content du résultat.&lt;/p&gt;
&lt;p&gt;La suite du récit arrivera dans les prochains jours.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Upgrade to Debian Jessie, introducing relay_access_restrictions in Postfix</title>
        <published>2016-06-10T10:51:42+00:00</published>
        <updated>2016-06-10T10:51:42+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/upgrade-to-jessie-postfix-relay-access-restrictions/"/>
        <id>https://univers-libre.net/posts/upgrade-to-jessie-postfix-relay-access-restrictions/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/upgrade-to-jessie-postfix-relay-access-restrictions/">&lt;p&gt;Abstract for TL;DR readers: since debconf append a relay_access_restrictions at
the end of your main.cf file with same values of recipient_access_restriction,
you have to do the same on all your services listed in master.cf.
relay_access_restrictions intends to replace recipient_access_restriction on
next Postfix releases.&lt;/p&gt;
&lt;p&gt;After upgrading my mail server to Debian Jessie, I faced a weird problem with
Postfix: emails sent from authenticated clients were rejected with a “Relay
access denied” error.&lt;/p&gt;
&lt;p&gt;I have a particular setup, though not-so-uncommon I think, since it should be the standard:
port 25 is for server-to-server communications, no authentication is supported
here. Instead, clients which want to send emails have to submit them on
submission port (obviously). Concretely on my master.cf file, I override
recipient_access_restriction for submission service to allow sending of emails
with minimum restrictions if clients got authenticated.&lt;/p&gt;
&lt;p&gt;So in my case, it seemed that the recipient_access_restriction option passed
to submission process was ignored, or the one setup on my main.cf file won.
Enabling debugging didn’t tell me anything. It even confirmed me that the
recipient_access_restriction option for submission process was ignored since I
saw Postfix testing all conditions specified on my main.cf&lt;/p&gt;
&lt;p&gt;Then after some time, I have seen a new line at the end of my main.cf file : relay_access_restrictions, with all the tests of recipient_access_restrictions. Searching this on postconf(5) manual confirmed me that it replace recipient_access_restriction, although this one is always supported and not planed to be removed on the next coming versions.
So debconf has added this new directive on my main.cf file, without any debconf advertisment as far as I remember, and without reason (Postfix don’t even raised a depreciation warning about that), and that breaks other services setted up on master.cf.&lt;/p&gt;
&lt;p&gt;No ones seem to mention that on the Internet.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Québec − janvier 2016 : gastronomie québécoise</title>
        <published>2016-01-31T17:28:50+00:00</published>
        <updated>2016-01-31T17:28:50+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/quebec-janvier-2016/"/>
        <id>https://univers-libre.net/posts/quebec-janvier-2016/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/quebec-janvier-2016/">&lt;h2 id=&quot;gastronomie-quebecoise&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#gastronomie-quebecoise&quot; aria-label=&quot;Anchor link for: gastronomie-quebecoise&quot;&gt;Gastronomie québécoise&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;En amateur de bonne bouffe, parlons un peu de la gastronomie d’ici.&lt;br /&gt;
Si on s’intéresse à la gastronomie du Québec, on devrait plutôt parler
d’archéogastronomie, car aujourd’hui il n’en reste que quelques traces, à part
les produits dérivés du sirop d’érable et la poutine (si on considère ça comme
un plat) qui restent courant. La culture américaine a largement pris le dessus.
Je trouve que comparativement à la France, il n’est pas rare de manger dans des
resto (hors fast-food) des trucs sans goût, aseptisés, fades… En fait, après 5 mois ici, j’ai
remarqué que les québécois, et je pense que c’est généralisable à tout le Canada
et l’Amérique du Nord, accordent beaucoup moins d’importance aux repas, à la
qualité de la nourriture et au plaisir de manger. Les « repas » sont souvent
expédiés et pris sur le pouce d’ailleurs, pas question de s’éterniser à table
comme on a l’habitude en France. Ils mangent presque par contrainte, juste pour
satisfaire leur faim. Ou plutôt leur envie de manger, car d’un autre coté je
vois régulièrement des gens obèses, dans le sens vraiment maladif.&lt;/p&gt;
&lt;p&gt;Mais Montréal abrite pourtant des milliers de restaurants qui représentent à peu
près toutes les cuisines du monde (Montréal est une ville extrêmement
cosmopolite). J’ai lu souvent dans les guides touristiques que Montréal est une
destination de choix pour quelqu’un qui veut gouter à la gastronomie de
différent pays. Mais même si les plats sont cuisinés effectivement avec le savoir
faire du pays d’origine, les ingrédients eux sont (au moins en partie) ce qu’on
trouve sur le continent américains, et j’ai du mal à croire qu’une choucroute
ou une pizza ici soit aussi bonne qu’en Allemagne ou qu’en Italie.&lt;/p&gt;
&lt;p&gt;Mais bref, on trouve donc à Montréal une très grande quantité de restaurants qui
reprennent la gastronomie de différents pays, sauf… celle du Canada, en
particulier du Québec !
Et forcement, si elle est déjà peu cuisinée ici, en dehors du Canada elle est
quasiment méconnue. Donc pour y gouter, il faut souvent cuisiner les plats
soit-même.&lt;/p&gt;
&lt;p&gt;Le blog d’À Boire et À Manger en &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://long.blog.lemonde.fr/?s=qu%C3%A9bec&quot;&gt;parle à
peine&lt;/a&gt; malheureusement (voir pas du
tout malgré les 4 épisodes), donc je vais vous en parler moi, mais sans dessins…&lt;/p&gt;
&lt;p&gt;Malgré qu’elle soit très peu connue, je trouve que la gastronomie québécoise vaut quand même le
détour. Elle est assez particulière dans le sens où les associations sont
souvent surprenantes et inhabituelles. C’est à l’opposé de la fine cuisine, les
plats sont généralement simples, sans raffinements, copieux et bien caloriques. Tout tourne
autour de la viande ou de la charcuterie.&lt;br /&gt;
La raison est que, premièrement, les pionniers de la Nouvelle France
(je ferrai peut-être un article sur l’histoire de la Nouvelle France, c’est
assez intéressant, et encore une fois complètement méconnu, je ne me souviens
même pas ne serait-ce que l’avoir entrevue en cours d’histoire à l’école)
étaient généralement assez pauvres (paysans ou ouvriers) et n’avaient pas une
très grande variété d’aliments à leur portée. Mais ils bénéficiez quand même de
beaucoup de produits importés grâce au commerce maritime entre la Nouvelle
France, les Antilles et la France, ou encore entre la Nouvelle France et la
Martinique. D’où la présence de sucre, de mélasse (résidu de raffinage de la canne ou
betterave à sucre, bien moins cher que le sucre à l’époque), de rhum depuis les
Antilles ou de vin et de sel depuis la France, dans leur cuisine.&lt;br /&gt;
L’omniprésence de viande s’explique par l’abondance de gibier et la liberté de
chasse (dans le sens pas contrôlée par un seigneur comme en France). Le climat
et le travail était difficile, donc il fallait quelque chose de très calorique.&lt;/p&gt;
&lt;p&gt;Parmi les plus connues, et le top du top pour moi, on trouve donc les fèves au
lard, appelées aussi bines, de l’anglais &lt;em&gt;bean&lt;/em&gt; (haricot/fève) qui ne sont donc
pas des fèves mais des haricots blanc (même si à l’époque c’était des gourganes
appelées aussi fèves des marais, si vous suivez toujours), qu’il faut
faire cuire au four pendant une dizaine d’heures à basse température, avec
beaucoup de lard, de la mélasse, du coulis de tomate et des épices comme du
gingembre et de la moutarde. Ça donne des haricots fondant et bien imprégné du
gras du lard, vraiment très bon mais à manger avec des pommes de terre ou du
pain, sinon seul c’est vraiment très gras.&lt;/p&gt;
&lt;p&gt;Connu surtout pour les controverses quand à son origine et sa facilité de
préparation, il y a le pâté chinois, qui consiste en un gratin composé d’une
couche de viande hachée, une couche de maïs en grains ou en crème (aussi appelé blé d’Inde)
et une couche de purée de pomme de terre. Certains affirment que ce nom a été
donné car le plat était consommé quotidiennement par les ouvriers chinois lors de la
construction de la ligne ferroviaire pancanadienne, d’autres pensent que ça n’a
rien à voir avec les chinois, et que son origine viendrait de la traduction de
&lt;em&gt;china pie&lt;/em&gt;, une spécialité locale de la ville de South China, dans l’état du
Maine. Il y a d’autres théories, mais en résumé on a perdu son origine.&lt;/p&gt;
&lt;p&gt;Autre plat typique, pour lequel presque chaque région a sa variante, la
tourtière à la viande. Au Sagenay-Lac-Saint-Jean, il s’agit de la tourtière du
Lac-Saint-Jean, en Gaspésie de la cipaille, etc… chacune est à priori
différente, mais le plat consiste en une couche de pâte, de la viande, hachée ou
en petits cubes, de gibier, de bœuf ou de porc, éventuellement marinée, des
épices, éventuellement des pommes de terre en cubes, et une seconde couche de
pâte pour fermer hermétiquement. Le tout cuit au four à basse température.
On peut aussi rajouter des légumes (carottes, navets…) ou remplacer la viande
par de la morue, ou encore du saumon. Bref, plein de variantes existent.
C’est pas très compliquer à faire, mais on en trouve assez facilement des toutes
prêtes dans des boucheries ou boulangeries.&lt;/p&gt;
&lt;p&gt;Et puis plein d’autres encore à base de viande toujours : ragout de
boulettes de viande, pain de viande, bouillons et ragoût en tout genre etc…&lt;/p&gt;
&lt;p&gt;En charcuterie, ils ont moins de chose qu’en France, mais on trouve le fameux
cretons, qui peut se comparer avec de la rillettes (d’ailleurs tous les 2 ne
s’écrivent qu’au pluriel !) mais fait généralement avec de la viande de porc
grasse, plus éventuellement du beurre (pour faire encore plus gras). C’est un
plat qui était surtout mangé au petit-déjeuner sur du pain, comme les fèves au
lard.
On retrouve sinon plein de pâtés (de gibier, de tête, à la bière, etc…), du
jambon fumé effiloché, qui est en fait un jambon cuit (blanc) puis fumé dans
lequel on prélève non pas des tranches mais des lanières de viande, etc…&lt;/p&gt;
&lt;p&gt;Outre tout ce gras, les colons faisaient quand même une très grande consommation
de soupe à base de légumes d’hiver qu’ils cultivaient (genre carottes, pommes de
terre, navets, courges, betterave etc…). Soupe dans laquelle ils pouvaient
rajouter, aller pour changer… un peu de viande ! C’est peut-être la seule chose
qui reste autant consommée aujourd’hui, quasiment n’importe quel fastfood,
boulangerie etc… qui propose des plats à emporter propose des soupes (mais il ne
faut pas s’attendre à un truc exceptionnel niveau goût).&lt;/p&gt;
&lt;p&gt;Au niveau sucré, on trouve bien sûr toute sorte de produits de l’érable, allant
de l’eau d’érable (aucune transformation) jusqu’au beurre et sucre d’érable,
avec la fameuse tire d’érable dans les cabanes à sucre au printemps.
Idem pour ce qui est des canneberges et des bleuets (variété de grosses
myrtilles), disponible sous pleins de formes différentes : fraiches, en jus, dans
des tartes, etc…&lt;/p&gt;
&lt;p&gt;En dessert, le plus consommé encore aujourd’hui est le pouding-chômeur fait,
encore une fois, avec des ingrédients bon marché : farine, beurre, œuf, lait et
sirop de cassonade.&lt;/p&gt;
&lt;p&gt;D’origine bien plus plus récente, les populaires &lt;em&gt;beavertails&lt;/em&gt; (ou queues de
castor) vendues dans des camions ambulants, lors des fêtes foraines et autres
animations, sont des pâtisseries faites d’une sorte de pâte à gaufre mise en
forme de queue de castor, puis frittes dans l’huile et recouvertes de diverses
garnitures. J’imaginais ça bien bourratif, mais en fait pas du tout.&lt;/p&gt;
&lt;p&gt;Le Québec fait une très grande production de pomme, principalement au début de
l’automne, et est donc un gros producteur de cidre et cidre de glace. Le cidre
de glace est fait à partir de jus de pomme concentré par l’action du froid (le
jus est stocké dehors à une température largement négative, l’eau qui a formé
des cristaux de glace est ainsi retirée au fur et à mesure. Ça permet d’obtenir
un cidre plus sucré et alcoolisé, plus ou moins équivalent au vin.&lt;/p&gt;
&lt;p&gt;D’origine plus récente, On trouve aussi plusieurs spécificités plus régionales,
comme la viande fumée ou les bagels à Montréal, les microbrasseries artisanales
un peu partout, les produits de la mer en Gaspésie, etc…&lt;/p&gt;
&lt;h2 id=&quot;les-trucs-chiants-cette-fois-ci&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#les-trucs-chiants-cette-fois-ci&quot; aria-label=&quot;Anchor link for: les-trucs-chiants-cette-fois-ci&quot;&gt;Les trucs chiants (cette fois-ci)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les unités de mesure… un sujet classique mais je ne me serais jamais douté que
c’était autant une prise de tête !&lt;br /&gt;
Tout d’abord il y a ceux qui parlent en pouces. Ça c’est simple. Ensuite ceux
qui parlent en pieds, mais comme ça ne tombe pas rond, soit parlent ensuite en
pouces, soit en fraction de pied. Tout en sachant qu’un pied n’équivaux évidemment
pas à un nombre entier de pouces.&lt;br /&gt;
Pour illustrer la situation, pour une rallonge électrique de même taille on peut
voir noter sur l’étiquette : 3 m, 9’ 10“, 118“, 9,84’ ou encore 9’ 4/5’.&lt;/p&gt;
&lt;p&gt;Et ils aime ça les fractions de pouce pour remplacer les millimètres, ils les
utilisent partout. J’ai acheté par exemple une boite de tournevis de précision,
dans lequel j’ai des tournevis de 3/32“, 5/64“ et 1/16“. Exercice : classez les
du plus petit au plus grand[1]. Bon oui, après avoir réfléchit un peu et avec
l’habitude ça vient plus facilement, n’empêche que c’est bien moins simple que
si ils avaient utilisé des millipouces (ou des poils de jambe pour continuer
dans le délire). Je n’avais lu nul part qu’il fallait réviser ses cours de math
avant de venir au Québec ! Car si je veux savoir combien fait 4mm en pouce,
diviser 4mm par 2,54 ne m’avancera pas beaucoup avec une bête calculette, je
n’aurai pas la fraction la plus proche… Un de mes meilleurs investissements est
donc un mètre ruban, gradué à la fois en mètres, pouces et pieds, en un coup
d’œil je trouve la bonne fraction.&lt;/p&gt;
&lt;p&gt;Et puis, ces histoires de pouces, ça peut devenir dangereux. Un dialogue qui
aurait pu arriver chez le coiffeur :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;− Et pis, combien tu veux-tu que je t’enlève de pouces?&lt;br /&gt;
− Euh, ne touche pas a mes pouces, coupe moi juste mes cheveux, ce sera suffisant!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;[1] Réponse : et bien ils sont déjà classés, ils ne sont pas sadiques au point de
ranger les tournevis dans le désordre !&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting Galaxy S2 GPS to work on Replicant</title>
        <published>2016-01-21T20:24:34+00:00</published>
        <updated>2016-01-21T20:24:34+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/galaxy-s2-gps-on-replicant/"/>
        <id>https://univers-libre.net/posts/galaxy-s2-gps-on-replicant/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/galaxy-s2-gps-on-replicant/">&lt;p&gt;Last week I gave a talk about &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.replicant.us/&quot;&gt;Replicant&lt;/a&gt; with a live
(re)installation of it on my phone at &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://web.archive.org/web/20181111020628/https://www.clublinuxatomic.org/&quot;&gt;Club Linux
Atomic&lt;/a&gt;.
You can download the slides (in french)
&lt;a href=&quot;/posts/galaxy-s2-gps-on-replicant/presentation-replicant.pdf&quot;&gt;here&lt;/a&gt; (and LaTeX sources &lt;a href=&quot;/posts/galaxy-s2-gps-on-replicant/presentation-replicant-cla.tar.xz&quot;&gt;here&lt;/a&gt;).
There are available under the Creative Common BY-SA 3.0 license.&lt;/p&gt;
&lt;p&gt;But let’s come back to the topic of this post, the GPS chip of the Samsung
Galaxy S2. After my talk, someone asked me how I got the GPS module to work on
my phone. There is indeed no support of it on Replicant as the chip (a SiRF star
IV GSD4t) is not recognized by standard free software tools like gpsd. Someones
already worked on it, but without success at this time. All the work is on this
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://redmine.replicant.us/projects/replicant/wiki/GSD4t&quot;&gt;Replicant’s wiki
page&lt;/a&gt;.  So if you
really need it, you have to use the proprietary code.&lt;/p&gt;
&lt;p&gt;I realize that there is no documentation explaining how to install this proprietary
code, so here is what I did on my phone. Bear in mind that, unlike proprietary
firmwares you need for WiFi/Bluetooth chipset, the proprietary code needed for
the GPS is a “real” software which run on your main SoC, and could
potentially have access to all your data.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;First, let’s &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://web.archive.org/web/20161118221944/http://download.cyanogenmod.org/?device=i9100&quot;&gt;download&lt;/a&gt; the CyanogenMod archive corresponding to the Galaxy
S2. Replicant is based on CyanogenMod and we are sure that the code we need
is chipped with the CyanogenMod distribution.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then you need to extract and upload to your phone this 2 files:
&lt;em&gt;gps.exynos4.so&lt;/em&gt; and &lt;em&gt;libsecril-client.so&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb push system/lib/hw/gps.exynos4.so /system/lib/hw/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb shell chmod 644 /system/lib/hw/gps.exynos4.so&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb push system/lib/libsecril-client.so /system/lib/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;adb shell chmod 644 /system/lib/libsecril-client.so&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And that’s it! Pretty simple, just 2 files but we should have to know the good
ones.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Québec − novembre/décembre 2015 : le vélo et le ski à Montréal</title>
        <published>2016-01-05T19:52:44+00:00</published>
        <updated>2016-01-05T19:52:44+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/quebec-decembre-2015/"/>
        <id>https://univers-libre.net/posts/quebec-decembre-2015/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/quebec-decembre-2015/">&lt;p&gt;Il n’a pas manqué du tout d’article pour novembre, c’est juste que cet article
en contient 2 pour le prix d’un !&lt;/p&gt;
&lt;p&gt;En fait ce n’est pas que les sujets à aborder manquent, mais plutôt que
je préfère attendre afin d’avoir un avis plus précis et de ne pas passer à coté
de choses que je n’aurai pas vu au premier abord. C’est le cas par exemple de
randonnées et des réputés (à tord) grands espaces, de la gastronomie
québécoise, complètement méconnue et pas mise en valeur à mon sens (à tord
encore une fois), de la démocratisation du logiciel libre ici…&lt;/p&gt;
&lt;p&gt;Mais tout ça ce sera pour après. Je vais plutôt parler de vélo et un peu de ski.&lt;/p&gt;
&lt;h2 id=&quot;le-velo-a-montreal&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#le-velo-a-montreal&quot; aria-label=&quot;Anchor link for: le-velo-a-montreal&quot;&gt;Le vélo à Montréal&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Couramment appelé bicycle d’ailleurs, même si le terme vélo reste
majoritairement utilisé.&lt;/p&gt;
&lt;p&gt;Il y a énormément de vélo à Montréal. En fait, Montréal fait parti des villes
d’Amérique du Nord les plus développées pour la pratique du vélo, et en
conséquence (ou à cause) qui possède le plus grand nombre de personnes se
déplaçant à vélo. Il est vraiment courant de faire une bonne partie de son
trajet sur une bande ou carrément une piste cyclable.&lt;br /&gt;
Surtout quand il fait beau, il y a en fait tellement de monde sur les bandes
cyclables que l’on ne peut pas doubler sans au moins regarder derrière soi, au
cas où il y aurait déjà un autre vélo en train de doubler.  Ça me semble
naturel maintenant, mais à Marseille c’était tellement peu probable qu’un
accident entre 2 vélos arrivent…&lt;/p&gt;
&lt;p&gt;Concernant le comportement des automobilistes face aux vélos, et en comparaison
avec Marseille toujours, c’est à peu près équivalent : ils ont moins tendance à
forcer le passage aux priorités (mais ça ça semble être le cas de manière générale
vis-à-vis des automobilistes entre eux, ils sont moins pressés, par contre
ils respectent moins les distances de sécurités (les mêmes qu’en France), alors
que les routes sont globalement plus larges. Je me suis déjà fait doubler en plusieurs fois
à quelques dizaines de centimètres, en même pas quatre mois, alors qu’après
plusieurs années à Marseille, ça ne m’était arrivé que très rarement (bon ils ne
respectaient pas le 1 mètre non plus, mais ça restait raisonnable). Du coup
j’ai quand même cette impression de ne pas être totalement en sécurité sur la
route à Montréal, et de chercher à faire des détours pour prendre des bandes
et pistes cyclables.&lt;/p&gt;
&lt;p&gt;Il y a d’ailleurs beaucoup de pistes cyclables, les vraies, celles complètement
séparées de la route, voir qui n’en suit pas. Elles se trouvent en général le
long des berges et quand on s’éloigne du centre-ville. Ainsi on peut faire le
tour complet de l’île de Montréal (attention, il faut être en forme, plus de
200 km !) uniquement sur des pistes cyclables qui longent le fleuve, traversent
des parcs etc…&lt;br /&gt;
C’est vraiment cool pour avoir l’impression de sortir de la ville tout en
commençant à pédaler de chez soi, sans avoir à prendre de voiture. Même au delà
de l’île, le réseaux de pistes cyclables continu et traverse des endroits moins
peuplés et avec bien plus de verdure.&lt;/p&gt;
&lt;p&gt;Un bémol par contre, plusieurs bandes cyclables ne sont plus réservées aux
cyclistes à partir de mi-novembre et deviennent des emplacements de
stationnement. Mais parfois uniquement sur certaines portions, ce qui fait
qu’on peut se retrouver d’un coup sans bande cyclable et à contre sens
de la circulation ! Légèrement dangereux…&lt;/p&gt;
&lt;p&gt;Il faut savoir aussi que globalement le Québec, mais Montréal particulièrement,
se situe sur une forte zone sismique. Bon ce n’est pas vrai :-), mais à voir
l’état des routes, c’est comme si ! Plein de fissures, d’affaissements et des
nids de poules de partout, alors la ville les rebouche de temps en temps (ça
devient des bosses, car c’est mal fait), puis d’autres nids de poule
apparaissent sur la réparation, et ils en rajoutent encore une couche par
dessus, etc… Ça donne des chaussés horribles. Je n’ai jamais vu ça en France,
même sur des petites départementales dans les Alpes pas entretenues depuis une
dizaine d’années.&lt;br /&gt;
Et pourtant, une grosse partie des gens roulent en vélo de course/route mais
honnêtement je me demande comment ils font. Avoir un vélo un minimum costaud et
des pneus pas trop fin pour absorber les chocs est pour moi à privilégier pour
espérer qu’il dure longtemps. Ça s’appelle des hybrides ici, ce qui est à peu
près l’équivalent des VTC en France.&lt;/p&gt;
&lt;p&gt;Pour le vélo l’hiver, ça se fait très bien avec des pneus hiver, jusqu’à
quelques centimètres de neige. Au delà ça se fait toujours mais c’est plus…
sportif disons, mais je trouve ça amusant personnellement.&lt;br /&gt;
De toute façon, les bandes cyclables finissent par être déneigées au bout de
quelques jours.&lt;/p&gt;
&lt;h2 id=&quot;le-ski-au-quebec&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#le-ski-au-quebec&quot; aria-label=&quot;Anchor link for: le-ski-au-quebec&quot;&gt;Le ski au Québec&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le Québec étant une région très plate, il se prête assez bien à la pratique du
ski de fond ou de randonnée nordique.  Malheureusement cette année la neige a
mis du temps à arriver et je n’ai eu jusqu’à présent l’occasion de skier qu’une
seule fois, mais ça n’empêche pas de commencer à en parler.&lt;/p&gt;
&lt;h3 id=&quot;vocabulaire&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#vocabulaire&quot; aria-label=&quot;Anchor link for: vocabulaire&quot;&gt;Vocabulaire&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Déjà au Québec, les différents sports de ski ne s’appellent pas de la même
façon qu’en France, donc voici un magnifique tableau pour s’y retrouver :&lt;/p&gt;
&lt;table border=&quot;1&quot; style=&quot;width:100%&quot;&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 33%&quot; /&gt;
&lt;col style=&quot;width: 33%&quot; /&gt;
&lt;col style=&quot;width: 33%&quot; /&gt;
&lt;/colgroup&gt;
&lt;tbody&gt;
  &lt;tr&gt;
    &lt;th&gt;Dénomination française&lt;/th&gt;&lt;th&gt;Dénomination québécoise&lt;/th&gt;&lt;th&gt;Dénomination anglaise&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;ski de fond (alternatif)&lt;/td&gt;&lt;td&gt;ski de fond (alternatif)&lt;/td&gt;&lt;td&gt;cross-country skiing&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;skating&lt;/td&gt;&lt;td&gt;ski de patin&lt;/td&gt;&lt;td&gt;skate skiing&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;ski de randonnée nordique (SRN)&lt;/td&gt;&lt;td&gt;ski hors-piste, ski de randonnée, ski de randonnée hors-piste&lt;/td&gt;&lt;td&gt;pas de terme vraiment adapté&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;ski de piste, ski alpin&lt;/td&gt;&lt;td&gt;ski alpin&lt;/td&gt;&lt;td&gt;alpine skiing&lt;/td&gt;&lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;ski de randonnée&lt;/td&gt;&lt;td&gt;ski de haute-route, ski hors-piste&lt;/td&gt;&lt;td&gt;ski touring&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;En résumé, ça va à peu près sauf pour le SRN où tout le monde l’appelle un peu
comme il veut, et on ne peut même pas utiliser le terme anglophone car c’est
pas mieux chez eux. Certains nomment le ski de randonnée également ski hors-piste, donc ça porte encore plus à confusion pour le SRN…&lt;br /&gt;
Comme le texte vise plutôt les français nouvellement arriver au Québec,
j’emploierai les termes français.&lt;/p&gt;
&lt;h3 id=&quot;location-achat-de-ski&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#location-achat-de-ski&quot; aria-label=&quot;Anchor link for: location-achat-de-ski&quot;&gt;Location/achat de ski&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Suivant votre utilisation, vous pouvez soit :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;en louer sur place à la journée, suivant les endroits où vous allez ;&lt;/li&gt;
&lt;li&gt;en louer pour un weekend ou la saison entière ;&lt;/li&gt;
&lt;li&gt;en acheter neuf ou d’occasion.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour en acheter neuf, les boutiques principales sont MEC et La Cordée, sortes
de Décathlon en plus petit et plus cher. Mais il y a à voir également D’un
Sport à l’Autre (majoritairement d’occasion, et peu de choix quand j’y suis
allé) et Sports aux Puces (de l’occasion aussi).
Les 2 premières font de la location à la journée/weekend, mais ça revient très
vite cher si vous comptez skier plus de quelques fois dans la saison (environ
20$/j).&lt;/p&gt;
&lt;p&gt;Mais l’option clairement intéressante est d’aller à La Poubelle du Ski, magasin
visiblement très connu à Montréal : ils proposent de louer des skis d’occasions
pour la saison entière, ou des skis neufs avec possibilité de les acheter ensuite
en fin de saison.  C’est donc assez intéressant si vous comptez en faire
beaucoup, et que vous n’êtes pas prêt à investir directement dans l’achat de
skis neufs.  Surtout que les tarifs sont plus qu’intéressants, les skis neufs étant des
modèles des années passées ou d’exposition. À titre d’exemple, pour des skis de
fond neufs à farter, fixations (pose comprise), bâtons et chaussures, j’en
ai eu pour légèrement plus de 100 $ pour la saison. En fin de saison, je peux
les acheter pour 100 $ de plus.  Le personnel est visiblement assez compétant
(beaucoup de jeunes), par contre vu la réputation de la boutique, il vaut mieux
y aller tôt le matin à l’ouverture, en soirée c’est la cohue…&lt;/p&gt;
&lt;h3 id=&quot;pistes-de-ski-de-fond-a-montreal&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#pistes-de-ski-de-fond-a-montreal&quot; aria-label=&quot;Anchor link for: pistes-de-ski-de-fond-a-montreal&quot;&gt;Pistes de ski de fond à Montréal&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Le truc vraiment bien, c’est que la ville trace des pistes de ski de fond dans
les grands parcs de la ville et en périphérie dans les parcs nature. Et L’accès
y est gratuit ! Les parcs skiables et les conditions de neige sont consultables
sur le &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://ville.montreal.qc.ca/portal/page?_pageid=7377,94521748&amp;amp;_dad=portal&amp;amp;_schema=PORTAL&quot;&gt;site de la
ville&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Par contre le skating étant moins populaire ici, les pistes ne sont faites que
pour le pas alternatif, et des pistes distinctes (plus rares) sont damées pour
la pratique du skating.&lt;/p&gt;
&lt;h2 id=&quot;les-trucs-marrants&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#les-trucs-marrants&quot; aria-label=&quot;Anchor link for: les-trucs-marrants&quot;&gt;Les trucs marrants&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Dans l’éternel et passionnant débat sur l’appellation pain au chocolat
versus chocolatine, les québécois viennent soutenir l’effectif des
sud-ouestien de France en appelant les pains au chocolat des chocolatines.
Heureusement ici un sac plastique reste un sac plastique.  Mais là où ils
sont bons, c’est qu’ils ont enfin résolu le problème du &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://grisebouille.net/arretons-avec-les-croissants/&quot;&gt;choix entre
croissant et pain au
chocolat&lt;/a&gt; en
inventant… le croissant au chocolat (et non la croissantine, preuve que
c’était une bonne idée) !&lt;/li&gt;
&lt;li&gt;Moi qui faisait toujours très attention à mettre une espace insécable avant
la plupart des points de ponctuation, j’ai appris qu’au Québec personne ne
s’embête avec ça, la règle est de ne rien mettre du tout (comme en
anglais donc). Donc maintenant, je fais attention suivant à qui j’écris.&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Québec − octobre 2015 : accès à Internet, meubles et un peu de tourisme</title>
        <published>2015-11-07T17:42:43+00:00</published>
        <updated>2015-11-07T17:42:43+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/quebec-octobre-2015/"/>
        <id>https://univers-libre.net/posts/quebec-octobre-2015/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/quebec-octobre-2015/">&lt;h2 id=&quot;petit-d-etat-des-lieux-des-fai-au-canada&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#petit-d-etat-des-lieux-des-fai-au-canada&quot; aria-label=&quot;Anchor link for: petit-d-etat-des-lieux-des-fai-au-canada&quot;&gt;Petit d’état des lieux des FAI au Canada&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Après l’achat d’un frigo et d’un matelas, dans l’ordre des priorités, vient
celui d’un abonnement à un fournisseur d’accès à Internet (protip : en prenant
d’abord un abonnement Internet, vous pouvez vous passer d’un matelas puisque
vous pourrez ne plus dormir. Et en suivant un régime spécial vous pourrez
en fait également vous passez aussi de frigo :-) ).&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://xkcd.com/1077/&quot;&gt;&lt;img src=&quot;https://imgs.xkcd.com/comics/home_organization.png&quot; alt=&quot;Home Organization&quot; title=&quot;Lifekacking!&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Attention, je ne vais parler que de l’offre résidentielle, il y en ai bien sûr
autrement pour l’offre à destination des entreprises.&lt;/p&gt;
&lt;p&gt;Au niveau offres disponibles sur le marché des FAI, c’est pas terrible : en fait
il y a de nombreux FAI, certains sont uniquement présents sur certains
secteurs (Grand Montréal, Ottawa-Gatineau, etc…), la majorité sur tout une
province, et les quelques gros sur plusieurs, mais aucun ne couvrent la totalité
du pays. Mais la concurrence ne semblent pas être très avantageuse pour les
consommateurs, les tarifs sont finalement assez identiques d’un FAI à l’autre,
de l’ordre de la quarantaine de dollars pour un accès ADSL en ligne sèche
(équivalent d’une ligne dégroupée en France).
Ça, c’est à condition d’accepter d’avoir une limite de ~150 Go téléchargés par
mois. Pour avoir plus ou, soyons fou, aucune limite (genre… comme en France en
fait), c’est plus cher. Et pour du VDSL ou de la fibre, pour votre santé
mentale, ne rêvez pas :-).
Les offres Internet/téléphonie VoIP/TV existent aussi, pour environ $100/mois…&lt;/p&gt;
&lt;p&gt;D’un point de vu plus technique… ce n’est pas mieux. Commençons quand même par
deux points positifs : plusieurs fournisseurs donnent la possibilité d’avoir
une adresse IP fixe (moyennant quelques dollars de plus sur l’abonnement).
Parmi eux, certains offrent aussi la possibilité d’avoir un /30, /29 voir /28
(!) moyennant un peu plus que quelques dollars par mois, mais c’est toujours
intéressant d’avoir cette possibilité en tant que particulier).&lt;/p&gt;
&lt;p&gt;Au niveau IPv6, à ma connaissance, seul TekSavvy fournit un accès en IPv6 natif
(officiellement en beta, dans le sens où il ne font pas de support, mais
relativement stable, et en place depuis plusieurs années). Quelques autres ont
une beta en cours de mise en place, ou bien offrent un tunnel via Hurricane
Electric.
TekSavvy fournit une IPv6 pour l’interco via DHCP-PD et un /56, on peut donc se
créer plusieurs réseaux locaux avec.&lt;/p&gt;
&lt;p&gt;À priori, tous laissent la possibilité d’utiliser son propre modem[1], et
d’héberger son serveur. TekSavvy bloque par défaut le port SMTP en sortie au
niveau de leur réseau, désactivable sur demande.&lt;/p&gt;
&lt;p&gt;Venons en là où ça fait mal : la gestion du réseau fonctionne un peu comme en
France, dans le sens où les quelques très gros opérateurs (Bell et Telus au
Québec) louent leurs infra aux opérateurs intermédiaires (équivalent de l’offre
de collecte en France). La différence est que la partie réseau qui est louée
passe d’abord par des équipements actifs des opérateurs de collecte, qui ont
pris la mauvaise habitude de faire de la limitation de trafic à base de DPI.
Donc au final, quelque soit l’opérateur qu’on choisisse, nos communications seront
analysés par Bell ou Telus !&lt;br /&gt;
Quelques opérateurs intermédiaires et unions de consommateurs ont porté plainte
contre Bell, sans trop de succès pour le moment. Du coup, quelques opérateurs
offrent des solutions de contournement : de manière radicale, Acanac fournit un
service de VPN, de l’abonné jusqu’à leur réseau par exemple. D’autres tel que
TekSavvy donnent la possibilité de faire du SLPPP (Single Link PPP, donc du
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://en.wikipedia.org/wiki/Point-to-point_protocol#Multilink_PPP&quot;&gt;MLPPP&lt;/a&gt;
à un seul lien PPP), ce qui permet (à l’heure actuelle) de passer au
travers des limitations imposées.&lt;/p&gt;
&lt;p&gt;Au sujet de la neutralité du net, y a-t-il des FAI associatifs qui visent à
fournir une connexion la plus neutre possible, comme tous les petits FAI
associatifs et FDN en France ?&lt;br /&gt;
Pas vraiment. Le seul qui s’en rapproche est &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.ncf.ca/&quot;&gt;NCF&lt;/a&gt;
(National Capital Freenet), surtout présent comme son nom l’indique sur la
région de la Capitale Nationale (Ottawa-Gatineau). C’est un OBNL (Organisme à
But Non Lucratif, à peu près équivalent aux associations Loi 1901 en France)
nait dans une université, dont le but affiché est plus de fournir un accès au
plus pas prix possible au plus grand nombre qu’un accès le plus neutre
possible. Bien qu’ils disent le contraire, je n’ai pas trouvé qu’ils étaient
moins cher que les FAI commerciaux, et certains trucs m’ont un peu rebuté : ils
donnent par défaut une IPv4 non fixe et font payer le fait d’avoir une IPv4
fixe, et comme ils passent par Bell, ils sont également impacté par le DPI. Ils
n’offrent rien contre ça, mais pire (ce n’est pas officiel), j’ai compris
qu’ils faisaient eux aussi de la limitation de débit sur certains ports. Sur
Montréal, les différentes personnes impliquées dans le logiciel libre
auxquelles j’ai pu parlé n’avait jamais entendu parlé de NCF…&lt;/p&gt;
&lt;p&gt;Pour retrouver le sourire, un projet plus sympa existe sur Montréal :
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://wiki.reseaulibre.ca/&quot;&gt;reseau-libre.ca&lt;/a&gt;, c’est un OBNL qui maintien un réseau mesh en WiFi. Il ne vise
pas de fournir un accès à Internet, mais plutôt d’avoir un réseau local
(surtout dans le sens agriculture locale, pas LAN) pour permettre au montréalais
de communiquer entre eux, et éviter de passer par les gros points de
concentration sur Internet.  Ce qui est cool, c’est que rien ne semble très
sérieux et ça fait un peu grand aire de jeux/bac à sable pour adminsys/admin
réseau : chacun peut ajouter sa petit machine sur le réseau en fournissant les
services qu’il veut (XMPP, serveur web d’une station météo, webcam d’un lieu
public…), en testant des nouveaux protocoles avec ses voisins, etc… Je ne les
ai pas encore rencontré, mais c’est clairement dans mes todo !&lt;/p&gt;
&lt;p&gt;Au final, j’ai donc opté pour TekSavvy, pour leur support d’IPv6, la possibilité de passer au travers du DPI de Bell, la possibilité d’avoir une IPv4 fixe et si besoin des IPv4 additionnelles, et leur support technique assez compétant (genre ils comprennent de quoi je parle si je leur demande d’ajouter un reverse DNS sur mon IPv4) d’après les différents retour d’utilisateurs. Je ferai probablement un retour plus poussé plus tard, et avec la bonne conf du démon pppd de FreeBSD qui supporte SLPPP.&lt;/p&gt;
&lt;p&gt;Quelques liens pour aider à choisir son FAI :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://canadianisp.ca/&quot;&gt;Canadian ISP&lt;/a&gt;, pour avoir une liste quasi exhaustive ;&lt;/li&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.dslreports.com/&quot;&gt;DSL Report&lt;/a&gt;, surtout pour les retours d’utilisateur et le forum très actif, concerne tous les FAI nord-américains.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[1]: À titre d’info les modem français/européens fonctionnent bien, j’utilise
un D-link DSL 320B, n’apportez pas votre câble gigogne &amp;lt;-&amp;gt; RJ11 par contre, ils ne
connaissent pas, c’est du RJ11 des 2 côtés.&lt;/p&gt;
&lt;h2 id=&quot;ou-trouver-des-meubles&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#ou-trouver-des-meubles&quot; aria-label=&quot;Anchor link for: ou-trouver-des-meubles&quot;&gt;Où trouver des meubles&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Parce que vivre dans un appart vide, ça devient vite peu agréable.  Voici
quelques endroits où trouver de quoi remplir un peu votre nouvel appart :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kijiji, équivalent de leboncoin en France, c’est la référence numéro 1. Avec un peu/beaucoup de patiente on peut tomber sur des superbes affaires. J’ai pu par exemple avoir un grand canapé 3 places comme neuf pour $170 livraison comprise, et une table et 2 chaises en état pas top mais pour $20 livraison comprise aussi ! La grande difficulté est de tomber sur des personnes qui acceptent/peuvent faire la livraison pour les gros meubles, et c’est pas forcement évident. Avoir la possibilité de louer une voiture aide pas mal, encore faut-il arriver à la rentabiliser ;&lt;/li&gt;
&lt;li&gt;les autres sites de petites annonces comme Craigslist ou Lespacs sont nettement moins fournit, mais ça peut être intéressant de jeter un œil de temps en temps ;&lt;/li&gt;
&lt;li&gt;plus pour ce qui est décoration intérieure et vaisselle, Renaissance, Le Village des Valeurs (traduction à la québécoise de Value Village, donc dans le sens économique plutôt qu’éthique, j’ai mis du temps à comprendre), l’Armée du Salut et les bazars dans les Églises. On trouve pas mal de choses pour quelques dollars, c’est des dons à la base, donc il faut pas s’attendre à des trucs super mais ça peut dépanner, ou si vous êtes vraiment juste au niveau budget ;&lt;/li&gt;
&lt;li&gt;les magasins de revente d’occasion : le gros plus c’est qu’ils font la livraison, parfois gratuitement, et il est facile de négocier le prix. J’y ai acheté matelas, frigo et cuisinière car ça permet d’avoir une petite garantie de quelques mois sur l’électroménager. Au niveau meubles, c’est quand même nettement plus cher que ce que vous pourrez trouver auprès de particuliers.
Ils y en a un peu partout dans Montréal, notamment sur l’avenue Papineau, à partir de la rue Rachel et en remontant assez loin vers le nord ;&lt;/li&gt;
&lt;li&gt;les magasins de destockage, là c’est du neuf, mais même avec des rabais important, c’est un autre budget ;&lt;/li&gt;
&lt;li&gt;et enfin Ikea, du neuf de qualité moyenne pour un prix moyen. Le gros inconvénient et qu’il est loin de tout et qu’il faut une voiture pour y aller (surtout si vous compter revenir avec plein de trucs).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;un-peu-de-tourisme&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#un-peu-de-tourisme&quot; aria-label=&quot;Anchor link for: un-peu-de-tourisme&quot;&gt;Un peu de tourisme&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;J’ai commencé à avoir un peu plus de temps libre, ce qui m’a permis de visiter enfinla ville. J’ai commencé tout près de chez moi, par le jardin botanique et son insectarium. Le jardin botanique de Montréal est le plus grand du Canada et vraiment super bien aménagé, avec des jardins à thème et un très grand arboretum, je n’ai pas encore tout vu. Au printemps, ça doit vraiment valoir le coup !
Pour les photos, c’est &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://photos.univers-libre.net/JardinBotanique/&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Et une &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://photos.univers-libre.net/SaintJerome/&quot;&gt;petite balade autour de St-Jérôme&lt;/a&gt;, petite ville accessible en bus la plus loin au nord de Montréal, car j’avais envie de sortir enfin de l’île.&lt;/p&gt;
&lt;h2 id=&quot;les-trucs-marrants&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#les-trucs-marrants&quot; aria-label=&quot;Anchor link for: les-trucs-marrants&quot;&gt;Les trucs marrants&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;En vrac, quelques trucs amusants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;aucun commerce ne ferment entre midi et 2, et ça c’est vraiment bien, car outre le fait que c’est… ouvert, pas besoin de se rappeler pour chaque commerce de quelle heure à quelle heure il ferme. Il est ouvert de 9h à 18h la journée, point. Dans le même genre, tous les commerces sont ouverts le dimanche, et la plupart ferme bien plus tard le jeudi/vendredi, vers 21h en général.&lt;/li&gt;
&lt;li&gt;En automne, ce n’est pas la neige qui recouvre les routes, mais les feuilles mortes, car il y a des arbres vraiment partout. À tel point que les feuilles mortes se ramassent… au tractopèle ! Pas de photos pour illustrer, mais c’était assez marrant.&lt;/li&gt;
&lt;li&gt;J’aurai l’occasion d’en reparler, mais en France j’avais l’habitude de voir dans les supermarchés des amandes provenant de Californie. Ici, au Québec, elles proviennent d’Italie. Magnifique.&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Québec − septembre 2015 : paperasse et recherche de logement</title>
        <published>2015-10-05T21:04:01+00:00</published>
        <updated>2015-10-05T21:04:01+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/quebec-septembre-2015/"/>
        <id>https://univers-libre.net/posts/quebec-septembre-2015/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/quebec-septembre-2015/">&lt;p&gt;Après un mois passé au Québec, voici un petit article dans lequel je tiens
surtout à laisser de l’information utile/que j’aurai bien aimé savoir avant de
partir pour d’autres immigrants.&lt;/p&gt;
&lt;h2 id=&quot;passage-de-l-immigration-au-canada&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#passage-de-l-immigration-au-canada&quot; aria-label=&quot;Anchor link for: passage-de-l-immigration-au-canada&quot;&gt;Passage de l’immigration au Canada&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Petit contexte avant tout, je travaille au Canada dans le cadre du
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.civiweb.com/FR/le-volontariat-international/definition-du-vi.aspx&quot;&gt;V.I.E&lt;/a&gt;,
pour une durée de 2 ans (durée maximum possible). Ce qui nécessite donc entre
autre d’avoir déjà un contrat de travail conclu avec un employeur canadien.&lt;/p&gt;
&lt;p&gt;Le statut de V.I.E étant purement français, au Canada je suis donc là dans le
cadre d’&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.cic.gc.ca/francais/travailler/eic/index.asp&quot;&gt;EIC Jeunes
professionnels&lt;/a&gt;. La
procédure pour obtenir la lettre officielle (Lettre d’Introduction) de demande
de permis de travail est un peu longue et fastidieuse, mais assez simple car
très bien documentée sur le site de &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.cic.gc.ca/francais/index.asp&quot;&gt;Citoyenneté et Immigration
Canada&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Par contre, la liste des documents à avoir pour le passage de l’immigration à
l’aéroport est restée assez floue. J’ai fini par trouver dans la FAQ de CIC,
cette
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.cic.gc.ca/francais/centre-aide/reponse.asp?q=852&amp;amp;t=25&quot;&gt;liste&lt;/a&gt;, mais
ce n’étais pas très clair, notamment comment faire si on a pas de billet de
retour (à priori il faut prouver qu’on a suffisamment d’argent pour l’acheter
sur place, mais comment ?), et leur définition de la « preuve de fonds
disponibles » n’est pas très claire, d’ailleurs ils ne précisent pas le montant.&lt;/p&gt;
&lt;p&gt;Au service d’immigration, l’agent m’a finalement demandé uniquement la lettre
d’introduction (forcement) et la lettre de mon employeur confirmant le contrat
de travail, document absolument pas mentionné dans la liste mais que j’avais
imprimé et avec moi, (ainsi que d’autres) au cas où. Et j’ai pu avoir mon beau
permis de travail !&lt;/p&gt;
&lt;p&gt;Pour la preuve de fond, je ne saurai donc pas ce qu’il fallait…&lt;/p&gt;
&lt;h2 id=&quot;demarches-une-fois-arrive&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#demarches-une-fois-arrive&quot; aria-label=&quot;Anchor link for: demarches-une-fois-arrive&quot;&gt;Démarches une fois arrivé&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On retrouve assez facilement les démarches à faire une fois sur place un peu
partout sur le net, beaucoup moins la notion de dépendance entre elles. Du coup
pour éviter un casse-tête à expliquer son cas à chaque fois et de perdre trop
de temps et de sous, voici les démarches à faire, &lt;em&gt;dans l’ordre&lt;/em&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;commencez par apprendre votre code postal par cœur (ou pensez à le noter
quelque part), c’est une suite de 3 chiffres et 3 lettres immémorisable et
qui dépend de la rue dans laquelle vous résidez (et non de la ville comme
en France). Ce n’est utile que pour la poste, pas pour trouver une adresse
sur une carte/un GPS ;&lt;/li&gt;
&lt;li&gt;demande du NAS (Numéro d’Assurance Sociale, pas d’équivalent en France) dans
un bureau de Service Canada : c’est une affaire d’une dizaine de minutes,
sauf entre midi et 2 où vous n’avez généralement pas beaucoup de temps et où
tout le monde à la bonne idée de venir au même moment. Sinon ça ouvre tard
le matin et ferme tôt l’après-midi.&lt;br /&gt;
Il ne vous faut que votre passeport et votre permis de travail, et il
faudra donner votre adresse (même temporaire) à laquelle vous résidez ;&lt;/li&gt;
&lt;li&gt;ouvrez un compte en banque, de préférence dans une banque ayant des offres
pour les immigrants comme la TD ou Desjardins). Il vous faudra toujours
votre passeport et votre permis de travail, toujours donner votre adresse
de résidence (avec son horrible code postal), et votre NAS récemment reçu.&lt;br /&gt;
Si vous avez pensez à amener des euros en espèces de France, faites-les
changer et déposez-les sur votre compte canadien. Sinon, là commence les
ennuis : si vous comptiez faire un virement international depuis votre
compte français pour avoir de l’argent rapidement, grave erreur. Sauf à être
dans une banque implantée à la fois en France et au Canada, leurs procédures
pour les
virements hors zone SEPA impliquent de faire une demande via un formulaire
papier à leur renvoyer signé, puis le temps qu’il le prennent en compte,
vous appelle pour vérifier les info et envoi l’ordre de virement, ça peut
prendre une dizaine de jours. Si il y a une information incomplète, vous
repartez à la case départ pour 10 jours supplémentaires.&lt;br /&gt;
Bref, il vaut mieux prévoir d’arriver avec déjà de l’argent en espèces à
mettre sur votre compte canadien ;&lt;/li&gt;
&lt;li&gt;ensuite, dans le but de trouver un appartement, il vous faut un numéro de
téléphone canadien, déjà pour éviter de trop payer en hors-forfais avec
votre forfait français, et surtout si un proprio doit vous rappelez c’est
mieux de lui donnez un numéro local qu’un numéro étranger.&lt;br /&gt;
Ça va dépendre des opérateurs, mais juste une adresse et une carte de débit
canadienne (avec des sous sur le compte) suffit ;&lt;/li&gt;
&lt;li&gt;Montréal étant grand, pour être efficace et pouvoir enchainer les visites,
il vaut mieux avoir un moyen de transport plus rapide et moi contraignant
que ses pieds et les transports en commun. Le vélo est à mon avis la
meilleure solution, et puis ça vous permet de visiter par la même occasion
les quartiers. À Montréal il y a les BiXi (équivalent des Vélib), mais
personnellement j’ai dessuite acheté un vélo d’occasion, vu mon utilisation
pour la suite ;&lt;/li&gt;
&lt;li&gt;après ça, vous êtes normalement parez pour rechercher efficacement un appart.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dès que vous aurez votre adresse permanente, il restera des démarches moins
urgentes et facultatives, notamment l’inscription au registre des français
établis hors de France auprès du consulat, la demande de la carte Soleil auprès
de la RamQ  (équivalent de la carte Vitale) qui permet juste de ne pas avoir à
avancer des frais de santé et la souscription d’une assurance habitation (qui
n’est pas obligatoire ici).
Et bien sûr, un service vital, une connexion Internet suffisamment fiable et
neutre, mais j’y reviendrai probablement par la suite, car c’est moins évident
qu’en France.&lt;/p&gt;
&lt;p&gt;Comme vous vous en doutez, ce scénario idéal n’était pas mon cas. En fait, j’ai
à peu près fait les démarches dans le bon ordre, mais sans attendre des sous
sur mon compte canadien, donc je n’ai pas pu acheter dessuite de forfait
mobile, et je n’ai pas attendu non plus d’avoir de forfait mobile pour chercher
un appart, ce qui m’a fait une sacrée facture de hors forfait. Et quand j’ai
signé mon bail, je n’avais toujours pas de sous sur mon compte canadien pour
faire de chèque… Donc beaucoup de stress que j’aurai pu éviter.&lt;/p&gt;
&lt;h2 id=&quot;la-recherche-de-logement&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#la-recherche-de-logement&quot; aria-label=&quot;Anchor link for: la-recherche-de-logement&quot;&gt;La recherche de logement&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Montréal a les logements les plus cher de tout le Québec. Mais le Québec a les logements les moins cher de tout le Canada. Et dans toute l’Amérique du Nord, j’en sais rien :).&lt;br /&gt;
Comparativement à la France, ça reste bien moins cher que Paris et le sud-est
de la France, hormis certains quartiers comme le centre-ville, le Plateau, et
les quartiers riches résidentiels d’Outreront et Westmount.&lt;/p&gt;
&lt;p&gt;Rapidement, car l’info se trouve assez facilement ailleurs :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;les annonces de location se trouvent sur les sites comme
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.kijiji.ca/&quot;&gt;Kijiji&lt;/a&gt;,
&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://montreal.craigslist.ca/&quot;&gt;Craigslist&lt;/a&gt; et &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.lespac.com/&quot;&gt;Les
Pacs&lt;/a&gt; équivalent de leboncoin français. On peut aussi
en trouver sur d’autres sites, dans les journaux etc… mais rien qu’avec ces
3 là il y a de quoi faire ;&lt;/li&gt;
&lt;li&gt;le truc particulièrement sympa par rapport à la France, c’est que les
propriétaires n’hésitent pas à mettre l’adresse exacte du logement dans
l’annonce, ce qui permet d’avoir &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://montreal.craigslist.ca/search/apa&quot;&gt;les résultats sur un
carte&lt;/a&gt; (fond de carte OSM +
LeafletJS en plus !). Il manque plus que de pouvoir filtrer la recherche en
traçant des polygones sur la carte, avec un peu plus de Leaflet, PostgreSQL + PostGIS \o/ ;&lt;/li&gt;
&lt;li&gt;beaucoup de propriétaire demandent soit des références d’anciens
propriétaires soit un historique de crédit. En arrivant bien sûr on a rien
de tout ça, donc il faut passer son chemin… ;&lt;/li&gt;
&lt;li&gt;les québécois commence à compter à partir de 1, donc le rez-de-chaussé est
le premier étage, le premier le deuxième etc… Sauf qu’il y a beaucoup de
français immigrés qui continus à appeler le rez-de-chaussé le
rez-de-chaussé, le premier le premier etc… donc en clair il n’est pas
possible d’être sûr de l’étage de l’appartement tant que vous ne l’avez pas
vu. Et les appart en demi sous-sol sont plutôt des 3/4 sous-sol ;&lt;/li&gt;
&lt;li&gt;au niveau vocabulaire, le tapis est la moquette, le bois franc le parquet,
la céramique le carrelage, le poêle la cuisinière, la laveuse le
lave-linge…&lt;/li&gt;
&lt;li&gt;le propriétaire connait rarement la superficie de ce qu’il loue et préfère
parler en nombre de pièces.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;les-trucs-marrants&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#les-trucs-marrants&quot; aria-label=&quot;Anchor link for: les-trucs-marrants&quot;&gt;Les trucs marrants&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;En vrac, quelques trucs amusants et particulièrements différents de la France :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;l’état semble plus laïque que la France : à
l’aéroport, une femme employée au service d’immigration
portait un voile (assortie à son uniforme d’ailleurs) ;&lt;/li&gt;
&lt;li&gt;parfois c’est difficile de se croire à l’étranger : beaucoup de produits
alimentaires (notamment les huiles, du sel, des conserves préparées,
confitures…) viennent de France, sans compter des marques classiques de
France qu’on retrouve ici aussi, puis les nombreuses rue aux noms de villes
française (rue de Marseille, de Bordeaux, avenue d’Orléans…, rue Mistral,
Charlemagne…), les nombreux vélos Peugeot…&lt;/li&gt;
&lt;li&gt;il y a globalement beaucoup de vélos dans Montréal, il y en a même
tellement dans certains quartiers qu’il y a parfois des bouchons sur les
pistes cyclables !&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to enlarge your raw disk image</title>
        <published>2015-09-10T17:04:19+00:00</published>
        <updated>2015-09-10T17:04:19+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/extend-disk-image/"/>
        <id>https://univers-libre.net/posts/extend-disk-image/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/extend-disk-image/">&lt;p&gt;Extending a disk image file (of a KVM guest for example) is a tricky operation,
especially if we haven’t enough disk space to keep a backup of the image we
will working on. So I write a little howto for the next time we have to do this
operation.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#prerequisites&quot; aria-label=&quot;Anchor link for: prerequisites&quot;&gt;Prerequisites&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;First, you need to have the following packages installed: &lt;code&gt;qemu-utils kpartx parted&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Make sure your VM is halted and no processes have opened the file:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# lsof $img&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note: for following commands, I assume &lt;code&gt;$img&lt;/code&gt; contains the path to your image file.&lt;/p&gt;
&lt;h2 id=&quot;extend-the-image-file&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#extend-the-image-file&quot; aria-label=&quot;Anchor link for: extend-the-image-file&quot;&gt;Extend the image file&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Pretty easy step, you can simply use qemu-img tool:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# qemu-img resize $img +50G&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Image resized.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can mount the image and check that it has the correct size:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# kpartx -v -a $img&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;add map loop0p1 (254:13): 0 195318207 linear /dev/loop0 63&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# fdisk -l /dev/loop0 &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Disk /dev/loop0: 214.7 GB, 214748364800 bytes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[...]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;extend-the-partition&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#extend-the-partition&quot; aria-label=&quot;Anchor link for: extend-the-partition&quot;&gt;Extend the partition&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Then, you have to extend the partition. That supposes of course either the disk
image contains only one partition (which could be a LVM PV) or the partition
you want to extend is at the end of the image.&lt;/p&gt;
&lt;p&gt;Before all, backup your partition table:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# sfdisk -d /dev/loop0 &amp;gt;~/loop0.parts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(It could be restored with &lt;code&gt;sfdisk /dev/loop0 &amp;lt;~/loop0.parts&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;And remove and recreate the partition using all free space with parted:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# parted /dev/loop0 print&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Model:  (file)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Disk /dev/loop0: 215GB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sector size (logical/physical): 512B/512B&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Partition Table: msdos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Number  Start   End    Size   Type     File system  Flags&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; 1      32.3kB  100GB  100GB  primary  ext3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;..&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# parted /dev/loop0 rm 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# parted /dev/loop0 mkpart primary ext3 32.3kB 215GB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# parted /dev/loop0 print&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remount the image to see her new size:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# kpartx -d $img&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loop deleted : /dev/loop0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# kpartx -v -a $img&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;add map loop0p1 (254:13): 0 419430337 linear /dev/loop0 63&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&quot;extend-the-filesystem&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#extend-the-filesystem&quot; aria-label=&quot;Anchor link for: extend-the-filesystem&quot;&gt;Extend the filesystem&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We are almost there, remaining the filesystem. First, this is a good thing to
run a fsck before all:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# e2fsck -f /dev/mapper/loop0p1 &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;e2fsck 1.42.5 (29-Jul-2012)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;/dev/mapper/loop0p1: recovering journal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Pass 1: Checking inodes, blocks, and sizes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Pass 2: Checking directory structure&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Pass 3: Checking directory connectivity&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Pass 4: Checking reference counts&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Pass 5: Checking group summary information&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;/dev/mapper/loop0p1: 41753/6111232 files (9.1% non-contiguous), 23479003/24414775 blocks&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, resize the filesystem:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# resize2fs /dev/mapper/loop0p1 &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;resize2fs 1.42.5 (29-Jul-2012)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Resizing the filesystem on /dev/mapper/loop0p1 to 52428792 (4k) blocks.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;The filesystem on /dev/mapper/loop0p1 is now 52428792 blocks long.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s done!
We can check if we see the correct size after mounting the partition:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mount /dev/mapper/loop0p1 /mnt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# df -h /mnt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filesystem           Size  Used Avail Use% Mounted on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;/dev/mapper/loop0p1  197G   89G  109G  45% /mnt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# umount /mnt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, unmount the image:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# kpartx -d $img&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;loop deleted : /dev/loop0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Départ pour le Québec</title>
        <published>2015-09-01T19:36:08+00:00</published>
        <updated>2015-09-01T19:36:08+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/depart-quebec/"/>
        <id>https://univers-libre.net/posts/depart-quebec/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/depart-quebec/">&lt;p&gt;Dans quelques jours, j’aurai mes pieds au Canada pour 2 ans au moins,
probablement plus. Avec toute ma vie que j’ai réussi à faire tenir dans 3 sacs.&lt;/p&gt;
&lt;p&gt;C’est le résultat d’un très dur choix que j’avais eu à faire en début d’année :
depuis 1 an, je préparais une grande rando/voyage à l’étranger (je n’avais
jusqu’alors jamais mis les pieds hors de France métropolitaine) au départ de
France pour remonter jusqu’en Norvège en train/ferry/stop… et de là, avancer
jusqu’au Cap Nord en marchant à travers les fjords, les Alpes scandinaves, et
la Laponie. Le but était vraiment de prendre mon temps et de profiter. Je
pensais partir pour 2 ou 3 mois, et ça impliquait beaucoup de choses, notamment
de quitter mon emploi à Evolix, et de me débarrasser de la plupart de ce que je
possédais.&lt;/p&gt;
&lt;p&gt;Mais alors que j’ai donné ma démission, j’ai eu une proposition qui a tout
remis en cause : partir ouvrir une filiale d’Evolix au Canada, à Montréal.
Alors que ma préparation pour mon projet initial avançait, que je m’étais
préparé psychologiquement à ce départ, le choix a été très dur, mais j’ai
finalement accepter de remettre mon projet dans un coin et de saisir cette
opportunité. C’était une opportunité qui ne se représenterait peut-être jamais,
quant à mon projet, je le garde bien au chaud dans un coin, avec tous mes
autres rêves à réaliser.&lt;/p&gt;
&lt;p&gt;Parmi tout ce que j’ai eu à faire dans les préparatifs, une chose a été bien
plus compliquée que ce que je pensais : faire tenir tout ce dont j’aurai besoin
dans quelques sac, sachant que je ne sais même pas pour combien de temps je
pars (2 ans au minimum, mais peut-être 5, vois plus…).
Je pensais que je ferai ça assez facilement car je suis relativement peu
attaché à des biens matériels en général, et j’achète très rarement des trucs (quand je
regarde mes connaissances autour de moi qui amassent des quantités faramineuses
de fatras chez eux dont ils ne se sont probablement jamais servi pour la
plupart, ou qu’ils commandent sans cesse un tas de gadgets dont j’ai du mal à
comprendre l’intérêt parfois, ça m’impressionne toujours…).  Mais le peu que je
possède, ce sont des trucs qui me servent plus ou moins régulièrement, et en
tout cas qui me manqueront forcement sur une période aussi grande.&lt;/p&gt;
&lt;p&gt;À l’inverse, je pensais que vendre dans les temps tout ce que je n’emporterai
pas serait un peu utopique (du moins j’avais peur de me retrouver avec des
meubles invendus dont je n’aurais su que faire), mais non, la demande est en
fait très forte en ce qui concerne l’ameublement et l’électroménager. Bon faut
pas espérer en tirer grand chose par contre, mais on ne peut pas tout avoir…&lt;/p&gt;
&lt;p&gt;À l’heure actuelle, je n’ai plus qu’une seule clé à mon trousseau, celle du
bureau, et ça fait vraiment bizarre ! Je n’ai plus ma petite zone de confort
qu’était mon appart, c’est assez excitant et stimulant.&lt;br /&gt;
J’ai arrêté la vie que je commençais à trouver bien trop monotone, le fameux
boulot-métro^Wvélo-dodo, et je re-vie enfin ! (c’est un peu ce que je
recherchais à l’origine en voulant partir en Norvège).&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Play a Vim macro on all opened buffers</title>
        <published>2015-05-28T19:16:40+00:00</published>
        <updated>2015-05-28T19:16:40+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/vim-play-macro-on-all-buffers/"/>
        <id>https://univers-libre.net/posts/vim-play-macro-on-all-buffers/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/vim-play-macro-on-all-buffers/">&lt;p&gt;Here is a small useful tip, which I use in my daily sysadmin work, when I have a
lot of similar configuration files to alter, but my modification is to
complex to be scripted with sed/awk.&lt;/p&gt;
&lt;p&gt;The perfect example is Apache’s vhost configurations in site-enabled/.&lt;/p&gt;
&lt;p&gt;Open all files in Vim and start recording your macro (with &lt;code&gt;q&lt;/code&gt;) on the first buffer.&lt;br /&gt;
Until now I opened the next buffer, replay my macro, then opened the next buffer, replay my macro again, etc…&lt;br /&gt;
Pretty boring.&lt;/p&gt;
&lt;p&gt;But I discovered recently that you can execute a command on all opened
buffers, and particularly a macro. Here is the magic line:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;:bufdo execute &amp;quot;normal @a&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace &lt;em&gt;a&lt;/em&gt; with the name of your macro of course, and don’t miss to &lt;code&gt;:write&lt;/code&gt;
at the end of your macro (or add a &lt;code&gt;| write&lt;/code&gt; at the end of the command).&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Get verbose output from an already launched cp/mv/rsync process</title>
        <published>2015-05-27T19:26:18+00:00</published>
        <updated>2015-05-27T19:26:18+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/get-verbose-output-with-strace/"/>
        <id>https://univers-libre.net/posts/get-verbose-output-with-strace/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/get-verbose-output-with-strace/">&lt;p&gt;This could be a bit obvious for others sysadmins, but I use this trick quite
often and it’s really helpfull.&lt;/p&gt;
&lt;p&gt;Imagine you connect on a server and see a running process (a cronjob for example) doing some
file copy operations, running for a while and launched without -v option (or
you can’t see his stdout).&lt;/p&gt;
&lt;p&gt;Or imagine you launched a big cp/mv (from a partition to another)/rsync or whatever, you know it will probably run for a while, but you missed to add the -v
option.&lt;/p&gt;
&lt;p&gt;No problem, here is how we could get an equivalent with strace:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;strace -p $(pidof cp) 2&amp;gt;&amp;amp;1 |grep open&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or for a rm:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;strace -p $(pidof rm) 2&amp;gt;&amp;amp;1 |grep unlink&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want just to see the current file your command is currently on:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lsof -p $(pidof cp)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Ghostscript − Concatenate pages with different orientations</title>
        <published>2014-08-10T08:35:15+00:00</published>
        <updated>2014-08-10T08:35:15+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/ghostscript-concatenate-page-with-different-orientations/"/>
        <id>https://univers-libre.net/posts/ghostscript-concatenate-page-with-different-orientations/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/ghostscript-concatenate-page-with-different-orientations/">&lt;p&gt;Concatenate multiple PDF documents while preserving orientation (portrait/landscape) of each page:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dAutoRotatePages=/PageByPage -sOutputFile=concatenated.pdf $(ls -v doc*.pdf)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Reverse proxy avec re-chiffrement du flux vers le backend</title>
        <published>2014-07-11T20:50:27+00:00</published>
        <updated>2014-07-11T20:50:27+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/reverse-proxy-https/"/>
        <id>https://univers-libre.net/posts/reverse-proxy-https/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/reverse-proxy-https/">&lt;p&gt;Dans un environnement web critique/à fort trafic, il est courant d’avoir de
multiples serveurs web, et un ou deux load-balancer devant permettant
de répartir la charge et d’avoir une tolérance de panne sur les serveurs web.&lt;br /&gt;
Dans le cas d’un site en HTTPS, le flux est en général déchiffré par les
load-balancer, puis transite en clair vers les frontaux. Cela permet de
décharger les frontaux du traitement cryptographique et au load-balancer
d’interpréter le HTTP, donc d’avoir certaines fonctionnalités intéressantes
(répartition du trafic en fonction du virtualhost ou de l’URL, gestion des
cookies de session, interprétation des codes d’erreurs HTTP renvoyés par les
frontaux pour anticiper un problème, etc…).&lt;br /&gt;
Cependant le fait que le flux HTTP transite en clair entre les load-balancers et les frontaux peut poser problème dans certains cas :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;les données qui y transitent nécessitent un haut degré de confidentialité (numéros de cartes bancaires par exemple) ;&lt;/li&gt;
&lt;li&gt;le réseau entre le load-balancer et les frontaux n’est pas sûr (le flux repasse sur Internet par exemple).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dans ces cas, la solution est de re-chiffrer le trafic après traitement par le
load-balancer, puis chaque frontal le déchiffre à nouveau. Il faut bien noter
que cette charge supplémentaire en traitement cryptographique (déchiffrement,
re-chiffrement, re-déchiffrement), n’est pas anodine et la quantité de requêtes
par seconde que peut encaisser la plateforme sera bien moindre que dans le cas
d’un simple déchiffrement du flux par le load-balancer.&lt;/p&gt;
&lt;p&gt;Pour en venir au cœur de l’article, j’ai dû mettre en place récemment une
architecture de ce type, et j’ai été confronté à un problème dont je ne
m’attendais pas vraiment : peu de reverse proxies HTTP savent re-chiffrer le
flux HTTP vers les backends !&lt;/p&gt;
&lt;p&gt;Parmi les logiciels existants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HAProxy : dans sa version stable actuelle (1.4), il ne sait pas déchiffrer
le trafic entrant, et donc encore moins re-chiffer derrière. Sa version
encore en dév (1.5) supporte le déchiffrement du HTTPS néanmoins ;&lt;/li&gt;
&lt;li&gt;Nginx : il sait bien sûr déchiffrer le HTTPS mais pas le re-chiffrer vers
les backends ensuite ;&lt;/li&gt;
&lt;li&gt;Pound : pareil que Nginx, ne sais que déchiffrer ;&lt;/li&gt;
&lt;li&gt;Apache : le seul après recherche à savoir faire les 2 !&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Voici la conf (en somme très simple) d’Apache pour lui dire de re-chiffrer le
flux vers les backends. Elle nécessite bien évidemment d’avoir mod_proxy_http
et mod_ssl :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;VirtualHost *:443&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # Activation de SSL pour le trafic entrant, cas dans le cas d&amp;#39;un&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # serveur web classique.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SSLEngine On&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SSLCertificateFile    /etc/ssl/certs/example.com.crt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SSLCACertificateFile  /etc/ssl/certs/example.com-intermediate.crt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SSLCertificateKeyFile /etc/ssl/private/example.com.key&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # Activation de SSL pour la communication avec les backends.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # On vérifie au passage que le certificat fourni par le backend est&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # bien valide.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SSLProxyEngine          On&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SSLProxyCheckPeerExpire On&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    SSLProxyVerifyDepth     10&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # Configuration classique du mod_proxy, mis à part qu&amp;#39;on spécifie bien&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # https dans l&amp;#39;URL du backend.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ProxyRequests     Off&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ProxyPreserveHost On&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ProxyPass         / https://192.0.2.42:443/ keepalive=On retry=5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ProxyPassReverse  / https://192.0.2.42:443/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ErrorLog  /var/log/apache2/example.com_error.log&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    CustomLog /var/log/apache2/example.com_access.log combined&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Ajout d&#39;une carte son à chaud dans un conteneur LXC</title>
        <published>2014-01-21T21:02:08+00:00</published>
        <updated>2014-01-21T21:02:08+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/lxc-ajout-carte-audio/"/>
        <id>https://univers-libre.net/posts/lxc-ajout-carte-audio/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/lxc-ajout-carte-audio/">&lt;p&gt;Voici un article express pour rajouter une carte son dans un conteneur LXC,
plus un aide-mémoire en fait, car c’est pas le genre de chose que je fais tous
les 4 matins.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Brancher la carte son à la machine hôte. Dans mon cas une carte USB, si
c’est en PCI, la procédure n’a que peu d’intérêt puisqu’il faudra dans tout
les cas redémarrer.&lt;/li&gt;
&lt;li&gt;le kernel doit la détecter et créer des fichiers spéciaux de type caractère
dans &lt;code&gt;/dev/snd&lt;/code&gt; :&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;```&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# ls -l /dev/snd/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 2 root root       60 Jan 21 19:44 by-id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr-xr-x 2 root root       60 Jan 21 19:44 by-path&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crw-rw---T 1 root audio 116,  4 Jan 21 19:44 controlC0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crw-rw---T 1 root audio 116,  3 Jan 21 19:44 pcmC0D0c&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crw-rw---T 1 root audio 116,  2 Jan 21 19:44 pcmC0D0p&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crw------T 1 root root  116,  1 Dec 17 09:24 seq&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;crw-rw---T 1 root audio 116, 33 Dec 17 09:24 timer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;```&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Notez le numéro majeur et mineur de chaque pseudo fichier (dans mon cas 116&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;et de 1 à 4 et 33).&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Ajoutez les autorisations nécessaires dans votre conf LXC pour le conteneur
en question :&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;```&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# /dev/snd/*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lxc.cgroup.devices.allow                = c 116:4 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lxc.cgroup.devices.allow                = c 116:3 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lxc.cgroup.devices.allow                = c 116:2 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lxc.cgroup.devices.allow                = c 116:1 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;lxc.cgroup.devices.allow                = c 116:33 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;```&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Adaptez bien sûr avec les bons numéro majeurs et mineurs.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;À ce stade, il faut redémarrer le conteneur pour que les nouveaux cgroups
s’appliquent. Comme j’avais pas envie de faire ça et que les cgroups
cesttropbien, On va appliquer les nouvelles règles à chaud via son pseudo
système de fichier :&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;```&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# cat &amp;gt;/sys/fs/cgroup/lxc/&amp;lt;nom du conteneur&amp;gt;/devices.allow&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c 116:4 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c 116:3 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c 116:2 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c 116:1 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;c 116:33 rwm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;^D&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;```&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;
&lt;p&gt;Maintenant, on peut créer manuellement les pseudo fichiers dans le conteneur :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mkdir /dev/snd; cd /dev/snd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mknod controlC0 c 116 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mknod pcmC0D0c c 116 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mknod pcmC0D0p c 116 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mknod seq c 116 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# mknod timer c 116 33&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# chgrp audio controlC0 pcm* timer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# chmod 1660 controlC0 pcm* timer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# chmod 600 seq&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Et ajoutez vous dans le groupe audio si besoin.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;
&lt;p&gt;Installer alsa-utils puis :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ alsactl init&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Votre carte devrait à présent être détectée, vous pouvez vérifier que tout&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fonctionne avec un `speaker-test`.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et voila.&lt;/p&gt;
&lt;p&gt;Bon c’est pas tout ça, allons mettre à jour le kernel et rebooter :-).&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Changer simplement la couleur du curseur dans rxvt</title>
        <published>2013-11-01T17:53:37+00:00</published>
        <updated>2013-11-01T17:53:37+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/rxvt-couleur-curseur/"/>
        <id>https://univers-libre.net/posts/rxvt-couleur-curseur/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/rxvt-couleur-curseur/">&lt;p&gt;Où comment identifier facilement le serveur de prod de celui de preprod (ou le
master du slave, ou celui de prod et son futur remplaçant…).&lt;br /&gt;
Bref, comment différencier facilement votre terminal avec une connexion SSH sur
un serveur critique, et celui vers un serveur où vous pouvez tout
casser^W^W^W^W^W moins critique.&lt;br /&gt;
C’est surtout valable quand les hostnames ne diffèrent que d’une lettre ou d’un
chiffre, où la confusion est plus facile.&lt;/p&gt;
&lt;p&gt;Si il s’agit d’un serveur perso, le plus simple reste de modifier le prompt de
votre shell. Mais ce n’est pas envisageable sur un serveur sur lequel vous vous
contentez d’intervenir, ou où plusieurs admin sont susceptibles d’utiliser le
compte root.&lt;/p&gt;
&lt;p&gt;La solution est d’agir au niveau de votre terminal, ici urxvt. Les options de
rxvt peuvent être quasiment toutes changées à chaud grâce à des commandes envoyées
dans des séquences d’échappement du shell. Par exemple, pour avoir un curseur
rouge, la commande à envoyer est &lt;code&gt;\033]12;red\007&lt;/code&gt;. Vous pouvez tester avec un
simple &lt;code&gt;echo&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ echo &amp;#39;\033]12;red\007&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;C’est magique, mais ça reste compliquer à écrire, et encore plus à retenir. On
va donc affecter la commande à une séquence de touche, par exemple Alt+!
(et Alt+Shift+!). Dans votre &lt;code&gt;.Xdefaults&lt;/code&gt;/&lt;code&gt;.Xressources&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;URxvt.keysym.M-S-exclam: command:\033]12;red\007&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;URxvt.keysym.M-exclam: command:\033]12;#657b83\007  # #657b83 à remplacer par la couleur de votre police par défaut.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;À noter qu’ainsi, même en étant dans un éditeur de texte, vous identifierez
rapidement le serveur de prod car le curseur restera rouge, ce qui n’est pas le
cas avec un prompt coloré.&lt;/p&gt;
&lt;p&gt;L’inconvénient est que le changement de couleur du curseur n’est pas
automatique, même si il est bien simplifié. Si vous avez une liste précise de
serveurs en prod, une idée peut être, à l’aide d’une extension Perl à rxvt, de
comparer le titre de la fenêtre X11 (qui contient le hostname du serveur) à
cette liste, pour pouvoir changer la couleur du curseur en conséquence.&lt;/p&gt;
&lt;p&gt;Référence :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://web.archive.org/web/20171111070243/http://artisan.karma-lab.net/urxvt-et-styles-curseur/&quot;&gt;Article de Ulhume&lt;/a&gt;
très intéressant et plus complet à propos des styles de curseur, avec une
utilisation différente.&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Limiter le nombre de connexions SSH avec pf</title>
        <published>2013-09-05T22:19:19+00:00</published>
        <updated>2013-09-05T22:19:19+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/pf-ratelimit/"/>
        <id>https://univers-libre.net/posts/pf-ratelimit/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/pf-ratelimit/">&lt;p&gt;Le port SSH doit probablement être parmi les plus testés par les scripts kiddies. Même si le
mieux reste de restreindre l’accès par IP et de n’autoriser l’authentification que
par clé, ce n’est des fois pas possible. Dans ce cas, on se retrouve avec une
avalanche de tentative de connexion et le auth.log qui explose en taille.
Ça devient lourd (dans les 2 sens du terme :-) ).&lt;/p&gt;
&lt;p&gt;Afin de bannir une IP au bout d’un trop grand nombre de connexions par unité de
temps, il existe différents outils qui analysent les logs et ajoutent des
règles dynamiquement comme &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.fail2ban.org/&quot;&gt;fail2ban&lt;/a&gt;, mais je préfère agir directement au niveau
pare-feu quand c’est possible. Avec iptables sous Linux, il existe le module
limit. Avec Packet Filter, voici comment procéder :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Créer une table, qui contiendra les IP bannies :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;table &amp;lt;badguys&amp;gt; persist&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;on drope donc tous ce qui provient des IP présentes dans la table :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;block in quick on $wan_if from &amp;lt;badguys&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;et enfin la règle intéressante :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pass in on $wan_if proto tcp to self port ssh flags S/SA keep state (max-src-conn 3, max-src-conn-rate 5/30, overload &amp;lt;badguys&amp;gt; flush global)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La règle permet de limiter l’établissement d’une connexion sur le port SSH à
3 connexion simultanée (&lt;code&gt;max-src-conn 3&lt;/code&gt;) et avec une limite de 5 connexion
par tranche de 30 secondes (&lt;code&gt;max-src-conn-rate 5/30&lt;/code&gt;). Si une IP dépasse
cette limite, elle est ajoutée à la table badguys (&lt;code&gt;overload &amp;lt;badguys&amp;gt;&lt;/code&gt;) et
tous les états que l’IP aurait déjà pu avoir sont supprimés (&lt;code&gt;flush global&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ensuite, on peut faire expirer les IP présentes dans la table avec un simple cron :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;33 3 * * *  /sbin/pfctl -t badguys -T expire 86400 2&amp;gt;&amp;amp;1 |grep -v &amp;quot;0/0 addresses expired.&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Archlinux dans un conteneur LXC et paquet filesystem</title>
        <published>2013-06-03T21:04:00+00:00</published>
        <updated>2013-06-03T21:04:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/archlinux-lxc-filesystem/"/>
        <id>https://univers-libre.net/posts/archlinux-lxc-filesystem/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/archlinux-lxc-filesystem/">&lt;p&gt;Parmis mes conteneurs LXC, il y en a un qui tourne sous Archlinux. Comme
j’avais un peu joué avec les &lt;code&gt;capabilities (7)&lt;/code&gt; du noyau, qu’on peut retirer
avec &lt;code&gt;lxc.cap.drop&lt;/code&gt; dans le fichier de conf du conteneur, mon &lt;em&gt;/sys/&lt;/em&gt; (entre
autre) est en lecture seule pour le système chrooté.&lt;br /&gt;
Par jouer il faut comprendre rajouter des &lt;code&gt;lxc.cap.drop&lt;/code&gt; sur des &lt;code&gt;capabilities&lt;/code&gt;
choisies au feeling, jusqu’à ce que ça ne marche plus. J’exagère mais c’était
un peu ça l’idée au final :-).&lt;/p&gt;
&lt;p&gt;Donc, comme mon &lt;em&gt;/sys/&lt;/em&gt; est en lecture seule, la mise à jour du paquet
&lt;em&gt;filesystem&lt;/em&gt; chie lamentablement dans la colle :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error: cannot remove file &amp;#39;/sys/&amp;#39;: Read-only file system&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error: could not commit transaction&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;error: failed to commit transaction (transaction aborted)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Par flème, lorsque une mise à jour du paquet était disponible, je l’excluais
manuellement avec :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# pacman --ignore filesystem -Syu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Puis vint le jour où la mise à jour d’un paquet demandait une version à jour du
paquet filesystem. Forcement, ça devait arriver un jour…&lt;/p&gt;
&lt;p&gt;Et c’est là qu’en cherchant un peu, j’ai découvert que dans la configuration de
&lt;code&gt;pacman&lt;/code&gt;, on peut lui dire d’empêcher un paquet de toucher à un fichier. Ça se
rapproche un peu du &lt;code&gt;dpkg-divert&lt;/code&gt; de Debian.&lt;/p&gt;
&lt;p&gt;Dans &lt;em&gt;/etc/pacman.conf&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NoUpgrade    = sys/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;NoExtract    = sys/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;le répertoire &lt;em&gt;/sys/&lt;/em&gt; sera ignoré, et la mise à jour de &lt;em&gt;filesystem&lt;/em&gt; se fait
sans soucis !&lt;/p&gt;
&lt;p&gt;Pour plus de détails, voir &lt;code&gt;pacman.conf(5)&lt;/code&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Viande séchée maison</title>
        <published>2013-05-20T15:18:45+00:00</published>
        <updated>2013-05-20T15:18:45+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/viande-sechee/"/>
        <id>https://univers-libre.net/posts/viande-sechee/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/viande-sechee/">&lt;p&gt;La charcuterie c’est bon ! Le problème c’est que, à part les produits
artisanaux (et encore), il y a toujours en prime un tas de cochonneries
ajoutées avec.&lt;br /&gt;
Je me suis donc lancé dans la fabrication de ma propre viande séchée. C’est
relativement simple, plus marrant que de l’acheter à la supérette du coin, et
très probablement moins cher au kilo.&lt;/p&gt;
&lt;p&gt;Au niveau des ingrédients, il faut :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;une belle pièce de viande de bœuf maigre de 1kg à peu près ;&lt;/li&gt;
&lt;li&gt;1kg de gros sel, voir plus ;&lt;/li&gt;
&lt;li&gt;des herbes et épices selon vos gouts et votre imagination (thym, poivre
concassé, cumin, clous de girofle, voir piment, ail…).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Plus beaucoup de patience (environ 1 à 2 mois) et ne pas avoir de gerçures aux
mains (nécessaire juste pour la première étape).&lt;/p&gt;
&lt;h2 id=&quot;premiere-etape-salage-de-la-viande&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#premiere-etape-salage-de-la-viande&quot; aria-label=&quot;Anchor link for: premiere-etape-salage-de-la-viande&quot;&gt;Première étape : salage de la viande&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Le but du salage est d’accélérer le séchage de la viande. Au fil des jours,
elle va rendre une bonne partie de son eau et se racrapoter sur elle même en
durcissant.&lt;/p&gt;
&lt;p&gt;Prenez la pièce de viande, une poignée de gros sel, et frotter la bien avec sur
chacun des coté. La viande ne doit plus sembler humide.&lt;br /&gt;
Une fois ceci fait (et après avoir, au passage, foutu du sel dans toute la
cuisine), prenez un plat/tupperware/ce-que-vous-avez d’assez grand pour mettre
la pièce de bœuf, déposer un fond de gros sel, la pièce de bœuf dessus, et la
recouvrir entièrement de gros sel.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/viande-sechee/image2_big.jpeg&quot;&gt;&lt;img src=&quot;/posts/viande-sechee/image2_thumb.jpeg&quot; alt=&quot;Salage de la viande&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/posts/viande-sechee/image3_big.jpeg&quot;&gt;&lt;img src=&quot;/posts/viande-sechee/image3_thumb.jpeg&quot; alt=&quot;Pièce de bœuf recouverte de gros sel&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Vous pouvez à présent l’oublier 5 jours au réfrigérateur (un peu plus ou un peu
moins en fonction du poids et de l’épaisseur de la viande).&lt;/p&gt;
&lt;h2 id=&quot;deuxieme-etape-dessalage&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#deuxieme-etape-dessalage&quot; aria-label=&quot;Anchor link for: deuxieme-etape-dessalage&quot;&gt;Deuxième étape : dessalage&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Passé les cinq jours, votre viande baigne dans un mélange d’eau à la couleur
douteuse et de gros sel, pas appétissant du tout. Mais c’est normal.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/viande-sechee/image4_big.jpeg&quot;&gt;&lt;img src=&quot;/posts/viande-sechee/image4_thumb.jpeg&quot; alt=&quot;Viande dans la saumure, 5 jours après&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/posts/viande-sechee/image5_big.jpeg&quot;&gt;&lt;img src=&quot;/posts/viande-sechee/image5_thumb.jpeg&quot; alt=&quot;Dessalage de la viande&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sortez la et frottez la bien sous l’eau claire pour faire partir tout le sel.
Remplissez ensuite un gros récipient dans lequel vous mettrez le morceau de
viande à tremper, pendant 12h environ.&lt;br /&gt;
Pensez à changer l’eau 2 ou 3 fois, d’abord assez souvent, toutes les 2 ou 3h,
puis moins fréquemment ensuite.&lt;/p&gt;
&lt;h2 id=&quot;troisieme-etape-sechage-et-epicage&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#troisieme-etape-sechage-et-epicage&quot; aria-label=&quot;Anchor link for: troisieme-etape-sechage-et-epicage&quot;&gt;Troisième étape : séchage et épiçage&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sortez la pièce de viande du bain et séchez la bien avec des feuilles de papier
absorbant. Ne pas hésiter à la presser pour faire partir l’eau, puis laissez la
à l’air libre quelques temps.&lt;/p&gt;
&lt;p&gt;Pendant ce temps, partez à la recherche d’un torchon propre et sans odeurs (de
lessive notamment) de préférence (faites le sécher au grand air par exemple).&lt;/p&gt;
&lt;p&gt;Déposer la viande sur le torchon, rassemblez les épices et herbes que vous
voulez, et frottez la viande avec, comme pour le sel lors de la première étape.
D’abord avec les épices, puis les herbes, et plantez éventuellement quelques
clous de girofle dans le morceau.&lt;/p&gt;
&lt;p&gt;Vous pouvez à présent l’emballer dans le tissu et la ligoter avec de la ficelle
en serrant bien, comme un rôti. Le but est de comprimer le torchon contre la
viande pour qu’il absorbe l’humidité.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/viande-sechee/image6_big.jpeg&quot;&gt;&lt;img src=&quot;/posts/viande-sechee/image6_thumb.jpeg&quot; alt=&quot;Ajout des épices&quot; /&gt;&lt;/a&gt;
&lt;a href=&quot;/posts/viande-sechee/image7_big.jpeg&quot;&gt;&lt;img src=&quot;/posts/viande-sechee/image7_thumb.jpeg&quot; alt=&quot;Empaquetage de la viande&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;C’est terminé, vous pouvez aller l’abandonner au moins 1 mois, soit suspendu dans
un endroit frai, genre une cave si vous avez la chance d’en avoir une, soit au
réfrigérateur, posé sur une grille (pour qu’elle puisse respirer par le
dessous).&lt;/p&gt;
&lt;p&gt;Sortez la de temps en temps pour la pressez, voir ouvrez le paquet et refermez
le d’une autre façon pour répartir l’humidité et les épices.&lt;/p&gt;
&lt;h2 id=&quot;quatrieme-etape-mangeage-degustation&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#quatrieme-etape-mangeage-degustation&quot; aria-label=&quot;Anchor link for: quatrieme-etape-mangeage-degustation&quot;&gt;Quatrième étape : &lt;del&gt;mangeage&lt;/del&gt; dégustation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Au bout d’un mois, la viande commence a être assez sèche pour être mangée, mais
reste assez molle. Vous pouvez attendre quelques semaines de plus, pour l’avoir
plus ferme.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/viande-sechee/image8_big.jpeg&quot;&gt;&lt;img src=&quot;/posts/viande-sechee/image8_thumb.jpeg&quot; alt=&quot;Résultat final&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pour la déguster, coupez des tranches les plus fines possible (1 mm maximum).&lt;/p&gt;
&lt;p&gt;Vu qu’il n’y a pas de conservateurs, la viande va continuer de sécher. Si vous
voulez la conserver sur plusieurs mois, le mieux est de la congeler ou la
mettre dans un sac sous vide, si vous avez les moyens de le faire.&lt;/p&gt;
&lt;p&gt;Pour conclure, je suis très satisfait de mon premier essai, sauf pour les
épices ; hormis en surface, la viande n’en a pas vraiment pris le goût et
l’odeur. Je ne vois pas vraiment de solution mise à part en mettre une plus
grande quantité la prochaine fois. Pour la v2, je vais d’ailleurs tenter le
dessalage dans du rouge, ou de l’eau de vie style cognac, calva… Ça ne devrait
être que meilleur :-).&lt;/p&gt;
&lt;p&gt;Je me suis inspiré pas mal de &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://web.archive.org/web/20180620112905/http://www.rhaaa.fr/faire-sa-viande-des-grisons&quot;&gt;l’article de
Rhaaa&lt;/a&gt;, avec quelques
modifications, notamment un salage un peu plus court, et l’ajout des épices
après le dessalage, pour ne pas les perdre dans l’eau.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Tracer un processus sur un système BSD</title>
        <published>2013-05-09T21:01:04+00:00</published>
        <updated>2013-05-09T21:01:04+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/ktrace/"/>
        <id>https://univers-libre.net/posts/ktrace/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/ktrace/">&lt;p&gt;Récemment sur un système OpenBSD, j’ai voulu suivre les appel système que
faisait un process :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# strace isakmpd -vd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ksh: strace: not found&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# pkg_add strace&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Can&amp;#39;t find strace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;OMG, comment faire ?!&lt;/p&gt;
&lt;p&gt;En fait, &lt;code&gt;strace&lt;/code&gt; est spécifique à Linux, et un équivalent existe sur les
systèmes BSD. Il s’agit du couple &lt;code&gt;ktrace&lt;/code&gt;/&lt;code&gt;kdump&lt;/code&gt;. En gros, &lt;code&gt;ktrace&lt;/code&gt; permet de
contrôler l’enregistrement ou non des appels que fait un process, et kdump
permet de lire le fichier binaire que son cousin a généré (nommé &lt;em&gt;ktrace.out&lt;/em&gt;
par défaut).&lt;/p&gt;
&lt;p&gt;Petit exemple d’utilisation :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ktrace &amp;lt;PID&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Équivalent de l’option &lt;code&gt;-f&lt;/code&gt; de &lt;code&gt;strace&lt;/code&gt; (pour tracer également les processus
fils) :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ktrace -id &amp;lt;PID d&amp;#39;une processe qui fait plein de petits&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Équivalent de l’option &lt;code&gt;-p&lt;/code&gt; de &lt;code&gt;strace&lt;/code&gt; (pour tracer un process existant, sans
devoir le relancer). Bon là ça ne change pas trop :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ktrace -p &amp;lt;PID d&amp;#39;un process applicatif super critique, lancé depuis une éternité, que plus personne ne sait comment le relancer et que si il crash c&amp;#39;est la fin du monde&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Quand vous avez récupéré suffisamment de traces à lire (ou quand vous vous
apercevez que votre ktrace.out a pris 100 % de l’espace libre restant sur la
partition), pour arrêter l’enregistrement :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ktrace -C&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Maintenant que vous avez votre bon gros fichier binaire avec plein de traces dedans :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;kdump |less&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si l’enregistrement des traces est toujours en cours, vous pouvez avoir l’équivalent d’un &lt;code&gt;tail -f&lt;/code&gt; :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;kdump -l&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pour plus de détail, voir bien sûr les man de &lt;code&gt;ktrace (1)&lt;/code&gt; et &lt;code&gt;kdump (1)&lt;/code&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Contact</title>
        <published>2013-04-01T15:12:41+00:00</published>
        <updated>2026-10-02T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/contact/"/>
        <id>https://univers-libre.net/contact/</id>
        
        <content type="html" xml:base="https://univers-libre.net/contact/">&lt;p&gt;You can reach me at the following e-mail address: &lt;a href=&quot;mailto:romain \_o&lt; @univers-libre.net&quot;&gt;&amp;lt;romain \_o&amp;lt; @univers-libre.net&amp;gt;&lt;/a&gt;&lt;br /&gt;
&lt;small&gt;(although ducks are really cool animals, you should remove the duck from the address link to get the real one)&lt;/small&gt;.&lt;/p&gt;
&lt;p&gt;Please follow these simple rules before sending me an e-mail:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;only plaintext e-mails, no HTML&lt;/li&gt;
&lt;li&gt;no &lt;strong&gt;AI-generated messages&lt;/strong&gt;. I will not read nor respond to your e-mail and I will mark it as spam. I’m not interested in interacting with a dumb chatbot.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can send me PGP encrypted e-mails. If you wish to do so, my GPG key fingerprint is &lt;code&gt;C59B 9EAF 6CA8 B9AE 0EAC  21D0 876B 9AB4 8BB6 2212&lt;/code&gt; and my GPG public key is available on key servers.&lt;/p&gt;
&lt;p&gt;I am not on any social networks. If you find someone there claiming to be me, he/she is most likely not me.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Passer root sans terminal</title>
        <published>2012-01-26T00:00:00+00:00</published>
        <updated>2012-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/passer-root-sans-terminal/"/>
        <id>https://univers-libre.net/posts/passer-root-sans-terminal/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/passer-root-sans-terminal/">&lt;p&gt;Dans certains rares cas, on peut vouloir exécuter des commandes en tant que
root sans avoir la possibilité d’allouer un terminal sur la machine en
question.&lt;/p&gt;
&lt;p&gt;Pour ceux qui aiment bien lire la fin en premier, je mets la fin au début :-) :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;mypassword&amp;quot; |sudo -S id&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pour illustrer le problème, prenons un cas concret qui m’est arrivé.&lt;br /&gt;
Un serveur s’est soudainement mis dans un état bizarre, à savoir que tout
marchait, les processus déjà en cours continuaient de s’exécuter, d’autres
processus pouvaient se créer, mais certaines choses ne marchaient pas,
notamment l’allocation de pseudo-terminaux (les &lt;strong&gt;/dev/pts/*&lt;/strong&gt;) ; si je tente
une connexion SSH au serveur, le serveur répond bien, l’authentification se
fait, et au moment d’avoir mon prompt, la connexion se freeze.&lt;br /&gt;
Après divers tests, je m’aperçois qu’en passant directement une commande à ssh,
ça marche :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ssh serveur-foireux dmesg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La différence vient du fait que dans le deuxième cas, ssh n’ouvre pas de
pseudo-terminal sur le serveur distant, puisqu’il se contente de récupérer
directement stderr et stdout.&lt;br /&gt;
On peut faire en sorte de se connecter sans allouer de terminal sur le serveur
avec l’option &lt;em&gt;-T&lt;/em&gt; de la commande ssh :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;     -T      Disable pseudo-tty allocation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On a ainsi un shell qui s’exécute sur la machine, et on récupère la sortie
brute de stderr et stdout (pas de prompt, d’édition de la commande en cours,
etc…). Pareil pour stdin, ce qui fait que les commandes &lt;code&gt;sudo&lt;/code&gt; ou &lt;code&gt;su&lt;/code&gt;
retournent une erreur, étant donné qu’elles font une manipulation spécifique
sur stdin (pas d’echo pour la saisie du mot de passe). De ce fait, on est un
peu coincé pour passer root.&lt;/p&gt;
&lt;p&gt;Il existe une solution (que j’ai bien sûr trouvé après avoir brutalement
redémarrer le serveur), une simple option à sudo qui permet de lire le mot de
passe depuis stdin. Et là, pas besoin d’exécuter la commande dans un terminal
donc !&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo &amp;quot;mypassword&amp;quot; |sudo -S id&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[sudo] password for rdessort: uid=0(root) gid=0(root) groupes=0(root)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et comme cela affiche votre mot de passe en clair sur l’écran, voici un petit
script pour améliorer la chose :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!/bin/bash&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo -n &amp;quot;Enter password: &amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;read -s passwd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ssh serveur-foireux &amp;quot;echo $passwd |sudo -S id&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Une autre application probablement beaucoup plus courante pourrait être de
pouvoir scripter des commandes nécessitant d’être root sur le serveur.
Notamment exécuter la même commande sur plusieurs dizaines de serveurs
d’affilée.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Utiliser AWStats sans CGI</title>
        <published>2011-01-09T00:00:00+00:00</published>
        <updated>2011-01-09T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/awstats-sans-cgi/"/>
        <id>https://univers-libre.net/posts/awstats-sans-cgi/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/awstats-sans-cgi/">&lt;p&gt;AWStats est un générateur de statistiques, le plus souvent utilisé pour générer
des stats sur des serveurs web (il peut aussi être utilisé pour des serveurs
mail, ftp…). C’est une appli en Perl, qui peut donc être appelé par le serveur
web via CGI pour générer les pages HTML.&lt;/p&gt;
&lt;p&gt;Sur Apache ou Lighttpd ça marche sans problème, mais sur un serveur web qui
ne supporte pas CGI (NginX par exemple, à moins de passer par des hacks assez
tordus) ça ne marche plus.&lt;/p&gt;
&lt;p&gt;La solution est donc de dire à AWStats de générer les page HTML
automatiquement après chaque mise à jour de sa base de données. Voici la
procédure :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Créez tout d’abord le répertoire qui contiendra les pages HTML, avec les
bons droits :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mkdir /var/www/awstats/&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chown www-data:www-data /var/www/awstats/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modifiez ensuite le fichier &lt;em&gt;/etc/cron.d/awstats&lt;/em&gt; pour appelez le script
&lt;em&gt;awstats_buildstaticpages.pl&lt;/em&gt; au lieu de &lt;em&gt;awstats.pl&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[ -x /usr/share/doc/awstats/examples/awstats_buildstaticpages.pl \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-a -f /etc/awstats/awstats.yoursite.conf -a -r /var/log/nginx/yoursite.access.log ] \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;amp;&amp;amp; perl /usr/share/doc/awstats/examples/awstats_buildstaticpages.pl -update \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;-config=yoursite -dir=/var/www/awstats -awstatsprog=/usr/lib/cgi-bin/awstats.pl &amp;gt;/dev/null&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;À adapter bien sûr avec les bons noms de fichiers de conf et de log.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;N’oubliez pas d’ajouter un alias dans la conf de votre serveur web pour les
icônes. Sous NginX, ça donne ça :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  location /awstats-icon/ {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      alias /usr/share/awstats/icon/;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Utiliser la fonction PHP imagerotate() sous Debian</title>
        <published>2010-09-18T00:00:00+00:00</published>
        <updated>2010-09-18T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/php-imagerotate-debian/"/>
        <id>https://univers-libre.net/posts/php-imagerotate-debian/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/php-imagerotate-debian/">&lt;p&gt;imagerotate est une fonction PHP qui, comme son nom l’indique, permet de
tourner une image selon un angle. Cependant elle n’est disponible que si PHP a
été compilé avec la version embarqué de la bibliothèque GD.&lt;/p&gt;
&lt;p&gt;Sous Debian ce n’est pas le cas, car cette version est difficilement
maintenable au niveau sécurité (cf le &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=321237&quot;&gt;bug report
Debian&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Pour contourner le problème, en cherchant un peu sur le net (&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://web.archive.org/web/20140125012344/http://www.mattiouz.com/blog/2010/01/28/recompiling-php5-to-get-imagerotate-and-other-functions-on-debian&quot;&gt;ici par
exemple&lt;/a&gt;),
beaucoup de monde recompile PHP avec la version embarqué de GD. Ce n’est à mon
avis pas la meilleure solution au niveau “maintenabilité”.&lt;/p&gt;
&lt;p&gt;Voici donc 2 autres possibilités.&lt;/p&gt;
&lt;h2 id=&quot;utiliser-les-depots-dotdeb&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#utiliser-les-depots-dotdeb&quot; aria-label=&quot;Anchor link for: utiliser-les-depots-dotdeb&quot;&gt;Utiliser les dépôts dotdeb&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Les &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://www.dotdeb.org/&quot;&gt;dépôts dotdeb&lt;/a&gt; contiennent des versions plus
récentes et/ou modifiés de paquets Debian pour serveurs LAMP. Le paquet php5
présent dans dotdeb est justement compilé avec la version embarqué de la
bibliothèque.&lt;/p&gt;
&lt;h2 id=&quot;reecrire-la-fonction-imagerotate&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#reecrire-la-fonction-imagerotate&quot; aria-label=&quot;Anchor link for: reecrire-la-fonction-imagerotate&quot;&gt;Réécrire la fonction imagerotate()&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Si vous n’avez besoin que de cette fonction et que vous n’avez pas envi
d’utiliser la version embarqué de GD, il est tout à fait envisageable de
réécrire la fonction en question :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;readImage($temp_src);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      $imagick-&amp;gt;rotateImage(new ImagickPixel($bgd_color?$bgd_color:&amp;#39;black&amp;#39;), $angle);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      $imagick-&amp;gt;writeImage($temp_dst);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      //trigger_error( &amp;#39;imagerotate(): could not write to &amp;#39; . $file1 . &amp;#39;, original image returned&amp;#39;, E_USER_WARNING );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      $result = imagecreatefromjpeg($temp_dst);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      unlink($temp_dst);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      unlink($temp_src);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      return $result;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>trier numériquement la sortie d’un du -h</title>
        <published>2010-09-11T00:00:00+00:00</published>
        <updated>2010-09-11T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/trier-sortie-du-h/"/>
        <id>https://univers-libre.net/posts/trier-sortie-du-h/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/trier-sortie-du-h/">&lt;p&gt;Afficher la taille que prend un répertoire ainsi que ses sous répertoires est
une tache assez courante, du moins pour un administrateur système. Cela se
fait simplement avec la commande :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;du -sh foo/*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ou bien, si on veut avoir aussi les sous sous répertoires :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;du -h --max-depth 2 foo/*&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;L’option -h permettant d’avoir la taille exprimé en kilo, méga, giga, etc…&lt;/p&gt;
&lt;p&gt;Là où les choses se compliquent, c’est lorsqu’on veut trier numériquement le
résultat par ordre décroissant. Si on fait un :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;du -sh foo/* |sort -rn&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;le tri sera faussé du fait de la présence des lettres qui suivent la taille.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;D’où l’astuce du jour : comment trier numériquement la sortie d’un du tout
en ayant la taille exprimé en “human readable” ?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Si vous avez le paquet coreutils en version ≥ 7.5, vous êtes sauvé, sort
implémente l’option -h qui répond exactement au problème :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;du -sh foo/* |sort -rh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dans le cas contraire (si vous êtes sur une Debian Lenny par exemple), c’est
un peu moins simple.&lt;br /&gt;
En cherchant un peu sur le net, il existe un tas d’astuces différentes
utilisant perl ou awk. Voici celle que j’utilise, qui me semble la moins tordue
(mais un peu quand même) :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;du -s foo/* |sort -rn |cut -f2 |xargs -d &amp;#39;\n&amp;#39; du -sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Le principe est d’obtenir d’abord la liste des répertoires avec leur taille
“brute”, de trier cette liste, puis de refaire un du (avec -h cette fois) sur
chaque répertoire de la liste).&lt;br /&gt;
Le fait d’exécuter 2 fois un du n’est pas super élégant point de
performance, mais en pratique, comme le résultat du premier du est caché en
mémoire, le second est très rapide.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gérer efficacement et rapidement ses todos avec devtodo</title>
        <published>2010-09-10T00:00:00+00:00</published>
        <updated>2010-09-10T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/devtodo/"/>
        <id>https://univers-libre.net/posts/devtodo/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/devtodo/">&lt;p&gt;Pour changer un peu de l’administration système, je vais vous présenter
aujourd’hui… devtodo.&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://swapoff.org/DevTodo&quot;&gt;devtodo&lt;/a&gt; est un petit (mais puissant) utilitaire
qui s’utilise en ligne de commande et qui va vous permettre de gérer votre (ou
vos) todo list. Avant de vous le présenter, sachez qu’il m’a fallu pas mal de
temps avant de trouver un todo list manager qui me convienne. Mon premier
critère de sélection était une application en ligne de commande
(éventuellement avec une interface ncurses). L’utilisation d’une interface
graphique pour ce genre de tâche n’est vraiment pas adapté, je perdais trop
de temps à clicouiller par-ci par-là pour saisir 3 mots que, finalement, je
ne tenais plus à jour ma todo list et elle partait aux oubliettes.&lt;/p&gt;
&lt;p&gt;À partir de là j’ai testé différents utilitaires (doneyet, task, devtodo,
w2do, todo.txt, et j’en passe). Mais seuls 2 répondaient à mon second
critère : savoir gérer les sous taches : doneyet et devtodo. doneyet est une
interface semi-graphique utilisant ncurses, mais ne me paraissait pas assez
ergonomique (sans compter un segfault à chaque caractère UTF-8 de tapé, que
je n’ai pas vraiment cherché à résoudre). J’ai donc choisi devtodo.&lt;/p&gt;
&lt;h2 id=&quot;presentation-rapide-des-fonctionnalites-de-devtodo&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#presentation-rapide-des-fonctionnalites-de-devtodo&quot; aria-label=&quot;Anchor link for: presentation-rapide-des-fonctionnalites-de-devtodo&quot;&gt;Présentation rapide des fonctionnalités de devtodo&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;gestion des taches sur plusieurs niveaux ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gestion de 5 niveaux de priorité ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;stockage de la todo list dans un fichier xml, très facile à exploiter par
la suite (une fonction d’export est quand même bien sûr prévue) ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gestion d’une todo list par répertoire (très pratique pour gérer
plusieurs projets à la fois).
Exemple : vous allez dans le répertoire mon-projet/, vous visualisez la todo
list de ce projet :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd mon-projet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;todo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# affichage des todos de &amp;quot;mon-projet&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vous voulez tout d’un coup travailler sur un autre projet :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cd ../autre-projet&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;todo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# affichage des todo de &amp;quot;autre-projet&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En fait, par défaut, devtodo lira le fichier xml .todo présent dans le
répertoire courant, d’où ce fonctionnement. On peut bien sur forcer
l’utilisation d’une todolist différente avec l’option &lt;code&gt;-G&lt;/code&gt; ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;filtrage et tri avancé de l’affichage des todos (suivant des critères
comme terminé, priorité, date de création…) ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;possibilité de redéfinir entièrement le formatage et la coloration de
l’affichage de la todo list (en accédant au variables via &lt;code&gt;%p&lt;/code&gt;, &lt;code&gt;%d&lt;/code&gt;, etc…) ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;je pense que ce sera tout, tout ça prenant un peu moins de 300Ko installé !&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;utilisation-basique&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#utilisation-basique&quot; aria-label=&quot;Anchor link for: utilisation-basique&quot;&gt;Utilisation basique&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Voici comment utiliser devtodo de manière “simple” :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ajout d’un todo avec une priorité faible (la plus haute est 1) :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tda -p 4 un premier todo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Voir sa liste de todo :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;todo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ajout d’une sous tache à la précédente :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tda -g 1 une sous tache du premier todo&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Marquer la sous tache comme faite :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tdd 1.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Édition d’une tache :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tde 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bref, je vous laisse lire le man pour plus de détails (qui est d’ailleurs
très clair, contrairement au site du projet).&lt;/p&gt;
&lt;h2 id=&quot;utilisation-avancee&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#utilisation-avancee&quot; aria-label=&quot;Anchor link for: utilisation-avancee&quot;&gt;Utilisation avancée&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id=&quot;filtrage&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#filtrage&quot; aria-label=&quot;Anchor link for: filtrage&quot;&gt;Filtrage&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;devtodo permet de filtrer l’affichage des todos suivant plusieurs critères.
Quelques exemples pratiques :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;N’afficher que les todos finissant par la chaîne toto (on commence simple)
:&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;todo -f &amp;quot;/toto$&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Afficher les todos non fait et avec une priorité supérieure ou égale à
high :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;todo -f &amp;quot;-done,+high&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Afficher les todos contenant foo ou Foo, en recherchant aussi dans les sous
tâches :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;todo -f &amp;quot;/[fF]oo,+children&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En bonus, vous pouvez définir un filtre par défaut, qui s’appliquera lorsque
vous taperez simplement la commande todo.
Cela ce fait dans le fichier .todorc :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;filter -done,children&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&quot;tri&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#tri&quot; aria-label=&quot;Anchor link for: tri&quot;&gt;Tri&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;De la même manière que vous pouvez filtrer la sortie, vous pouvez aussi la
trier. Le principe est un peu le même que pour les filtres :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Trier par date de création :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;todo --sort created&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Trier d’abord par priorité, puis par ordre alphabétique :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;todo --sort priority,text&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le tri à appliquer par défaut est définit par la directive sort dans le
fichier de conf.&lt;/p&gt;
&lt;h3 id=&quot;formatage&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#formatage&quot; aria-label=&quot;Anchor link for: formatage&quot;&gt;Formatage&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Le formatage de la sortie de todo ne vous convient pas ? eh bien vous pouvez la
réécrire complètement.
Avant tout sachez aussi que vous pouvez utiliser l’option -v pour un affichage
plus complet.&lt;/p&gt;
&lt;p&gt;La définition des formats se passent (de préférence) dans le fichier de
conf. Vous retrouvez les formats par défaut qui y sont décrits, puis vous
pouvez écrire les votre en dessous, en utilisant la forme :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;format nomDuFormat=templateString&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;templateString est la chaîne qui affichera le todo. Vous pouvez donc insérer
des variables sur le même principe que la fonction C &lt;code&gt;printf()&lt;/code&gt;. Un petit
exemple :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;format display=%4&amp;gt;%i%[info]%f%2n.%[priority]%+1T&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pour avoir plus d’information sur l’écriture de la chaîne (notamment la liste
des variables),… cf. le man.&lt;/p&gt;
&lt;p&gt;Après avoir écrit votre nouveau format, 2 solutions : soit il déchire tout
et vous voulez l’utiliser à la place de celui par défaut, soit il déchire
aussi mais vous voulez l’utilisez que dans certains cas plus spécifiques.
Dans le premier cas, rajoutez la ligne suivante dans votre conf :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;use-format display=nomDuFormat&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remplacez display par verbose-display si le format doit être utilisé dans le
cas de l’utilisation de l’option -v.
Dans le second cas, vous pouvez bien sur spécifier le thème dans les options
de la ligne de commande directement, via –use-format, en utilisant la même
syntaxe que ci-dessus.&lt;/p&gt;
&lt;p&gt;Je pense avoir fait un tour global sur cet outil vraiment sympa, cependant il
reste encore quelques astuces dont je n’ai pas parlé, mais bien décrite dans
le man.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hard reboot à distance</title>
        <published>2010-08-09T00:00:00+00:00</published>
        <updated>2010-08-09T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/hard-reboot-distant/"/>
        <id>https://univers-libre.net/posts/hard-reboot-distant/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/hard-reboot-distant/">&lt;p&gt;Voici une astuce bien utile si votre serveur est complètement planté.
Il faut néanmoins pouvoir se connecter en SSH sur la machine et avoir un shell
en root.&lt;/p&gt;
&lt;p&gt;Dans mon cas, il s’agissait d’un problème d’accès disque, la plupart des
commandes exécutées renvoyaient des erreurs d’entrée/sortie, y compris la
commande reboot, qui a besoin d’exécuter les scripts d’init de niveau 6.&lt;/p&gt;
&lt;p&gt;Mais tout n’est pas perdu, si vous n’avez pas d’accès physique à la machine !
On va passer par le pseudo système de fichier /proc pour parler directement au
noyau et lui dire de redémarrer la machine.
Avant tout (et si il ne s’agit pas d’un problème disque), on tente de forcer
la synchronisation du cache vers le disque :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sync&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On active ensuite les &lt;a class=&quot;external-link&quot; rel=&quot;external&quot; href=&quot;https://fr.wikipedia.org/wiki/Magic_SysRq_key&quot;&gt;magic sysrq
key&lt;/a&gt; si elles ne le sont pas
déjà :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo 1 &amp;gt; /proc/sys/kernel/sysrq&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Puis on modifie l’état de la machine :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo b &amp;gt; /proc/sysrq-trigger&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette dernière action a exactement le même effet que la combinaison &lt;code&gt;Alt + Syst + b&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Après cela, priez pour que la machine redémarre correctement :-).&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Compter le nombre de connections par IP</title>
        <published>2010-06-18T00:00:00+00:00</published>
        <updated>2010-06-18T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/compter-connexions-par-ip/"/>
        <id>https://univers-libre.net/posts/compter-connexions-par-ip/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/compter-connexions-par-ip/">&lt;p&gt;Aujourd’hui au boulot, j’ai été confronté à un petit problème : sur un serveur
victime d’une attaque DDoS (visiblement), je voulais savoir quelles IP
ouvraient le plus de connections. Ne trouvant rien de bien intéressant dans les
commandes Unix, j’ai écris un petit script en Perl.&lt;/p&gt;
&lt;p&gt;Il se charge de récupérer la sortie de netstat (la commande est à adapter à
votre besoin) et compte le nombre de lignes identiques (donc d’IP), qu’il se
charge ensuite de trier par ordre décroissant et d’afficher.&lt;/p&gt;
&lt;p&gt;Voici le script en question :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#!/usr/bin/perl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;use strict;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;use warnings;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;my %addrs = ();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;my @netstatOut = split( /\n/, `netstat -taupen | grep SYN | tr -s &amp;quot; &amp;quot; | cut -d&amp;quot; &amp;quot; -f 5 | cut -d: -f1` );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;for (@netstatOut) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    chomp $_;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $addrs{$_} += 1;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;for my $key ( sort {$addrs{$b} &amp;lt;=&amp;gt; $addrs{$a}} keys %addrs ) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    print $addrs{$key}.&amp;quot;\t$key\n&amp;quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Le script retourne alors son résultat sous la forme :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nbConnection    IP1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nbConnection    IP2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Il ne vous reste plus qu’à blacklister les IP les plus actives avec la commande&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;iptables -I INPUT -s IP -j DROP&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Connexion ssh derrière un proxy</title>
        <published>2009-11-17T00:00:00+00:00</published>
        <updated>2009-11-17T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/corkscrew/"/>
        <id>https://univers-libre.net/posts/corkscrew/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/corkscrew/">&lt;p&gt;Peut-être avez vous déjà rencontré ce problème, il n’est pas possible de se
connecter en SSH sur un serveur lorsqu’on se trouve derrière un proxy.&lt;/p&gt;
&lt;p&gt;Je m’en suis aperçu quelques jours après le début des cours à l’IUT de Nancy
lorsque j’ai voulu créer un tunnel SSH (on verra comment par la suite) pour
pouvoir accéder à mes mails, les messageries instantanées, etc… Le réseau de
l’université se trouve en effet derrière un proxy qui bloque tout et n’importe
quoi (en fait seul les ports http et https sont autorisés).&lt;br /&gt;
&lt;em&gt;Souvenir du réseau wifi de l’IUT de Marseille où on pouvait télécharger en P2P
les &lt;del&gt;films&lt;/del&gt; ISO Linux en quelques minutes… :(&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Pour résoudre le problème (du ssh, pas du P2P), il y a deux choses à faire.&lt;/p&gt;
&lt;h2 id=&quot;cote-serveur&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#cote-serveur&quot; aria-label=&quot;Anchor link for: cote-serveur&quot;&gt;Coté serveur&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bien entendu, comme le proxy bloque tout sauf http et https, il n’y a pas de
miracles, il faut faire écouter le serveur SSH sur le port https (les transfert
sont chiffrés pour https et SSH, le proxy ne peut pas voir la différence). Pour
ça, modifiez votre &lt;em&gt;/etc/ssh/sshd_config&lt;/em&gt; pour changer la valeur de &lt;em&gt;Port&lt;/em&gt; :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Port 443&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Redémarrez OpenSSH et assurez vous de changer les ports également dans votre
pare feu et votre routeur.&lt;/p&gt;
&lt;h2 id=&quot;cote-client&quot;&gt;&lt;a class=&quot;zola-anchor&quot; href=&quot;#cote-client&quot; aria-label=&quot;Anchor link for: cote-client&quot;&gt;Coté client&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;À priori, on peut croire que le problème est maintenant résolu, le serveur
écoute sur le port https, le proxy laisse passer les données sur le port https,
et le client indique de ce connecter par le port https. Et bien non, ce n’est
pas aussi simple, et je n’ai eu la réponse qu’aujourd’hui, pendant un cours sur
les serveurs web.&lt;/p&gt;
&lt;p&gt;En fait, le fait de passer par un proxy interdit de faire une connection direct
entre le client et le serveur (un proxy étant fait pour s’intercaler entre les
échanges). Il faut donc dire explicitement au proxy d’établir une connection
direct entre les deux machines, et de ne plus s’en mêler ensuite. C’est grâce à
la commande HTTP CONNECT que c’est possible (vous voyez mieux le rapport avec
les serveurs web à présent ;) ).&lt;/p&gt;
&lt;p&gt;Pour réaliser ça en pratique, on va utiliser corkscrew. Installez le puis
modifiez votre fichier client &lt;em&gt;/etc/ssh/ssh_config&lt;/em&gt; comme ceci :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Host univers-libre.net-proxy&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Hostname univers-libre.net&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Port 443&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        ProxyCommand /usr/bin/corkscrew vivianen.iuta.univ-nancy2.fr 3128 %h %p&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Host univers-libre.net&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        Port 443&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Explications :&lt;br /&gt;
on a définit 2 configurations (host, dans le fichier) : une dans le cas normal
(univers-libre.net) et une autre avec un proxy (univers-libre.net-proxy).&lt;br /&gt;
Ainsi, si vous êtes derrière le proxy, vous devrez taper :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ssh univers-libre.net-proxy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dans le cas contraire :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ssh univers-libre.net&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dans la configuration avec proxy, on indique que, en fait le vrai nom n’est pas
univers-libre.net-proxy mais univers-libre.net (avec la directive hostname). Le
port est bien sûr fixé à 443 (https) dans les 2 cas.&lt;br /&gt;
Viens la ligne ProxyCommand : on dit à OpenSSH de faire appel à corkscrew en
lui passant en paramètre l’adresse du proxy (ici vivianen.iuta.univ-nancy2.fr),
le port du proxy (3128 qui est le port par défaut des proxies). %h et %p
indiquent respectivement l’hôte à atteindre et son port (univers-libre.net et
443).&lt;/p&gt;
&lt;p&gt;Maintenant que vous avez un accès SSH sur votre serveur à vous la liberté :) .
Vous pouvez alors créer un tunnel SSH pour certaines applications, en rajoutant
une ligne de ce type dans le fichier &lt;em&gt;/etc/ssh/ssh_config&lt;/em&gt; de votre client :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LocalForward 143 localhost:143&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dans cet exemple je dis de rediriger toutes les demandes de connections qui
sont envoyées sur le port 143 (imap), vers le même port et sur le même serveur
que le serveur SSH (localhost). Ainsi mon client mail pourra accéder à mon
serveur imap, le tout de façon transparente, mais crypté dans le tunnel :-).&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Passer une partition de ext2 à ext3 sans la reformater</title>
        <published>2009-01-19T00:00:00+00:00</published>
        <updated>2009-01-19T00:00:00+00:00</updated>
        
        <author>
          <name>Romain</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://univers-libre.net/posts/conversion-ext2-ext3/"/>
        <id>https://univers-libre.net/posts/conversion-ext2-ext3/</id>
        
        <content type="html" xml:base="https://univers-libre.net/posts/conversion-ext2-ext3/">&lt;p&gt;Même si plus beaucoup de monde utilise encore le système de fichier ext2, il
se peut qu’il vous reste de vielles partitions ext2 qui traine dans un coin de
votre disque dur.&lt;/p&gt;
&lt;p&gt;Si c’est votre cas, et que vous avez toujours eu la flemme de sauvegarder les
données de la partition, la formater, puis restaurer les données, voici la
commande magique, à appliquer tel quel, sans sauvegarde des données :&lt;/p&gt;
&lt;pre class=&quot;giallo z-code&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tune2fs -j votre_partition&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Petite explication (et la commande semblera moins magique :-) ) :&lt;br /&gt;
Il faut savoir que la différence entre ext2 et ext3 vient uniquement du fait
que ext3 est journalisé, c’est à dire (en gros) que toutes les écritures
réalisées sur le disque (appelées transactions) sont inscrites (journalisées)
dans un journal stocké sur la partition. Cela permet, si un crash du disque
survient (coupure de courant, freeze, …), de garder une cohérence dans les
données écrites sur le disque (en analysant uniquement le journal, pas besoin
d’aller scanner tout le disque).&lt;br /&gt;
Pour revenir à notre commande, celle ci ne fait que créer ce fameux journal
sur la partition, rien de plus. Au prochain montage de la partition, celle ci
sera monté en tant qu’ext3.&lt;/p&gt;
</content>
        
    </entry>
</feed>
