<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>bisko.be - Dev</title><description>Technologie, développement, matériel et expériences.</description><link>https://bisko.be/fr/posts/dev/</link><language>fr</language><item><title>Faire tourner Ollama avec de vieux GPU sur CachyOS</title><link>https://bisko.be/fr/posts/dev/running-ollama-with-older-gpus-on-cachyos/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/running-ollama-with-older-gpus-on-cachyos/</guid><description>Aujourd&apos;hui, je migrais ma VM Windows 11 vers Linux, pour avoir plus de flexibilité sur les services qui y tournent, et je suis tombé sur un problème : Ollama refusait de tourner sur mes vieux GPU, une GTX1070 et une GTX970</description><pubDate>Sat, 28 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;tldr&quot;&gt;TL;DR;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ollama-cuda&lt;/code&gt; sur CachyOS ne supporte (à l’heure actuelle) que &lt;code&gt;compute &gt;= 7.5&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si vous avez de vieux GPU avec un &lt;code&gt;compute&lt;/code&gt; inférieur, vous DEVEZ faire l’une de ces 2 choses :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compiler &lt;code&gt;ollama-cuda&lt;/code&gt; depuis les sources, avec le support des anciennes cibles de compute&lt;/li&gt;
&lt;li&gt;Installer &lt;code&gt;ollama-vulkan&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;J’ai choisi &lt;code&gt;ollama-vulkan&lt;/code&gt; et ça marche parfaitement !&lt;/p&gt;
&lt;h3 id=&quot;lheure-du-récit&quot;&gt;L’heure du récit&lt;/h3&gt;
&lt;p&gt;Aujourd’hui, j’ai eu l’inspiration d’enfin éteindre ma VM Windows 11 et de la migrer vers Linux.&lt;/p&gt;
&lt;p&gt;Il fallait que je puisse faire tourner :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ollama - pour la magie des modèles en local&lt;/li&gt;
&lt;li&gt;Docker - pour le développement à distance&lt;/li&gt;
&lt;li&gt;Steam - pour jouer&lt;/li&gt;
&lt;li&gt;Jellyfin - pour l’archive de vidéos familiales&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je vais me concentrer uniquement sur Ollama, parce que l’expérience était intéressante et qu’elle m’a fait me demander pourquoi les choses ne sont pas plus évidentes.&lt;/p&gt;
&lt;p&gt;La machine contient 2 GPU :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GTX 1070 - 8 Go&lt;/li&gt;
&lt;li&gt;GTX 970 - 4 Go&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je voulais faire tourner Ollama dessus, pour jouer avec des modèles locaux et voir comment je pourrais l’intégrer dans certains projets. Par exemple : anonymiser des données en local, monter une implémentation non destructive d’OpenClaw adaptée à mes cas d’usage, faire de l’OCR local pour les documents que je scanne avec mon téléphone, automatiser certaines tâches de la gestion quotidienne d’une maison.&lt;/p&gt;
&lt;p&gt;Alors naturellement, j’ai installé &lt;code&gt;ollama&lt;/code&gt; et &lt;code&gt;ollama-cuda&lt;/code&gt;, puisque j’ai 2 GPU Nvidia là-dedans, en m’attendant à ce que ça marche sans souci, vu que ça fonctionnait sous Windows quelques minutes plus tôt.&lt;/p&gt;
&lt;p&gt;J’ai lancé Ollama, chargé &lt;code&gt;qwen3:8b&lt;/code&gt; pour un test rapide et… ça tournait sur le CPU 🤔&lt;/p&gt;
&lt;p&gt;Les GPU étaient parfaitement capables de le garder en VRAM, mais pour une raison quelconque Ollama choisissait de le faire tourner sur le CPU.&lt;/p&gt;
&lt;p&gt;Après avoir essayé de comprendre à partir des logs, j’ai demandé un coup de main à Claude, qui est arrivé à cette conclusion plutôt décourageante :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;The&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; logs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; tell&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; the&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; story&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; clearly.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Both&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; your&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; GPUs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; are&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; detected&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; but&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; then&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; filtered&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; out&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; because&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; they&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; fail&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; CUDA&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; initialization:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  &quot;filtering device which didn&apos;t fully initialize&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; id=GPU-eb132a13-b9f4-40e3-d85d-60f211dfd21e&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ...&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; library=CUDA&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  &quot;filtering device which didn&apos;t fully initialize&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; id=GPU-550263c8-37e2-2a25-c0b6-10cc7511ed20&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ...&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; library=CUDA&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  The&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; reason&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; is&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; the&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; CUDA&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; library&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; bundled&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; with&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Ollama&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0.17.4&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; was&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; compiled&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; these&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; architectures&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; only:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  CUDA.0.ARCHS&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;=750,800,860,870,880,890,900,1000,1030,1100,1200,1210&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  The&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; minimum&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; supported&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; compute&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; capability&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; is&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 7.5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (Turing &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; RTX&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; 20xx&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; series&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;). Your GPUs are older than that:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  ┌──────────┬────────────────────┬──────────────┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  │&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;   GPU&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    │&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Compute&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Capability&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; │&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Architecture&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  ├──────────┼────────────────────┼──────────────┤&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  │&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; GTX&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1070&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; │&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 6.1&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                │&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Pascal&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;       │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  ├──────────┼────────────────────┼──────────────┤&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  │&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; GTX&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 970&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  │&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5.2&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                │&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Maxwell&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;      │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  └──────────┴────────────────────┴──────────────┘&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  Neither&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; is&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; in&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; the&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; supported&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; list,&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; so&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; CUDA&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; initialization&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; fails&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; both,&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; and&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Ollama&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; falls&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; back&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; to&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; CPU-only&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; inference.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  Your&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; options:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  1.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Downgrade&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Ollama&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; to&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; an&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; older&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; version&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; that&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; still&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; included&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Pascal/Maxwell&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; support&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (pre-0.6.x &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;era&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; had&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; broader&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; arch&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; coverage,&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; but&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; check&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; release&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; notes&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; for&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; specifics&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  2.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Build&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Ollama&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; from&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; source&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; with&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; CUDA_ARCHITECTURES=&quot;52;61;75;80;86&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; to&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; include&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; your&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; GPU&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; architectures.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  3.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Upgrade&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; GPUs&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; to&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; at&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; least&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; an&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; RTX&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2060&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; or&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; newer&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (compute &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;7.5+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Franchement, ça m’a un peu douché, parce que je veux exploiter ces GPU au maximum avant de passer à un nouveau.&lt;/p&gt;
&lt;p&gt;Je n’avais pas envie de recompiler Ollama depuis les sources, vu que ça devrait fonctionner out of the box, et j’étais très perplexe de voir que ce n’était pas le cas, alors que sous Windows ces architectures étaient bien supportées.&lt;/p&gt;
&lt;p&gt;Ces cartes étaient même indiquées comme supportées sur le site d’Ollama !&lt;/p&gt;
&lt;p&gt;Pour résumer des heures de recherches Google :&lt;/p&gt;
&lt;p&gt;Il se trouve que &lt;code&gt;ollama-cuda&lt;/code&gt; ne vient qu’avec les prérequis listés plus haut… et la suggestion était d’installer &lt;code&gt;ollama-vulkan&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Après ça, tout s’est mis à fonctionner très bien !&lt;/p&gt;</content:encoded><category>linux</category><category>llm</category><category>ollama</category><category>cachyos</category><category>vulcan</category><category>cuda</category></item><item><title>[Linux] Récupérer une session `apt dist-upgrade` déconnectée</title><link>https://bisko.be/fr/posts/dev/linux-recovering-a-disconnected-apt-dist-upgrade-session/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/linux-recovering-a-disconnected-apt-dist-upgrade-session/</guid><description>Aujourd&apos;hui, je mettais à jour mon installation Proxmox à distance via la console intégrée, mais j&apos;ai oublié ce que j&apos;étais en train de faire et j&apos;ai fermé l&apos;onglet en plein milieu. Résultat : impossible de me reconnecter, car les paquets étaient déjà en cours de mise à jour en arrière-plan et la mise à jour avait posé une question sur le remplacement d&apos;un fichier et attendait ma réponse</description><pubDate>Wed, 23 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Aujourd’hui, je mettais à jour mon installation Proxmox à distance via la console intégrée, mais j’ai oublié ce que j’étais en train de faire et j’ai fermé l’onglet en plein milieu.&lt;/p&gt;
&lt;p&gt;Résultat : impossible de me reconnecter, car les paquets étaient déjà en cours de mise à jour en arrière-plan et la mise à jour avait posé une question sur le remplacement d’un fichier et attendait ma réponse.&lt;/p&gt;
&lt;p&gt;Je pouvais donc me connecter en SSH, mais je ne pouvais rien faire, puisque le processus attendait toujours une réponse sur une console à laquelle je n’arrivais pas à me connecter, l’interface ne s’ouvrant pas.&lt;/p&gt;
&lt;p&gt;Après avoir fouillé un peu, je suis tombé sur un &lt;a href=&quot;https://serverfault.com/questions/19634/how-to-reconnect-to-a-disconnected-ssh-session&quot;&gt;fil Serverfault&lt;/a&gt; qui mentionnait l’utilisation de &lt;code&gt;reptyr&lt;/code&gt; pour reprendre la main sur une session de terminal via SSH.&lt;/p&gt;
&lt;p&gt;Je note ici ce que j’ai fait exactement pour récupérer la session et terminer la mise à jour :&lt;/p&gt;
&lt;p&gt;D’après &lt;a href=&quot;https://serverfault.com/questions/19634/how-to-reconnect-to-a-disconnected-ssh-session#comment1506308_979180&quot;&gt;ce commentaire&lt;/a&gt; :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;git&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; clone&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; https://github.com/nelhage/reptyr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;cd&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; reptyr&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;make&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; install&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cela a installé &lt;code&gt;reptyr&lt;/code&gt; sur la machine.&lt;/p&gt;
&lt;p&gt;Ensuite, j’ai cherché toutes les sessions ouvertes avec &lt;code&gt;ps ax | grep pts&lt;/code&gt; pour trouver le processus qui m’intéressait.&lt;/p&gt;
&lt;p&gt;Puis j’ai trouvé le processus le plus haut dans l’arbre d’appels auquel un &lt;code&gt;pts&lt;/code&gt; était assigné, et je m’y suis attaché via son PID :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;reptyr&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -T&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1390511&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et j’ai enfin pu terminer la mise à jour ! 🎉&lt;/p&gt;</content:encoded><category>Uncategorized</category></item><item><title>[Linux] Syncthing – système de fichiers en lecture seule lorsqu’il tourne en tant que service</title><link>https://bisko.be/fr/posts/dev/linux-syncthing-read-only-file-system-when-running-as-service/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/linux-syncthing-read-only-file-system-when-running-as-service/</guid><description>J’utilise Syncthing depuis un moment pour synchroniser ma copie de travail avec un serveur de dev local, depuis quelques mois. Au début, je l’utilisais en me connectant et en le lançant à la main via la CLI. Ça marchait bien, donc je n’ai pas réfléchi à deux fois quand je suis passé à un lancement en tant que service.</description><pubDate>Wed, 06 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;J’utilise &lt;a href=&quot;https://syncthing.net/&quot;&gt;Syncthing&lt;/a&gt; depuis un moment pour synchroniser ma copie de travail avec un serveur de dev local, depuis quelques mois.&lt;/p&gt;
&lt;p&gt;Au début, je l’utilisais en me connectant et en le lançant à la main via la CLI. Ça marchait bien, donc je n’ai pas réfléchi à deux fois quand je suis passé à un lancement en tant que service. Il a démarré, il a synchronisé des données, tout allait bien.&lt;/p&gt;
&lt;p&gt;Jusqu’à ce que ça ne soit plus le cas, bien sûr ! 🙂&lt;/p&gt;
&lt;p&gt;Il s’avère que je n’avais pas remarqué toute une série d’erreurs qui apparaissaient dans les logs, indiquant que le système de fichiers du serveur de dev était en lecture seule, ce qui empêchait Syncthing de synchroniser quoi que ce soit.&lt;/p&gt;
&lt;p&gt;Je pensais que c’était un bug et qu’il affichait simplement &lt;code&gt;Out of Sync&lt;/code&gt; pour les dossiers, mais qu’il synchronisait quand même. Eh bien, je me trompais.&lt;/p&gt;
&lt;p&gt;Après avoir débogué pendant quelques heures sans trouver le moindre indice sur les forums à coups de recherches Google, je suis tombé sur un &lt;a href=&quot;https://wiki.archlinux.org/title/syncthing#read-only_file_system_error_on_/etc_although_run_as_root&quot;&gt;article sur Syncthing dans l’ArchWiki&lt;/a&gt;, qui décrivait exactement mon cas :&lt;/p&gt;
&lt;p&gt;read-only file system error on /etc although run as root&lt;/p&gt;
&lt;p&gt;C’était exactement mon cas d’usage, sauf que le dossier problématique n’était pas &lt;code&gt;/etc&lt;/code&gt;, mais &lt;code&gt;/usr/local/src&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Bref, après avoir lu ce que ça disait, il s’avère que si vous lancez Syncthing (ou n’importe quoi d’autre) via &lt;code&gt;systemd&lt;/code&gt; et que &lt;code&gt;ProtectSystem&lt;/code&gt; est réglé sur &lt;code&gt;full&lt;/code&gt; pour le service, certains répertoires seront en lecture seule par défaut. &lt;code&gt;/usr&lt;/code&gt; fait partie de ces chemins.&lt;/p&gt;
&lt;p&gt;Pour corriger ça, il faut ajouter une nouvelle ligne dans la configuration du service et redémarrer le service (sans oublier &lt;code&gt;daemon-reload&lt;/code&gt;) :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ReadWritePaths=/usr/local/src&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Après ça, Syncthing devrait fonctionner correctement.&lt;/p&gt;</content:encoded><category>Homelab</category><category>linux</category><category>permissions</category><category>read-only</category><category>syncthing</category><category>systemd</category></item><item><title>[Linux] Exécuter plusieurs commandes sur plusieurs serveurs en parallèle</title><link>https://bisko.be/fr/posts/dev/linux-running-multiple-commands-on-multiple-servers-in-parallel/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/linux-running-multiple-commands-on-multiple-servers-in-parallel/</guid><description>J’ai chez moi un cluster de Raspberry Pi qui font tourner Docker Swarm. Pour garder le contrôle sur tout ça, ils utilisent tous la même configuration : utilisateurs, versions de Docker, etc. Parfois, certaines mises à jour demandent d’exécuter la même chose sur tous les nœuds du cluster – par exemple – créer un nouveau réseau Docker macvlan. Pour</description><pubDate>Mon, 19 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;J’ai chez moi un cluster de Raspberry Pi qui font tourner Docker Swarm. Pour garder le contrôle sur tout ça, ils utilisent tous la même configuration : utilisateurs, versions de Docker, etc.&lt;/p&gt;
&lt;p&gt;Parfois, certaines mises à jour demandent d’exécuter la même chose sur tous les nœuds du cluster – par exemple – créer un nouveau réseau Docker macvlan.&lt;/p&gt;
&lt;p&gt;Pour ça, il faut soit lancer les mêmes commandes à la main sur tous les nœuds, en se connectant en &lt;strong&gt;ssh&lt;/strong&gt; sur chacun d’eux, en exécutant les commandes puis en passant au suivant.&lt;/p&gt;
&lt;p&gt;Comme j’essaie de me faciliter la vie sur le long terme et de garder les choses aussi organisées que possible, je me suis mis à chercher des moyens d’exécuter des commandes sur tous les nœuds en même temps.&lt;/p&gt;
&lt;h3 id=&quot;itération-1--un-script-python-maison&quot;&gt;Itération 1 : un script Python maison&lt;/h3&gt;
&lt;p&gt;La première itération a consisté à écrire un script Python maison. D’un côté, ça me permettait d’apprendre un peu mieux Python ; de l’autre, je ne trouvais pas de moyen correct d’exécuter des commandes de façon plus native.&lt;/p&gt;
&lt;p&gt;Comme on peut s’y attendre (eh, j’ai encore peu d’expérience dans ce langage 🙂 ), c’est devenu un gros bazar assez vite, et ça cassait très facilement.&lt;/p&gt;
&lt;p&gt;Il me fallait trouver une autre solution, sans avoir à réapprendre ce que j’avais fait il y a 3 semaines et ce qui avait planté la dernière fois.&lt;/p&gt;
&lt;h3 id=&quot;itération-2--pssh&quot;&gt;Itération 2 : &lt;code&gt;pssh&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;En fouillant sur Google, je suis tombé sur &lt;code&gt;[pssh](https://linux.die.net/man/1/pssh)&lt;/code&gt;, qui permet d’exécuter des commandes en parallèle via SSH.&lt;/p&gt;
&lt;p&gt;Tout bien considéré, c’était plutôt facile à mettre en place.&lt;/p&gt;
&lt;p&gt;Le problème, c’est que pour exécuter certaines choses, j’avais besoin de passer par &lt;code&gt;sudo&lt;/code&gt;. Faire circuler des mots de passe n’était pas l’idéal, alors j’ai dû chercher à nouveau comment envoyer le mot de passe &lt;code&gt;sudo&lt;/code&gt; quand le serveur distant le demandait.&lt;/p&gt;
&lt;p&gt;Il s’avère que c’est assez simple si on tombe sur le bon &lt;a href=&quot;https://unix.stackexchange.com/a/487558/134974&quot;&gt;commentaire StackOverflow&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;la-version-tldr&quot;&gt;La version TL;DR; :&lt;/h3&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;stty&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -echo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;printf&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Password: &quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;read&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; PASS&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;stty&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; echo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;PASS&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; |&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;pssh&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -h&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;HOSTFIL&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;E&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -o&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; /tmp/output&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -t&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -I&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;`&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;cat&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; ./commands.sh`&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Le &lt;code&gt;-I &quot;`cat ./commands.sh`&quot;&lt;/code&gt; doit obligatoirement être écrit comme ça (entouré de guillemets et d’accents graves), sinon les commandes ne s’exécutent pas correctement. Le mot de passe sera envoyé comme une commande à part et non récupéré comme une entrée de &lt;strong&gt;sudo&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;L’autre subtilité : vu la façon dont tout ça est configuré, il faut lancer &lt;code&gt;sudo&lt;/code&gt; avec le paramètre &lt;code&gt;-S&lt;/code&gt; pour qu’il lise correctement le mot de passe.&lt;/p&gt;</content:encoded><category>Uncategorized</category></item><item><title>Deviner le mot de passe numérique d&apos;un fichier zip uniquement avec des utilitaires en ligne de commande</title><link>https://bisko.be/fr/posts/dev/guessing-a-numeric-zip-file-password-only-with-command-line-utilities/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/guessing-a-numeric-zip-file-password-only-with-command-line-utilities/</guid><description>Aujourd&apos;hui j&apos;ai reçu ma facture mensuelle de mon fournisseur internet et quelque chose m&apos;a semblé bizarre. La facture, contenue dans le mail, était dans un fichier ZIP avec un mot de passe. Sans parler de l&apos;étrangeté de recevoir une pièce jointe sous forme de fichier ZIP de nos jours (spam, malware, phishing, etc.), le</description><pubDate>Mon, 14 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Aujourd’hui j’ai reçu ma facture mensuelle de mon fournisseur internet et quelque chose m’a semblé bizarre.&lt;/p&gt;
&lt;p&gt;La facture, contenue dans le mail, était dans un fichier ZIP avec un mot de passe.&lt;/p&gt;
&lt;p&gt;Sans parler de l’étrangeté de recevoir une pièce jointe sous forme de fichier ZIP de nos jours (spam, malware, phishing, etc.), le mot de passe qu’ils avaient choisi m’a paru très faible.&lt;/p&gt;
&lt;p&gt;C’est la date de naissance du titulaire du compte au format &lt;code&gt;YYMMDD&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;J’ai fait un calcul très grossier dans ma tête pendant que j’étais à la salle de sport et le résultat était un nombre très réduit de combinaisons possibles. Après avoir utilisé un outil en ligne pour calculer le nombre de jours écoulés (puisque toutes les combinaisons ne donneraient pas une date valide) depuis le 1900-01-01, il s’avère que les combinaisons sont seulement 44 075 (jusqu’au 2020-09-14).&lt;/p&gt;
&lt;p&gt;Sachant que des outils optimisés utilisant la puissance du GPU pour craquer des hashs peuvent faire des millions de tentatives par seconde, je voulais voir à quelle vitesse le mot de passe pouvait être deviné sans les utiliser, en me servant uniquement de la ligne de commande Linux/macOS (n’ayant accès qu’à un VPS depuis la salle de sport).&lt;/p&gt;
&lt;p&gt;J’ai concocté le code suivant qui fonctionne sur macOS :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;echo {1..44000} | xargs -P 16 -n 1 -I{} date -v &quot;-{}d&quot; +&quot;%y%m%d&quot; | xargs -P 16 -I{} sh -c &apos;unzip -qqoP &quot;{}&quot; 0417160508.zip &amp;#x26;&amp;#x26; echo &quot;{}&quot; &amp;#x26;&amp;#x26; exit 255&apos;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;La commande est assez simple dans son fonctionnement, même si elle paraît compliquée.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;echo {1..44000}&lt;/code&gt; génère les nombres de 1 à 44 000 et les transmet à l’étape suivante.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;xargs -P 16 -n 1 -I{} date -v &quot;-{}d&quot; +&quot;%y%m%d&quot;&lt;/code&gt; – prend l’entrée de la première étape et génère des dates au format &lt;code&gt;YYMMDD&lt;/code&gt; en exploitant la fonctionnalité de &lt;code&gt;date&lt;/code&gt; permettant « d’augmenter » une date d’une quantité spécifique. Dans ce cas, cela va soustraire X jours à la date actuelle. Où X est le nombre généré à la première étape. Ainsi, on peut générer des dates depuis aujourd’hui jusque dans les années 1900.&lt;/p&gt;
&lt;p&gt;La troisième étape est la plus intéressante, donc je vais la diviser en deux parties :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;xargs -P 16 -I{} sh -c &apos;...&apos;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Cela prend les dates générées à l’étape 2 et exécute une commande sur chacune de ces dates. &lt;code&gt;-P 16&lt;/code&gt; signifie ici que cela va s’exécuter sur 16 processus parallèles, pour accélérer le traitement des données. La même astuce est appliquée à l’étape 2 pour accélérer la génération des dates.&lt;/p&gt;
&lt;p&gt;La deuxième partie est l’endroit où les tentatives ont lieu :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;unzip -qqoP &quot;{}&quot; 0417160508.zip &amp;#x26;&amp;#x26; echo &quot;{}&quot; &amp;#x26;&amp;#x26; exit 255&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ce que cela fait, c’est d’abord essayer de décompresser le fichier zip en utilisant le mot de passe généré à l’étape 2. Si c’est réussi, cela affiche (&lt;code&gt;echo&lt;/code&gt;) le mot de passe deviné puis &lt;code&gt;exit 255&lt;/code&gt; force &lt;code&gt;xargs&lt;/code&gt; à arrêter l’exécution. On ne veut pas continuer à deviner si le mot de passe a été trouvé.&lt;/p&gt;
&lt;p&gt;En somme, c’était une assez mauvaise décision de choisir cela comme mot de passe pour le fichier, car exécuter la commande ci-dessus prend seulement environ 10 secondes pour deviner le bon mot de passe de ma facture. Pas beaucoup plus pour n’importe qui d’autre.&lt;/p&gt;</content:encoded><category>Uncategorized</category></item><item><title>Gérer le code spaghetti en PHP : utiliser des fonctions anonymes pour extraire des morceaux de code de template</title><link>https://bisko.be/fr/posts/dev/dealing-with-spaghetti-code-in-php-using-anonymous-functions-to-extract-pieces-of-template-code/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/dealing-with-spaghetti-code-in-php-using-anonymous-functions-to-extract-pieces-of-template-code/</guid><description>Récemment, j’ai aidé un ami à comprendre du code et à voir comment le modifier pour qu’il fonctionne bien avec des appels asynchrones vers le backend. Un bonus serait de pouvoir l’écrire de façon plus modulaire et réutilisable. Le code est un plugin WordPress qui a été écrit</description><pubDate>Sat, 08 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Récemment, j’ai aidé un ami à essayer de comprendre du code et à voir comment le modifier pour qu’il fonctionne bien avec des appels asynchrones vers le backend. Un bonus serait de pouvoir l’écrire de façon plus modulaire et réutilisable.&lt;/p&gt;
&lt;p&gt;Le code est un plugin WordPress écrit avec une approche très legacy : un mélange de logique métier et de logique frontend au même endroit. Des manipulations de données faites en plein milieu du code de template, et ainsi de suite.&lt;/p&gt;
&lt;p&gt;Bref, ce qu’on voyait sur les sites PHP au début des années 2000, avant toutes les super additions OOP au langage et avant l’arrivée d’un tas de frameworks matures.&lt;/p&gt;
&lt;p&gt;Le cas sur lequel j’ai planché aujourd’hui était le suivant : vous avez un tableau qui affiche plein d’entrées. Il fallait ajouter plusieurs filtres au tableau et le faire fonctionner via AJAX pour rafraîchir rapidement l’UI, sans recharger toute la page d’administration de WordPress.&lt;/p&gt;
&lt;p&gt;Filtrer les données était facile : un petit &lt;code&gt;array_filter&lt;/code&gt; en ligne pour filtrer les données avant de les passer au code du template (pour garder le même style de code, c’était aussi dans le fichier de template 😇).&lt;/p&gt;
&lt;p&gt;Le problème est arrivé quand on a commencé à vouloir rendre le tableau affichable via AJAX.&lt;/p&gt;
&lt;p&gt;Il se trouve au milieu d’un tas d’autre code de template et de code métier. Si on voulait limiter la sortie AJAX au seul tableau, on n’avait que quelques options.&lt;/p&gt;
&lt;p&gt;La première serait d’entourer le HTML avant et après le tableau de GROS blocs &lt;code&gt;if&lt;/code&gt; pour s’assurer qu’il ne soit pas rendu.&lt;/p&gt;
&lt;p&gt;Une autre serait d’extraire le template dans un fichier séparé et de l’inclure dans l’action AJAX que l’on définirait dans le code du plugin.&lt;/p&gt;
&lt;p&gt;Les fonctions anonymes à la rescousse !&lt;/p&gt;
&lt;p&gt;En réfléchissant à la façon la plus simple de gérer ça, j’ai essayé de définir une fonction PHP normale contenant le code du tableau, mais il y avait un problème.&lt;/p&gt;
&lt;p&gt;Le code s’exécute dans une méthode de classe. Il y a des références à &lt;code&gt;$this&lt;/code&gt; dans le template du tableau. Si on ne veut pas trop changer le code, on voudrait passer &lt;code&gt;$this&lt;/code&gt; en argument de la fonction. Eh bien ça ne marche pas trop, car on ne peut pas passer &lt;code&gt;$this&lt;/code&gt; en paramètre 🤷‍♂️.&lt;/p&gt;
&lt;p&gt;J’étais un peu déçu à l’idée de devoir réécrire un tas de choses dans le template, et il y avait pas mal de références qu’on voulait garder en tête pour que tout continue de fonctionner.&lt;/p&gt;
&lt;p&gt;Puis je me suis rappelé que le site ne tourne pas sous PHP 5.2 mais sous PHP 7, et que les fonctions anonymes seraient donc supportées.&lt;/p&gt;
&lt;p&gt;Elles ont cette fonctionnalité bien pratique qui permet de définir quelles variables du scope appelant seront passées à la fonction quand elle est appelée. Par exemple :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$table_function &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ( $pages, $current_page, $items ) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // ... Table render code&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cela vous permet de référencer directement &lt;code&gt;$pages&lt;/code&gt; ou &lt;code&gt;$items&lt;/code&gt; dans le corps de la fonction.&lt;/p&gt;
&lt;p&gt;Ce qui est génial, c’est qu’on peut aussi passer &lt;code&gt;$this&lt;/code&gt; comme variable dans le scope de la fonction !&lt;/p&gt;
&lt;p&gt;On a donc pu extraire complètement le code de rendu du tableau dans une fonction séparée, qu’on peut appeler de façon isolée pendant l’appel AJAX !&lt;/p&gt;
&lt;p&gt;Bien sûr, il faut faire très attention aux variables utilisées dans le corps de la fonction, car elles doivent être définies ; soyez donc prudent quant à l’endroit où la fonction AJAX peut être appelée.&lt;/p&gt;
&lt;p&gt;Pour nous, cela signifie qu’on va ajouter une toute petite action dans la classe principale qui fera toujours le &lt;code&gt;require&lt;/code&gt; du fichier, mais on aura plus de contrôle pour désactiver toutes les autres sorties qui se produiraient.&lt;/p&gt;</content:encoded><category>Snippets</category><category>lambda-functions</category><category>php</category><category>WordPress</category></item><item><title>Arduino/ESP32 : désactiver le watchdog des tâches</title><link>https://bisko.be/fr/posts/dev/arduino-esp32-disabling-the-task-watchdog/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/arduino-esp32-disabling-the-task-watchdog/</guid><description>Récemment, je me suis amusé avec les fonctionnalités multicœur de l’ESP32 et l’épinglage de tâches sur des cœurs spécifiques. J’utilisais AutoConnect pour gérer la connexion WiFi sans stocker d’identifiants dans le code et proposer des mises à jour OTA via l’interface web. C’était pour un projet qui devait contrôler des ventilateurs CPU PWM à 4 broches qui se trouvent dans</description><pubDate>Wed, 29 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Récemment, je me suis amusé avec les fonctionnalités multicœur de l’ESP32 et l’épinglage de tâches sur des cœurs spécifiques.&lt;/p&gt;
&lt;p&gt;J’utilisais &lt;a href=&quot;https://github.com/Hieromon/AutoConnect&quot;&gt;AutoConnect&lt;/a&gt; pour gérer la connexion WiFi sans stocker d’identifiants dans le code et proposer des mises à jour OTA via l’interface web.&lt;/p&gt;
&lt;p&gt;C’était pour un projet qui devait contrôler des ventilateurs CPU PWM à 4 broches qui se trouvent dans mon placard serveur, pour refroidir l’air à l’intérieur. Pour cela, je voulais séparer la logique en deux tâches.&lt;/p&gt;
&lt;p&gt;Une tâche pour gérer les API, la lecture des capteurs, les mises à jour, le WiFi, etc., et une tâche pour gérer l’interruption et le contrôle PWM des ventilateurs.&lt;/p&gt;
&lt;p&gt;Tout allait bien, les tâches étaient créées, mais à l’exécution du code, si je mettais l’ESP32 dans le mode où il faut se connecter à lui pour lui dire de rejoindre votre réseau WiFi, il se mettait à avoir un comportement étrange : il réinitialisait le contrôleur toutes les quelques secondes et je n’arrivais pas à établir la connexion.&lt;/p&gt;
&lt;p&gt;Ce fut un moment pénible, car il fallait démonter le contrôleur de son emplacement et le brancher en USB pour flasher un nouveau firmware.&lt;/p&gt;
&lt;p&gt;Après ça, j’ai remarqué que l’erreur venait du watchdog :&lt;/p&gt;
&lt;p&gt;Task watchdog got triggered. The following tasks did not feed the watchdog in time:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;IDLE (CPU 1)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Tasks currently running:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;CPU 0: ManageTask&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;CPU 1: ControllerTask&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En fouillant un peu, il s’avère que c’est déclenché par le Task Watchdog de l’ESP32, qui s’assure que les tâches aient leur tour d’exécution sur le CPU.&lt;/p&gt;
&lt;p&gt;Il semblait aussi qu’AutoConnect n’était pas très flexible dans le contexte d’une tâche, comparé à une exécution en dehors, directement avec tout le reste du code et des fonctionnalités.&lt;/p&gt;
&lt;p&gt;Après avoir creusé un peu et essayé différentes choses, il semble que le moyen le plus simple de s’en sortir soit de simplement désactiver le watchdog et d’espérer que tout s’exécute à temps 🙂 La tâche n’est pas critique, donc ce n’est pas grave d’attendre plus longtemps qu’elle termine ce qu’elle fait.&lt;/p&gt;
&lt;p&gt;Pour désactiver le watchdog, il faut faire deux choses :&lt;/p&gt;
&lt;p&gt;D’abord, inclure l’en-tête &lt;code&gt;esp_task_wdt.h&lt;/code&gt;. Pour cela, ajoutez &lt;code&gt;#include &amp;#x3C;esp_task_wdt.h&gt;&lt;/code&gt; dans votre section d’includes.&lt;/p&gt;
&lt;p&gt;Ensuite, faire en sorte que le watchdog ne réinitialise pas le contrôleur et attende plus longtemps. Pour cela, ajoutez &lt;code&gt;esp_task_wdt_init(30, false);&lt;/code&gt; au début du code de votre tâche.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;cpp&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; manage_core_task&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;pv_parameters&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    esp_task_wdt_init&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // .... rest of the code ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cela règle le délai du watchdog à 30 &lt;strong&gt;SECONDES&lt;/strong&gt; et désactive la réinitialisation du contrôleur s’il se déclenche.&lt;/p&gt;
&lt;p&gt;Si vous voulez que le contrôleur se réinitialise quand même après le déclenchement du watchdog, changez le second paramètre de l’appel de fonction de &lt;code&gt;false&lt;/code&gt; à &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;</content:encoded><category>Uncategorized</category><category>arduino</category><category>code</category><category>esp32</category><category>espressif</category><category>multi-core</category><category>multi-threading</category></item><item><title>Configurer une YubiKey pour signer ses commits Git</title><link>https://bisko.be/fr/posts/dev/setting-up-a-yubikey-for-git-commit-signing/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/setting-up-a-yubikey-for-git-commit-signing/</guid><description>J’utilise une YubiKey comme clé d’authentification à deux facteurs et pour signer mes commits Git. Jusqu’à il y a quelques jours, j’utilisais une YubiKey 4. Comme mon ordinateur actuel n’a aucun port USB-A, je me trimballais des adaptateurs USB-A vers USB-C dans mon sac à dos et utiliser la clé était devenu une corvée pour le</description><pubDate>Wed, 08 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;J’utilise une YubiKey comme clé d’&lt;a href=&quot;https://fr.wikipedia.org/wiki/Authentification_multifacteur&quot;&gt;authentification à deux facteurs&lt;/a&gt; et pour signer mes commits Git. Jusqu’à il y a quelques jours, j’utilisais une YubiKey 4. Comme mon ordinateur actuel n’a aucun port USB-A, je jongle depuis un an avec des adaptateurs USB-A vers USB-C dans mon sac à dos, et utiliser la clé est devenu une vraie galère. C’est pour ça que j’ai décidé qu’il était temps de passer à ma « nouvelle » YubiKey 5C, et de ne plus avoir à jongler avec ces adaptateurs.&lt;/p&gt;
&lt;p&gt;En fait, j’ai cette clé depuis un moment : je l’avais commandée en même temps qu’une YubiKey 4 de remplacement, à cause du problème du &lt;a href=&quot;https://www.yubico.com/2017/10/infineon-rsa-key-generation-issue/&quot;&gt;TPM Infineon&lt;/a&gt; qu’ils avaient identifié, mais ce n’est que maintenant que je me décide à passer à la nouvelle clé.&lt;/p&gt;
&lt;p&gt;L’autre raison de le faire maintenant, c’est que mes anciennes clés GPG ont expiré et que j’ai dû les réémettre, donc je peux utiliser la clé pour signer mes commits Git.&lt;/p&gt;
&lt;h3 id=&quot;la-folie-gpg&quot;&gt;La folie GPG&lt;/h3&gt;
&lt;p&gt;Si vous avez déjà eu affaire aux clés GPG (ou si c’est le cas en ce moment), vous savez qu’il peut être assez difficile de tout mettre en place correctement et en toute sécurité quand on ne l’a jamais fait. Garder les clés maîtresses hors ligne, faire circuler les clés publiques, réémettre les clés quand elles expirent, éventuellement les signer avec les clés précédentes pour les vérifier, révoquer des clés… Il n’est déjà pas facile de suivre les bonnes pratiques en théorie. Quand il s’agit de les appliquer en pratique, ça devient extrêmement compliqué.&lt;/p&gt;
&lt;p&gt;La plupart des tutoriels en ligne expliquent comment générer ses clés en ligne de commande, en naviguant dans des menus au design peu commun, et c’est une vraie plaie à mettre en place. La plupart disent d’utiliser une machine hors ligne, comme un Raspberry PI, et/ou de générer les clés maîtresses et les sous-clés hors ligne, puis de garder la clé maîtresse loin de votre ordinateur.&lt;/p&gt;
&lt;p&gt;🤯&lt;/p&gt;
&lt;p&gt;Je me coltine ça chaque début de janvier depuis presque 4 ans. Je redoute le moment où j’obtiens l’erreur suivante, qui m’indique que mes clés de signature ont expiré.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;error: gpg failed to sign the data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;fatal: failed to write commit object&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette année, j’ai décidé qu’il était temps d’essayer de rendre ce processus beaucoup plus simple, en utilisant la génération de certificats intégrée et en évitant toute la galère de la génération de clés GPG et compagnie.&lt;/p&gt;
&lt;h3 id=&quot;génération-des-clés-directement-sur-la-yubikey&quot;&gt;Génération des clés directement sur la YubiKey&lt;/h3&gt;
&lt;p&gt;Il faut toujours passer par l’interface en ligne de commande, mais c’est un peu plus évident, car il y a moins d’étapes.&lt;/p&gt;
&lt;p&gt;Il faut d’abord configurer la carte/l’appareil.&lt;/p&gt;
&lt;h3 id=&quot;configuration-de-la-cartede-lappareil&quot;&gt;Configuration de la carte/de l’appareil&lt;/h3&gt;
&lt;p&gt;Lancez &lt;code&gt;gpg --card-status&lt;/code&gt; dans le terminal et vous devriez voir quelque chose comme ceci :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Reader ………..: Yubico Yubikey 4 OTP U2F CCID&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Application ID …: &amp;#x3C;Serial number&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Version ……….: 2.1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Manufacturer …..: Yubico&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Serial number ….: &amp;#x3C;Device serial number&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Name of cardholder: unspecified&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Language prefs …: en&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Sex …………..: unspecified&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;URL of public key : \[not set\]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Login data …….: &amp;#x3C;e-mail or nothing&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Signature PIN ….: not forced&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Key attributes …: rsa4096 rsa4096 rsa4096&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Max. PIN lengths .: 127 127 127&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;PIN retry counter : 3 0 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Signature counter : 9&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si vous voyez quelque chose de similaire et qu’aucune erreur n’apparaît, vous pouvez continuer.&lt;/p&gt;
&lt;p&gt;Lancez &lt;code&gt;gpg --card-edit&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Vous arriverez dans une interface en ligne de commande qui affiche les mêmes informations qu’au début, puis une invite de commande en bas : &lt;code&gt;gpg/card&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tapez &lt;code&gt;admin&lt;/code&gt; et appuyez sur Entrée.&lt;/p&gt;
&lt;p&gt;Vous pouvez maintenant taper &lt;code&gt;help&lt;/code&gt; pour découvrir comment modifier les informations du titulaire et les codes PIN de la carte.&lt;/p&gt;
&lt;p&gt;Il y a une chose que vous &lt;strong&gt;&lt;em&gt;DEVEZ&lt;/em&gt;&lt;/strong&gt; faire : changer les codes PIN par défaut de la carte. Il y en a deux. Le premier est le code PIN que vous utilisez pour accéder aux clés de la carte. Le second est le PIN « Admin » ou PUK (Personal Unblocking Code, code de déblocage personnel).&lt;/p&gt;
&lt;p&gt;Pour cela, tapez &lt;code&gt;passwd&lt;/code&gt; et vous verrez un menu :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;gpg/card&gt; passwd  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;gpg: OpenPGP card no. &amp;#x3C;Serial number&gt; detected&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;1 - change PIN  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;2 - unblock PIN  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;3 - change Admin PIN  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;4 - set the Reset Code  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Q - quit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tapez &lt;code&gt;1&lt;/code&gt; et suivez les instructions pour changer votre PIN. Le PIN par défaut est &lt;code&gt;123456&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ensuite, choisissez &lt;code&gt;3&lt;/code&gt; pour changer le PIN Admin. Celui par défaut est &lt;code&gt;12345678&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Une fois les deux PIN changés, revenez au menu principal pour terminer la mise à jour des informations de la clé.&lt;/p&gt;
&lt;p&gt;Les commandes que vous pouvez utiliser sont :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; – pour changer le nom du titulaire&lt;/li&gt;
&lt;li&gt;&lt;code&gt;login&lt;/code&gt; – pour changer l’adresse e-mail ou l’identifiant du titulaire&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Après cela, nous pouvons passer à la génération des clés proprement dite.&lt;/p&gt;
&lt;h3 id=&quot;génération-des-clés&quot;&gt;Génération des clés&lt;/h3&gt;
&lt;p&gt;Il est maintenant temps de générer les clés.&lt;/p&gt;
&lt;p&gt;Pour cela, tapez &lt;code&gt;generate&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On vous demandera &lt;code&gt;Make off-card backup of encryption key? (Y/n)&lt;/code&gt;, mais comme l’indique la documentation de YubiKey, il ne s’agit que d’une sauvegarde factice qui ne crée pas de sauvegarde complète des clés secrètes, donc peu importe que vous répondiez &lt;code&gt;Yes&lt;/code&gt; ou &lt;code&gt;No&lt;/code&gt;. Je réponds &lt;code&gt;No(n)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;S’il y a déjà des clés stockées sur la carte, on vous demandera si vous voulez les remplacer :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;gpg: Note: keys are already stored on the card!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Replace existing keys? (y/N)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assurez-vous de ne pas remplacer quelque chose d’important dont vous n’avez pas de sauvegarde, puis continuez avec &lt;code&gt;Y&lt;/code&gt;. S’il y a quelque chose d’important, mieux vaut quitter tout le processus avec &lt;code&gt;Ctrl+C&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On vous demandera le code PIN de la carte que vous avez défini plus tôt.&lt;/p&gt;
&lt;p&gt;Ensuite, vous devrez choisir la durée de validité des clés :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Please specify how long the key should be valid.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;        0 = key does not expire&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;      &amp;#x3C;n&gt; = key expires in n days&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;     &amp;#x3C;n&gt;w = key expires in n weeks&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;     &amp;#x3C;n&gt;m = key expires in n months&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;     &amp;#x3C;n&gt;y = key expires in n years&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; Key is valid for? (0)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si vous voulez que les clés ne soient valides qu’un an, tapez &lt;code&gt;1y&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On vous demandera de confirmer la date d’expiration. Vérifiez que tout est correct et confirmez.&lt;/p&gt;
&lt;p&gt;Ensuite, on vous demandera de saisir les informations du propriétaire de la clé :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Is this correct? (y/N) y&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;GnuPG needs to construct a user ID to identify your key.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Real name: &amp;#x3C;Your name&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Email address: &amp;#x3C;Your e-mail&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Comment: &amp;#x3C;Comment is optional&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; You selected this USER-ID:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;     &quot;&amp;#x3C;Your name&gt; &amp;#x3C;comment&gt; &amp;#x3C;your e-mail&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt; Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Type `O` to confirm if everything seems correct.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ensuite, on vous demandera votre PIN Admin ou PUK. C’est nécessaire, car cela effectue une opération d’écriture sur la carte.&lt;/p&gt;
&lt;p&gt;Si tout est correct, la YubiKey se mettra à clignoter et continuera un bon moment (pour moi, environ cinq minutes).&lt;/p&gt;
&lt;p&gt;Une fois terminé, vous verrez le message suivant :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;gpg: key &amp;#x3C;Short ID&gt; marked as ultimately trusted&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;gpg: revocation certificate stored as &apos;/Users/bisko/.gnupg/openpgp-revocs.d/&amp;#x3C;LONG ID&gt;.rev&apos; public and secret key created and signed.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notez bien le &lt;code&gt;&amp;#x3C;Short ID&gt;&lt;/code&gt;, car nous l’utiliserons plus tard.&lt;/p&gt;
&lt;p&gt;À ce stade, vous pouvez quitter l’invite GPG avec &lt;code&gt;quit&lt;/code&gt; ou &lt;code&gt;Ctrl+C&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Il est maintenant temps de sauvegarder la clé publique, afin de pouvoir réutiliser la clé sur un autre ordinateur.&lt;/p&gt;
&lt;p&gt;Pour cela, lancez la commande suivante :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;gpg&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --armor&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --export&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Short&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; I&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;D&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Short&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; I&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;D&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.asc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cela exportera la clé publique dans un fichier nommé &lt;code&gt;&amp;#x3C;Short ID&gt;.asc&lt;/code&gt;. Il vous servira plus tard si vous voulez utiliser la YubiKey sur un autre ordinateur ou si vous perdez votre configuration GPG.&lt;/p&gt;
&lt;p&gt;Pour restaurer la clé publique dans votre trousseau, il faut faire :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;gpg&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --import&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Short&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; I&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;D&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.asc&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;gpg:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; key&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Short&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; I&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;D&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; public&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; key&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Your Name &amp;#x3C;your@email&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; imported&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;gpg:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; Total&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; number&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; processed:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;gpg:&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; imported:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Une remarque très importante ici.&lt;/em&gt;&lt;/strong&gt; S’il s’agit d’une nouvelle installation de GPG ou d’un autre ordinateur, GPG ne reconnaîtra pas tout seul les clés présentes sur la carte. Vous devez lancer &lt;code&gt;gpg --card-status&lt;/code&gt; pour qu’il lise la carte et détecte les clés qui s’y trouvent.&lt;/p&gt;
&lt;h3 id=&quot;configurer-git-pour-la-signature&quot;&gt;Configurer Git pour la signature&lt;/h3&gt;
&lt;p&gt;Pour configurer Git afin qu’il signe vos commits, vous devez ajouter ce qui suit à votre &lt;code&gt;~/.gitconfig&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Dans la section &lt;code&gt;[user]&lt;/code&gt;, ajoutez (ou mettez à jour) la ligne suivante :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;signingkey = 0x&amp;#x3C;Short ID&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ensuite, si vous voulez signer tous vos commits, ajoutez ce qui suit à la fin du fichier :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;ini&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[gpg]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  program&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; = /usr/local/bin/gpg&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;[commit]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  gpgsign&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; = true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Git signera alors tous vos commits.&lt;/p&gt;
&lt;p&gt;Pour configurer GitHub, vous devez ajouter votre clé publique à votre profil. Pour cela, allez dans &lt;code&gt;GitHub -&gt; Settings -&gt; SSH and GPG keys -&gt; New GPG key&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Vous verrez alors une zone de texte dans laquelle vous devez coller tout le contenu du fichier &lt;code&gt;&amp;#x3C;Short ID&gt;.asc&lt;/code&gt; que nous avons généré plus haut.&lt;/p&gt;
&lt;p&gt;Si vous voulez copier le contenu du fichier (sur macOS), vous pouvez faire :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cat &amp;#x3C;Short ID&gt;.asc | pbcopy&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Cela copiera le contenu de tout le fichier dans le presse-papiers.&lt;/p&gt;
&lt;p&gt;Collez-le dans la zone de texte sur GitHub et cliquez sur le bouton &lt;code&gt;Add GPG key&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Après ça, vous pouvez essayer de faire un commit et un push vers GitHub, et vous devriez voir le joli badge &lt;code&gt;Verified&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;débogage&quot;&gt;Débogage&lt;/h3&gt;
&lt;p&gt;Parfois, les choses ne fonctionnent pas du premier coup. Pour obtenir plus d’informations, vous pouvez essayer ce qui suit :&lt;/p&gt;
&lt;h3 id=&quot;signer-avec-gpg&quot;&gt;Signer avec GPG&lt;/h3&gt;
&lt;p&gt;Essayez d’abord de signer quelque chose avec la clé :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;gpg -s &amp;#x3C;file&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Si ça échoue, essayez de comprendre pourquoi. Je ne suis pas expert, donc je ne pourrai pas vous aider sur ce point.&lt;/p&gt;
&lt;p&gt;Regardez la sortie de Git avecGIT_TRACE=1 git commit -am “test”&lt;/p&gt;
&lt;p&gt;Cela vous donnera le détail de tout ce que Git fait quand il essaie de faire le commit et de le signer. Cela devrait vous donner une idée de la raison de l’échec de la signature.&lt;/p&gt;
&lt;p&gt;Vous pouvez aussi y voir que Git exécute la commande suivante :&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sh&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;/usr/local/bin/gpg&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; --status-fd=2&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; -bsau&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;Key&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; I&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;D&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vous pouvez essayer de l’exécuter manuellement pour voir si elle vous donne une meilleure erreur.&lt;/p&gt;</content:encoded><category>Snippets</category><category>Technology</category><category>git</category><category>github</category><category>gpg</category><category>key</category><category>public-key</category><category>secrets</category><category>sign</category><category>yubikey</category></item><item><title>e1000e  eth0: Detected Hardware Unit Hang</title><link>https://bisko.be/fr/posts/dev/e1000e-device-id-eth0-detected-hardware-unit-hang/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/e1000e-device-id-eth0-detected-hardware-unit-hang/</guid><description>Récemment, mon serveur maison et hôte de VM a commencé à perdre sa connectivité réseau de façon aléatoire. De l&apos;extérieur, on aurait dit qu&apos;il fonctionnait toujours, mais impossible d&apos;y accéder à distance, quelle que soit la méthode. L&apos;adaptateur ethernet semblait actif d&apos;après le switch, donc le problème devait se trouver quelque part côté logiciel. Ce ne serait pas</description><pubDate>Wed, 18 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Récemment, mon serveur maison et hôte de VM a commencé à perdre sa connectivité réseau de façon aléatoire. De l’extérieur, on aurait dit qu’il fonctionnait toujours, mais impossible d’y accéder à distance, quelle que soit la méthode. L’adaptateur ethernet semblait actif d’après le switch, donc le problème devait se trouver quelque part côté logiciel.&lt;/p&gt;
&lt;p&gt;Ce ne serait pas la première fois qu’un pilote est à l’origine d’une connexion réseau qui plante. Par le passé, je me suis déjà fait avoir par des pilotes WiFi buggés sur des machines Linux et Windows.&lt;/p&gt;
&lt;p&gt;Après avoir fouillé un peu dans les logs système, je suis tombé sur ceci :&lt;/p&gt;
&lt;p&gt;vmhost kernel: e1000e 0000:00:1f.6 eth0: Detected Hardware Unit Hang:&lt;br&gt;
vmhost kernel:   TDH                  &amp;#x3C;0&gt;&lt;br&gt;
vmhost kernel:   TDT                  &amp;#x3C;1&gt;&lt;br&gt;
vmhost kernel:   next_to_use          &amp;#x3C;1&gt;&lt;br&gt;
vmhost kernel:   next_to_clean        &amp;#x3C;0&gt;&lt;br&gt;
vmhost kernel: buffer_info[next_to_clean]:&lt;br&gt;
vmhost kernel:   time_stamp           &amp;#x3C;10fbc2f81&gt;&lt;br&gt;
vmhost kernel:   next_to_watch        &amp;#x3C;0&gt;&lt;br&gt;
vmhost kernel:   jiffies              &amp;#x3C;10fbc3871&gt;&lt;br&gt;
vmhost kernel:   next_to_watch.status &amp;#x3C;0&gt;&lt;br&gt;
vmhost kernel: MAC Status             &amp;#x3C;40080083&gt;&lt;br&gt;
vmhost kernel: PHY Status             &amp;#x3C;796d&gt;&lt;br&gt;
vmhost kernel: PHY 1000BASE-T Status  &amp;#x3C;7800&gt;&lt;br&gt;
vmhost kernel: PHY Extended Status    &amp;#x3C;3000&gt;&lt;br&gt;
vmhost kernel: PCI Status             &amp;#x3C;10&gt;&lt;br&gt;
vmhost kernel: e1000e 0000:00:1f.6 eth0: Reset adapter unexpectedly&lt;br&gt;
vmhost kernel: vmbr0: port 1(eth0) entered disabled state&lt;/p&gt;
&lt;p&gt;Ensuite, il réinitialisait l’adaptateur réseau, puis recommençait un peu plus tard, jusqu’à ce que la machine passe complètement hors ligne.&lt;/p&gt;
&lt;p&gt;En cherchant des réponses en ligne, je suis tombé sur &lt;a href=&quot;https://serverfault.com/questions/616485/e1000e-reset-adapter-unexpectedly-detected-hardware-unit-hang&quot;&gt;ce fil ServerFault&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cause&lt;/p&gt;
&lt;p&gt;D’après différentes sources et listes de rapports de bugs, la meilleure façon de reproduire le problème semble être de mettre l’appareil dans une situation de forte bande passante, c’est-à-dire de faire transiter de grandes quantités de données qui saturent l’interface.&lt;/p&gt;
&lt;p&gt;Dans mon cas, ça arrivait généralement quand je diffusais des médias depuis le serveur Plex local vers un appareil. À cause de la façon dont le réseau est configuré, la VM Windows qui fait tourner Plex doit récupérer le fichier média depuis un partage réseau NFS sur un autre appareil, le transcoder dans la VM, puis l’envoyer à l’appareil de lecture.&lt;/p&gt;
&lt;p&gt;Ça représente beaucoup de trafic réseau, généralement ~40-100 mbit/s, selon l’appareil qui lit le fichier et la qualité du fichier source.&lt;/p&gt;
&lt;p&gt;Le même problème s’est manifesté en streamant des jeux via Steam Link vers notre Apple TV. La connexion est filaire, mais il n’est pas rare que le réseau tombe. Je pense que c’est lié au même problème, mais je garde un œil dessus pour voir si ça se reproduit après le correctif.&lt;/p&gt;
&lt;p&gt;Correctif possible&lt;/p&gt;
&lt;p&gt;Il semblerait qu’un correctif possible consiste à désactiver &lt;strong&gt;GSO&lt;/strong&gt; &lt;em&gt;(Generic Segmentation Offload)&lt;/em&gt;, &lt;strong&gt;TSO&lt;/strong&gt; &lt;em&gt;(TCP Segmentation Offload)&lt;/em&gt; et &lt;strong&gt;GRO&lt;/strong&gt; &lt;em&gt;(Generic Receive Offload)&lt;/em&gt; sur l’interface réseau* :&lt;/p&gt;
&lt;p&gt;ethtool -K eth0 gso off gro off tso off&lt;/p&gt;
&lt;p&gt;J’ai appliqué ça à ma configuration et j’attends de voir si ça résout vraiment le problème sur le long terme.&lt;/p&gt;
&lt;p&gt;Notes de bas de page&lt;/p&gt;
&lt;p&gt;* Ces options servent à déléguer la segmentation des paquets au contrôleur d’interface réseau afin de réduire l’utilisation du CPU de la machine. Plus de détails dans &lt;a href=&quot;https://en.wikipedia.org/wiki/Large_send_offload&quot;&gt;cet article de Wikipédia&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>Homelab</category><category>bandwidth</category><category>bug</category><category>network</category><category>nic</category><category>plex</category><category>proxmox</category><category>steam</category><category>streaming</category></item><item><title>Snippets : faire tourner un registre d&apos;images Docker local/privé avec swarm</title><link>https://bisko.be/fr/posts/dev/snippets-running-a-local-private-swarm-docker-image-registry/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/snippets-running-a-local-private-swarm-docker-image-registry/</guid><description>Aujourd&apos;hui, j&apos;essayais de générer une image Docker à partir d&apos;un projet Node.js et je voulais la déployer sur mon swarm de test local. Malheureusement, quand on construit une image Docker en local, elle n&apos;est stockée et accessible que sur le nœud où elle a été créée, et les autres nœuds du swarm n&apos;y ont pas accès. La</description><pubDate>Fri, 11 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Aujourd’hui, j’essayais de générer une image Docker à partir d’un projet Node.js et je voulais la déployer sur mon swarm de test local.&lt;/p&gt;
&lt;p&gt;Malheureusement, quand on construit une image Docker en local, elle n’est stockée et accessible que sur le nœud où elle a été créée, et les autres nœuds du swarm n’y ont pas accès.&lt;/p&gt;
&lt;p&gt;Pour régler ça, il faut pousser l’image vers un registre Docker où tous les nœuds du swarm pourront la récupérer.&lt;/p&gt;
&lt;p&gt;Création du registre&lt;/p&gt;
&lt;p&gt;Pour instancier un service de registre dans le swarm, lancez :&lt;/p&gt;
&lt;p&gt;docker service create —name registry —publish 5000:5000 registry:latest&lt;/p&gt;
&lt;p&gt;Cela va créer le service de registre et l’exécuter dans le swarm, le rendant accessible à tous les nœuds du swarm.&lt;/p&gt;
&lt;p&gt;Pousser une image vers le registre&lt;/p&gt;
&lt;p&gt;Pour pousser une image vers le registre, il y a deux choses à faire : taguer l’image, puis la pousser.&lt;/p&gt;
&lt;p&gt;Voici un exemple pour construire et taguer l’image en une seule fois :&lt;/p&gt;
&lt;p&gt;docker build . -t localhost.localdomain:5000/&lt;image-name&gt;:latest&lt;/image-name&gt;&lt;/p&gt;
&lt;p&gt;Et comment la pousser vers le registre :&lt;/p&gt;
&lt;p&gt;docker push localhost.localdomain:5000/&lt;image-name&gt;:latestUtiliser l’image dans un service/conteneur/etc.&lt;/image-name&gt;&lt;/p&gt;
&lt;p&gt;Pour utiliser l’image dans un service ou un conteneur, on indique le chemin complet vu plus haut, c’est-à-dire &lt;code&gt;localhost.localdomain:5000/&amp;#x3C;image-name&gt;:latest&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Les nœuds du swarm auront accès à l’image et pourront la récupérer et l’exécuter.&lt;/p&gt;
&lt;p&gt;Remarque importante sur l’adresse du registre&lt;/p&gt;
&lt;p&gt;Dans la plupart des tutoriels en ligne, l’URL du registre est donnée sous la forme &lt;code&gt;localhost:5000&lt;/code&gt;. Malheureusement, ça ne fonctionne pas et on obtient généralement un timeout quand on essaie de l’utiliser. Si on la remplace par &lt;code&gt;localhost.localdomain&lt;/code&gt;, ça marche !&lt;/p&gt;
&lt;p&gt;Je ne sais pas pourquoi ça se passe ainsi, alors que &lt;code&gt;localhost&lt;/code&gt; et &lt;code&gt;localhost.localdomain&lt;/code&gt; se résolvent tous les deux en &lt;code&gt;127.0.0.1&lt;/code&gt;.&lt;/p&gt;</content:encoded><category>Homelab</category><category>Snippets</category><category>Technology</category><category>docker</category><category>docker-swarm</category><category>registry</category><category>swarm</category></item><item><title>Snippets : remapper la touche Section des claviers Apple sur l&apos;accent grave ( § vers ` )</title><link>https://bisko.be/fr/posts/dev/snippets-map-apple-keyboard-section-sign-key-to-back-quote-%C2%A7-to/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/snippets-map-apple-keyboard-section-sign-key-to-back-quote-%C2%A7-to/</guid><description>J&apos;utilise des claviers Apple depuis un moment, mais quand on vit en Europe, il n&apos;est pas facile de trouver les modèles avec la disposition US auxquels je suis habitué. Sur macOS, il existe une façon « facile » de remapper le clavier avec une simple commande dans le terminal : watch -n1 -x hidutil property -m ‘{“ProductID”:592, “VendorID”:1452}’ –set ‘{“UserKeyMapping”:[{“HIDKeyboardModifierMappingSrc”:0x700000035,”HIDKeyboardModifierMappingDst”:0x700000064}]}’ Ce que ce</description><pubDate>Wed, 31 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;J’utilise des claviers Apple depuis un moment, mais quand on vit en Europe, il n’est pas facile de trouver les modèles avec la disposition US auxquels je suis habitué.&lt;/p&gt;
&lt;p&gt;Sur macOS, il existe une façon « facile » de remapper le clavier avec une simple commande dans le terminal :&lt;/p&gt;
&lt;p&gt;watch -n1 -x hidutil property -m ’{“ProductID”:592, “VendorID”:1452}’ —set ’{“UserKeyMapping”:[{“HIDKeyboardModifierMappingSrc”:0x700000035,“HIDKeyboardModifierMappingDst”:0x700000064}]}’&lt;/p&gt;
&lt;p&gt;Ce que fait ce morceau de code, c’est changer le mappage de la touche Section ( § ) pour qu’elle écrive la touche accent grave/tilde ( &lt;code&gt;`/ ~&lt;/code&gt; ).&lt;/p&gt;
&lt;p&gt;La partie &lt;code&gt;watch -n1 -x&lt;/code&gt; répète l’opération toutes les secondes, parce que macOS aime parfois perdre le réglage, généralement quand l’ordinateur se met en veille ou quand le clavier est débranché puis rebranché.&lt;/p&gt;
&lt;p&gt;Notez que sur certaines versions de macOS, l’utilitaire &lt;code&gt;watch&lt;/code&gt; n’est pas installé et doit être récupéré via quelque chose comme &lt;a href=&quot;https://brew.sh/&quot;&gt;Homebrew&lt;/a&gt; ou &lt;a href=&quot;https://www.macports.org/&quot;&gt;MacPorts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Le code ci-dessus fonctionne avec le clavier externe Apple en USB, disposition européenne avec lettres bulgares. Il faudra peut-être ajuster légèrement les valeurs hexadécimales des touches pour d’autres types de claviers.&lt;/p&gt;
&lt;p&gt;Une variante de la commande fonctionne bien pour le même type de clavier sur le MacBook Pro lui-même. Il suffit d’inverser la position des valeurs &lt;code&gt;0x700000035&lt;/code&gt; et &lt;code&gt;0x700000064&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;J’ai pensé à écrire un outil pour faire ça automatiquement, mais pour l’instant, je crois qu’il vaut mieux investir dans un nouveau clavier avec la bonne disposition 🙂&lt;/p&gt;</content:encoded><category>Uncategorized</category></item><item><title>Réinitialiser/Redémarrer la télécommande de l&apos;Apple TV</title><link>https://bisko.be/fr/posts/dev/resetting-restarting-apple-tv-remote/</link><guid isPermaLink="true">https://bisko.be/fr/posts/dev/resetting-restarting-apple-tv-remote/</guid><description>Hier soir, pendant la visite d&apos;invités, j&apos;ai réussi à plonger notre télécommande Apple TV sous l&apos;eau. Le manque de sommeil et des verres instables, ça donne des accidents. La télécommande fonctionnait très bien hier soir, mais aujourd&apos;hui, elle ne marche plus. Aucune réaction, quoi que je fasse. J&apos;ai essayé de la cogner contre ma main, de la secouer pour en faire sortir l&apos;eau. Ça</description><pubDate>Sun, 17 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hier soir, pendant la visite d’invités, j’ai réussi à plonger notre télécommande Apple TV sous l’eau. Le manque de sommeil et des verres instables, ça donne des accidents.&lt;/p&gt;
&lt;p&gt;La télécommande fonctionnait très bien hier soir, mais aujourd’hui, elle ne marche plus. Aucune réaction, quoi que je fasse. J’ai essayé de la cogner contre ma main, de la secouer pour en faire sortir l’eau. Ça n’a servi à rien.&lt;/p&gt;
&lt;p&gt;On a pensé qu’elle était fichue et on a commencé à chercher le sachet de riz dans les placards.&lt;/p&gt;
&lt;p&gt;Je suis allé sur internet, surtout pour rire, pour voir si je pouvais essayer de la « redémarrer ».&lt;/p&gt;
&lt;p&gt;Un guide bien utile m’a indiqué de maintenir enfoncés les boutons Volume Plus et Menu pendant 2-3 secondes pour réinitialiser la télécommande et la mettre en mode d’appairage.&lt;/p&gt;
&lt;p&gt;J’ai été vraiment surpris quand &lt;strong&gt;ça a vraiment&lt;/strong&gt; &lt;strong&gt;marché&lt;/strong&gt; !&lt;/p&gt;
&lt;p&gt;Donc, si quelque chose cloche, essayez d’abord de réinitialiser la télécommande. Si ça ne marche pas, vous pourrez toujours tenter le riz et l’intervention matérielle.&lt;/p&gt;
&lt;p&gt;TL;DR;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Maintenez Menu + Volume Plus pendant 2-3 secondes&lt;/li&gt;
&lt;li&gt;Attendez quelques secondes&lt;/li&gt;
&lt;li&gt;Essayez d’interagir avec l’Apple TV&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>Apple</category><category>Technology</category><category>AppleTV</category><category>Have you tried turning it off and on again?</category><category>remote</category><category>reset</category><category>restart</category></item></channel></rss>