<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    
    <title>The Blue Book</title>
    <description>My personal digital garden</description>
    <link>https://lyz-code.github.io/blue-book</link>
    <atom:link href="https://lyz-code.github.io/blue-book/daily.xml" rel="self" type="application/rss+xml"/>

    
    <managingEditor>Lyz</managingEditor>

    
    <pubDate>2026-09-07 15:49:32+00:00</pubDate>
    <ttl>1440</ttl>

    
    <generator>mkdocs-newsletter - v1.1.0</generator>

    
    
    <image><url>https://lyz-code.github.io/blue-book/img/logo.bmp</url><title>The Blue Book</title>
      <link>https://lyz-code.github.io/blue-book</link>
    </image>
    

    
    
    <item><title>3rd September 2026</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt; &lt;ul&gt; &lt;li&gt;Correction: Replace broken awesome-prometheus-alerts link.&lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;September 7, 2026 15:49:32 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2026-09-07T15:49:32+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;September 7, 2026 15:49:32 UTC&#34;&gt;2026-09-07&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2026_09_03/</link>
      <pubDate>2026-09-07 15:49:32+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2026_09_03/</guid>
      
    </item>
    
    <item><title>25th December 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;life-navigation&#34;&gt;Life navigation&lt;/h2&gt; &lt;h3 id=&#34;content-management&#34;&gt;Content Management&lt;/h3&gt; &lt;h4 id=&#34;jellyfin&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/&#34;&gt;Jellyfin&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#rollback&#34;&gt;How to rollback.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Copy the &lt;code&gt;/srv/jellyfin/app&lt;/code&gt; directory to &lt;code&gt;bk.app&lt;/code&gt; and then restore the directory from backup.&lt;/p&gt; &lt;p&gt;If the permissions have gone amiss you&#39;ll need to fix them before you start the server or you&#39;ll get an &lt;code&gt;attempt to write a readonly database&lt;/code&gt; error feat(linux_snippets#Resize an image): Resize an image&lt;/p&gt; &lt;p&gt;To resize an image, you can use the convert command from ImageMagick. For example, to resize an image named input.jpg to have a width of 800 pixels while maintaining the aspect ratio, use the following command:&lt;/p&gt;  &lt;p&gt;You can also specify both width and height if you want to resize the image to specific dimensions:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;convert&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.jpg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-resize&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;800x600&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input_resized_exact.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;beets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/beets/&#34;&gt;Beets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/beets/#plugins&#34;&gt;Add plugins.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://beets.readthedocs.io/en/stable/plugins/chroma.html&#34;&gt;Chromaprint&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Programmatically interact with beets&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There is the &lt;a href=&#34;https://beets.readthedocs.io/en/v1.3.18/dev/api.html&#34;&gt;python api reference&lt;/a&gt; but I don&#39;t see how to import for example.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;technology&#34;&gt;Technology&lt;/h2&gt; &lt;h3 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h3&gt; &lt;h4 id=&#34;vector&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vector/&#34;&gt;vector&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vector/#vector-permission-debugging-with-systemd-tmpfiles&#34;&gt;Vector Permission Debugging with systemd tmpfiles.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Vector fails to read log files after reboots or log rotation with permission errors:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ERROR: Failed reading file for fingerprinting. error=Permission denied (os error 13)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Solution with tmpfiles&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Create &lt;code&gt;/etc/tmpfiles.d/vector-permissions.conf&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;z /data/apps/myapp/logs/logfile.log 0644 vector vector -
z /path/to/another/logfile.log 0644 vector vector -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Apply immediately:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemd-tmpfiles&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/tmpfiles.d/vector-permissions.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;What is tmpfiles&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;systemd tmpfiles.d is a mechanism for managing temporary files, directories, and their permissions at boot time and periodically during system operation.&lt;/p&gt; &lt;p&gt;What it does:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Creates/removes files and directories&lt;/li&gt; &lt;li&gt;Sets ownership and permissions&lt;/li&gt; &lt;li&gt;Runs at boot via systemd-tmpfiles-setup.service&lt;/li&gt; &lt;li&gt;Can be triggered manually or periodically&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Configuration format:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Type Path Mode UID GID Age Argument
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Common types:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;d&lt;/code&gt; - Create directory&lt;/li&gt; &lt;li&gt;&lt;code&gt;f&lt;/code&gt; - Create file&lt;/li&gt; &lt;li&gt;&lt;code&gt;z&lt;/code&gt; - Set ownership/permissions on existing path&lt;/li&gt; &lt;li&gt;&lt;code&gt;Z&lt;/code&gt; - Recursively set ownership/permissions&lt;/li&gt; &lt;li&gt;&lt;code&gt;x&lt;/code&gt; - Ignore/exclude path&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;d /var/run/myapp 0755 myuser mygroup -
f /var/log/myapp.log 0644 myuser mygroup -
z /existing/file 0644 myuser mygroup -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Files in /etc/tmpfiles.d/ with .conf extension are processed automatically at boot and can be manually applied with systemd-tmpfiles --create. Also, if the &lt;code&gt;systemd-tmpfiles-clean.timer&lt;/code&gt; is enabled (which is by default) it will be check each day.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#fix-systemd-tmpfiles-detected-unsafe-path-transition-/-→-/dev-during-canonicalization-of-/dev.&#34;&gt;Fix systemd-tmpfiles Detected unsafe path transition / → /dev during canonicalization of /dev.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;with each system start&lt;/p&gt; &lt;p&gt;Here are some examples of the logs: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemd-tmpfiles[248]: Detected unsafe path transition / → /dev during canonicalization of /dev.
systemd-tmpfiles[485]: Detected unsafe path transition / → /var during canonicalization of /var.
systemd-tmpfiles[485]: Detected unsafe path transition / → /var during canonicalization of /var/lib.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;This suggests that your root dir, /dev and /var are owned by differing users&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;brain-food&#34;&gt;Brain food&lt;/h2&gt; &lt;h3 id=&#34;galas&#34;&gt;Galas&lt;/h3&gt; &lt;h4 id=&#34;galas-2025&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/galas_2025/&#34;&gt;Galas 2025&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir las galas de 2025.&lt;/p&gt; &lt;p&gt;Los premios al mejor contenido de 2025.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;#mejores-libros-de-2025&#34;&gt;Mejores libros de 2025&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#mejores-series-de-2025&#34;&gt;Mejores series de 2025&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#mejores-películas-de-2025&#34;&gt;Mejores películas de 2025&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#mejores-podcasts-de-2025&#34;&gt;Mejores podcasts de 2025&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#mejores-videojuegos-de-2025&#34;&gt;Mejores videojuegos de 2025&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Mejores libros de 2025&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;#tratise-on-efficacy-de-françois-jullien&#34;&gt;Treatise on efficacy de François Jullien&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#el-deseo-según-gilles-deleuze-de-maite-larrauri&#34;&gt;El deseo según Gilles Deleuze de Maite Larrauri&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#looking-backward,-2000-1887-de-edward-bellamy&#34;&gt;Looking Backward, 2000-1887 de Edward Bellamy&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;** Transformadores**&lt;/p&gt; &lt;p&gt;Qué hacen un crack dentro de ti que te transforma&lt;/p&gt; &lt;p&gt;&lt;strong&gt;# Treatise on efficacy de François Jullien&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/treatise_on_efficacy.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2004&lt;/li&gt; &lt;li&gt;género: filosofía&lt;/li&gt; &lt;li&gt;longitud: 211 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Mi libro favorito del año sin duda. Lo he leído 2 veces y media. Mucho subrayado, muchas notas al margen. Es uno de esos libros que te dan unas nuevas gafas para ver el mundo de otra forma.&lt;/p&gt; &lt;p&gt;Ha transformado completamente mi concepción del tiempo, la eficacia, eficiencia, acción, transformación, oportunidad, ...&lt;/p&gt; &lt;p&gt;Eso si, es lectura densa, pero muy muy recomendable.&lt;/p&gt; &lt;p&gt;Me encanta el puente que nos regala Jullien del pensamiento chino vivido y entendido desde la experiencia de ojos europeos.&lt;/p&gt; &lt;p&gt;** El deseo según Gilles Deleuze de Maite Larrauri**&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/deseo_deleuze.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2000&lt;/li&gt; &lt;li&gt;género: filosofía&lt;/li&gt; &lt;li&gt;longitud: 94 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Lo \&#34;leí\&#34; cómo nunca antes había leído un libro, simplemente maravilloso. Después lo he leído otras 2 veces.&lt;/p&gt; &lt;p&gt;Maite hace accesible a profanos conceptos clave de Deleuze sobre el deseo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Capitalismo libidinal&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/capitalismo_libidinal.gif&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: filosofía&lt;/li&gt; &lt;li&gt;longitud: 224 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Libro maravilloso que me abrió la mente a otra concepción del tiempo y del deseo.&lt;/p&gt; &lt;p&gt;La vida se ha hecho mercado. Como si fuese nuestra segunda naturaleza, nos movemos en Uber, viajamos con Airbnb, ligamos en Tinder, compramos en Glovo, nos entretenemos en Netflix, hablamos de nosotros mismos en el lenguaje del capital humano.&lt;/p&gt; &lt;p&gt;Esta segunda naturaleza, que Amador Fernández-Savater llama capitalismo libidinal, nos promete la felicidad, pero lo que produce realmente es sufrimiento y malestar, en forma de precariedad, endeudamiento y dolor psíquico. Paradójicamente, la derecha parece hoy más eficaz que nadie para canalizar esa desesperación y su fuerza de rechazo (Trump, Bolsonaro, Milei), mientras que las estrategias de comunicación y las políticas de contención de la izquierda se muestran insuficientes.&lt;/p&gt; &lt;p&gt;¿Es posible reapropiarnos de nuestro malestar como energía de transformación social? Será necesario aprender a escuchar y hablar el lenguaje del cuerpo, imaginar y activar políticas del deseo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Utopía no es una isla de Layla Martínez&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/utopia_no_es_una_isla.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2020&lt;/li&gt; &lt;li&gt;género: ensayo&lt;/li&gt; &lt;li&gt;longitud: 212 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Una guía de vida, lo he vuelto a leer después de 3 o 4 años. Este libro fue el que me dio las energías para volver a militar tras un largo periodo de hartazgo y desilusión. También me abrió en su momento el camino a buscar la utopía.&lt;/p&gt; &lt;p&gt;El libro te atrapa y es un viaje maravilloso.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Life-Changing Magic of Tidying Up de Marie Kondo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/kondo.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2014&lt;/li&gt; &lt;li&gt;género: autoayuda&lt;/li&gt; &lt;li&gt;longitud: 231 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Me pilló en la mudanza y de nuevo quitando toda la mierda capitalista y las grilladas japas, tiene ideas de trasfondo muy interesantes.&lt;/p&gt; &lt;p&gt;Japanese cleaning consultant Marie Kondo takes tidying to a whole new level, promising that if you properly simplify and organize your house once, you&#39;ll never have to do it again. Most methods advocate a room-by-room approach, which doom you to pick away at your piles of stuff forever. The KonMari Method, with its revolutionary category-by-category system, leads to lasting results. In fact, none of Kondo&#39;s clients have lapsed (and she still has a three-month wait list).&lt;/p&gt; &lt;p&gt;With detailed guidance for determining which items in your house \&#34;spark joy\&#34; (and which don\&#39;t), this international best-seller featuring Tokyo\&#39;s newest lifestyle phenomenon will help you clear your clutter and enjoy the unique magic of a tidy home - and the calm, motivated mindset it can inspire.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Bullet Journal method de Ryder Carroll&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/bullet_journal.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2018&lt;/li&gt; &lt;li&gt;género: autoayuda&lt;/li&gt; &lt;li&gt;longitud: 320 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Un libro que me ha dado muchísimas ideas, pero para disfrutarlo tienes que ser capaz de obviar toda la mierda que lo rodea: su speech sobre su vida típico de libro de autoayuda, su enfoque belicista épico, horrenda visión individualista de que somos culpables de nuestras situaciones y que sólo nosotros podemos arreglarlas con una salida individual.&lt;/p&gt; &lt;p&gt;For years, Ryder Carroll tried countless organizing systems, online and off, but none of them fit the way his mind worked. Out of sheer necessity, he developed a method called the Bullet Journal that helped him become consistently focused and effective. When he started sharing his system with friends who faced similar challenges, it went viral. Just a few years later, to his astonishment, Bullet Journaling is a global movement. The Bullet Journal Method is about much more than organizing your notes and to-do lists. It\&#39;s about what Carroll calls \&#34;intentional living\&#34;: weeding out distractions and focusing your time and energy in pursuit of what\&#39;s truly meaningful, in both your work and your personal life. It\&#39;s about spending more time with what you care about, by working on fewer things. Carroll wrote this book for frustrated list-makers, overwhelmed multitaskers, and creatives who need some structure. Whether you\&#39;ve used a Bullet Journal for years or have never seen one before, The Bullet Journal Method will help you go from passenger to pilot of your own life.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Unf*ck Your Habitat de Rachel Hoffman&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/unfuck_habitat.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2017&lt;/li&gt; &lt;li&gt;género: autoayuda&lt;/li&gt; &lt;li&gt;longitud: 256 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Impresionantes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Looking Backward, 2000-1887 de Edward Bellamy&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/looking_backward.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1888!!&lt;/li&gt; &lt;li&gt;género: novela, sci-fy&lt;/li&gt; &lt;li&gt;longitud: 276 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Ha despertado en mi sentimientos e ideas como no lo ha hecho un libro en mucho tiempo. Sobretodo la sorpresa de que mucho de la actualidad es realmente muy antigua.&lt;/p&gt; &lt;p&gt;Empecé leyéndolo en inglés pero no me enteraba de nada. El estilo tampoco me estaba enganchando. Hasta que descubrí que se escribió en el 1888!!! También ayuda a entender aquellas cosas que rechinan, como hablar sólo \&#34;del hombre\&#34;.&lt;/p&gt; &lt;p&gt;Es impresionante y triste que ya imagina ideas socialistas aún inalcanzables que me siguen emocionando aún en 2025...&lt;/p&gt; &lt;p&gt;Flipo con la perspectiva feminista de los cuidados, la visión del trabajo, el antipunitivismo (imaginaba ya un mundo sin cárceles) ya en 1888. Me sorprende que habla de desahucios en masa, fraudes millonarios, especulaciones con productos de primera necesidad. Luego tiene ciertos campos en los que es un poco mas meh: la sanidad pública está un poco retrasada, la parte romántica es horrenda, es bastante clasista y tecnócrata. Y es muy curioso a la par que gracioso, con todo los avances que ha sido capaz de imaginar, que no pudiese ver el final de la religión.&lt;/p&gt; &lt;p&gt;El flipe se me relajó cuando vi que el manifiesto comunista se había escrito 40 años antes. Y luego vino el efecto rebote. En vez de ser una lectura inspiradora, que también, me está entrando un poco de desesperación por la mierda de mundo que me está tocando vivir, lo lejos que estamos de un mundo bello de vivir, y a la velocidad a la que nos estamos alejando&lt;/p&gt; &lt;p&gt;Es una bonita crónica del despertar comunista cuando se te cae la venda de los ojos. Apaga la tele, enciende la mente. En el paseo por el barrio pobre hace una bonita descripción del quitar la venda de la deshumanización del pobre como vía de acabar con dicha opresión.&lt;/p&gt; &lt;p&gt;Me ha gustado mucho el final y el tierno epílogo, se mascaba la revolución rusa ya en el 1888 Qué pena que el capitalismo saliese victorioso... Dónde estaríamos ahora si no...&lt;/p&gt; &lt;p&gt;A man being put into a hypnotic sleep, is awakened 113 years later to an entirely new social structure.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Entretenidos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un pasatiempos agradable. Para días tontos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Ñu de Pau luque&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/nu.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: filosofía&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pau tiene una curiosa manera de filosofar, más cercana a la gente.Se lee muy bien, te ríes bastante a menudo. Eso si, no tiene un sólo capítulo, y eso hace que sea muy jodido dejar de leerlo.&lt;/p&gt; &lt;p&gt;Me hace mucha gracia Curiel, pienso que me gustaría conocerla pero luego pienso, que menudo vértigo!&lt;/p&gt; &lt;p&gt;«Lo más sospechoso de las soluciones es que se las encuentra siempre que se quiere.» Esta frase de Rafael Sánchez Ferlosio abre un libro excepcional, tan brillante como inclasificable. Entre el relato, la autobiografía y el ensayo filosófico, Pau Luque convoca una galería de personajes extravagantes y tiernos para pensar con ellos la incertidumbre que caracteriza a toda existencia humana: bellos italianos de oficio desconocido, boxeadores frustrados, adolescentes con dentaduras caóticas, poetas clandestinas, émulos de san Ignacio de Loyola, filósofos abrumados por las cuestiones prácticas más triviales o swingers confundidos vagan y divagan por las calles de Barcelona, Génova, Ciudad de México o Vilafranca del Penedès. Son criaturas mugrientas y deslumbrantes que se enfrentan a problemas cotidianos pero también trascendentales.&lt;/p&gt; &lt;p&gt;Frente a las soluciones simples (el ñu que se suele utilizar en los crucigramas en español para rellenar huecos --casi un chiste entre los aficionados--) y a las recetas de manual, Pau Luque hace una loa a los secretos, los equívocos, los errores e incluso las contradicciones. Ñu es un iluminador libro de antiayuda.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;We have always lived in the castle de Shirley Jackson&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/lived_in_the_castle.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1962&lt;/li&gt; &lt;li&gt;género: novela, drama&lt;/li&gt; &lt;li&gt;longitud: 187 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Recomendado por Layla Martinez, autora de utopía no es una isla y carcoma, el estilo ne recuerda mucho a Aury en the slow regard of silent things.&lt;/p&gt; &lt;p&gt;La casa tiene mucha presencia como en carcoma. Al principio hubo un momento que casi lo dejo, pero me alegro de haberlo acabado.&lt;/p&gt; &lt;p&gt;El estilo es curioso y agradable de leer, me cuadra que le guste a layla.&lt;/p&gt; &lt;p&gt;Shirley Jackson\&#39;s beloved gothic tale of a peculiar girl named Merricat and her family\&#39;s dark secret&lt;/p&gt; &lt;p&gt;Taking readers deep into a labyrinth of dark neurosis, We Have Always Lived in the Castle is a deliciously unsettling novel about a perverse, isolated, and possibly murderous family and the struggle that ensues when a cousin arrives at their estate.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Una belleza terrible de Edurne Portela&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/belleza_terrible.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: novela histórica&lt;/li&gt; &lt;li&gt;longitud: 335 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Una mirada novelada a la historia de mujeres troskistas. Al final engancha pero me costaron un poco ciertas partes.&lt;/p&gt; &lt;p&gt;Algunos pensamientos que fui apuntando mientras lo leía:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Ay qué ilusión me dio ver que había sacado un nuevo libro. Al leer la descripción no me pude contener y empecé a dar palmadas y emitir ruidos nerviosos.&lt;/li&gt; &lt;li&gt;Ya lo tengo entre mis manos, huele bien, como todos los de gutenberg.&lt;/li&gt; &lt;li&gt;El primer capítulo me encanta, no solo leo su obra sino que encima la acompaño en esta aventura. Me recuerda un poco a su reflexión con maddie y las fronteras pero está vez está acompañada y la reflexión es más madura. Debe ser que Maddie le dio fuerzas. Al decir que compartía casa con jose ovejero me puse a buscar como loco si eran pareja, y luego pensé, qué más da!&lt;/li&gt; &lt;li&gt;De nuevo, como en sus otros libros, el estilo de la escritura te atrapa, ay qué bien tener estas 300 páginas por delante.&lt;/li&gt; &lt;li&gt;Me gusta cómo se centra en las historias de ellas incluso cuando están rodeadas de peña tan importante&lt;/li&gt; &lt;li&gt;Me gusta mucho su filosofía de escritura, el imaginar sobre el inventar incluso a costa de potencial novelístico. Creo que tiene mucho más fuerza y es mucho más respetuosa por las historias verdaderas que intentan representar.&lt;/li&gt; &lt;li&gt;Sus finales que siempre son maravillosos Ganas de comentarla con henar, caps y rosa&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;A Deadly Education de Naomi Novik&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/deadly_education.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2020&lt;/li&gt; &lt;li&gt;género: novela fantasía mágica&lt;/li&gt; &lt;li&gt;longitud: 320 páginas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Crea un mundo muy interesante, es como un harry potter más oscuro.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejores series de 2025&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este 2025 mis series favoritas han sido:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href=&#34;#say-nothing&#34;&gt;Say nothing&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#adolescencia&#34;&gt;Adolescencia&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#animal&#34;&gt;Animal&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Impactantes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Contenido original, que deja su huella.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Say nothing&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/say_nothing.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: drama&lt;/li&gt; &lt;li&gt;longitud: 9 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Ambientada a lo largo de toda la historia del IRA, es interesante que no cuentan la versión de los vencedores, sin dejar de ser crítica con los vencidos. Me sorprendieron mucho los paralelismos con ETA.&lt;/p&gt; &lt;p&gt;Cada capítulo es una joya. Probablemente la mejor serie que he visto en 2025.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Adolescencia&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/adolescencia.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: drama, crimen&lt;/li&gt; &lt;li&gt;longitud: 4 episodios largos e intensos&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Serie que engancha muy fuertemente, que nos hace reflexionar sobre la relación adulto - joven, el papel de la tecnología y a donde tiende el mundo.&lt;/p&gt; &lt;p&gt;Creo que es una serie que deberían de ver todos los padres y madres con sus hijes, también en los institutos. Creo que se podrían generar unos debates muy ricos.&lt;/p&gt; &lt;p&gt;El formato también es muy especial. La grabación contínua hace que la acción no te deje un respiro. Yo pensaba que el formato de grabación contínua lo conseguían haciendo cortes y uniéndolo con efectos gráficos, pero no. Cada capítulo está grabado de un tirón, y si se equivocan, a empezar de nuevo. Flipo.&lt;/p&gt; &lt;p&gt;Cómo actua todo el reparto es impresionante.&lt;/p&gt; &lt;p&gt;El único pero que le pongo es que sólo muestra una visión muy pesimista de la juventud, en la que es fácil caer en la desesperación de que no tienen remedio y nos vamos al carajo. Que aunque es cierto, también hay otra gran cantidad de jóvenes que vienen pisando con mucha fuerza sobre los que podríamos aprender mucho.&lt;/p&gt; &lt;p&gt;El mundo de una familia se pone patas arriba cuando Jamie Miller, de 13 años, es arrestado y acusado de asesinar a una compañera de clase. Los cargos contra su hijo les obliga a enfrentarse a la peor pesadilla de cualquier padre.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tiernas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Contenido de domingo noche, aquel que te abraza, que es calentito, en el que los personajes se convierten parte de tu familia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Doctor en Alaska&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/doctor_en_alaska.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1990&lt;/li&gt; &lt;li&gt;género: comedia, drama, fantasía&lt;/li&gt; &lt;li&gt;longitud: 110 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Zona de comfort absoluta que ha envejecido genial. Después de verla hace unos años, he revisitado capítulos sueltos con la familia. Si no la has visto es un acompañamiento bueno para el invierno.&lt;/p&gt; &lt;p&gt;Joel Fleishman es un médico recién licenciado. Debido a una cláusula de la letra pequeña del contrato de su beca acaba en la remota y descaradamente extraña ciudad de Cicely (Alaska). Cordialmente bienvenido por el fundador de Cicely, Maurice Minnifield, antiguo astronauta de la NASA, y por el resto de la peña de inadaptados y excéntricos que forma el vecindario, Joel descubre que es cada vez más difícil abandonar la ciudad a la que inconscientemente ha llegado. Todo se complica por la presencia de Maggie O&#39;Connell, alcaldesa de Cicely y piloto de la localidad, una mujer hermosa pero completamente independiente; ambientado todo ello por el musical y filosófico programa de radio presentado por Chris en la KBHR.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Graciosas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Contenido que arranca carcajadas&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Animal S01&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/animal.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia&lt;/li&gt; &lt;li&gt;longitud: 9 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;La serie más graciosa que he visto en el año. Carcajada tras carcajada, la retranca gallega en todo su explendor. Mais unha pena que non fose en galego :(&lt;/p&gt; &lt;p&gt;Antón, un veterinario sin un duro, acepta trabajar en una tienda de mascotas de lujo y pasa de cuidar animales en el campo a vender cucaditas y caprichos para perros mimados.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;División Palermo S02&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/division_palermo.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia&lt;/li&gt; &lt;li&gt;longitud: 6 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Quizá es por la pérdida de novedad, pero no me reí tanto como con la primera. Aun así tiene muchos puntos muy muy graciosos.&lt;/p&gt; &lt;p&gt;Una Guardia Urbana inclusiva, ideada como operación de marketing para mejorar la imagen de las fuerzas de seguridad, descubrirá algo que no debía y se enfrentará con unos extraños narcos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Bear S03&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/the_bear.jpeg&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: comedia, drama&lt;/li&gt; &lt;li&gt;longitud: 6 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Su majestad S01&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/su_majestad.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia&lt;/li&gt; &lt;li&gt;longitud: 7 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Me la vi casi del tirón en un momento de bajona anímica. Es muy divertido cómo se mete con los borbones, pero duele que consigue que al final empatices con ella. Maldito cine.&lt;/p&gt; &lt;p&gt;Cuando se ve salpicado por un escándalo financiero, el rey Alfonso XIV decide apartarse de la primera línea pública durante unos meses. Pero alguien debe quedarse al frente de la institución. No hay más alternativa que su única hija, Pilar. Ahora la princesa tendrá que demostrarle al país que no es la irresponsable, vaga e inútil que todos creen. Lo que pasa es que igual tienen razón.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Entretenidas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un pasatiempos agradable. Para días tontos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Detective Touré&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/toure.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: comedia, misterio&lt;/li&gt; &lt;li&gt;longitud: 6 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Es bastante divertida y está genial cómo meten el contenido político&lt;/p&gt; &lt;p&gt;Touré, un inmigrante guineano asentado en Bilbao, se gana la vida como improvisado detective de poca monta. Su pericia, intuición y particular sentido del humor le hacen ganarse la confianza de la Ertzaintza y le sumergen en una compleja investigación en la que se enfrentará a múltiples peligros: conocerá de cerca la corrupción inmobiliaria, los tejemanejes del conflictivo barrio de San Francisco e incluso se topará con la mafia nigeriana.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Andor S02&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/andor.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia, crímen&lt;/li&gt; &lt;li&gt;longitud: 12 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;No le llega a la suela del zapato de la primera temporada (que si no has visto, merece mucho la pena). Pero sigue siendo entretenida, empieza flojilla y va ganando con los episodios.&lt;/p&gt; &lt;p&gt;Son bonitos los guiños a Palestina&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Eric&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/eric.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: drama, misterio&lt;/li&gt; &lt;li&gt;longitud: 6 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Un padre desesperado y un tenaz policía luchan contra sus propios demonios en la Nueva York de los años 80 mientras buscan a su hijo de nueve años, que ha desaparecido.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;La residencia S01&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;img/la_residencia.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia, crímen&lt;/li&gt; &lt;li&gt;longitud: 8 episodios&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Empieza un poco flojilla pero con el tiempo va mejorando.&lt;/p&gt; &lt;p&gt;Una excéntrica y brillante inspectora investiga un crimen en la Casa Blanca, donde todos los empleados e invitados a la cena de Estado esconden un secreto y podrían ser el asesino.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejores películas de 2025&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este año mis películas favoritas han sido:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href=&#34;#arsénico-por-compasion&#34;&gt;Arsénico por compasión&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#coco&#34;&gt;Coco&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#el-gran-dictador&#34;&gt;El gran dictador&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#barrio&#34;&gt;Barrio&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#tiempos-modernos&#34;&gt;Tiempos modernos&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Es curioso cómo ha pesado el cine antíguo frente al moderno.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Transformadoras&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Barrio&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/barrio.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1998&lt;/li&gt; &lt;li&gt;género: drama&lt;/li&gt; &lt;li&gt;longitud: 1h34m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;En uno de esos barrios situados al sur de las grandes ciudades, a los que no llega ni el metro ni el dinero, Javi, Manu y Rai son compañeros de instituto, pero, sobre todo, amigos. Tienen esa edad en la que ni se es hombre ni se es niño, en la que se habla mucho de chicas y muy poco con ellas. Comparten también la vida en el barrio, el calor del verano y un montón de problemas. El primero es el propio barrio, un lugar de grandes bloques de viviendas sociales, de ladrillo oscuro y arquitectura deprimente y depresiva. Allí hay pocas cosas que hacer, y en agosto aún menos. El centro de la ciudad queda lejos y las comunicaciones son malas, así que los tres amigos pasan la mayor parte del tiempo por las calles del barrio.[&lt;/p&gt; &lt;p&gt;&lt;strong&gt;No Other Land&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/no_other_land.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: documental&lt;/li&gt; &lt;li&gt;longitud: 1h25m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Podría haber caído tanto en impactante como en transformadora. Una producción muy necesaria tras más de un año de genocidio en Palestina...&lt;/p&gt; &lt;p&gt;Un joven activista palestino documenta durante cinco años los violentos desalojos de palestinos en Cisjordania. Con la colaboración de cineastas israelíes y palestinos, narra la compleja relación que surge entre él y un periodista israelí dispuesto a unirse a su lucha, a pesar de sus diferentes circunstancias. Una obra conmovedora que explora resistencia, empatía y esperanza en un contexto de conflicto.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cómo tener sexo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/como_tener_sexo.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2023&lt;/li&gt; &lt;li&gt;género: drama&lt;/li&gt; &lt;li&gt;longitud: 1h31m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Película que sería interesante ver con los jóvenes ya sea en casa o en los institutos. Aborda muy bien el tema del consentimiento.&lt;/p&gt; &lt;p&gt;Tres adolescentes británicas se van de vacaciones para celebrar sus ritos de iniciación: beber, salir de fiesta y ligar, en lo que debería ser el mejor verano de sus vidas.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Graciosas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Contenido que arranca carcajadas.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Arsénico por compasión&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/arsenico_por_compasion.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1944&lt;/li&gt; &lt;li&gt;género: comedia, crimen&lt;/li&gt; &lt;li&gt;longitud: 1h58m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;La vi dos veces del tirón en una semana, me parece una obra maestra. Siento que ya no se hacen comedias como esta. El guión es maravilloso, y la traducción también. Aunque soy un aférrimo defensor de ver las películas en versión original, esta recomendaría verla en castellano.&lt;/p&gt; &lt;p&gt;Un crítico teatral que acaba de casarse decide visitar a sus ancianas tías antes de marcharse de luna de miel. Durante la visita descubrirá que las encantadoras viejecitas tienen una manera muy peculiar de practicar la caridad.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;El gran dictador&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/el_gran_dictador.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1940&lt;/li&gt; &lt;li&gt;género: comedia, bélica&lt;/li&gt; &lt;li&gt;longitud: 2h05m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;El discurso final es memorable.&lt;/p&gt; &lt;p&gt;Un humilde barbero judío tiene un parecido asombroso con el dictador de la nación Tomania, que promete sacar adelante y que culpa a los judíos de la situación del país. El dictador ataca al país fronterizo, pero es confundido con el barbero por sus propios guardias, siendo ingresado en un campo de concentración. Simultáneamente, el pobre barbero es confundido con el dictador...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tiempos modernos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/tiempos_modernos.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1936&lt;/li&gt; &lt;li&gt;género: comedia, drama, romance&lt;/li&gt; &lt;li&gt;longitud: 1h27m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Es muy triste que sea tan actual...&lt;/p&gt; &lt;p&gt;Extenuado por el frenético ritmo de la cadena de montaje, un obrero metalúrgico acaba perdiendo la razón. Después de recuperarse en un hospital, sale y es encarcelado por participar en una manifestación en la que se encontraba por casualidad. En la cárcel, también sin pretenderlo, ayuda a controlar un motín, gracias a lo cual queda en libertad. Una vez fuera, reemprende la lucha por la supervivencia en compañía de una joven huérfana a la que conoce en la calle.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;El apartamento&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/el_apartamento.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1960&lt;/li&gt; &lt;li&gt;género: comedia, drama, romance&lt;/li&gt; &lt;li&gt;longitud: 2h05m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Otra comedia impresionante, con crítica social.&lt;/p&gt; &lt;p&gt;C.C. Baxter es un modesto pero ambicioso empleado de una compañía de seguros de Manhattan. Está soltero y vive solo en un discreto apartamento que presta ocasionalmente a sus superiores para sus citas amorosas. Tiene la esperanza de que estos favores le sirvan para mejorar su posición en la empresa. Pero la situación cambia cuando se enamora de una ascensorista que resulta ser la amante de uno de los jefes que usan su apartamento.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;La vida segun Philomena Cunk&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/philomena_cunk.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: comedia&lt;/li&gt; &lt;li&gt;longitud: 1h10m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Conmovedoras&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Coco&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/coco.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2017&lt;/li&gt; &lt;li&gt;género: animación, aventura&lt;/li&gt; &lt;li&gt;longitud: 1h49m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Segunda vez que la veo y no pierde. Al principio me dio mucho miedo de lo que podía hacer disney con méxico, pero la verdad es que es una obra de arte.&lt;/p&gt; &lt;p&gt;Un joven aspirante a músico llamado Miguel se embarca en un viaje extraordinario a la mágica tierra de sus ancestros. Allí, el encantador embaucador Héctor se convierte en su inesperado amigo y le ayuda a descubrir los misterios detrás de las historias y tradiciones de su familia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Entretenidas&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un pasatiempos agradable. Para días tontos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;La princesa prometida&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/la_princesa_prometida.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1987&lt;/li&gt; &lt;li&gt;género: Aventura, comedia, fantasía, romance&lt;/li&gt; &lt;li&gt;longitud: 1h45m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Me resistí mucho tiempo a verla porque tenía miedo que fuese una ñoñería de amor romantico. Que tristemente lo es xD, pero todo lo demás hace que sea una maravilla. Los diálogos, las coreografías, los personajes... Eso si, prepárate para exasperarte ante el papel de princesa objeto inútil.&lt;/p&gt; &lt;p&gt;Me volvió a despertar el sentimiento de \&#34;ya no se hacen películas como estas\&#34;. Tiene un algo que lo despierta (además de la retrogradez machista)&lt;/p&gt; &lt;p&gt;Después de buscar fortuna durante cinco años, Westley retorna a su tierra para casarse con su amada, la bella Buttercup, a la que había jurado amor eterno. Sin embargo, para recuperarla habrá de enfrentarse a Vizzini y sus esbirros. Una vez derrotados éstos, tendrá que superar el peor de los obstáculos: el príncipe Humperdinck pretende desposar a la desdichada Buttercup, pese a que ella no lo ama, ya que sigue enamorada de Westley.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Kneecap&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/kneecap.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: Comedia, drama&lt;/li&gt; &lt;li&gt;longitud: 1h45m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Me encanta que sean ellos mismos los que actuan, la historia está muy chula y el grupo mola todo.&lt;/p&gt; &lt;p&gt;En Irlanda hay 80.000 hablantes de irlandés, 6.000 viven en el norte y tres de ellos lo van a poner todo patas arriba cuando formen un trío de rap llamado Kneecap. Anárquicos, salvajes y dispuestos a todo para salvar su lengua materna.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Inside Out 2&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/inside_out_2.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 2024&lt;/li&gt; &lt;li&gt;género: animación, aventura, comedia&lt;/li&gt; &lt;li&gt;longitud: 1h36m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Riley entra en la adolescencia y el Cuartel General de su cabeza sufre una repentina reforma para hacerle hueco a algo totalmente inesperado propio de la pubertad: ¡nuevas emociones! Alegría, Tristeza, Ira, Miedo y Asco, con años de impecable gestión a sus espaldas (según ellos...) no saben muy bien qué sentir cuando aparece con enorme ímpetu Ansiedad. Y no viene sola: le acompañan envidia, vergüenza y aburrimiento.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;El tercer hombre&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/el_tercer_hombre.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;año: 1949&lt;/li&gt; &lt;li&gt;género: misterio, suspense&lt;/li&gt; &lt;li&gt;longitud: 1h44m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Orson Welles es Harry Lime y Joseph Cotten actúa como su amigo de la infancia, Holly Martins, en este clásico thriller de Graham Greene, dirigido por Carol Reed. Martins busca a Lime en la caótica postguerra de Viena, y se encuentra así mismo metido en un entorno de amores, decepción y asesinatos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Los Rose&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/los_rose.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia, drama, romance&lt;/li&gt; &lt;li&gt;longitud: 1h45m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;La vida parece fácil para la pareja perfecta que forman Ivy y Theo: carreras de éxito, un matrimonio feliz y unos hijos estupendos. Pero detrás de la fachada de su supuesta vida ideal, se avecina una tormenta: la carrera de Theo se desploma mientras que las ambiciones de Ivy despegan, lo que desencadena una caja de Pandora de competitividad y resentimiento ocultos.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Una historia verdadera&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/una_historia_verdadera.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 2025&lt;/li&gt; &lt;li&gt;género: comedia, drama, romance&lt;/li&gt; &lt;li&gt;longitud: 1h45m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Alvin Straight (Richard Farnsworth) es un achacoso anciano que vive en Iowa con una hija discapacitada (Sissy Spacek). Además de sufrir un enfisema y pérdida de visión, tiene graves problemas de cadera que casi le impiden permanecer de pie. Cuando recibe la noticia de que su hermano Lyle (Stanton), con el que está enemistado desde hace diez años, ha sufrido un infarto, a pesar de su precario estado de salud, decide ir a verlo a Wisconsin. Para ello tendrá que recorrer unos 500 kilometros, y lo hace en el único medio de transporte del que dispone: una máquina cortacésped.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;El mago de Oz&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/el_mago_de_oz.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1939&lt;/li&gt; &lt;li&gt;género: aventura, fantasía&lt;/li&gt; &lt;li&gt;longitud: 1h43m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;La gran evasión&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/la_gran_evasion.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1963&lt;/li&gt; &lt;li&gt;género: aventura, bélica, drama&lt;/li&gt; &lt;li&gt;longitud: 2h43m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;La quimera del oro&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/la_quimera_del_oro.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1925&lt;/li&gt; &lt;li&gt;género: aventura, comedia, drama&lt;/li&gt; &lt;li&gt;longitud: 1h35m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Aventuras de un solitario buscador de oro en Alaska, donde se topa con varios personajes rudos, y se enamora de la hermosa Georgia, a la que trata de conquistar.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mujeres al borde de un ataque de nervios&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/mujeres_al_borde.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★☆&lt;/li&gt; &lt;li&gt;año: 1988&lt;/li&gt; &lt;li&gt;género: comedia, drama&lt;/li&gt; &lt;li&gt;longitud: 1h28m&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Pepa e Iván son actores de doblaje. Él es un mujeriego empedernido y, después de una larga relación, rompe con Pepa: le deja un mensaje en el contestador pidiéndole que le prepare una maleta con sus cosas. Al quedarse sola, Pepa no soporta vivir en una casa llena de recuerdos y decide alquilarla. Mientras espera que Iván vaya a recoger la maleta, la casa se le va llenando de gente extravagante de la que aprenderá muchas cosas sobre la soledad y la locura.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejores podcasts de 2025&lt;/strong&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;a href=&#34;#punzadas-sonoras&#34;&gt;Punzadas sonoras&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#quieto-todo-el-mundo&#34;&gt;Quieto todo el mundo&lt;/a&gt;&lt;/li&gt; &lt;li&gt;(de eso no se habla) temporada 2: Se llamaba como yo&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;#no-es-el-fin-del-mundo&#34;&gt;No es el fin del mundo&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://punzadas.com/punzadas-sonoras/&#34;&gt;Punzadas sonoras&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Paula Ducay e Inés García me han recordado la importancia de la Filosofía como nadie. Gracias a ellas he descubierto nuevas maneras de ver, me han regalado palabras que describen a la percepción pensamientos y sensaciones que tengo y gracias a ellas he conseguido esclarecer un poco más mi entendimiento del mundo y de mi mismo. En especial han sido la base para desenterrar pilares imprescindibles de mi vida como son el deambular creativo y la solitud.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/punzadas_sonoras.jpeg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Siento que mi camino con ellas ha sido perfecto, me enamoré de ellas en los derroteros de &lt;a href=&#34;#carne-cruda&#34;&gt;Carne cruda&lt;/a&gt; en 2023. Eran episodios de 20 minutos muy accesibles, y una vez que ya me enganché a ellas, los programas de una hora se hacen cortos.&lt;/p&gt; &lt;p&gt;Escucharlas es un absoluto placer.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.ivoox.com/podcast-quieto-todo-mundo_sq_f11778903_1.html&#34;&gt;Quieto todo el mundo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Facu Díaz y Miguel Maldonado han conseguido alegrarme las horas de cocina de los lunes con la manera más amable de acercarme desde la comedia a la actualidad política. Hacen un combo maravilloso.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/quieto_todo_el_mundo.jpeg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Con un tono divertido y relajado, en el programa van comentando desde la ignorancia, la improvisación y, en ocasiones, la desidia las noticias más importantes de la semana.&lt;/p&gt; &lt;p&gt;Esta misa roja ha creado una verdadera religión a lo largo de los programas, no sólo por el lore sino por el vacío existencial que dejan esa semana que no publican programa. Especialmente cuando es porque los nazis les ocupan los espacios, asco de pais...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;(de eso no se habla) temporada 3: Se llamaba como yo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En «De eso no se habla» hablamos de los silencios que crea esa frase, tanto en nosotras como en la sociedad: de las historias que se esconden detrás de ellos, y de qué pasa cuando los rompemos.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/de_eso_no_se_habla.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;Esta tercera temporada trata sobre la memoria de la niña Begoña Urroz, sobre las cinco décadas de silencio de una familia… Y sobre el ruido que lo rompió. Muestra cómo la guerra sucia del estado contra ETA&lt;/p&gt; &lt;p&gt;&lt;strong&gt;No es el fin del mundo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Una mirada muy interesante a la geopolítica mundial&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/no_es_el_fin_del_mundo.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;El podcast semanal de El Orden Mundial (EOM) para entender qué pasa en el mundo. Análisis, contexto y matices sobre la realidad internacional. Porque estar al día de qué pasa más allá de nuestras fronteras no debería ser ni complicado ni aburrido.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejores videojuegos de 2025&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Mi juego favorito de este año ha sido [&lt;em&gt;Thronefall&lt;/em&gt;]{.spurious-link target=&#34;Thronefall&#34;}&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Thronefall&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/thronefall.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;platforms: linux&lt;/li&gt; &lt;li&gt;year: 2024&lt;/li&gt; &lt;li&gt;genre: Strategy, tactical, puzzle, arcade&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Al principio era un poco escéptico porque tienes unas localizaciones fijas para las torres, pero sigue siendo un juego difícil y entretenido. Además que los gráficos son preciosos.&lt;/p&gt; &lt;p&gt;A minimalist game about building and defending a little kingdom. Thronefall is a classic strategy game without unnecessary complexity, just some healthy hack-and-slay. Build up your base during the day, and defend it &#39;til your last breath at night.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dragonsweeper/&#34;&gt;Dragonsweeper&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/dragon_sweeper.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;year: 2025&lt;/li&gt; &lt;li&gt;genre: puzzle&lt;/li&gt; &lt;li&gt;platform: desktop, mobile&lt;/li&gt; &lt;li&gt;price: free&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Simple de jugar pero muy adictivo.&lt;/p&gt; &lt;p&gt;A minesweeper game that requires observation by mixing roguelike elements with the classic gameplay.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;You Must Build A Boat&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/you_must_build_a_boat.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;platforms: android, linux&lt;/li&gt; &lt;li&gt;year: 2015&lt;/li&gt; &lt;li&gt;genre: puzzle&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You Must Build A Boat is the sequel to the award winning \&#34;10000000\&#34;. Travel the world, run procedurally generated dungeons finding artifacts, capturing monsters and recruiting crew for your...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;10000000 {#section-1}&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;&#34; src=&#34;./img/1000.webp&#34;/&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;disfrute: ★★★★★&lt;/li&gt; &lt;li&gt;platforms: android, linux&lt;/li&gt; &lt;li&gt;year: 2012&lt;/li&gt; &lt;li&gt;genre: puzzle&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;10000000 is an award winning hybrid RPG/Action/Puzzle game. Matching tiles controls your character enabling you to explore, fight and loot. When you are not facing monsters you will be back in your prison, constructing buildings and getting stronger for your next run.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;December 26, 2025 06:59:15 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-12-26T06:59:15+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;December 26, 2025 06:59:15 UTC&#34;&gt;2025-12-26&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_12_25/</link>
      <pubDate>2025-12-26 06:59:15+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_12_25/</guid>
      
    </item>
    
    <item><title>23rd December 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;militancy&#34;&gt;Militancy&lt;/h2&gt; &lt;h3 id=&#34;antifascism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascism/&#34;&gt;Antifascism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir web sistemapunk.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://sistemapunk.com&#34;&gt;Sistemapunk&lt;/a&gt;: hace investigaciones sobre grupos nazis&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-navigation&#34;&gt;Life navigation&lt;/h2&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;signal&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/signal/&#34;&gt;Signal&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add note on AWS use.&lt;/p&gt; &lt;p&gt;It runs on AWS. On October 2025 there was an AWS outage and signal fell&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;technology&#34;&gt;Technology&lt;/h2&gt; &lt;h3 id=&#34;coding&#34;&gt;Coding&lt;/h3&gt; &lt;h4 id=&#34;vim-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_snippets/&#34;&gt;Vim Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_snippets/#create-quickmarks-across-files&#34;&gt;Create quickmarks across files.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use capital letters for the mark.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;http://vim.wikia.com/wiki/Using_marks&#34;&gt;http://vim.wikia.com/wiki/Using_marks&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Marks can span across files. To use such marks one has to use upper-case registers i.e. A-Z. Lower-case registers are used only within files and do not span files. That&#39;s to say, if you were to set a mark in a file foo.c in register &#34;a&#34; and then move to another file and hit &#39;a, the cursor will not jump back to the previous location. If you want a mark which will take you to a different file then you will need to use an upper-case register. For example, use mA instead of ma.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/&#34;&gt;Python Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-value-of-enum-by-value&#34;&gt;Get value of enum by value.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Sometimes it’s useful to access members in enumerations programmatically (i.e. situations where Color.RED won’t do because the exact color is not known at program-writing time). Enum allows such access:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RED&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BLUE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you want to access enum members by name, use item access:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;RED&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RED&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;GREEN&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GREEN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;```&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#get-the-directory-of-a-python-script&#34;&gt;Get the directory of a python script.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This can be useful to create relative paths between the script parts in a way that you can still run the script from another directory.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;script_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__file__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;script_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;script_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;../another-file&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h3&gt; &lt;h4 id=&#34;velero&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/&#34;&gt;Velero&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/velero/#debug-a-failed-backup&#34;&gt;Debug a failed backup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To get the available backups you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;velero&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backups
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Check the ones that have Failed in the name and then see the logs with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;velero&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;logs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;backup-1h-20251215113154&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;level=info&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;vector&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vector/&#34;&gt;vector&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce vector.&lt;/p&gt; &lt;p&gt;Vector is a lightweight, ultra-fast tool for building observability pipelines&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://vector.dev/docs/setup/installation/package-managers/apt/&#34;&gt;On debian&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, add the Vector repo:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bash&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-L&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://setup.vector.dev&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then you can install the vector package:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vector
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Tweak the configuration and then enable the service.&lt;/p&gt; &lt;p&gt;To be sure that vector is able to push to loki create the &lt;code&gt;/usr/local/bin/wait-for-loki.sh&lt;/code&gt; file&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;true&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;http://localhost:3100/ready&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$response&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ready&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;sleep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Make it executable &lt;code&gt;chmod +x /usr/local/bin/wait-for-loki.sh&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Then update your &lt;code&gt;vector.service&lt;/code&gt; (&lt;code&gt;/usr/lib/systemd/system/vector.service&lt;/code&gt;)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ExecStartPre=/usr/local/bin/wait-for-loki.sh
ExecStartPre=/usr/bin/vector validate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Run &lt;code&gt;systemctl daemon-reload&lt;/code&gt; to reload the service configuration.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://vector.dev/docs/reference/configuration/&#34;&gt;Configuration&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The config lives at &lt;code&gt;/etc/vector/vector.yaml&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://vector.dev/docs/reference/configuration/sources/docker_logs/&#34;&gt;Docker&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First add &lt;code&gt;vector&lt;/code&gt; to the &lt;code&gt;docker&lt;/code&gt; group: &lt;code&gt;usermod -a -G docker vector&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;sources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;docker&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker_logs&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;transforms&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;docker_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;remap&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;.service_name = get(.label, [&#34;com.docker.compose.project&#34;]) ?? &#34;unknown&#34;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;sinks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loki_docker&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker_labels&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;http://localhost:3100/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;json&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;docker&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://vector.dev/docs/reference/configuration/sources/journald/&#34;&gt;journald&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To avoid the services that run docker to be indexed twice&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;sources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;journald&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;transforms&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;journald_filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;filter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;condition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;# Exclude docker-compose systemd services&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;!contains(string!(.SYSLOG_IDENTIFIER), &#34;docker-compose&#34;) &amp;amp;&amp;amp;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;!contains(string!(.SYSLOG_IDENTIFIER), &#34;docker&#34;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;journald_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;remap&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald_filter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;.service_name = ._SYSTEMD_UNIT || &#34;unknown&#34;&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;sinks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;loki_systemd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald_labels&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;http://localhost:3100/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;json&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;ZFS&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Prepare the file to be readable by vector:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;chown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root:vector&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/spl/kstat/zfs/dbgmsg
chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;640&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/spl/kstat/zfs/dbgmsg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;sources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;zfs_log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;file&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/proc/spl/kstat/zfs/dbgmsg&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;zfs_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;loki&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs_log&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;http://localhost:3100/&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;codec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;json&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;file&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;service_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;zfs&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;sinks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Unable to open checkpoint file. path=&#34;/var/lib/vector/journald/checkpoint.txt&#34;&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ERROR source{component_kind=&#34;source&#34; component_id=journald component_type=journald}: vector::internal_events::journald: Unable to open checkpoint file. path=&#34;/var/lib/vector/journald/checkpoint.txt&#34; error=Permission denied (os error 13) error_type=&#34;io_failed&#34; stage=&#34;receiving&#34;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/vector/journald
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-R&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vector:vector&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/vector
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;755&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/vector
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;755&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/vector/journald
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://vector.dev/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;unison&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/unison/&#34;&gt;unison&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/unison/#installation&#34;&gt;Installation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you are on debian or ubuntu, the version of the repositories &lt;a href=&#34;https://github.com/bcpierce00/unison/issues/208&#34;&gt;does not allow you to run the program with the file watcher&lt;/a&gt;, so you may need to build it yourself:&lt;/p&gt; &lt;p&gt;First install the dependencies:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ocaml-native-compilers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;UNISON_VERSION&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.53.8
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Install Unison.&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pushd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/tmp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/bcpierce00/unison/archive/v&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;.tar.gz&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tar&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-xzvf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;v&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;.tar.gz&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;v&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;.tar.gz&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pushd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unison-&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/local/bin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./src/unison&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./src/unison-fsmonitor&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;popd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-rf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unison-&lt;span class=&#34;nv&#34;&gt;$UNISON_VERSION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;popd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then remove the ocaml compilers as they take quite some space:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remove&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ocaml-native-compilers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/unison/#run-in-the-background-watching-changes&#34;&gt;Run in the background watching changes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Create the systemd service in: &lt;code&gt;~/.config/systemd/user/unison.service&lt;/code&gt; (assuming that your profile is orgfiles)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[Unit]
Description=unison

[Service]
ExecStart=/usr/local/bin/unison orgfiles
Restart=on-failure
RestartSec=3

[Install]
WantedBy=default.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#debugging-inotify-watch-exhaustion:-&#34; title=&#34;no-space-left-on-device&#34;&gt;Debugging Inotify Watch Exhaustion: &#34;No space left on device&#34;.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you get &lt;code&gt;No space left on device&lt;/code&gt; errors in systemd logs, but disk space is fine:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemd[755863]: my-service.service: Failed to add control inotify watch descriptor for control group: No space left on device
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This is actually an &lt;strong&gt;inotify watches exhaustion&lt;/strong&gt; issue, not disk space.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Diagnosis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check Current Limits&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/sys/fs/inotify/max_user_watches
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Count Current Watch Usage&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/*/fdinfo/*&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-exec&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;^inotify&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;awk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{sum+=$1} END {print sum}&#39;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fd/*&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-L&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;readlink&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-q&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;anon_inotify&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fdnum&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;basename&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;watches&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;^inotify&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fdinfo/&lt;span class=&#34;nv&#34;&gt;$fdnum&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;watches&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;comm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;unknown&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sort&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-nr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;head&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Find High File Descriptor Processes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Often the culprits have many open files:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pid&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;fd_count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ls&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;/fd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd_count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;ps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;comm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$fd_count&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; FDs: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$pid&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Common Culprits&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Media servers&lt;/strong&gt;: Jellyfin, Plex&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Download managers&lt;/strong&gt;: Sonarr, Radarr, Lidarr&lt;/li&gt; &lt;li&gt;&lt;strong&gt;File sync&lt;/strong&gt;: Syncthing, Nextcloud&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Development tools&lt;/strong&gt;: IDEs, file watchers&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Container platforms&lt;/strong&gt;: Docker, containerd&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. Increase Limits (Quick Fix)&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;500000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/sys/fs/inotify/max_user_watches

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;fs.inotify.max_user_watches=500000&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/sysctl.conf
sysctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Memory cost&lt;/strong&gt;: ~540 bytes per watch (500k watches ≈ 270MB kernel memory)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2. Configure Applications&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Better long-term solution:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Sonarr/Radarr/Lidarr&lt;/strong&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Settings → Media Management → Disable &#34;Scan for changes&#34;&lt;/li&gt; &lt;li&gt;Use scheduled scans instead&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Jellyfin&lt;/strong&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Admin → Dashboard → Libraries → Disable real-time monitoring&lt;/li&gt; &lt;li&gt;Use periodic library scans&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Syncthing&lt;/strong&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Use polling instead of inotify for large directories&lt;/li&gt; &lt;li&gt;Add &lt;code&gt;.stignore&lt;/code&gt; for unnecessary paths&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#manage-bluetooth&#34;&gt;Manage bluetooth.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;List devices&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Once you&#39;ve paired your devices you can see them with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bluetoothctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devices
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To check the ones that are connected use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bluetoothctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devices&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Connected
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Connect device&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;From the list above you will see the device ID, then you can:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bluetoothctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;connect&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;device_ID
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;But it&#39;s better to use &lt;code&gt;blueman-manager&lt;/code&gt; because it handles better the connections and disconnections&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Multidevice connection&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Sometimes the laptop is not able to send the audio streams back to the connected device. Restart the controlling device with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;restart&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wireplumber.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#bluetooth-pairing-troubleshooting:-when-ble-devices-won&#39;t-connect&#34;&gt;Bluetooth Pairing Troubleshooting: When BLE Devices Won&#39;t Connect.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Bluetooth Low Energy (BLE) devices like wireless earbuds appear in device scans but fail to pair with &#34;Device not available&#34; errors, even though they&#39;re visible to other devices.&lt;/p&gt; &lt;p&gt;The root ’cause may be that the HCI controller corruption causing discovery operations to fail. The Bluetooth hardware gets stuck in a state where it rejects pairing attempts with error code -16 (EBUSY).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;hcitool lescan&lt;/code&gt; shows the device&lt;/li&gt; &lt;li&gt;&lt;code&gt;bluetoothctl&lt;/code&gt; scan shows device briefly or not at all&lt;/li&gt; &lt;li&gt;&lt;code&gt;bluetoothctl pair [MAC]&lt;/code&gt; returns &#34;Device not available&#34;&lt;/li&gt; &lt;li&gt;&lt;code&gt;dmesg&lt;/code&gt; shows HCI opcode failures like: &lt;code&gt;Bluetooth: hci0: Opcode 0x0401 failed: -16&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Complete Bluetooth stack reset:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;stop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bluetooth

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;btusb

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;modprobe&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;btusb

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bluetooth
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If that doesn&#39;t work. Try forcing bluetoothctl to see LE devices specifically:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bluetoothctl&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# this will open the bluetooth cli&lt;/span&gt;
menu&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scan
clear
transport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;le
back
scan&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;on
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#how-to-increase-touchpad-sensitivity-on-linux&#34;&gt;How to Increase Touchpad Sensitivity on Linux.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Adjust touchpad sensitivity settings for better responsiveness and control on Linux systems.&lt;/p&gt; &lt;p&gt;First, identify your touchpad device:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xinput&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Check current properties:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xinput&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list-props&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Synaptics TM3381-002&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Increase pointer sensitivity (range: -1.0 to 1.0):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xinput&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;set-prop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Synaptics TM3381-002&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;libinput Accel Speed&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Make scrolling more sensitive:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xinput&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;set-prop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Synaptics TM3381-002&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;libinput Scrolling Pixel Distance&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Once you have the correct values make it permanent across reboots by adding them to your startup scripts.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#how-to-disable-trackpoint-on-linux&#34;&gt;How to Disable Trackpoint on Linux.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The trackpoint (that red nub in the middle of ThinkPad keyboards) can be accidentally triggered while typing, or if you replace the keyboard it might make the mouse slide randomly without any user intervention. Here&#39;s how to disable it on Linux systems.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;with xinput&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Get the property of your trackpoint with &lt;code&gt;xinput list | grep -i track&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Then disable the trackpoint with &lt;code&gt;xinput set-prop &#34;TPPS/2 Elan TrackPoint&#34; &#34;Device Enabled&#34; 0&lt;/code&gt;&lt;/p&gt; &lt;p&gt;To make it persistent add that line to your desktop startup scripts. It can be run by a non privileged user.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;With udev rules&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The problem with this approach is that the event number may change across reboots&lt;/p&gt; &lt;p&gt;First, find your trackpoint in the system:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/proc/bus/input/devices&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A5&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-B5&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;trackpoint
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Look for entries like &#34;TPPS/2 Elan TrackPoint&#34; or similar. Note the event number (e.g., &lt;code&gt;event14&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;Create a udev rule to ignore the trackpoint device:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;echo &#34;KERNEL==\&#34;event[0-9]*\&#34;, SUBSYSTEM==\&#34;input\&#34;, ATTRS{name}==\&#34;*TrackPoint*\&#34;, ENV{LIBINPUT_IGNORE_DEVICE}=\&#34;1\&#34;&#34; &amp;gt; /etc/udev/rules.d/90-disable-trackpoint.rules&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Replace &lt;code&gt;event[0-9]*&lt;/code&gt; with your specific event number if needed.&lt;/p&gt; &lt;p&gt;Reload udev rules:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;udevadm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;control&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--reload-rules
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;udevadm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;trigger
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Test that the trackpoint no longer responds to input. The udev method typically works immediately and persists across reboots.&lt;/p&gt; &lt;p&gt;This may have an ugly side effect, that you won&#39;t any longer be able to use the touchpad mouse buttons. Sadly the trackpoint and those buttons are controlled by the same device.&lt;/p&gt; &lt;p&gt;The solution is to use the touchpad instead (see below).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Be able to click using the touchpad&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Activate tap for clicking in touchpad by pasting following lines in /etc/X11/xorg.confg.d/30-touchpad.conf&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Section &#34;InputClass&#34;
    Identifier &#34;touchpad&#34;
    Driver &#34;libinput&#34;
    MatchIsTouchpad &#34;on&#34;
    Option &#34;Tapping&#34; &#34;on&#34;
    Option &#34;TappingButtonMap&#34; &#34;lrm&#34;
EndSection
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;lrm&lt;/code&gt; means that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;1 finger tap is a left click&lt;/li&gt; &lt;li&gt;2 finger tap is a right click&lt;/li&gt; &lt;li&gt;3 finger tap is a middle click&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You&#39;ll need to logout and back in for the change to be applied.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;watchtower&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/watchtower/&#34;&gt;Watchtower&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Change the default docker image.&lt;/p&gt; &lt;p&gt;From &lt;code&gt;containrrr/watchtower&lt;/code&gt; to &lt;code&gt;nickfedor/watchtower&lt;/code&gt;. &lt;a href=&#34;https://github.com/containrrr/watchtower/issues/2122&#34;&gt;The official repo has not been updated in a while&lt;/a&gt; use &lt;a href=&#34;https://github.com/nicholas-fedor/watchtower&#34;&gt;this fork instead&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;hardware&#34;&gt;Hardware&lt;/h3&gt; &lt;h4 id=&#34;kobo&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kobo/&#34;&gt;Kobo&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/kobo/#kobo-forma-suddenly-drains-battery-in-days&#34;&gt;Kobo Forma suddenly drains battery in days.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The solution was to a factory restore, disconnect the wifi and detect which ebook is being the problem.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Some of the user suggestions&lt;/strong&gt; - My battery started doing this many 3 times now. Every time it was a certain book. The first time was something I downloaded from the kobo store, I removed my recent batch of downloads and it was fine (still not sure which is the offending book tbh). The next two were sideloaded borrowbox books. I think its something to do with a download not being downloaded correctly/having all the correct information. The kobos system tries to keep getting the information it wants but fails and keeps doing this in a cycle causing it to drain the battery&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I haven&#39;t bought any new books lately, but I&#39;ve been reading a ton of library books. About when the battery drain started, I had returned a few books directly from the Kobo, instead of doing it on my phone in the Libby app. That&#39;s got to be the problem.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I disabled the wifi, turned off my Kobo, turned it back on, then restarted the wifi, BUT I did it in Settings, instead of with the quick toggle at the top of the Home screen (when you touch the wifi signal strength indicator). It took longer for the wifi to fully connect than it had all the times I&#39;ve tried this over the last week. Then I did a Sync, which went through quickly.&lt;/p&gt; &lt;p&gt;It&#39;s been 8+ hours, and my Kobo is still at 89%, which is where it was when I started the process!&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;i did find out that it wasn&#39;t going to sleep or powering off if I just closed the cover anymore. It will sleep/ power off if the cover is not closed. I haven&#39;t changed any settings so I&#39;m not sure why this started happening. I&#39;ve had to power it off manually before closing the cover to make sure there is no battery drain.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Basically, the Forma will either go to sleep on its own or I&#39;ll put it to sleep and the battery is at some reasonable amount. Usually overnight, but once while it was sitting on the desk next to me for about an hour, the battery will drain down to nothing. It will shut all the way down and sometimes display the warning that it needs charging. Other times, I don&#39;t even get that warning.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.reddit.com/r/kobo/comments/13npudr/45_year_old_kobo_forma_suddenly_drains_battery_in/&#34;&gt;https://www.reddit.com/r/kobo/comments/13npudr/45_year_old_kobo_forma_suddenly_drains_battery_in/&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.mobileread.com/forums/showthread.php?t=351513&#34;&gt;https://www.mobileread.com/forums/showthread.php?t=351513&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bugs.launchpad.net/calibre/+bug/1829422&#34;&gt;https://bugs.launchpad.net/calibre/+bug/1829422&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;science&#34;&gt;Science&lt;/h2&gt; &lt;h3 id=&#34;artificial-intelligence&#34;&gt;Artificial Intelligence&lt;/h3&gt; &lt;h4 id=&#34;ocr&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ocr/&#34;&gt;OCR&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add deekseek ocr tool.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Bogdanovich77/DeekSeek-OCR---Dockerized-API&#34;&gt;DeekSeek-OCR&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce aerc email command line client.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://aerc-mail.org/&#34;&gt;aerc&lt;/a&gt; is an email client that runs in your terminal.&lt;/p&gt; &lt;p&gt;Some of its more interesting features include:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Editing emails in an embedded terminal tmux-style, allowing you to check on incoming emails and reference other threads while you compose your replies&lt;/li&gt; &lt;li&gt;Render HTML emails with an interactive terminal web browser, highlight patches with diffs, and browse with an embedded less session&lt;/li&gt; &lt;li&gt;Vim-style keybindings and ex-command system, allowing for powerful automation at a single keystroke&lt;/li&gt; &lt;li&gt;First-class support for working with git &amp;amp; email&lt;/li&gt; &lt;li&gt;Open a new tab with a terminal emulator and a shell running for easy access to nearby git repos for parallel work&lt;/li&gt; &lt;li&gt;Support for multiple accounts, with IMAP, Maildir, Notmuch, Mbox and JMAP backends. Along with IMAP, JMAP, SMTP, and sendmail transfer protocols.&lt;/li&gt; &lt;li&gt;Asynchronous IMAP and JMAP support ensures the UI never gets locked up by a flaky network.&lt;/li&gt; &lt;li&gt;Efficient network usage - aerc only downloads the information which is necessary to present the UI, making for a snappy and bandwidth-efficient experience&lt;/li&gt; &lt;li&gt;Email threading (with and/or without IMAP server support).&lt;/li&gt; &lt;li&gt;PGP signing, encryption and verification using GNUpg.&lt;/li&gt; &lt;li&gt;100% free and open source software!&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://git.sr.ht/~rjarry/aerc/tree/0.21.0/item/README.md&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Download the &lt;a href=&#34;https://git.sr.ht/~rjarry/aerc&#34;&gt;latest version&lt;/a&gt; Compile it with the repo instructions&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Debian&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The debian version is very old, compile it directly&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aerc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The docs are few and hard to read online, but there are throughout in local.&lt;/p&gt; &lt;p&gt;If you&#39;re lost you can always run again the tutorial with &lt;code&gt;:help tutorial&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On its first run, aerc will copy the default config files to &lt;code&gt;~/.config/aerc&lt;/code&gt; on Linux. When you start the program for the first time a wizard will configure an account and start up the tutorial.&lt;/p&gt; &lt;p&gt;Read &lt;a href=&#34;https://bence.ferdinandy.com/2023/07/20/email-in-the-terminal-a-complete-guide-to-the-unix-way-of-email/#sending-msmtpq&#34;&gt;Bence&lt;/a&gt; post, it&#39;s a nice guideline.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://bence.ferdinandy.com/2023/07/20/email-in-the-terminal-a-complete-guide-to-the-unix-way-of-email/#notmuch&#34;&gt;notmuch&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Notmuch can be used directly as a backend for several email clients, including alot, dodo, Emacs, vim and (more importantly for us) aerc. While it can be used on its own, we are going to use it for its search index, and ability to seamlessly operate over multiple accounts&#39; maildir folder. This will provide us with the ability to search all of our email regardless of account, and to show a unified overview of certain folders, e.g. a unified inbox. If you are only setting this up for a single account, I still recommend using notmuch for its search capabilities.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://frostyx.cz/posts/synchronize-your-2fa-gmail-with-mbsync&#34;&gt;Gmail&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If &lt;a href=&#34;https://frostyx.cz/posts/synchronize-your-2fa-gmail-with-mbsync&#34;&gt;these guidelines&lt;/a&gt; don&#39;t work, try &lt;a href=&#34;https://bence.ferdinandy.com/2023/07/20/email-in-the-terminal-a-complete-guide-to-the-unix-way-of-email/#oauth-mailctl&#34;&gt;this others&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Monitorization&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you are using the mailsync scripts proposed above or on Bence&#39;s post you can check if the service failed with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;email&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;MailsyncError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count_over_time({user_service_name=~&#34;mailsync-.*&#34;} |= `Failed` [15m]) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Error&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;syncing&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;email&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;service&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.user_service_name&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.host}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It assumes that you have the &lt;code&gt;user_service_name&lt;/code&gt; label defined in your logs. I create them with &lt;a href=&#34;https://lyz-code.github.io/blue-book/vector/&#34;&gt;vector&lt;/a&gt; with the next config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;transforms&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;journald_labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;remap&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;inputs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;journald_filter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;.service_name = ._SYSTEMD_UNIT || &#34;unknown&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;.user_service_name = .USER_UNIT || ._SYSTEMD_USER_UNIT || &#34;unknown&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;aerc&lt;/code&gt; has many commands that can be bound to keybindings, to see them all check &lt;code&gt;man 1 aerc&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Main page&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;c-p&gt;, &lt;c-n&gt;: Cycles to the previous or next tab&lt;/c-n&gt;&lt;/c-p&gt;&lt;/li&gt; &lt;li&gt;k, j: Scrolls up and down between messages&lt;/li&gt; &lt;li&gt;&lt;c-u&gt;, &lt;c-d&gt;: Scrolls half a page up or down&lt;/c-d&gt;&lt;/c-u&gt;&lt;/li&gt; &lt;li&gt;g, G: Selects the first or last message, respectively&lt;/li&gt; &lt;li&gt;K, J: Switches between folders in the sidebar&lt;/li&gt; &lt;li&gt;&lt;enter&gt;: Opens the selected message&lt;/enter&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can also search the selected folder with /, or filter with . When searching you can use n and p to jump to the next and previous result. Filtering hides any non-matching message.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Message viewer&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Press &lt;enter&gt; to open a message. By default, the message viewer will display your message using less(1). This should also have familiar, vim-like keybindings for scrolling around in your message.&lt;/enter&gt;&lt;/p&gt; &lt;p&gt;Multipart messages (messages with attachments, or messages with several alternative formats) show a part selector on the bottom of the message viewer.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;c-k&gt;, &lt;c-j&gt;: Cycle between parts of a multipart message&lt;/c-j&gt;&lt;/c-k&gt;&lt;/li&gt; &lt;li&gt;q: Close the message viewer&lt;/li&gt; &lt;li&gt;f: next message&lt;/li&gt; &lt;li&gt;b: previous message&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;To show HTML messages, uncomment the text/html filter in your aerc.conf file (which is probably in ~/.config/aerc/) and install its dependencies: w3m and dante-utils.&lt;/p&gt; &lt;p&gt;You can also do many tasks you could do in the message list from here, like replying to emails, deleting the email, or view the next and previous message (J and K).&lt;/p&gt; &lt;p&gt;Some interesting commands are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;:unsubscribe&lt;/code&gt;: Attempt to automatically unsubscribe the user from the mailing list through use of the List-Unsubscribe header. If supported, aerc may open a compose window pre-filled with the unsubscribe information or open the unsubscribe URL in a web browser.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Composing messages&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;C: Compose a new message&lt;/li&gt; &lt;li&gt;rr: Reply-all to a message&lt;/li&gt; &lt;li&gt;rq: Reply-all to a message, and pre-fill the editor with a quoted version of the message being replied to&lt;/li&gt; &lt;li&gt;Rr: Reply to a message&lt;/li&gt; &lt;li&gt;Rq: Reply to a message, and pre-fill the editor with a quoted version of the message being replied to&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The message composer will appear. You should see To, From, and Subject lines, as well as your $EDITOR. You can use &lt;tab&gt; or &lt;c-j&gt; and &lt;c-k&gt; to cycle between these fields (tab won&#39;t cycle between fields once you enter the editor, but &lt;c-j&gt; and &lt;c-k&gt; will).&lt;/c-k&gt;&lt;/c-j&gt;&lt;/c-k&gt;&lt;/c-j&gt;&lt;/tab&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://aerc-mail.org/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://git.sr.ht/~rjarry/aerc&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://man.sr.ht/~rjarry/aerc/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://todo.sr.ht/~rjarry/aerc?__goaway_challenge=meta-refresh&amp;amp;__goaway_id=7efb941c2542b6ec58b84a4b88e1c20b&#34;&gt;Issues&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Interesting configurations&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://bence.ferdinandy.com/2023/07/20/email-in-the-terminal-a-complete-guide-to-the-unix-way-of-email/#sending-msmtpq&#34;&gt;Bence post&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.acarg.ch/posts/aerc-email-setup/&#34;&gt;Acarg post&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://drewdevault.com/2021/05/17/aerc-with-mbsync-postfix.html&#34;&gt;Drew post&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce autorandr.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/phillipberndt/autorandr&#34;&gt;autorandr&lt;/a&gt; is a command line tool to automatically select a display configuration based on connected devices.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Save your current display configuration and setup with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--save&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mobile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Connect an additional display, configure your setup and save it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--save&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docked
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now autorandr can detect which hardware setup is active:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;mobile
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;docked&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;detected&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To automatically reload your setup:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--change
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To manually load a profile:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--load&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;profile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;or simply:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autorandr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;profile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;December 24, 2025 07:00:38 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-12-24T07:00:38+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;December 24, 2025 07:00:38 UTC&#34;&gt;2025-12-24&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_12_23/</link>
      <pubDate>2025-12-24 07:00:38+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_12_23/</guid>
      
    </item>
    
    <item><title>5th November 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;militancy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antiracism/&#34;&gt;Militancy&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#references&#34;&gt;Añadir pantube.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://pantube.tv/&#34;&gt;Pantube&lt;/a&gt;: YouTube de izquierdas&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#references&#34;&gt;Add rich don&#39;t work representation.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://therichdont.work&#34;&gt;The rich don&#39;t work&lt;/a&gt;: game to get a grasp of how much money they make without doing anything&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#podcasts&#34;&gt;Añadir podcast sobre la Operación Gladio.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.podtrac.com/pts/redirect.mp3/pdst.fm/e/chrt.fm/track/B1992E/traffic.megaphone.fm/EOM2231294568.mp3?updated=1727251558&#34;&gt;No es el fin del mundo: 46. ¿Qué fue la Operación Gladio?&lt;/a&gt;: Para pasárselo a cualquier persona reformista&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Añadir vídeos de David zona zero.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://bsky.app/profile/davidzonazero.bsky.social/post/3lz6p4tmvos2r&#34;&gt;David zona zero y los distintos barrios&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;antifascism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antifascism/&#34;&gt;Antifascism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir un par de artículos interestantes.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.newsweek.com/hitler-incompetent-lazy-nazi-government-clown-show-opinion-1408136&#34;&gt;Hitler Was Incompetent and Lazy—and His Nazi Government Was an Absolute Clown Show&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://awards.journalists.org/entries/open-source-extremist-identifications/&#34;&gt;Bellincat Open-Source Extremist Identifications&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;anticapacitismo&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anticapacitismo/&#34;&gt;Anticapacitismo&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir proyecto artefactos.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.artefactos.org&#34;&gt;https://www.artefactos.org&lt;/a&gt;: son gente de tecnología y familias de críos con distintas necesidades, colaborando juntos. Hacen prototipos en 3D que te puedes imprimir&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-navigation&#34;&gt;Life navigation&lt;/h2&gt; &lt;h3 id=&#34;knowledge-management&#34;&gt;Knowledge Management&lt;/h3&gt; &lt;h4 id=&#34;anki&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/&#34;&gt;Anki&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/#file-location&#34;&gt;File location.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;On Linux:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;recent Anki versions store your user data in &lt;code&gt;~/.local/share/Anki2&lt;/code&gt;, or &lt;code&gt;$XDG_DATA_HOME/Anki2&lt;/code&gt; if you have set a custom data path.&lt;/li&gt; &lt;li&gt;Anki’s launcher is installed in &lt;code&gt;/usr/local/share/anki&lt;/code&gt;&lt;/li&gt; &lt;li&gt;When you install/update Anki with the launcher, it downloads support files and places them in &lt;code&gt;~/.local/share/AnkiProgramFiles&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Removing that folder will cause the launcher to behave like a fresh install.&lt;/p&gt; &lt;p&gt;The AnkiProgramFiles contains all the files needed to run Anki aside from the launcher.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;calistenia&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/&#34;&gt;Calistenia&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/#shrimp-squat-vs-pistol-squat&#34;&gt;Shrimp squat vs pistol squat.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://gmb.io/shrimp-squats-vs-pistol-squats/&#34;&gt;https://gmb.io/shrimp-squats-vs-pistol-squats/&lt;/a&gt; &lt;a href=&#34;https://www.reddit.com/r/bodyweightfitness/comments/5loylk/pistol_squats_vs_shrimp_squats/&#34;&gt;https://www.reddit.com/r/bodyweightfitness/comments/5loylk/pistol_squats_vs_shrimp_squats/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/#nordic-curl&#34;&gt;Nordic curl.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;relevant-content&#34;&gt;Relevant content&lt;/h2&gt; &lt;h3 id=&#34;board-games&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/board_games/&#34;&gt;Board Games&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/board_games/#cooperative-games&#34;&gt;Add cooperative games references.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.reddit.com/r/boardgames/comments/rih0z3/your_favorite_cooperative_board_games/?tl=es-es&#34;&gt;Favourite coop games&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;December 23, 2025 10:03:21 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-12-23T10:03:21+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;December 23, 2025 10:03:21 UTC&#34;&gt;2025-12-23&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_11_05/</link>
      <pubDate>2025-12-23 10:03:21+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_11_05/</guid>
      
    </item>
    
    <item><title>28th August 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;militancy&#34;&gt;Militancy&lt;/h2&gt; &lt;h3 id=&#34;collaborating-tools&#34;&gt;Collaborating tools&lt;/h3&gt; &lt;h4 id=&#34;aleph&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/investigative_journalism/&#34;&gt;Aleph&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add warning for new potential users.&lt;/p&gt; &lt;p&gt;WARNING: Check out the &lt;a href=&#34;https://lyz-code.github.io/blue-book/investigative_journalism/&#34;&gt;investigative journalism article before using Aleph&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Compare investigative journalism tools.&lt;/p&gt; &lt;p&gt;After reviewing Aleph Pro, Open Aleph, &lt;a href=&#34;https://dataresearchcenter.org/&#34;&gt;DARC&lt;/a&gt; and Datashare I feel that the investigative reporting software environment, as of June 2025, is very brittle and under a huge crisis that will have a breaking point on October of 2025, day where OCCRP will do the switch from Aleph to Aleph Pro.&lt;/p&gt; &lt;p&gt;Given this scenario, I think the best thing to do, if you already have an Aleph instance, is to keep using it until things stabilise. As you won\&#39;t have software updates since October 2025, I suggest that from then on you protect the service behind an VPN and/or SSL client certificate.&lt;/p&gt; &lt;p&gt;I also feel it\&#39;s also a great moment to make a strategic decision on how you want to use an investigative reporting platform. Some key questions are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;How much do you care of our data being leaked or lost by third parties?&lt;/li&gt; &lt;li&gt;How much do you trust OCCRP, DARC or ICIJ?&lt;/li&gt; &lt;li&gt;Do you want to switch from a self hosted platform to an external managed one? Will they be able to give a better service?&lt;/li&gt; &lt;li&gt;If you want to stay on the self hosted solution. Shall you migrate to Datashare instead of Open Aleph?&lt;/li&gt; &lt;li&gt;How dependent are you on open source software? How fragile are the teams that support that software? Can you help change that fragility?&lt;/li&gt; &lt;li&gt;Shall you use the AI for your investigative processes? If so, where and when?&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I hope the analysis below may help shed some light on some of these questions. The only one that is not addressed is the AI as it\&#39;s a more political, philosophical one, that would make the document even longer.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Analysis of the present&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Development dependent in US government&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The two main software are developed by non-profits, Aleph by OCCRP and Datashare by ICIJ, that received part of their funding from the US government. This funding was lost after Naranjitler\&#39;s administration funding cuts:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.occrp.org/en/feature/with-a-strike-of-a-pen-trumps-aid-cuts-threaten-independent-journalism-around-the-world&#34;&gt;OCCRP lost this year 38% of their operational funds&lt;/a&gt;: \&#34;As a result, we had to lay off 40 people --- one fifth of our staff --- and have temporarily reduced some of the salaries of others. But there is more. OCCRP has also been funding a number of organizations across Europe, in some of the most difficult countries. Eighty percent of those sub-grants that we provide to other newsrooms have been cut as well.\&#34;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.icij.org/news/2025/03/unable-to-stay-in-the-country-unable-to-return-home-reporters-face-grim-prospects-after-latest-trump-cuts/&#34;&gt;ICIJ lost this year 8.6% of their operational funds&lt;/a&gt; with no apparent effects on the software or the staff.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;OCCRP decided to close the source code of Aleph triggering the team split up&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;With &lt;a href=&#34;https://www.occrp.org/en/announcement/occrp-announces-a-new-chapter-for-its-investigative-data-platform-aleph-pro&#34;&gt;OCCRP decision to close the source of Aleph&lt;/a&gt; an &lt;a href=&#34;https://dataresearchcenter.org/who-we-are/&#34;&gt;important part of their team&lt;/a&gt; (the co-leader of the research and data team, the Chief Data Editor and a developer) decided to &lt;a href=&#34;https://openaleph.org/blog/2025/03/OpenAleph-commits-to-the-commons/3510138e-16b3-4b5d-a06c-41af0aa2d517/&#34;&gt;leave the project&lt;/a&gt; and fund &lt;a href=&#34;https://dataresearchcenter.org&#34;&gt;DARC&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Although they look to &lt;a href=&#34;https://openaleph.org/blog/2025/03/OpenAleph-commits-to-the-commons/3510138e-16b3-4b5d-a06c-41af0aa2d517/&#34;&gt;be in good terms&lt;/a&gt;. They\&#39;re collaborating, although it could be OCCRP trying to save their face on this dark turn.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;These software have very few developers and no community behind them&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/aleph/graphs/contributors&#34;&gt;Aleph&lt;/a&gt; looks to be currently developed by 2 developers, and it\&#39;s development has stagnated since the main developer (`pudo`) stopped developing and moved to &lt;a href=&#34;https://github.com/opensanctions/opensanctions/graphs/contributors&#34;&gt;Open Sanctions&lt;/a&gt; 4 years ago. 3 key members of their team have moved on to Open Aleph after the split. We can only guess if this is the same team that is developing Aleph Pro. If it\&#39;s not then they are developers we know nothing about and can\&#39;t audit.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/alephdata/aleph/compare/main...openaleph:openaleph:main&#34;&gt;Open Aleph&lt;/a&gt; looks to be developed by 4 people, 3 of them were part of the Aleph development team until the break up. The other one created a company to host Aleph instances 4 years ago.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/ICIJ/datashare/graphs/contributors&#34;&gt;Datashare&lt;/a&gt; seems to be developed by &lt;a href=&#34;https://www.icij.org/about/our-team/&#34;&gt;6 developers&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In all projects pull requests by the community have been very scarce.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The community support is not that great&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;My experience requesting features, proposing fixes with Aleph before the split is that they answer well on their slack, but are slow on the issues and the pull requests that fall outside their planned roadmap. Even if they are bugs. I\&#39;ve been running a script on each ingest to fix an UI bug for a year already. I tried to work with them in solving it without success.&lt;/p&gt; &lt;p&gt;I don\&#39;t have experience with Datashare, but they do answer and fix the issues the people open.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Analysis of the available software&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Aleph Pro&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The analysis is based on their &lt;a href=&#34;https://www.occrp.org/en/announcement/occrp-announces-a-new-chapter-for-its-investigative-data-platform-aleph-pro&#34;&gt;announcement&lt;/a&gt; and their &lt;a href=&#34;https://www.occrp.org/en/announcement/aleph-pro-frequently-asked-questions-on-the-future-of-occrps-investigative-data-platform&#34;&gt;FAQ&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;As long as you have less than 1TB of data and are a nonprofit it will, for now, cost you way less than hosting your solution&lt;/li&gt; &lt;li&gt;OCCRP is behind the project&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;They seem to have an unstable, small and broken development team&lt;/li&gt; &lt;li&gt; &lt;p&gt;They only offer 1TB of data which is enough for small to medium projects but doesn\&#39;t give much space to grow&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;They lost my trust&lt;/p&gt; &lt;p&gt;There are several reasons that make me hesitant to trust them:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;They don\&#39;t want to publish their source code&lt;/li&gt; &lt;li&gt;They decided that the path to solve a complicated financial situation is to close their source code&lt;/li&gt; &lt;li&gt;They advocated in the past (and even now!) that being open-sourced was a corner part of the project and yet they close their code.&lt;/li&gt; &lt;li&gt;They hid that &lt;a href=&#34;https://report.az/en/analytics/independent-investigation-us-gov-t-funded-occrp-and-appointed-its-leadership/&#34;&gt;52% of their funding came from the US government&lt;/a&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;With the next consequences:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I would personally not give them my data or host their software.&lt;/li&gt; &lt;li&gt;I wouldn\&#39;t be surprised if in the future they retract on their promises, such as offering Aleph Pro for free forever for nonprofit journalism organizations.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;You loose sovereignty of your data&lt;/p&gt; &lt;p&gt;Either if you upload your data to their servers or host a closed sourced program in yours, you have no way of knowing what are they doing with your data. Given their economical situation, doing business with the data could be an option.&lt;/p&gt; &lt;p&gt;It could also be potentially difficult to extract your data in the future.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;You loose sovereignty of your service&lt;/p&gt; &lt;p&gt;If they host the service you depend on them for any operations such as maintenance, upgrades, and keeping the service up.&lt;/p&gt; &lt;p&gt;You\&#39;ll also no longer be able to change the software to apply patches to problems and would depend on them for their implementation and application.&lt;/p&gt; &lt;p&gt;You\&#39;ll no longer have any easy way to know what does the program do. This is critical from a security point of view as introduced backdoors would go unnoticed. It\&#39;s also worrying as we could not audit how they implement the AI. It is known that AI solutions tend to be biased and may thwart the investigative process.&lt;/p&gt; &lt;p&gt;Finally, if they decide to shutdown or change the conditions you\&#39;re sold.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;I looks like they are selling smoke&lt;/p&gt; &lt;p&gt;Their development activity has dropped in the recent years, they have a weakened team and yet they are promising a complete rewrite to create a brand new software. In an announce that is filled with buzzwords such as AI without giving any solid evidence.&lt;/p&gt; &lt;p&gt;I feel that the whole announcement is written to urge people to buy their product and to save their face. Its not written to the community or their users, is for those that can give them money.&lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;They offer significant performance upgrades and lower infrastructure costs at the same time that they incorporate the latest developments in data-analysis and AI&lt;/p&gt; &lt;p&gt;Depending on how they materialise the data-analysis and AI new features it will mean a small to a great increase in infrastructure costs. Hosting these processes is very resource intensive and expensive.&lt;/p&gt; &lt;p&gt;The decrease in infra costs may come from:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Hosting many aleph instances under the same infrastructure is more efficient than each organisation having their own.&lt;/li&gt; &lt;li&gt;They might migrate the code to a more efficient language like rust or go&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;So even though Aleph Pro will require more resources, as they are all going to be hosted in OCCRP it will be cheaper overall.&lt;/p&gt; &lt;p&gt;I\&#39;m not sure how they want to implement the AI, I see two potential places:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;To improve the ingest process.&lt;/li&gt; &lt;li&gt;To use LLM (like ChatGPT) to query the data.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Both features are very, very, very expensive resource wise. The only way to give those features at the same time as lowering the infra costs is by outsourcing the AI services. If they do this, it will mean that your data will be processed by that third party, with all the awful consequences it entails.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;They are selling existent features as new or are part of other open source projects&lt;/p&gt; &lt;p&gt;Such as:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Rebuilt the ingest pipeline: they recently released it in the latest versions of Aleph&lt;/li&gt; &lt;li&gt;Modular design: The source is already modular (although it can always be improved)&lt;/li&gt; &lt;li&gt;Enhanced data models for better linking, filtering, and insights. Their model is based on followthemoney which is open source.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ol&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;They are ditching part of their user base&lt;/p&gt; &lt;p&gt;They only support self-hosted solutions to enterprise license clients. This leaves out small organisations or privacy minded individuals. Even this solution is said to be maintained in partnership with OCCRP.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;The new version benefits may not be worth the costs&lt;/p&gt; &lt;p&gt;They say that Aleph Pro will deliver a faster, smarter, and more flexible platform, combining a modern technical foundation with user-centered design and major performance gains. But if you do not do a heavy use of the service you may not need some of these improvements. Although they for sure would be nice to have.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;It could be unstable for a while&lt;/p&gt; &lt;p&gt;A complete platform rewrite is usually good in the long run but these kind of migrations tend to have an unstable period of time where some of the functionality might be missing&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;You need to make the decision blindly&lt;/p&gt; &lt;p&gt;Even though they are going to give a beta if you request it, I\&#39;m not sure of this, before doing the switch, you need to make the decision beforehand. You may not even like the new software&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Datashare&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ICIJ, a more reliable non profit, is behind it.&lt;/li&gt; &lt;li&gt;Has the biggest and stable development team&lt;/li&gt; &lt;li&gt;Is the most active project&lt;/li&gt; &lt;li&gt;Better community support&lt;/li&gt; &lt;li&gt;You can host it&lt;/li&gt; &lt;li&gt;It\&#39;s open source&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you have an Aleph instance there is no documented way to migrate to Datashare. And there is still not an easy way to do the migration, as they don&#39;t yet use the &lt;code&gt;followthemoney&lt;/code&gt; data schema.&lt;/li&gt; &lt;li&gt;They won\&#39;t host an instance for you.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Open Aleph&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;You can host it&lt;/li&gt; &lt;li&gt;It\&#39;s open source&lt;/li&gt; &lt;li&gt;The hosted solution will probably cost you way less than hosting your own solution (although &lt;a href=&#34;https://openaleph.org/managed/&#34;&gt;they don\&#39;t show prices&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;The people behind it have proven their ethic values&lt;/li&gt; &lt;li&gt;I know one of their developers. She is a fantastic person which is very involved in putting technology in the service of society, and has been active at the CCC.&lt;/li&gt; &lt;li&gt;They are actively reaching out to give support with the migration&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A new small organisation is behind the project&lt;/li&gt; &lt;li&gt;A small development team with few recent activity. Since their creation (3 months ago) their development &lt;a href=&#34;https://github.com/openaleph/openaleph/pulse/monthly&#34;&gt;pace is slow&lt;/a&gt; (the contributors don\&#39;t even load). It could be because they are still setting up the new organisation and doing the fork.&lt;/li&gt; &lt;li&gt;It may not have all the features Aleph has. They started the fork on November of 2024 and are 137 commits ahead and 510 behind. But they could be squash commits.&lt;/li&gt; &lt;li&gt;Their &lt;a href=&#34;https://darc.social/&#34;&gt;community forum&lt;/a&gt; doesn\&#39;t have much activity&lt;/li&gt; &lt;li&gt;The remote hosted solution has the same problems as Aleph Pro in terms of data and service sovereignty. Although I do trust more DARC than OCCRP.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-navigation&#34;&gt;Life navigation&lt;/h2&gt; &lt;h3 id=&#34;time-navigation&#34;&gt;Time navigation&lt;/h3&gt; &lt;h4 id=&#34;org-mode&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;Org Mode&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#exporting&#34;&gt;Exporting to pdf or markdown.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;To pdf&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want to convert it with python you first need to install the dependencies: &lt;code&gt;sudo apt install texlive-xetex&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Then you can do&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;To markdown&lt;/strong&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pandoc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.org&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;content-management&#34;&gt;Content Management&lt;/h3&gt; &lt;h4 id=&#34;news-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/news_management/&#34;&gt;News Management&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add forensic architecture.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://forensic-architecture.org/&#34;&gt;Forensic architecture&lt;/a&gt;: Forensic Architecture (FA) is a research agency based at Goldsmiths, University of London. Our mandate is to develop, employ, and disseminate new techniques, methods, and concepts for investigating state and corporate violence. Our team includes architects, software developers, filmmakers, investigative journalists, scientists, and lawyers.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;torrent-management&#34;&gt;Torrent management&lt;/h3&gt; &lt;h4 id=&#34;qbittorrent&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/&#34;&gt;qBittorrent&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/qbittorrent/#metrics-monitorisation&#34;&gt;Metrics monitorisation.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;technology&#34;&gt;Technology&lt;/h2&gt; &lt;h3 id=&#34;coding&#34;&gt;Coding&lt;/h3&gt; &lt;h4 id=&#34;bash-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/bash_snippets/&#34;&gt;Bash snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add context switches column meanings.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;UID: The real user identification number of the task being monitored.&lt;/li&gt; &lt;li&gt;USER: The name of the real user owning the task being monitored.&lt;/li&gt; &lt;li&gt;PID: The identification number of the task being monitored.&lt;/li&gt; &lt;li&gt;cswch/s: Total number of voluntary context switches the task made per second. A voluntary context switch occurs when a task blocks because it requires a resource that is unavailable.&lt;/li&gt; &lt;li&gt;nvcswch/s: Total number of non voluntary context switches the task made per second. A involuntary context switch takes place when a task executes for the duration of its time slice and then is forced to relinquish the processor.&lt;/li&gt; &lt;li&gt;Command: The command name of the task.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;configure-docker-to-host-the-application&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/&#34;&gt;Configure Docker to host the application&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#do-a-copy-of-a-list-of-docker-images-in-your-private-registry&#34;&gt;Do a copy of a list of docker images in your private registry.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-euo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pipefail

&lt;span class=&#34;nv&#34;&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;dirname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BASH_SOURCE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[0]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/bitnami-images.txt&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &amp;lt;image_list_file&amp;gt; &amp;lt;target_registry&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Example: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; bitnami-images.txt your.docker.registry.org&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: Image list file &#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#39; not found&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

log&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;+%Y-%m-%d %H:%M:%S&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$*&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

extract_image_name_and_tag&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;full_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove registry prefix to get org/repo:tag&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Examples:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# docker.io/bitnami/discourse:3.4.7 -&amp;gt; bitnami/discourse:3.4.7&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# registry-1.docker.io/bitnami/os-shell:11-debian-11-r95 -&amp;gt; bitnami/os-shell:11-debian-11-r95&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$full_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;^&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;^/&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;*&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;^/&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;+/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Contains registry with dot - remove everything up to first /&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;full_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;#*/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# No registry prefix&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$full_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

pull_and_push_multiarch&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;source_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_registry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;image_name_with_tag
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_name_with_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;extract_image_name_and_tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_registry&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_name_with_tag&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Processing: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; -&amp;gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=()&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;architectures&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;linux/amd64&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;linux/arm64&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;amd64&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;arm64&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Try to pull and push each architecture&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!architectures[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;architectures&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Attempting to pull &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--platform&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$platform&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pulled &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Tag with architecture-specific tag for manifest creation&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_specific_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_image&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffix&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pushing &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image as &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_specific_tag&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pushed &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to push &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;⚠️  &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image not available for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; - skipping&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ No images were successfully pushed for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Create the main tag with proper multi-arch manifest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Creating multi-arch manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove any existing manifest (in case of retry)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Annotate each architecture in the manifest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!pushed_images[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;annotate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--arch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--os&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;linux
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pushing multi-arch manifest to &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✅ Successfully pushed multi-arch image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to push manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to create manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Only one architecture - tag and push directly&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Single architecture available, pushing as &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[0]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✅ Successfully pushed single-arch image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to push &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Clean up local images to save space&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting multi-architecture image pull and push&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Source list: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Target registry: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Enable experimental CLI features for manifest commands&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;DOCKER_CLI_EXPERIMENTAL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;enabled

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=()&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;IFS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;image_line&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Skip empty lines and comments&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;^&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;:space:&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;*#&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove leading/trailing whitespace&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_line&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/^[[:space:]]*//;s/[[:space:]]*$//&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] Processing: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull_and_push_multiarch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✓ Success: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✗ Failed: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Progress: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; completed&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;----------------------------------------&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Final Summary:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Total images processed: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successful: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$successful_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed images:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;  %s\n&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;🎉 All images processed successfully!&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#migrate-away-from-bitnami&#34;&gt;Migrate away from bitnami.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Bitnami is changing their pull policy making it unfeasible to use their images (More info here: &lt;a href=&#34;https://www.reddit.com/r/selfhosted/comments/1ma5d8t/migrating_away_from_bitnami/&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://archive.ph/dIVZk&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://www.reddit.com/r/kubernetes/comments/1mc73s4/bitnami_moving_most_free_container_images_to_a/?chainedPosts=t3_1ma5d8t&#34;&gt;3&lt;/a&gt;), so there is the need to migrate to other image providers.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Which alternative to use&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The migration can be done to the official maintained images (although this &lt;a href=&#34;https://www.reddit.com/r/selfhosted/comments/1ma5d8t/migrating_away_from_bitnami/&#34;&gt;has some disadvantages&lt;/a&gt;) or to any of the common docker image builders:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/home-operations/containers/&#34;&gt;https://github.com/home-operations/containers/&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/linuxserver&#34;&gt;https://github.com/linuxserver&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/11notes&#34;&gt;https://github.com/11notes&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;There is an effort &lt;a href=&#34;https://github.com/bitcompat&#34;&gt;to build a fork of bitnami images&lt;/a&gt; but it has not yet much inertia.&lt;/p&gt; &lt;p&gt;Regarding the alternatives of helm charts, a quick look shown &lt;a href=&#34;https://github.com/groundhog2k/helm-charts/tree/master/charts&#34;&gt;this one&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Infrastructure archeology&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First you need to know which images are you using, to do that you can:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#clone-al-git-repositories-of-a-series-of-organisations&#34;&gt;Clone al git repositories of a series of organisations&lt;/a&gt; and do a local grep&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#search-all-the-container-images-in-use-that-match-a-desired-string&#34;&gt;Search all the container images in use in kubernetes that match a desired string&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#recursively-pull-a-copy-of-all-helm-charts-used-by-an-argocd-repository&#34;&gt;Recursively pull a copy of all helm charts used by an argocd repository&lt;/a&gt; and then do a grep.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Create a local copy of the images&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It&#39;s wise to make a copy of the used images in your local registry to be able to pull the dockers once bitnami does not longer let you.&lt;/p&gt; &lt;p&gt;To do that you can save the used images in a &lt;code&gt;bitnami-images.txt&lt;/code&gt; file and run the next script:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-euo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pipefail

&lt;span class=&#34;nv&#34;&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;dirname&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BASH_SOURCE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[0]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;SCRIPT_DIR&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/bitnami-images.txt&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &amp;lt;image_list_file&amp;gt; &amp;lt;target_registry&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Example: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; bitnami-images.txt registry.cloud.icij.org&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: Image list file &#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#39; not found&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

log&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;+%Y-%m-%d %H:%M:%S&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$*&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

extract_image_name_and_tag&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;full_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove registry prefix to get org/repo:tag&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Examples:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# docker.io/bitnami/discourse:3.4.7 -&amp;gt; bitnami/discourse:3.4.7&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# registry-1.docker.io/bitnami/os-shell:11-debian-11-r95 -&amp;gt; bitnami/os-shell:11-debian-11-r95&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# registry-proxy.internal.cloud.icij.org/bitnami/minideb:stretch -&amp;gt; bitnami/minideb:stretch&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$full_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;^&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;^/&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;*&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;^/&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;+/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Contains registry with dot - remove everything up to first /&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;full_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;#*/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# No registry prefix&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$full_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

pull_and_push_multiarch&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;source_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_registry&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;image_name_with_tag
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_name_with_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;extract_image_name_and_tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_registry&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_name_with_tag&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Processing: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; -&amp;gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=()&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;architectures&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;linux/amd64&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;linux/arm64&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;amd64&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;arm64&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Try to pull and push each architecture&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!architectures[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;architectures&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Attempting to pull &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--platform&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$platform&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pulled &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Tag with architecture-specific tag for manifest creation&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_specific_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target_image&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffix&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pushing &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image as &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_specific_tag&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pushed &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to push &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_specific_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;⚠️  &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;platform&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; image not available for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; - skipping&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ No images were successfully pushed for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Create the main tag with proper multi-arch manifest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Creating multi-arch manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove any existing manifest (in case of retry)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Annotate each architecture in the manifest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;!pushed_images[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_tag&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;arch_suffixes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;annotate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch_tag&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--arch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$arch&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--os&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;linux
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pushing multi-arch manifest to &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✅ Successfully pushed multi-arch image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to push manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to create manifest for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Only one architecture - tag and push directly&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Single architecture available, pushing as &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[0]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✅ Successfully pushed single-arch image: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;❌ Failed to push &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Clean up local images to save space&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$source_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;pushed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-eq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rmi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$target_image&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting multi-architecture image pull and push&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Source list: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Target registry: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Enable experimental CLI features for manifest commands&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;DOCKER_CLI_EXPERIMENTAL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;enabled

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;total_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=()&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;IFS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;image_line&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Skip empty lines and comments&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;^&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;:space:&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;*#&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Remove leading/trailing whitespace&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;image_line&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/^[[:space:]]*//;s/[[:space:]]*$//&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;processed_images&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] Processing: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull_and_push_multiarch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TARGET_REGISTRY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;successful_images&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✓ Success: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;✗ Failed: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$image_line&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Progress: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$total_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; completed&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;----------------------------------------&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$IMAGE_LIST_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Final Summary:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Total images processed: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$processed_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successful: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$successful_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${#&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-gt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed images:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;  %s\n&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;failed_images&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;🎉 All images processed successfully!&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Replace a bitnami image with a local one&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you for some reason need to pull &lt;code&gt;bitnami/discourse:3.4.7&lt;/code&gt; and get an error you need instead to pull it from &lt;code&gt;{your_registry}/bitnami/discourse:3.4.7&lt;/code&gt;. If you want to pull a specific architecture you can append it at the end (&lt;code&gt;{your_registry}/bitnami/discourse:3.4.7-amd64&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;If you need to do the changes in an argocd managed kubernetes application search in the &lt;code&gt;values.yaml&lt;/code&gt; or &lt;code&gt;values-{environment}.yaml&lt;/code&gt; files for the &lt;code&gt;image:&lt;/code&gt; string. If it&#39;s not defined you may need to look at the helm chart definition. To do that open the &lt;code&gt;Chart.yaml&lt;/code&gt; file to find the chart and the version used. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;apiVersion&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;v2&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;discourse&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1.0.0&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;discourse&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;12.6.2&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;https://charts.bitnami.com/bitnami&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can pull a local copy of the chart with:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If the chart is using an &lt;code&gt;oci&lt;/code&gt; url:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;oci://registry-1.docker.io/bitnamicharts/postgresql&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8&lt;/span&gt;.10.X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--untar&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;postgres8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;If it&#39;s using an &lt;code&gt;https&lt;/code&gt; url:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cost-analyzer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://kubecost.github.io/cost-analyzer/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.7.2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And inspect the &lt;code&gt;values.yaml&lt;/code&gt; file and all the templates until you find which key value you need to add.&lt;/p&gt; &lt;p&gt;feat(docker#Cannot invoke &#34;jdk.internal.platform.CgroupInfo.getMountPoint()&#34; because &#34;anyController&#34; is null) : Cannot invoke &#34;jdk.internal.platform.CgroupInfo.getMountPoint()&#34; because &#34;anyController&#34; is null&lt;/p&gt; &lt;p&gt;It&#39;s caused because the docker is not able to access the cgroups, this can be caused by a docker using the legacy cgroups v1 while the linux kernel (&amp;gt;6.12) is using the v2.&lt;/p&gt; &lt;p&gt;The best way to fix it is to upgrade the docker to use v2, if you can&#39;t you need to force the system to use the v1. To do that:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Edit &lt;code&gt;/etc/default/grub&lt;/code&gt; to add the configuration &lt;code&gt;GRUB_CMDLINE_LINUX=&#34;systemd.unified_cgroup_hierarchy=0&#34;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Then update GRUB: &lt;code&gt;sudo update-grub&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Reboot&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#clone-al-git-repositories-of-a-series-of-organisations&#34;&gt;Clone al git repositories of a series of organisations.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It assumes you have &lt;code&gt;tea&lt;/code&gt; configured to interact with the desired gitea instance.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e

&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ansible-playbooks&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;ansible-roles&#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;

clone_org_repos&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;has_more&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$has_more&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Fetching page &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$page&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;...&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;csv_output
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;csv_output&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;tea&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ls&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;csv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--page&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$page&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$csv_output&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$csv_output&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&#34;owner&#34;,&#34;name&#34;,&#34;type&#34;,&#34;ssh&#34;&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$csv_output&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-lt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;No more repositories found on page &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$page&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;has_more&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;repo_count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;IFS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;,&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;owner&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ssh_url&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$owner&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&#34;owner&#34;&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;owner&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$owner&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/&#34;//g&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/&#34;//g&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ssh_url&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ssh_url&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;s/&#34;//g&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# echo &#34;owner: $owner name: $name ssh_url: $ssh_url&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ssh_url&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[*]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;~&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$owner&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Cloning repository: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;clone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ssh_url&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$owner&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to clone &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;, skipping...&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Repository &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; already exists, skipping...&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;repo_count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;repo_count&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$csv_output&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;((&lt;/span&gt;page++&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;..
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Finished processing &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting repository cloning process...&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Target organizations: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[*]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tea&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: &#39;tea&#39; command not found. Please install gitea tea CLI.&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: &#39;git&#39; command not found. Please install git.&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;org&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;clone_org_repos
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Repository cloning process completed!&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Check the following directories:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;org&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ORGANIZATIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[@]&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;  - &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/ (&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$org&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-maxdepth&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-type&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; repositories)&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/&#34;&gt;Python Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#remove-a-directory-with-content&#34;&gt;Remove a directory with content.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;shutil&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;shutil&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rmtree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/path/to/directory&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#recursively-find-files&#34;&gt;Recursively find files if you only want the files and directories of the first level.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/your/directory&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iterdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;File: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Directory: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;item&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;feat(helm#Download a chart): Download a chart&lt;/p&gt; &lt;p&gt;If the chart is using an &lt;code&gt;oci&lt;/code&gt; url: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;oci://registry-1.docker.io/bitnamicharts/postgresql&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8&lt;/span&gt;.10.X&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--untar&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;postgres8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;If it&#39;s using an &lt;code&gt;https&lt;/code&gt; url:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pull&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cost-analyzer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://kubecost.github.io/cost-analyzer/&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.7.2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h3&gt; &lt;h4 id=&#34;argocd&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/postgres/&#34;&gt;ArgoCD&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#recursively-pull-a-copy-of-all-helm-charts-used-by-an-argocd-repository&#34;&gt;Recursively pull a copy of all helm charts used by an argocd repository.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Including the dependencies of the dependencies.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;argparse&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sys&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;typing&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Set&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;yaml&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;HelmChartPuller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;fm&#34;&gt;__init__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup_logging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;setup_logging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;basicConfig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;level&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(asctime)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(levelname)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(message)s&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;datefmt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;%Y-%m-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%d&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; %H:%M:%S&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getLogger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;parse_chart_yaml&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Parse Chart.yaml file and return its contents.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;r&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;utf-8&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;yaml&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;safe_load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to parse &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Extract dependencies from chart data.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;dependencies&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[])&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;is_chart_pulled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Check if chart has already been pulled.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;chart_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_id&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;mark_chart_pulled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Mark chart as pulled to avoid duplicates.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;chart_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;pull_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Pull a Helm chart using appropriate method (OCI or traditional).&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_chart_pulled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Chart &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; already pulled, skipping&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;

        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pulling chart: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; version &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; from &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;startswith&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;oci://&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;oci_url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;helm&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;pull&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;oci_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;--version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;--untar&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;helm&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;pull&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;--repo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;--version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                    &lt;span class=&#34;s2&#34;&gt;&#34;--untar&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
                &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

            &lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;capture_output&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;check&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Successfully pulled chart: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mark_chart_pulled&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CalledProcessError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to pull chart &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;process_chart_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Process dependencies from a Chart.yaml file recursively.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Processing dependencies from: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_chart_yaml&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;No dependencies found in &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
           &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;repository&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]):&lt;/span&gt;
                &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Incomplete dependency in &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dep&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;

            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pull_chart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repository&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;pulled_chart_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pulled_chart_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;dep_chart_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pulled_chart_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Chart.yaml&#34;&lt;/span&gt;
                    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dep_chart_file&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
                        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Found Chart.yaml in pulled dependency: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dep_chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;process_chart_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dep_chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;find_chart_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;search_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Find all Chart.yaml files in the given directory.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Searching for Chart.yaml files in: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_dir&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rglob&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Chart.yaml&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;check_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Check if required dependencies are available.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;helm&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;capture_output&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;check&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CalledProcessError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;FileNotFoundError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;helm command not found. Please install Helm.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;yaml&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ImportError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;s2&#34;&gt;&#34;PyYAML module not found. Install with: pip install PyYAML&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Main execution method.&#34;&#34;&#34;&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;target_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Directory &#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_dir&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#39; does not exist&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;sys&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting to process Helm charts in: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_path&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Charts will be pulled to current directory: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cwd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;n&#34;&gt;chart_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_chart_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;No Chart.yaml files found&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chart_files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Found Chart.yaml: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;process_chart_dependencies&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;chart_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Completed processing. Total unique charts pulled: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pulled charts: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;, &#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pulled_charts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Recursively pull Helm charts and their dependencies from Chart.yaml files&#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;directory&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Directory to search for Chart.yaml files&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;puller&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;HelmChartPuller&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;puller&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#cordon-all-arm64-nodes&#34;&gt;Cordon all arm64 nodes.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nodes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubernetes.io/arch&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;arm64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{.items[*].metadata.name}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xargs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cordon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#search-all-the-container-images-in-use-that-match-a-desired-string&#34;&gt;Search all the container images in use that match a desired string.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e

log&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;[&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;date&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;+%Y-%m-%d %H:%M:%S&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;] &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$*&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

usage&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Describes all pods in all namespaces and greps for images containing &#39;bitnami&#39;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

check_dependencies&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: kubectl command not found&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Test kubectl connectivity&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;!&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cluster-info&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error: Cannot connect to Kubernetes cluster&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

find_bitnami_images&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Getting all pods from all namespaces...&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Get all pods from all namespaces and describe them&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pods&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--all-namespaces&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wide&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--no-headers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;namespace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ready&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;restarts&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;age&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nominated&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;readiness&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Describing pod: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$namespace&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Describe the pod and grep for bitnami images&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;describe&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$namespace&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Look for image lines containing bitnami&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bitnami_images&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$description&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;image:&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;bitnami&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$bitnami_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;=========================================&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Pod: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$namespace&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Status: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$status&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Bitnami Images Found:&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$bitnami_images&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;=========================================&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;o&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$#&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-ne&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;usage
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;check_dependencies

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting search for Bitnami images in all pods across all namespaces&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;find_bitnami_images
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Search completed&#34;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;

main&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$@&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#force-the-removal-of-a-node-from-the-cluster&#34;&gt;Force the removal of a node from the cluster.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To force the removal of a node from a Kubernetes cluster, you have several options depending on your situation:&lt;/p&gt; &lt;p&gt;To prevent new pods from being scheduled while you prepare:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cordon&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;1. Graceful Node Removal (Recommended)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, try the standard approach:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;drain&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--ignore-daemonsets&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--delete-emptydir-data

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;2. Force Removal When Node is Unresponsive&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If the node is unresponsive or the graceful removal fails:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;drain&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--ignore-daemonsets&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--delete-emptydir-data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--grace-period&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Immediate Forced Removal&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;For emergency situations where you need immediate removal:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;node-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--grace-period&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Common Drain Options&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;--ignore-daemonsets&lt;/code&gt;: Ignores DaemonSet pods (they&#39;ll be recreated anyway)&lt;/li&gt; &lt;li&gt;&lt;code&gt;--delete-emptydir-data&lt;/code&gt;: Deletes pods using emptyDir volumes&lt;/li&gt; &lt;li&gt;&lt;code&gt;--force&lt;/code&gt;: Forces deletion of pods not managed by controllers&lt;/li&gt; &lt;li&gt;&lt;code&gt;--grace-period=0&lt;/code&gt;: Immediately kills pods without waiting&lt;/li&gt; &lt;li&gt;&lt;code&gt;--timeout=300s&lt;/code&gt;: Sets timeout for the drain operation&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Raise alert when value is empty.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Using vector(0)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;One way to solve it is to use &lt;a href=&#34;https://github.com/grafana/loki/pull/7023&#34;&gt;the &lt;code&gt;vector(0)&lt;/code&gt;&lt;/a&gt; operator with &lt;a href=&#34;https://stackoverflow.com/questions/76489956/how-to-return-a-zero-vector-in-loki-logql-metric-query-when-grouping-is-used-and&#34;&gt;the operation &lt;code&gt;or on() vector(0)&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;(count_over_time({filename=&#34;/var/log/mail.log&#34;} |= `Mail is sent` [24h]) or on() vector(0)) &amp;lt; 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Using unless&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re doing an aggregation over a label this approach won&#39;t work because it will add a new time series with value 0. In those cases use a broader search that includes other logs and the &lt;code&gt;unless&lt;/code&gt; operator:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;} [1h]))
unless
sum by(hostname) (count_over_time({service_name=&#34;watchtower&#34;} [1d]))) &amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will return a value &amp;gt; 0 for any hostname that has systemd-journal logs but no watchtower logs in the past day, which is perfect for alerting conditions.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/postgres/#upgrade-postgres&#34;&gt;Upgrade postgres.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.goauthentik.io/docs/troubleshooting/postgres/upgrade_docker&#34;&gt;Using dump and import&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dump your database&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Dump your existing database with a command similar to &lt;code&gt;docker compose exec postgresql pg_dump -U authentik -d authentik -cC &amp;gt; upgrade_backup_12.sql&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Before continuing, ensure the SQL dump file &lt;code&gt;upgrade_backup_12.sql&lt;/code&gt; includes all your database content.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Stop your application stack&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Stop all services with &lt;code&gt;docker compose down&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Backup your existing database&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Move the directory where your data is to a new one: &lt;code&gt;mv /path/to/database /path/to/v12-backup&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Modify your docker-compose.yml file&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Update the PostgreSQL service image from &lt;code&gt;docker.io/library/postgres:12-alpine&lt;/code&gt; to &lt;code&gt;docker.io/library/postgres:17-alpine&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Add &lt;code&gt;network_mode: none&lt;/code&gt; and comment out any &lt;code&gt;network&lt;/code&gt; directive to prevent connections being established to the database during the upgrade.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Recreate the database container&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Pull new images and re-create the PostgreSQL container: &lt;code&gt;docker compose pull &amp;amp;&amp;amp; docker compose up --force-recreate -d postgresql&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Apply your backup to the new database: &lt;code&gt;cat upgrade_backup_12.sql | docker compose exec -T postgresql psql -U authentik&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Remove the network configuration setting &lt;code&gt;network_mode: none&lt;/code&gt; that you added to the Compose file in the previous step.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Bring the service up&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Start again the service with &lt;code&gt;docker compose up&lt;/code&gt; and see that everything is working as expected.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;openzfs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;OpenZFS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#monitor-the-zfs-ram-usage&#34;&gt;Monitor the zfs ram usage.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;HostOutOfMemory&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# if we don&#39;t add the node_zfs_arc_size, the ARC is taken as used space triggering the alert as a false positive&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;(node_memory_MemAvailable_bytes + node_zfs_arc_size)/ node_memory_MemTotal_bytes * 100 &amp;lt; 10&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Host out of memory (instance {{ $labels.instance }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Node&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;memory&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;filling&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(&amp;lt;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;10%&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;left)\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;\ }}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(linux_snippets#Unattended upgrades): Unattended upgrades&lt;/p&gt; &lt;p&gt;unattended-upgrades runs daily at a random time&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How to tell when unattended upgrades will run today:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The random time is set by a cron job (/etc/cron.daily/apt.compat), and you can read the random time for today by asking systemd:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list-timers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-daily.timer
NEXT&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;LEFT&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;LAST&lt;span class=&#34;w&#34;&gt;                         &lt;/span&gt;PASSED&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;UNIT&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;ACTIVATES
Tue&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-11&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;01&lt;/span&gt;:53:29&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CDT&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;13h&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;left&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Mon&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:22:40&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CDT&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;1h&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;9min&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ago&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-daily.timer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-daily.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this case, you can see that it ran 1 hour and 9 minutes ago.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How to tell if unattended upgrades are still running:&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;One easy way is to check the timestamp files for the various apt components:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ls&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/apt/periodic/
total&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
-rw-r--r--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Jul&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:24&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unattended-upgrades-stamp
-rw-r--r--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Jul&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update-stamp
-rw-r--r--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Jul&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:24&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update-success-stamp
-rw-r--r--&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;root&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Jul&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:24&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade-stamp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Putting the data together, you can see that the timer started apt at 11:22. It ran an update which completed at 11:23, then an upgrade which completed at 11:24. Finally, you can see that apt considered the upgrade to be a success (no error or other failure).&lt;/p&gt; &lt;p&gt;Obviously, if you see a recent timer without a corresponding completion timestamp, then you might want to check ps to see if apt is still running.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How to tell which step apt is running right now&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;One easy way is to check the logfile.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;less&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/log/unattended-upgrades/unattended-upgrades.log
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:00,348&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Initial&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blacklisted&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;packages:
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:00,349&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Initial&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;whitelisted&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;packages:
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:00,349&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Starting&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unattended&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrades&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;script
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:00,349&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Allowed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;origins&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;are:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;o=Ubuntu,a=zesty-security&#39;&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;o=Ubuntu,a=zesty-updates&#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:10,485&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Packages&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;that&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;will&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;be&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgraded:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apport-gtk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libpoppler-glib8&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libpoppler-qt5-1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libpoppler64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;poppler-utils&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;python3-apport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;python3-problem-report
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:23:10,485&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Writing&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dpkg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;to&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;/var/log/unattended-upgrades/unattended-upgrades-dpkg.log&#39;&lt;/span&gt;
&lt;span class=&#34;m&#34;&gt;2017&lt;/span&gt;-07-10&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;:24:20,419&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INFO&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;All&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrades&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;installed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Here you can see the normal daily process, including the &#39;started&#39; and &#39;completed&#39; lines, and the list of packages that were about to be upgraded.&lt;/p&gt; &lt;p&gt;If the list of packages is not logged yet, then apt can be safely interrupted. Once the list of packages is logged, DO NOT interrupt apt.&lt;/p&gt; &lt;p&gt;**Check the number of packages that need an upgrade **&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--upgradeable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; **Manually run the unattended upgrades **&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;unattended-upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;node-exporter&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/node_exporter/&#34;&gt;Node Exporter&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/node_exporter/#host-requires-a-reboot&#34;&gt;Monitor host requires a reboot.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Node exporter &lt;a href=&#34;https://github.com/prometheus/node_exporter/issues/625&#34;&gt;does not support this metric&lt;/a&gt;, but you can monitor reboot requirements using Prometheus node exporter&#39;s textfile collector. Here&#39;s how to set it up:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Create the monitoring script&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, create a script that checks for the reboot-required file and outputs metrics in Prometheus format:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Make the script executable and place it in the right location:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-required-check.sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/local/bin/
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/local/bin/reboot-required-check.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;TEXTFILE_DIR&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/var/lib/node_exporter/textfile_collector&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;METRIC_FILE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TEXTFILE_DIR&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/reboot_required.prom&#34;&lt;/span&gt;

mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$TEXTFILE_DIR&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/run/reboot-required&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;REBOOT_REQUIRED&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;REBOOT_REQUIRED&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$METRIC_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt; EOF&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;node_reboot_required $REBOOT_REQUIRED&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;EOF&lt;/span&gt;

chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;644&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$METRIC_FILE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Ensure the textfile collector directory exists:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/node_exporter/textfile_collector
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node_exporter:node_exporter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/node_exporter/textfile_collector
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Create a systemd service to run the script periodically:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Check if system requires reboot&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;network.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;oneshot&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/local/bin/reboot-required-check.sh&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;node_exporter&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Group&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;node_exporter&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Create a systemd timer to run it regularly:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Check if system requires reboot every 5 minutes&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Requires&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;reboot-check.service&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Timer]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;OnBootSec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;1min&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;OnUnitActiveSec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5min&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;timers.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Install and enable the systemd units:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/systemd/system/
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.timer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/systemd/system/
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;daemon-reload
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.timer
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.timer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Configure node exporter to use the textfile collector:&lt;/strong&gt; Make sure your node exporter is started with the &lt;code&gt;--collector.textfile.directory&lt;/code&gt; flag:&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;node_exporter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--collector.textfile.directory&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/var/lib/node_exporter/textfile_collector
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Prometheus alerting rule&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can create an alerting rule in Prometheus to notify when a reboot is required:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;system.rules&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SystemRebootRequired&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;node_reboot_required == 1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;System&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;requires&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;reboot&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;System&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;requires&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;reboot&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;due&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;to:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.reason&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can test the setup by:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Run the script manually:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/local/bin/reboot-required-check.sh
cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/node_exporter/textfile_collector/reboot_required.prom
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Check if the timer is working:&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.timer
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;journalctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;reboot-check.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Verify metrics are being collected:&lt;/strong&gt; Visit &lt;code&gt;http://your-server:9100/metrics&lt;/code&gt; and search for &lt;code&gt;node_reboot_required&lt;/code&gt;&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;The metrics will show &lt;code&gt;node_reboot_required 1&lt;/code&gt; when a reboot is required and &lt;code&gt;node_reboot_required 0&lt;/code&gt; when it&#39;s not. The &lt;code&gt;node_reboot_required_packages_info&lt;/code&gt; metric includes information about which packages triggered the reboot requirement.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#resize-a-partition-of-an-ec2-instance&#34;&gt;Resize a partition of an EC2 instance.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If it&#39;s the first partition of the first disk.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;growpart&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/nvme0n1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
resize2fs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/nvme0n1p1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;mobile-keyboards&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mobile_keyboards/&#34;&gt;Mobile Keyboards&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce mobile keyboards comparison.&lt;/p&gt; &lt;p&gt;Finding the right mobile keyboard that balances functionality, privacy, and usability can be challenging. This guide explores the best open-source and privacy-focused keyboard options available for Android devices.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Quick Recommendations&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;For Gboard users transitioning&lt;/strong&gt;: HeliBoard&lt;/li&gt; &lt;li&gt;&lt;strong&gt;For advanced features and AI&lt;/strong&gt;: FUTO Keyboard&lt;/li&gt; &lt;li&gt;&lt;strong&gt;For unique input method&lt;/strong&gt;: Thumb-Key&lt;/li&gt; &lt;li&gt;&lt;strong&gt;For future consideration&lt;/strong&gt;: FlorisBoard (when stable)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;FUTO Keyboard ⭐ Recommended&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;FUTO represents the cutting edge of privacy-focused keyboard technology, incorporating AI features while maintaining offline functionality.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;What Makes FUTO Special&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;FUTO stands out with &lt;strong&gt;transformer-based predictions&lt;/strong&gt; using llama.cpp and &lt;strong&gt;integrated voice input&lt;/strong&gt; powered by whisper.cpp. Unlike other keyboards that require proprietary libraries, FUTO includes swipe/glide typing by default.&lt;/p&gt; &lt;p&gt;The keyboard is currently in pre-alpha, so expect some bugs and missing features. However, the privacy-preserving approach and innovative AI integration make it worth trying.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Smart Text Prediction&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Uses pre-trained transformer models for intelligent autocorrect&lt;/li&gt; &lt;li&gt;Personal language model that learns from your typing (locally only)&lt;/li&gt; &lt;li&gt;Currently optimized for English, with other languages in development&lt;/li&gt; &lt;li&gt;Spanish support is still limited&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Privacy-First Design&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All AI processing happens on-device&lt;/li&gt; &lt;li&gt;Your data never leaves your phone&lt;/li&gt; &lt;li&gt;FUTO doesn&#39;t view or store any typing data&lt;/li&gt; &lt;li&gt;Internet access only for updates and crash reporting (planned to be removed)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Customization Options&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Multilingual typing support&lt;/li&gt; &lt;li&gt;Custom keyboard layouts&lt;/li&gt; &lt;li&gt;Swipe typing works well out of the box&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Current Limitations&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Pre-alpha software with occasional bugs&lt;/li&gt; &lt;li&gt;Limited language support beyond English&lt;/li&gt; &lt;li&gt;Uses a custom &#34;Source First&#34; license (not traditional open source)&lt;/li&gt; &lt;li&gt;Screen movement issues when using swipe typing&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Licensing Concerns&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;FUTO uses a custom license rather than traditional open source licenses like GPL. While the source code is available, the licensing terms are more restrictive than typical open source projects. The team promises to adopt proper open source licensing eventually, but this transition hasn&#39;t happened yet.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://keyboard.futo.org/&#34;&gt;Official Website&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.keyboard.futo.org/&#34;&gt;Documentation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://gitlab.futo.org/alex/voiceinput&#34;&gt;Source Code&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://privseclaw.info/posts/futokeyboard/&#34;&gt;Privacy Analysis&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Not there yet&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The futo voice has a weird bug at least in spanish that sometimes adds at the end of the transcription phrases like: Subscribe! or Chau or Thanks for watching my video!. This is kind of annoying and scary &lt;code&gt;(¬º-°)¬&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;HeliBoard - The Reliable Choice&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;HeliBoard serves as an excellent middle ground, especially for users transitioning from Gboard.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Why Choose HeliBoard&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Active development&lt;/strong&gt;: Fork of OpenBoard with regular updates&lt;/li&gt; &lt;li&gt;&lt;strong&gt;No network access&lt;/strong&gt;: Completely offline operation&lt;/li&gt; &lt;li&gt;&lt;strong&gt;User-friendly&lt;/strong&gt;: Much simpler than AnySoftKeyboard&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Gboard-like experience&lt;/strong&gt;: Familiar interface for Google Keyboard users&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Trade-offs&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The main limitation is glide typing, which requires a closed-source library. This compromises the fully open source nature but provides the swipe functionality many users expect.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Helium314/HeliBoard&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Thumb-Key - The Innovative Alternative&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;For users willing to try something completely different, Thumb-Key offers a unique approach to mobile typing.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Thumb-Key Concept&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Instead of traditional QWERTY, Thumb-Key uses a &lt;strong&gt;3x3 grid layout&lt;/strong&gt; with swipe gestures for less common letters. This design prioritizes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Large, predictable key positions&lt;/li&gt; &lt;li&gt;Muscle memory development&lt;/li&gt; &lt;li&gt;Eyes staying on the text area&lt;/li&gt; &lt;li&gt;Fast typing speeds once mastered&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Users open to learning new input methods&lt;/li&gt; &lt;li&gt;Those who prefer larger touch targets&lt;/li&gt; &lt;li&gt;Privacy enthusiasts who want to avoid predictive text entirely&lt;/li&gt; &lt;li&gt;People who find traditional keyboards cramped&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The keyboard is highly configurable and focuses on accuracy through key positioning rather than AI predictions.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/dessalines/thumb-key&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;FlorisBoard - Future Potential&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;FlorisBoard shows promise but isn&#39;t ready for daily use yet.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Current Status&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Early beta development&lt;/li&gt; &lt;li&gt;Planned integration with GrapheneOS&lt;/li&gt; &lt;li&gt;Missing key features like suggestions and glide typing&lt;/li&gt; &lt;li&gt;Limited documentation available&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Worth Watching&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;While not currently recommended for primary use, FlorisBoard could become a strong contender once it reaches stability.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/florisboard/florisboard&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://florisboard.org/&#34;&gt;Official Website&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Alternative Approaches&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Unexpected Keyboard&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A minimalist keyboard with a unique layout approach.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Julow/Unexpected-Keyboard&#34;&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Using Proprietary Keyboards with Restrictions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On privacy-focused ROMs like GrapheneOS and DivestOS, you can use proprietary keyboards while blocking internet access. However, this approach has limitations due to inter-process communication between apps.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This method isn&#39;t foolproof, as apps can still potentially communicate through IPC mechanisms.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;My Current Setup&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;After testing various options:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Primary choice&lt;/strong&gt;: FUTO Keyboard with swipe enabled&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Backup plan&lt;/strong&gt;: Try FUTO voice input for longer texts when privacy features improve&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Alternative&lt;/strong&gt;: Thumb-Key if FUTO doesn&#39;t work out&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;The main issue encountered is screen movement during swipe typing, which may be device-specific.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References and Further Reading&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://discuss.privacyguides.net/t/recommend-open-source-android-keyboards/17808/36&#34;&gt;Privacy Guides Discussion on Android Keyboards&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://discuss.privacyguides.net/t/futo-keyboard/18896&#34;&gt;FUTO Keyboard Community Discussion&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/GrapheneOS/os-issue-tracker/issues/2810&#34;&gt;GrapheneOS IPC Communication Issue&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;filosofia&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/&#34;&gt;Filosofía&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/#tiempo&#34;&gt;Nuevos capítulos relevantes sobre el tiempo y otras cosas.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL8763758424.mp3?updated=1712825949&#34;&gt;Punzadas Sonoras: Mirar atrás: un gesto íntimo&lt;/a&gt;: Ruptura de la concepción lineal del tiempo, aplicado entre otras cosas a las relaciones. Hablan también sobre el artículo de &lt;a href=&#34;https://www.publico.es/opinion/tribunas/te-gusto.html&#34;&gt;Leonor Cervantes, Ya no te gusto como antes&lt;/a&gt; que da una perspectiva muy chula sobre las relaciones.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL3665741609.mp3?updated=1749652341&#34;&gt;Punzadas Sonoras: Artesano y artista: desnaturalizar la distinción&lt;/a&gt;: Capítulo super interesante para analizar las dinámicas de poder en el mundo laboral, el concepto de &lt;em&gt;mingei&lt;/em&gt;, pensar sobre &#34;el arte de programar&#34;, ...&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL2682413261.mp3?updated=1713967606&#34;&gt;Punzadas Sonoras: El ritmo del habitar con Blanca Lacasa&lt;/a&gt;: Filosofando sobre la casa, en especial sobre la cocina como jaula y reino. También sobre la relación entre madres e hijas&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;calistenia&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/&#34;&gt;Calistenia&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/#sentadilla-búlgara&#34;&gt;Sentadilla búlgara.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Hay bastante diversidad de opiniones: &lt;a href=&#34;https://www.youtube.com/watch?v=x_k90ghjPPw&amp;amp;t=225&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/watch?v=SkNsa3eBwLA&amp;amp;t=116&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://www.youtube.com/watch?v=fSyiHxm1Igw&amp;amp;t=208&#34;&gt;3&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/#vídeos&#34;&gt;Añadir vídeos de Cris heria.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://inv.nadeko.net/search?q=Cris%20heria&#34;&gt;Cris Heria&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;languages&#34;&gt;Languages&lt;/h2&gt; &lt;h3 id=&#34;galego&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/galego/&#34;&gt;Galego&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Descubrimiento de os arquivos da meiga.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.osarquivosdameiga.com/&#34;&gt;Os arquivos da meiga&lt;/a&gt;: Foro de contenido en galego&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;August 29, 2025 06:51:20 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-08-29T06:51:20+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;August 29, 2025 06:51:20 UTC&#34;&gt;2025-08-29&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_08_28/</link>
      <pubDate>2025-08-29 06:51:20+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_08_28/</guid>
      
    </item>
    
    <item><title>25th June 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;militancy&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/diversity/&#34;&gt;Militancy&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir poema sobre la falta de acción.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://es.wikipedia.org/wiki/Primero_se_llevaron...&#34;&gt;Maravilloso poema de alemán Martin Niemöller&lt;/a&gt; sobre la cobardía de los intelectuales alemanes tras el ascenso de los nazis al poder y la subsiguiente purga de sus objetivos escogidos, grupo tras grupo.&lt;/p&gt;  &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#apps-para-no-saltarte-el-boycott&#34;&gt;Apps para no saltarte el boycott.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://play.google.com/store/apps/details?id=com.bashsoftware.boycott&amp;amp;hl=en-US&#34;&gt;No Thanks&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Oslo advertisement on the importance of the symbols.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://bsky.app/profile/javiermarin.com/post/3lqhdlafjf22k&#34;&gt;link&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;feminism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/&#34;&gt;Feminism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/#references&#34;&gt;Add good movies and tv shows to discuss practical feminism with teenagers and adults.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.themoviedb.org/tv/249042-adolescence&#34;&gt;Adolescence (TV Series 2025-2025)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.themoviedb.org/movie/1075175-how-to-have-sex&#34;&gt;How to Have Sex (2023)&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;memoria-historica&#34;&gt;Memoria histórica&lt;/h3&gt; &lt;h4 id=&#34;conflicto-vasco&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/conflicto_vasco/&#34;&gt;Conflicto vasco&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir referencias sobre el conflicto vasco.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.deesonosehabla.com/temporada-3/&#34;&gt;Tercera temporada de (de eso no se habla)&lt;/a&gt;: &#34;Se llamaba como&#34; yo es una serie documental sobre la memoria de la niña Begoña Urroz, sobre las cinco décadas de silencio de una familia… Y sobre el ruido que lo rompió.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;laboral&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/laboral/&#34;&gt;Laboral&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/laboral/#references&#34;&gt;Añadir referencia a la novela Tierra de la luz.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://omny.fm/shows/no-hay-negros-en-el-t-bet/episodio-47-luc-a-asu-mbom-o&#34;&gt;No hay negros en el Tíbet: Episodio 47 - Lucía Asué Mbomío&lt;/a&gt;: Presentan la novela &#34;Tierra de la Luz&#34; de Lucía Asué MbomÍo. Un relato que pone el foco en los temporeros del sur que trabajan en los invernaderos en unas condiciones durísimas, y las injusticias que se viven en el campo. Una novela “bajo plásticos”, cargada de emoción, crítica y toques de realismo mágico.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;collaborating-tools&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/collaborating_tools/&#34;&gt;Collaborating tools&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/collaborating_tools/#collaborating-event-date-picker&#34;&gt;Collaborating event date picker.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://crab.fit/&#34;&gt;https://crab.fit/&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/collaborating_tools/#collaborating-book-libraries&#34;&gt;Collaborating book libraries.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://inventaire.io/welcome&#34;&gt;https://inventaire.io/welcome&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-navigation&#34;&gt;Life navigation&lt;/h2&gt; &lt;h3 id=&#34;time-navigation&#34;&gt;Time navigation&lt;/h3&gt; &lt;h4 id=&#34;org-mode&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;Org Mode&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Use unison to sync.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;dawarich&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dawarich/&#34;&gt;dawarich&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/dawarich/#how-to-see-the-coordinates-of-a-point&#34;&gt;How to see the coordinates of a point.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You need to enable the &#34;Points&#34; layer, which is on the layers menu at the top right of the map.&lt;/p&gt; &lt;p&gt;Then if you click on one point you can get the coordinates&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;knowledge-management&#34;&gt;Knowledge Management&lt;/h3&gt; &lt;h4 id=&#34;aleph&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/&#34;&gt;Aleph&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Correct the releases url.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/alephdata/aleph/releases/&#34;&gt;latest release&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;technology&#34;&gt;Technology&lt;/h2&gt; &lt;h3 id=&#34;coding&#34;&gt;Coding&lt;/h3&gt; &lt;h4 id=&#34;configure-docker-to-host-the-application&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/&#34;&gt;Configure Docker to host the application&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#push-an-image-with-different-architectures-after-building-it-in-different-instances&#34;&gt;Push an image with different architectures after building it in different instances.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To push both an &lt;strong&gt;ARM&lt;/strong&gt; and &lt;strong&gt;AMD&lt;/strong&gt; Docker image to a Docker registry, from two separate machines (e.g., an ARM-based and an AMD-based instance), you have two options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Run two different pipelines and then build a manifest&lt;/li&gt; &lt;li&gt;Use &lt;a href=&#34;https://docs.docker.com/build/ci/github-actions/configure-builder/#append-additional-nodes-to-the-builder&#34;&gt;two buildx remotes&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;QEMU was discarted because it took too long to build the images.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h3&gt; &lt;h4 id=&#34;authentik&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;Authentik&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/#upgrading&#34;&gt;Upgrading.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can no longer use the &lt;a href=&#34;https://docs.goauthentik.io/docs/releases/2025.2&#34;&gt;latest tag&lt;/a&gt; as it can lead to unintentional updates and potentially broken setups.&lt;/p&gt; &lt;p&gt;The tag will not be removed, however it will also not be updated past &lt;code&gt;2025.2&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;They strongly recommend the use of a specific version tag for authentik instances&#39; container images like &lt;code&gt;:2025.2&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/helm/helm/#get-the-values-of-a-chart&#34;&gt;Get the values of a chart.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;show&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;values&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zammad&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--repo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://zammad.github.io/zammad-helm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;14&lt;/span&gt;.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Timestamp Issues (&#34;entry too far behind&#34;).&lt;/p&gt; &lt;p&gt;The most frequent error shows log entries being rejected because their timestamps are too old.&lt;/p&gt; &lt;p&gt;This suggests either:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Clock synchronization issues between your log sources and Loki&lt;/li&gt; &lt;li&gt;Delayed log shipping/buffering&lt;/li&gt; &lt;li&gt;Replay of old logs&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;To solve this:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check that your hosts&#39; clocks are sync&lt;/li&gt; &lt;li&gt;Adjust Loki&#39;s ingestion window in your config: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;limits_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;reject_old_samples&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;reject_old_samples_max_age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;168h&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Increase from default (usually 1h)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can also prune the logs. For example in the case of a docker container (named &lt;code&gt;dawarich_app&lt;/code&gt;) you can:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;truncate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/docker/containers/&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;inspect&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{{.Id}}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dawarich_app&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;/&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;inspect&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{{.Id}}&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dawarich_app&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;-json.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/#ingestion-rate-limit-exceeded-for-user&#34;&gt;Ingestion rate limit exceeded for user.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Increase rate limits in Loki config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;limits_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;ingestion_rate_mb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Increase from 4MB default&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ingestion_burst_size_mb&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Also check which logs are triggering this rate limit because it may be the case that the amount of logs is too great due to an error.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;debugging&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kubernetes_debugging/&#34;&gt;Debugging&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/kubernetes_debugging/#pvc-or-pv-is-stuck-deleting&#34;&gt;PVC or PV is stuck deleting.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When PVs and PVCs get stuck during deletion, it&#39;s usually due to finalizers that prevent the cleanup process from completing. Here are several approaches to resolve this:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check for Finalizers&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, examine what&#39;s preventing the deletion:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pv-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;finalizers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;
kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pvc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pvc-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;namespace&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;finalizers&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Remove Finalizers (Most Common Solution)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you see finalizers like &lt;code&gt;kubernetes.io/pv-protection&lt;/code&gt; or &lt;code&gt;kubernetes.io/pvc-protection&lt;/code&gt;, you can remove them:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;patch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pvc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pvc-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;namespace&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{&#34;metadata&#34;:{&#34;finalizers&#34;:null}}&#39;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;patch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pv-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{&#34;metadata&#34;:{&#34;finalizers&#34;:null}}&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h3&gt; &lt;h4 id=&#34;kitty&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/kitty/&#34;&gt;Kitty&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Error opening terminal: xterm-kitty.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/kovidgoyal/kitty/issues/1613&#34;&gt;The not so good solution but that solves the issue is&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;TERM&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;xterm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;filosofia&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/&#34;&gt;Filosofía&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/#pensamientos-sueltos&#34;&gt;Pensamientos sueltos.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cómo transformar&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.ivoox.com/en/ver-al-otro-narrativa-democracia-audios-mp3_rf_146744850_1.html&#34;&gt;Punzadas Sonoras: Ver al otro: narrativa y democracia&lt;/a&gt;: cómo la literatura puede ser un mecanismo muy potente de transformación social.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL3439441041.mp3?updated=1748445535&#34;&gt;Punzadas Sonoras: Límite: lugar de enunciación&lt;/a&gt;: El límite como elemento transformador&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Deseo&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.ivoox.com/deseo-tiempos-tinder-pensando-fuerte-audios-mp3_rf_148986477_1.html&#34;&gt;Carne Cruda - PROGRAMAS: El deseo en tiempos de Tinder&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Otros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL3665741609.mp3?updated=1749652341&#34;&gt;Punzadas Sonoras: Artesano y artista: desnaturalizar la distinción&lt;/a&gt;: Capítulo super interesante para analizar las dinámicas de poder en el mundo laboral, el concepto de &lt;em&gt;mingei&lt;/em&gt;, pensar sobre &#34;el arte de programar&#34;, ...&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Recomiendan dos libros interesantes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;La belleza del objeto cotidiano - Soetsu Yanagi&lt;/li&gt; &lt;li&gt;Costumbres en común - E. P. Thompson&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://traffic.megaphone.fm/PMSL7390189795.mp3?updated=1718881108&#34;&gt;Punzadas Sonoras: Matar al Autor: el destino del texto&lt;/a&gt;: No infantilizar al receptor&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;June 26, 2025 06:55:33 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-06-26T06:55:33+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;June 26, 2025 06:55:33 UTC&#34;&gt;2025-06-26&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_06_25/</link>
      <pubDate>2025-06-26 06:55:33+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_06_25/</guid>
      
    </item>
    
    <item><title>27th May 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;life-navigation&#34;&gt;Life navigation&lt;/h2&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;dawarich&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dawarich/&#34;&gt;dawarich&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce dawarich.&lt;/p&gt; &lt;p&gt;Dawarich is a self-hostable alternative to Google Location History (Google Maps Timeline)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://dawarich.app/docs/intro/#setup-your-dawarich-instance&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Tweak the &lt;a href=&#34;https://github.com/Freika/dawarich/blob/master/docker/docker-compose.yml&#34;&gt;official docker-compose&lt;/a&gt; keeping in mind:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;To configure the &lt;a href=&#34;https://dawarich.app/docs/tutorials/reverse-proxy&#34;&gt;&lt;code&gt;APPLICATION_HOST&lt;/code&gt;&lt;/a&gt; if you&#39;re using a reverse proxy&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Then run &lt;code&gt;docker compose up&lt;/code&gt;. You can now visit your Dawarich instance at &lt;a href=&#34;http://localhost:3000&#34;&gt;http://localhost:3000&lt;/a&gt; or http://&lt;your-server-ip&gt;:3000. The default credentials are &lt;code&gt;demo@dawarich.app&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt;&lt;/your-server-ip&gt;&lt;/p&gt; &lt;p&gt;Go to your account and change the default account and password.&lt;/p&gt; &lt;p&gt;Be careful not to upgrade with watchtower, the devs say that it&#39;s not safe yet to do so.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Not there yet&lt;/strong&gt; - &lt;a href=&#34;https://github.com/Freika/dawarich/issues/1071&#34;&gt;Immich photos are not well shown&lt;/a&gt;: This happens when opening the map, or selecting one of the buttons &#34;Yesterday&#34;, &#34;Last 7 Days&#34; or &#34;Last month&#34;. If you select the same date range through the date-pickers, the photos are shown. - &lt;a href=&#34;https://github.com/Freika/dawarich/issues/1261&#34;&gt;Support import of OSMand+ favourites gpx&lt;/a&gt; - &lt;a href=&#34;https://github.com/Freika/dawarich/issues/65&#34;&gt;OpenID/Oauth support&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://dawarich.app/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://dawarich.app/docs/intro/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/Freika/dawarich&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;technology&#34;&gt;Technology&lt;/h2&gt; &lt;h3 id=&#34;coding&#34;&gt;Coding&lt;/h3&gt; &lt;h4 id=&#34;forgejo&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pipx/&#34;&gt;Forgejo&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/forgejo/#push-to-a-forgejo-docker-registry&#34;&gt;Push to a forgejo docker registry.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Login to the container registry&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To push an image or if the image is in a private registry, you have to authenticate:&lt;/p&gt;  &lt;p&gt;If you are using 2FA or OAuth use a personal access token instead of the password.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Image naming convention&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Images must follow this naming convention:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;{registry}/{owner}/{image}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When building your docker image, using the naming convention above, this looks like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;build&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;registry&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;owner&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;image&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;tag&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.

docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tag&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;some-existing-image&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;tag&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;registry&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;owner&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;image&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;tag&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where your registry is the domain of your forgejo instance (e.g. forgejo.example.com). For example, these are all valid image names for the owner testuser:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;forgejo.example.com/testuser/myimage&lt;/li&gt; &lt;li&gt;forgejo.example.com/testuser/my-image&lt;/li&gt; &lt;li&gt;forgejo.example.com/testuser/my/image&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;NOTE: The registry only supports case-insensitive tag names. So image:tag and image:Tag get treated as the same image and tag.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Push an image&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Push an image by executing the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;forgejo.example.com/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;owner&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;image&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;:&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;tag&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;forgejo.example.com/testuser/myimage:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pipx/#installing-all-the-binaries-the-application-installs&#34;&gt;Installing all the binaries the application installs.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If the package installs more than one binary (for example &lt;code&gt;ansible&lt;/code&gt;), you need to use the &lt;code&gt;--install-deps&lt;/code&gt; flag&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pipx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--install-deps&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ansible
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;configure-docker-to-host-the-application&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/&#34;&gt;Configure Docker to host the application&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#push-an-image-with-different-architectures-after-building-it-in-different-instances&#34;&gt;Push an image with different architectures after building it in different instances.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To push both an &lt;strong&gt;ARM&lt;/strong&gt; and &lt;strong&gt;AMD&lt;/strong&gt; Docker image to &lt;strong&gt;Docker Hub&lt;/strong&gt;, from two separate machines (e.g., an ARM-based and an AMD-based instance), follow these steps:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tag the image correctly on each architecture&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On &lt;strong&gt;each instance&lt;/strong&gt;, build your image as normal, but &lt;strong&gt;tag it with a platform-specific suffix&lt;/strong&gt;, like &lt;code&gt;myuser/myimage:arm64&lt;/code&gt; or &lt;code&gt;myuser/myimage:amd64&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;On the ARM machine:&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;build&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:arm64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.
docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:arm64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;On the AMD machine:&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;build&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:amd64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.
ocker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:amd64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Create a multi-architecture manifest (on one machine)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want users to pull the image without worrying about the platform (e.g., just &lt;code&gt;docker pull myuser/myimage:latest&lt;/code&gt;), you can create and push a &lt;strong&gt;manifest list&lt;/strong&gt; that combines the two:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Choose either machine to run this (after both images are pushed):&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:latest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;--amend&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:amd64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;--amend&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:arm64

docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;manifest&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;push&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;myuser/myimage:latest
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: Add note to run gitea actions runners in kubernetes.&lt;/p&gt; &lt;p&gt;Kubernetes act runner, there is a &lt;a href=&#34;https://gitea.com/gitea/act_runner/issues/264&#34;&gt;stale issue&lt;/a&gt; and &lt;a href=&#34;https://gitea.com/gitea/act_runner/src/branch/main/examples/kubernetes&#34;&gt;an ugly implementation&lt;/a&gt; to run docker in docker inside the kubernetes node.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;streamlit&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/streamlit/&#34;&gt;Streamlit&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/streamlit/#show-a-spinner-while-the-data-is-loading&#34;&gt;Show a spinner while the data is loading.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;st&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Title&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;st&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;spinner&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Loading data...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;long_process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;st&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;markdown&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;content shown once the data is loaded&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/streamlit/#deploy&#34;&gt;Deploy in docker.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Here&#39;s an example &lt;code&gt;Dockerfile&lt;/code&gt; that you can add to the root of your directory&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;python:3.11-slim&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;WORKDIR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/app&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-y&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;build-essential&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;software-properties-common&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-rf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/apt/lists/*

&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pip3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requirements.txt

&lt;span class=&#34;k&#34;&gt;EXPOSE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;8501&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;HEALTHCHECK&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CMD&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--fail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;http://localhost:8501/_stcore/health

&lt;span class=&#34;k&#34;&gt;ENTRYPOINT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;streamlit&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;run&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;app.py&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;--server.port=8501&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;--server.address=0.0.0.0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;While you debug you may want to replace the &lt;code&gt;COPY . .&lt;/code&gt; to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requirements.txt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.

&lt;span class=&#34;k&#34;&gt;RUN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pip3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requirements.txt

&lt;span class=&#34;k&#34;&gt;COPY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app.py&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;So that the build iterations are faster.&lt;/p&gt; &lt;p&gt;You can build it with &lt;code&gt;docker build -t streamlit .&lt;/code&gt;, then test it with &lt;code&gt;docker run -p 8501:8501 streamlit&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Once you know it&#39;s working you can create a docker compose&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;streamlit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;hm2025_nodos&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;my_app&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;env_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;.env&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;8501:8501&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;healthcheck&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;CMD&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;curl&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;--fail&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;http://localhost:8501/_stcore/health&#34;&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;30s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;10s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;retries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you use &lt;a href=&#34;&#34;&gt;swag&lt;/a&gt; from linuxserver you can expose the service with the next nginx configuration:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;server&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ssl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;[::]:443&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ssl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;server_name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_app.*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/config/nginx/ssl.conf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;client_max_body_size&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;location&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# enable the next two lines for http auth&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#auth_basic &#34;Restricted&#34;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#auth_basic_user_file /config/nginx/.htpasswd;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# enable the next two lines for ldap auth&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#auth_request /auth;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;#error_page 401 =200 /login;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/config/nginx/proxy.conf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;resolver&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;127&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;.0.0.11&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;valid=30s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$upstream_streamlit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;kn&#34;&gt;proxy_pass&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;http://&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$upstream_streamlit:8501&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And if you save your &lt;code&gt;docker-compose.yaml&lt;/code&gt; file into &lt;code&gt;/srv/streamlit&lt;/code&gt; you can use the following systemd service to automatically start it on boot.&lt;/p&gt; &lt;p&gt;``ini [Unit] Description=my_app Requires=docker.service After=docker.service&lt;/p&gt; &lt;p&gt;[Service] Restart=always User=root Group=docker WorkingDirectory=/srv/streamlit TimeoutStartSec=100 RestartSec=2s ExecStart=/usr/bin/docker compose -f docker-compose.yaml up ExecStop=/usr/bin/docker compose -f docker-compose.yaml down&lt;/p&gt; &lt;p&gt;[Install] WantedBy=multi-user.target ```&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h3&gt; &lt;h4 id=&#34;aws&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/aws/aws/&#34;&gt;AWS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/aws/aws/#remove-the-public-ip-of-an-ec2-instance&#34;&gt;Remove the public IP of an ec2 instance.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Navigate to the network interfaces of the instance&lt;/li&gt; &lt;li&gt;Click on the one that contains the public IP&lt;/li&gt; &lt;li&gt;Actions/Manage IP addresses&lt;/li&gt; &lt;li&gt;Click on the Interface to unfold the configuration&lt;/li&gt; &lt;li&gt;Click on Auto-assign public IP&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#check-the-file-encoding&#34;&gt;Check the file encoding.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;file&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;path_to_file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#simulate-the-environment-of-a-cron-job&#34;&gt;Simulate the environment of a cron job.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Add this to your crontab (temporarily):&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* * * * * env &amp;gt; ~/cronenv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;After it runs, do this:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;env&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/cronenv&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/bin/sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This assumes that your cron runs /bin/sh, which is the default regardless of the user&#39;s default shell.&lt;/p&gt; &lt;p&gt;Footnote: if env contains more advanced config, eg &lt;code&gt;PS1=$(__git_ps1 &#34; (%s)&#34;)$&lt;/code&gt;, it will error cryptically &lt;code&gt;env: &#34;: No such file or directory&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;wireguard&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/wg-easy/&#34;&gt;Wireguard&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: More wg-easy configurations.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki/Using-WireGuard-Easy-with-Ansible&#34;&gt;configure with ansible&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/pull/737&#34;&gt;Split tunneling&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Keep in mind though that the &lt;code&gt;WG_ALLOWED_IPS&lt;/code&gt; only sets the routes on the client, it does not limit the traffic at server level. For example, if you set &lt;code&gt;172.30.1.0/24&lt;/code&gt; as the allowed ips, but the client changes it to &lt;code&gt;172.30.0.0/16&lt;/code&gt; it will be able to access for example &lt;code&gt;172.30.2.1&lt;/code&gt;. The suggested way to prevent this behavior is to add the kill switch in the Pre and Post hooks (&lt;code&gt;WG_POST_UP&lt;/code&gt; and &lt;code&gt;WG_POST_DOWN&lt;/code&gt;)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki/Restrict-Access-to-Networks-with-iptables&#34;&gt;Restrict Access to Networks with iptables&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you need to restrict many networks you can use &lt;a href=&#34;https://www.procustodibus.com/blog/2021/03/wireguard-allowedips-calculator/&#34;&gt;this allowed ips calculator&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://airvpn.org/forums/topic/50601-kill-switch-settings-for-wireguard-on-ubuntu-20/&#34;&gt;Kill switch&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Monitorization&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want to use the prometheus metrics &lt;a href=&#34;https://github.com/wg-easy/wg-easy/issues/1373&#34;&gt;you need to use a version greater than 14&lt;/a&gt;, as &lt;code&gt;15&lt;/code&gt; is &lt;a href=&#34;https://github.com/wg-easy/wg-easy/pkgs/container/wg-easy/versions&#34;&gt;not yet released&lt;/a&gt; (as of 2025-03-20) I&#39;m using &lt;code&gt;nightly&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;You can enable them with the environment variable &lt;code&gt;ENABLE_PROMETHEUS_METRICS=true&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Scrape the metrics&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Add to your scrape config the required information&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;vpn-admin&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/metrics&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;your vpn private ip&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;:{your vpn exporter port}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Create the monitor client&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To make sure that the vpn is working we&#39;ll add a client that is always connected. To do so we&#39;ll use &lt;a href=&#34;https://github.com/linuxserver/docker-wireguard&#34;&gt;linuxserver&#39;s wireguard docker&lt;/a&gt;&lt;/p&gt; &lt;p&gt;# References&lt;/p&gt; &lt;p&gt;diff --git a/mkdocs.yml b/mkdocs.yml index 77e5ba92b2..ef6703047d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -86,6 +86,7 @@ nav: - Trip management: - Route management: route_management.md - Map management: map_management.md + - dawarich: dawarich.md - Food management: food_management.md - Stock management: - Grocy: grocy_management.md @@ -212,514 +213,522 @@ nav: - Fitness Tracker: - fitness_band.md - Amazfit Band 5: amazfit_band_5.md - - Coding: - - Learning to code: - - code_learning.md - - Frontend developer: frontend_learning.md - - Languages: - - Python: - - python.md - - Project Template: - - coding/python/python_project_template.md - - Command-line Project Template: - - coding/python/python_project_template/python_cli_template.md - - Configure SQLAlchemy for projects without flask: &amp;gt;- - coding/python/python_project_template/python_sqlalchemy_without_flask.md - - Flask Project Template: &amp;gt;- - coding/python/python_project_template/python_flask_template.md - - Microservices Project Template: &amp;gt;- - coding/python/python_project_template/python_microservices_template.md - - Common configurations: - - Create the documentation repository: &amp;gt;- - coding/python/python_project_template/python_docs.md - - Load config from YAML: coding/python/python_config_yaml.md - - Configure SQLAlchemy to use the MariaDB/Mysql backend: - &amp;gt;- - coding/python/python_project_template/python_sqlalchemy_mariadb.md - - Configure Docker to host the application: &amp;gt;- - coding/python/python_project_template/python_docker.md - - Libraries: - - Alembic: coding/python/alembic.md - - asyncio: asyncio.md - - aiocron: aiocron.md - - Apprise: apprise.md - - aiohttp: aiohttp.md - - BeautifulSoup: beautifulsoup.md - - Boto3: boto3.md - - Click: coding/python/click.md - - Dash: coding/python/dash.md - - Dash Leaflet: coding/python/dash_leaflet.md - - DeepDiff: coding/python/deepdiff.md - - FactoryBoy: coding/python/factoryboy.md - - Faker: coding/python/faker.md - - FastAPI: fastapi.md - - Flask: coding/python/flask.md - - Flask Restplus: coding/python/flask_restplus.md - - Folium: coding/python/folium.md - - Feedparser: coding/python/feedparser.md - - Gettext: gettext.md - - GitPython: coding/python/gitpython.md - - Goodconf: goodconf.md - - ICS: ics.md - - Inotify: python_inotify.md - - watchdog: watchdog_python.md - - Jinja2: python_jinja2.md - - Maison: maison.md - - mkdocstrings: coding/python/mkdocstrings.md - - NetworkX: networkx.md - - Org-rw: org_rw.md - - Pandas: coding/python/pandas.md - - Passpy: coding/python/passpy.md - - pexpect: pexpect.md - - Prompt Toolkit: - - coding/python/prompt_toolkit.md - - REPL: prompt_toolkit_repl.md - - Full screen applications: prompt_toolkit_fullscreen_applications.md - - Pydantic: - - coding/python/pydantic.md - - Pydantic Field Types: coding/python/pydantic_types.md - - Pydantic Validators: coding/python/pydantic_validators.md - - Pydantic Exporting Models: coding/python/pydantic_exporting.md - - Pydantic Validating Functions: coding/python/pydantic_functions.md - - Pydantic Factories: pydantic_factories.md - - Pydantic Mypy Plugin: coding/python/pydantic_mypy_plugin.md - - Pypika: coding/python/pypika.md - - psycopg2: psycopg2.md - - Elasticsearch: python_elasticsearch.md - - python-gnupg: python_gnupg.md - - Python Mysql: python_mysql.md - - pythonping: pythonping.md + - Technology: + - Coding: + - Learning to code: + - code_learning.md + - Frontend developer: frontend_learning.md + - Languages: + - Python: + - python.md + - Project Template: + - coding/python/python_project_template.md + - Command-line Project Template: + - coding/python/python_project_template/python_cli_template.md + - Configure SQLAlchemy for projects without flask: &amp;gt;- + coding/python/python_project_template/python_sqlalchemy_without_flask.md + - Flask Project Template: &amp;gt;- + coding/python/python_project_template/python_flask_template.md + - Microservices Project Template: &amp;gt;- + coding/python/python_project_template/python_microservices_template.md + - Common configurations: + - Create the documentation repository: &amp;gt;- + coding/python/python_project_template/python_docs.md + - Load config from YAML: coding/python/python_config_yaml.md + - Configure SQLAlchemy to use the MariaDB/Mysql backend: + &amp;gt;- + coding/python/python_project_template/python_sqlalchemy_mariadb.md + - Configure Docker to host the application: &amp;gt;- + coding/python/python_project_template/python_docker.md + - Libraries: + - Alembic: coding/python/alembic.md + - asyncio: asyncio.md + - aiocron: aiocron.md + - Apprise: apprise.md + - aiohttp: aiohttp.md + - BeautifulSoup: beautifulsoup.md + - Boto3: boto3.md + - Click: coding/python/click.md + - Dash: coding/python/dash.md + - Dash Leaflet: coding/python/dash_leaflet.md + - DeepDiff: coding/python/deepdiff.md + - FactoryBoy: coding/python/factoryboy.md + - Faker: coding/python/faker.md + - FastAPI: fastapi.md + - Flask: coding/python/flask.md + - Flask Restplus: coding/python/flask_restplus.md + - Folium: coding/python/folium.md + - Feedparser: coding/python/feedparser.md + - Gettext: gettext.md + - GitPython: coding/python/gitpython.md + - Goodconf: goodconf.md + - ICS: ics.md + - Inotify: python_inotify.md + - watchdog: watchdog_python.md + - Jinja2: python_jinja2.md + - Maison: maison.md + - mkdocstrings: coding/python/mkdocstrings.md + - NetworkX: networkx.md + - Org-rw: org_rw.md + - Pandas: coding/python/pandas.md + - Passpy: coding/python/passpy.md + - pexpect: pexpect.md + - Prompt Toolkit: + - coding/python/prompt_toolkit.md + - REPL: prompt_toolkit_repl.md + - Full screen applications: prompt_toolkit_fullscreen_applications.md + - Pydantic: + - coding/python/pydantic.md + - Pydantic Field Types: coding/python/pydantic_types.md + - Pydantic Validators: coding/python/pydantic_validators.md + - Pydantic Exporting Models: coding/python/pydantic_exporting.md + - Pydantic Validating Functions: coding/python/pydantic_functions.md + - Pydantic Factories: pydantic_factories.md + - Pydantic Mypy Plugin: coding/python/pydantic_mypy_plugin.md + - Pypika: coding/python/pypika.md + - psycopg2: psycopg2.md + - Elasticsearch: python_elasticsearch.md + - python-gnupg: python_gnupg.md + - Python Mysql: python_mysql.md + - pythonping: pythonping.md + - Python Prometheus: python-prometheus.md + - Python Telegram: + - python-telegram.md + - pytelegrambotapi: pytelegrambotapi.md + - Python VLC: python_vlc.md + - Playwright: playwright.md + - Plotly: coding/python/plotly.md + - questionary: questionary.md + - rich: rich.md + - Ruamel YAML: coding/python/ruamel_yaml.md + - Selenium: selenium.md + - Streamlit: streamlit.md + - SQLAlchemy: coding/python/sqlalchemy.md + - sqlite3: sqlite3.md + - Redis-py: coding/python/redis-py.md + - Requests: requests.md + - Requests-mock: coding/python/requests_mock.md + - Rq: coding/python/rq.md + - python_systemd: python_systemd.md + - sh: python_sh.md + - Talkey: talkey.md + - Tenacity: tenacity.md + - TinyDB: coding/python/tinydb.md + - Torch: torch.md + - Typer: typer.md + - Yoyo: coding/python/yoyo.md + - Type Hints: coding/python/type_hints.md + - Logging: python_logging.md + - Code Styling: coding/python/python_code_styling.md + - Docstrings: coding/python/docstrings.md + - Properties: python_properties.md + - Protocols: python_protocols.md + - Package Management: + - python_package_management.md + - PDM: pdm.md + - pipx: pipx.md + - Pipenv: pipenv.md + - Poetry: python_poetry.md + - Lazy loading: lazy_loading.md + - Plugin System: python_plugin_system.md + - Profiling: python_profiling.md + - Optimization: python_optimization.md + - Anti-Patterns: coding/python/python_anti_patterns.md + - Pytest: + - coding/python/pytest.md + - Parametrized testing: coding/python/pytest_parametrized_testing.md + - Pytest-cases: coding/python/pytest_cases.md + - Pytest-HttpServer: pytest_httpserver.md + - Pytest-xprocess: pytest-xprocess.md + - Internationalization: python_internationalization.md + - Python Snippets: coding/python/python_snippets.md + - Data Classes: coding/python/data_classes.md + - Vue.js: + - vuejs.md + - Vue snippets: vue_snippets.md + - Vuetify: vuetify.md + - Development tools: + - Cypress: cypress.md + - Vite: vite.md + - Vitest: vitest.md + - Bash: + - Bash snippets: bash_snippets.md + - Bash testing: bats.md + - lua: lua.md + - JSON: coding/json/json.md + - SQL: coding/sql/sql.md + - SQLite: sqlite.md + - YAML: coding/yaml/yaml.md + - Promql: coding/promql/promql.md + - Logql: logql.md + - HTML: html.md + - CSS: css.md + - Javascript: + - coding/javascript/javascript.md + - Javascript snippets: javascript_snippets.md + - MermaidJS: mermaidjs.md + - Latex: latex.md + - Graphql: graphql.md + - Qwik: qwik.md + - nodejs: linux/nodejs.md + - JWT: devops/jwt.md + - React: coding/react/react.md + - Coding tools: + - IDES: + - Vim: + - vim.md + - Vim configuration: + - vim_config.md + - Vim Keymaps: vim_keymaps.md + - Vim Package Manager: + - vim_plugin_managers.md + - LazyVim: lazyvim.md + - Packer: vim_packer.md + - UI management configuration: + - Vim foldings: vim_foldings.md + - Vim movement: vim_movement.md + - Tabs vs Buffers: vim_tabs.md + - File management configuration: + - NeoTree: neotree.md + - Telescope: telescope.md + - fzf.nvim: fzf_nvim.md + - Editing specific configuration: + - vim_editor_plugins.md + - Vim formatters: vim_formatters.md + - Vim autocomplete: vim_completion.md + - Vim markdown: vim_markdown.md + - Vim spelling: vim_spelling.md + - Vim autosave: vim_autosave.md + - Coding specific configuration: + - vim_coding_plugins.md + - Treesitter: vim_treesitter.md + - LSP: vim_lsp.md + - Snippets: luasnip.md + - DAP: vim_dap.md + - Git management configuration: + - vim_git.md + - Diffview: diffview.md + - gitsigns: gitsigns.md + - Testing management configuration: vim_testing.md + - Email management: vim_email.md + - Other Vim Plugins: + - linux/vim/vim_plugins.md + - Vim Snippets: vim_snippets.md + - Vim Troubleshooting: vim_troubleshooting.md + - Neovim Plugin Development: vim_plugin_development.md + - Vi vs Vim vs Neovim: vim_vs_neovim.md + - Tridactyl: tridactyl.md + - VSCodium: vscodium.md + - Coding with AI: ai_coding.md + - Git: + - git.md + - Github cli: gh.md + - Forgejo: forgejo.md + - Gitea: gitea.md + - Radicle: radicle.md + - Data orchestrators: + - data_orchestrators.md + - Kestra: kestra.md + - memorious: memorious.md + - Scrapers: + - morph.io: morph_io.md + - ETL: + - Singer: singer.md + - Espanso: espanso.md + - Generic Coding Practices: + - How to code: how_to_code.md + - Program Versioning: + - versioning.md + - Semantic Versioning: semantic_versioning.md + - Calendar Versioning: calendar_versioning.md + - Use warnings to evolve your code: use_warnings.md + - Keep a Changelog: changelog.md + - Writing good documentation: documentation.md + - Conventional comments: conventional_comments.md + - TDD: coding/tdd.md + - GitOps: gitops.md + - Abstract Syntax Trees: abstract_syntax_trees.md + - Software Architecture: + - SOLID: architecture/solid.md + - Domain Driven Design: + - architecture/domain_driven_design.md + - Repository Pattern: architecture/repository_pattern.md + - Service Layer Pattern: architecture/service_layer_pattern.md + - Architecture Decision Record: adr.md + - Database Architecture: architecture/database_architecture.md + - ORM, Query Builder or Raw SQL: architecture/orm_builder_query_or_raw_sql.md + - Microservices: architecture/microservices.md + - Restful APIS: architecture/restful_apis.md + - OCR: + - Table parsing: + - Camelot: camelot.md + - Frontend Development: frontend_development.md + - Park programming: park_programming.md + - Sponsor: sponsor.md + - Issues: issues.md + - DevSecOps: + - devops/devops.md + - Infrastructure as Code: + - Helm: + - devops/helm/helm.md + - Helm Installation: devops/helm/helm_installation.md + - Helm Commands: devops/helm/helm_commands.md + - Helm Secrets: devops/helm/helm_secrets.md + - Helm Git: helm_git.md + - Helmfile: devops/helmfile.md + - Terraform: terraform.md + - Ansible: + - Ansible Snippets: ansible_snippets.md + - Molecule: molecule.md + - Nix: nix.md + - Dotfiles: + - dotfiles.md + - Home Manager: home-manager.md + - Chezmoi: chezmoi.md + - Dotdrop: dotdrop.md + - Infrastructure Solutions: + - Kubernetes: + - devops/kubernetes/kubernetes.md + - Architecture: devops/kubernetes/kubernetes_architecture.md + - Resources: + - Namespaces: devops/kubernetes/kubernetes_namespaces.md + - Pods: devops/kubernetes/kubernetes_pods.md + - ReplicaSets: devops/kubernetes/kubernetes_replicasets.md + - Deployments: devops/kubernetes/kubernetes_deployments.md + - Horizontal Pod Autoscaling: &amp;gt;- + devops/kubernetes/kubernetes_hpa.md + - Volumes: devops/kubernetes/kubernetes_volumes.md + - Services: devops/kubernetes/kubernetes_services.md + - Labels: devops/kubernetes/kubernetes_labels.md + - Annotations: devops/kubernetes/kubernetes_annotations.md + - Ingress: devops/kubernetes/kubernetes_ingress.md + - Jobs: devops/kubernetes/kubernetes_jobs.md + - Kubectl: + - devops/kubectl/kubectl.md + - Kubectl Installation: devops/kubectl/kubectl_installation.md + - Kubectl Commands: devops/kubectl/kubectl_commands.md + - Additional Components: + - Metrics Server: devops/kubernetes/kubernetes_metric_server.md + - Ingress Controller: &amp;gt;- + devops/kubernetes/kubernetes_ingress_controller.md + - External DNS: devops/kubernetes/kubernetes_external_dns.md + - Cluster Autoscaler: &amp;gt;- + devops/kubernetes/kubernetes_cluster_autoscaler.md + - Dashboard: devops/kubernetes/kubernetes_dashboard.md + - Storage Driver: devops/kubernetes/kubernetes_storage_driver.md + - Vertical Pod Autoscaler: &amp;gt;- + devops/kubernetes/kubernetes_vertical_pod_autoscaler.md + - Networking: devops/kubernetes/kubernetes_networking.md + - Debugging: kubernetes_debugging.md + - Backups: + - Velero: velero.md + - Operators: devops/kubernetes/kubernetes_operators.md + - Tools: + - devops/kubernetes/kubernetes_tools.md + - Krew: krew.md + - Ksniff: ksniff.md + - Mizu: mizu.md + - AWS: + - devops/aws/aws.md + - AWS Snippets: aws_snippets.md + - AWS Savings plan: aws_savings_plan.md + - Security groups workflow: devops/aws/security_groups.md + - EKS: devops/aws/eks.md + - EFS: efs.md + - IAM: + - devops/aws/iam/iam.md + - IAM Commands: devops/aws/iam/iam_commands.md + - IAM Debugging: devops/aws/iam/iam_debug.md + - S3: devops/aws/s3.md + - WAF: aws_waf.md + - Databases: + - Redis: architecture/redis.md + - RabbitMQ: rabbitmq.md + - Continuous Deployment: + - ArgoCD: argocd.md + - Continuous Integration: + - devops/ci.md + - Drone: drone.md + - Linters: + - Alex: devops/alex.md + - Flakeheaven: flakeheaven.md + - Flake8: devops/flake8.md + - Markdownlint: devops/markdownlint.md + - Proselint: devops/proselint.md + - Shellcheck: shellcheck.md + - Yamllint: devops/yamllint.md + - Write Good: devops/write_good.md + - Formatters/Fixers: + - Black: devops/black.md + - Yamlfix: yamlfix.md + - Pyment: pyment.md + - mdformat: mdformat.md + - Type Checkers: + - Mypy: devops/mypy.md + - Security Checkers: + - pip-audit: pip_audit.md + - Bandit: devops/bandit.md + - Safety: devops/safety.md + - Dependency managers: + - Pip-tools: devops/pip_tools.md + - Automating Processes: + - copier: copier.md + - cookiecutter: linux/cookiecutter.md + - cruft: linux/cruft.md + - renovate: renovate.md + - letsencrypt: letsencrypt.md + - Threat modeling: + - Privacy threat modeling: privacy_threat_modeling.md + - Storage: + - storage.md + - NAS: nas.md + - OpenZFS: + - linux/zfs.md + - OpenZFS storage planning: zfs_storage_planning.md + - Sanoid: sanoid.md + - ZFS Prometheus exporter: zfs_exporter.md + - Hard drive health: + - hard_drive_health.md + - Smartctl: smartctl.md + - badblocks: badblocks.md + - Resilience: + - linux_resilience.md + - Memtest: memtest.md + - watchdog: watchdog.md + - Magic keys: magic_keys.md + - Monitoring: + - Monitoring Comparison: monitoring_comparison.md + - Prometheus: + - devops/prometheus/prometheus.md + - Architecture: devops/prometheus/prometheus_architecture.md + - Prometheus Operator: devops/prometheus/prometheus_operator.md + - Prometheus Install: devops/prometheus/prometheus_installation.md + - AlertManager: devops/prometheus/alertmanager.md + - Blackbox Exporter: devops/prometheus/blackbox_exporter.md + - cAdvisor: cadvisor.md + - Elasticsearch Exporter: elasticsearch_exporter.md + - Node Exporter: devops/prometheus/node_exporter.md + - Process Exporter: process_exporter.md - Python Prometheus: python-prometheus.md - - Python Telegram: - - python-telegram.md - - pytelegrambotapi: pytelegrambotapi.md - - Python VLC: python_vlc.md - - Playwright: playwright.md - - Plotly: coding/python/plotly.md - - questionary: questionary.md - - rich: rich.md - - Ruamel YAML: coding/python/ruamel_yaml.md - - Selenium: selenium.md - - Streamlit: streamlit.md - - SQLAlchemy: coding/python/sqlalchemy.md - - sqlite3: sqlite3.md - - Redis-py: coding/python/redis-py.md - - Requests: requests.md - - Requests-mock: coding/python/requests_mock.md - - Rq: coding/python/rq.md - - python_systemd: python_systemd.md - - sh: python_sh.md - - Talkey: talkey.md - - Tenacity: tenacity.md - - TinyDB: coding/python/tinydb.md - - Torch: torch.md - - Typer: typer.md - - Yoyo: coding/python/yoyo.md - - Type Hints: coding/python/type_hints.md - - Logging: python_logging.md - - Code Styling: coding/python/python_code_styling.md - - Docstrings: coding/python/docstrings.md - - Properties: python_properties.md - - Protocols: python_protocols.md - - Package Management: - - python_package_management.md - - PDM: pdm.md - - pipx: pipx.md - - Pipenv: pipenv.md - - Poetry: python_poetry.md - - Lazy loading: lazy_loading.md - - Plugin System: python_plugin_system.md - - Profiling: python_profiling.md - - Optimization: python_optimization.md - - Anti-Patterns: coding/python/python_anti_patterns.md - - Pytest: - - coding/python/pytest.md - - Parametrized testing: coding/python/pytest_parametrized_testing.md - - Pytest-cases: coding/python/pytest_cases.md - - Pytest-HttpServer: pytest_httpserver.md - - Pytest-xprocess: pytest-xprocess.md - - Internationalization: python_internationalization.md - - Python Snippets: coding/python/python_snippets.md - - Data Classes: coding/python/data_classes.md - - Vue.js: - - vuejs.md - - Vue snippets: vue_snippets.md - - Vuetify: vuetify.md - - Development tools: - - Cypress: cypress.md - - Vite: vite.md - - Vitest: vitest.md - - Bash: - - Bash snippets: bash_snippets.md - - Bash testing: bats.md - - lua: lua.md - - JSON: coding/json/json.md - - SQL: coding/sql/sql.md - - SQLite: sqlite.md - - YAML: coding/yaml/yaml.md - - Promql: coding/promql/promql.md - - Logql: logql.md - - HTML: html.md - - CSS: css.md - - Javascript: - - coding/javascript/javascript.md - - Javascript snippets: javascript_snippets.md - - MermaidJS: mermaidjs.md - - Latex: latex.md - - Graphql: graphql.md - - Qwik: qwik.md - - nodejs: linux/nodejs.md - - JWT: devops/jwt.md - - React: coding/react/react.md - - Coding tools: - - IDES: - - Vim: - - vim.md - - Vim configuration: - - vim_config.md - - Vim Keymaps: vim_keymaps.md - - Vim Package Manager: - - vim_plugin_managers.md - - LazyVim: lazyvim.md - - Packer: vim_packer.md - - UI management configuration: - - Vim foldings: vim_foldings.md - - Vim movement: vim_movement.md - - Tabs vs Buffers: vim_tabs.md - - File management configuration: - - NeoTree: neotree.md - - Telescope: telescope.md - - fzf.nvim: fzf_nvim.md - - Editing specific configuration: - - vim_editor_plugins.md - - Vim formatters: vim_formatters.md - - Vim autocomplete: vim_completion.md - - Vim markdown: vim_markdown.md - - Vim spelling: vim_spelling.md - - Vim autosave: vim_autosave.md - - Coding specific configuration: - - vim_coding_plugins.md - - Treesitter: vim_treesitter.md - - LSP: vim_lsp.md - - Snippets: luasnip.md - - DAP: vim_dap.md - - Git management configuration: - - vim_git.md - - Diffview: diffview.md - - gitsigns: gitsigns.md - - Testing management configuration: vim_testing.md - - Email management: vim_email.md - - Other Vim Plugins: - - linux/vim/vim_plugins.md - - Vim Snippets: vim_snippets.md - - Vim Troubleshooting: vim_troubleshooting.md - - Neovim Plugin Development: vim_plugin_development.md - - Vi vs Vim vs Neovim: vim_vs_neovim.md - - Tridactyl: tridactyl.md - - VSCodium: vscodium.md - - Coding with AI: ai_coding.md - - Git: - - git.md - - Github cli: gh.md - - Forgejo: forgejo.md - - Gitea: gitea.md - - Radicle: radicle.md - - Data orchestrators: - - data_orchestrators.md - - Kestra: kestra.md - - memorious: memorious.md - - Scrapers: - - morph.io: morph_io.md - - ETL: - - Singer: singer.md - - Espanso: espanso.md - - Generic Coding Practices: - - How to code: how_to_code.md - - Program Versioning: - - versioning.md - - Semantic Versioning: semantic_versioning.md - - Calendar Versioning: calendar_versioning.md - - Use warnings to evolve your code: use_warnings.md - - Keep a Changelog: changelog.md - - Writing good documentation: documentation.md - - Conventional comments: conventional_comments.md - - TDD: coding/tdd.md - - GitOps: gitops.md - - Abstract Syntax Trees: abstract_syntax_trees.md - - Software Architecture: - - SOLID: architecture/solid.md - - Domain Driven Design: - - architecture/domain_driven_design.md - - Repository Pattern: architecture/repository_pattern.md - - Service Layer Pattern: architecture/service_layer_pattern.md - - Architecture Decision Record: adr.md - - Database Architecture: architecture/database_architecture.md - - ORM, Query Builder or Raw SQL: architecture/orm_builder_query_or_raw_sql.md - - Microservices: architecture/microservices.md - - Restful APIS: architecture/restful_apis.md - - OCR: - - Table parsing: - - Camelot: camelot.md - - Frontend Development: frontend_development.md - - Park programming: park_programming.md - - Sponsor: sponsor.md - - Issues: issues.md - - DevSecOps: - - devops/devops.md - - Infrastructure as Code: - - Helm: - - devops/helm/helm.md - - Helm Installation: devops/helm/helm_installation.md - - Helm Commands: devops/helm/helm_commands.md - - Helm Secrets: devops/helm/helm_secrets.md - - Helm Git: helm_git.md - - Helmfile: devops/helmfile.md - - Terraform: terraform.md - - Ansible: - - Ansible Snippets: ansible_snippets.md - - Molecule: molecule.md - - Nix: nix.md - - Dotfiles: - - dotfiles.md - - Home Manager: home-manager.md - - Chezmoi: chezmoi.md - - Dotdrop: dotdrop.md - - Infrastructure Solutions: - - Kubernetes: - - devops/kubernetes/kubernetes.md - - Architecture: devops/kubernetes/kubernetes_architecture.md - - Resources: - - Namespaces: devops/kubernetes/kubernetes_namespaces.md - - Pods: devops/kubernetes/kubernetes_pods.md - - ReplicaSets: devops/kubernetes/kubernetes_replicasets.md - - Deployments: devops/kubernetes/kubernetes_deployments.md - - Horizontal Pod Autoscaling: &amp;gt;- - devops/kubernetes/kubernetes_hpa.md - - Volumes: devops/kubernetes/kubernetes_volumes.md - - Services: devops/kubernetes/kubernetes_services.md - - Labels: devops/kubernetes/kubernetes_labels.md - - Annotations: devops/kubernetes/kubernetes_annotations.md - - Ingress: devops/kubernetes/kubernetes_ingress.md - - Jobs: devops/kubernetes/kubernetes_jobs.md - - Kubectl: - - devops/kubectl/kubectl.md - - Kubectl Installation: devops/kubectl/kubectl_installation.md - - Kubectl Commands: devops/kubectl/kubectl_commands.md - - Additional Components: - - Metrics Server: devops/kubernetes/kubernetes_metric_server.md - - Ingress Controller: &amp;gt;- - devops/kubernetes/kubernetes_ingress_controller.md - - External DNS: devops/kubernetes/kubernetes_external_dns.md - - Cluster Autoscaler: &amp;gt;- - devops/kubernetes/kubernetes_cluster_autoscaler.md - - Dashboard: devops/kubernetes/kubernetes_dashboard.md - - Storage Driver: devops/kubernetes/kubernetes_storage_driver.md - - Vertical Pod Autoscaler: &amp;gt;- - devops/kubernetes/kubernetes_vertical_pod_autoscaler.md - - Networking: devops/kubernetes/kubernetes_networking.md - - Debugging: kubernetes_debugging.md - - Backups: - - Velero: velero.md - - Operators: devops/kubernetes/kubernetes_operators.md - - Tools: - - devops/kubernetes/kubernetes_tools.md - - Krew: krew.md - - Ksniff: ksniff.md - - Mizu: mizu.md - - AWS: - - devops/aws/aws.md - - AWS Snippets: aws_snippets.md - - AWS Savings plan: aws_savings_plan.md - - Security groups workflow: devops/aws/security_groups.md - - EKS: devops/aws/eks.md - - EFS: efs.md - - IAM: - - devops/aws/iam/iam.md - - IAM Commands: devops/aws/iam/iam_commands.md - - IAM Debugging: devops/aws/iam/iam_debug.md - - S3: devops/aws/s3.md - - WAF: aws_waf.md + - Instance sizing analysis: devops/prometheus/instance_sizing_analysis.md + - Prometheus Troubleshooting: &amp;gt;- + devops/prometheus/prometheus_troubleshooting.md + - Grafana: grafana.md + - Log analysis: + - Loki: + - loki.md + - Logcli: logcli.md + - Promtail: promtail.md + - Graylog: graylog.md + - Elastic Security: elastic_security.md + - SIEM: siem.md - Databases: - - Redis: architecture/redis.md - - RabbitMQ: rabbitmq.md - - Continuous Deployment: - - ArgoCD: argocd.md - - Continuous Integration: - - devops/ci.md - - Drone: drone.md - - Linters: - - Alex: devops/alex.md - - Flakeheaven: flakeheaven.md - - Flake8: devops/flake8.md - - Markdownlint: devops/markdownlint.md - - Proselint: devops/proselint.md - - Shellcheck: shellcheck.md - - Yamllint: devops/yamllint.md - - Write Good: devops/write_good.md - - Formatters/Fixers: - - Black: devops/black.md - - Yamlfix: yamlfix.md - - Pyment: pyment.md - - mdformat: mdformat.md - - Type Checkers: - - Mypy: devops/mypy.md - - Security Checkers: - - pip-audit: pip_audit.md - - Bandit: devops/bandit.md - - Safety: devops/safety.md - - Dependency managers: - - Pip-tools: devops/pip_tools.md - - Automating Processes: - - copier: copier.md - - cookiecutter: linux/cookiecutter.md - - cruft: linux/cruft.md - - renovate: renovate.md - - letsencrypt: letsencrypt.md - - Threat modeling: - - Privacy threat modeling: privacy_threat_modeling.md - - Storage: - - storage.md - - NAS: nas.md - - OpenZFS: - - linux/zfs.md - - OpenZFS storage planning: zfs_storage_planning.md - - Sanoid: sanoid.md - - ZFS Prometheus exporter: zfs_exporter.md - - Hard drive health: - - hard_drive_health.md - - Smartctl: smartctl.md - - badblocks: badblocks.md - - Resilience: - - linux_resilience.md - - Memtest: memtest.md - - watchdog: watchdog.md - - Magic keys: magic_keys.md - - Monitoring: - - Monitoring Comparison: monitoring_comparison.md - - Prometheus: - - devops/prometheus/prometheus.md - - Architecture: devops/prometheus/prometheus_architecture.md - - Prometheus Operator: devops/prometheus/prometheus_operator.md - - Prometheus Install: devops/prometheus/prometheus_installation.md - - AlertManager: devops/prometheus/alertmanager.md - - Blackbox Exporter: devops/prometheus/blackbox_exporter.md - - cAdvisor: cadvisor.md - - Elasticsearch Exporter: elasticsearch_exporter.md - - Node Exporter: devops/prometheus/node_exporter.md - - Process Exporter: process_exporter.md - - Python Prometheus: python-prometheus.md - - Instance sizing analysis: devops/prometheus/instance_sizing_analysis.md - - Prometheus Troubleshooting: &amp;gt;- - devops/prometheus/prometheus_troubleshooting.md - - Grafana: grafana.md - - Log analysis: - - Loki: - - loki.md - - Logcli: logcli.md - - Promtail: promtail.md - - Graylog: graylog.md - - Elastic Security: elastic_security.md - - SIEM: siem.md - - Databases: - - PostgreSQL: - - postgres.md - - Postgres operators: - - postgres_operators.md - - Zalando Postgres operator: zalando_postgres_operator.md - - elasticsearch: linux/elasticsearch.md - - Oracle Database: oracle_database.md - - Authentication: - - Authentik: authentik.md - - API Management: - - devops/api_management.md - - Kong: devops/kong/kong.md - - Scrum: - - scrum.md - - Templates: - - Refinement Template: refinement_template.md - - Hardware: - - CPU: cpu.md - - RAM: - - ram.md - - ECC RAM: - - ecc.md - - rasdaemon: rasdaemon.md - - Power Supply Unit: psu.md - - GPU: gpu.md - - Pedal PC: pedal_pc.md - - Pentesting: pentesting.md - - Operating Systems: - - Linux: - - linux.md - - Linux Snippets: linux_snippets.md - - Distros: - - Libreelec: libreelec.md - - Tails: tails.md - - Recovery tools: - - finnix: finnix.md - - Security tools: - - fail2ban: linux/fail2ban.md - - pass: pass.md - - Wireshark: wireshark.md - - Canary tokens: canary_tokens.md + - PostgreSQL: + - postgres.md + - Postgres operators: + - postgres_operators.md + - Zalando Postgres operator: zalando_postgres_operator.md + - elasticsearch: linux/elasticsearch.md + - Oracle Database: oracle_database.md + - Authentication: + - Authentik: authentik.md + - API Management: + - devops/api_management.md + - Kong: devops/kong/kong.md + - Scrum: + - scrum.md + - Templates: + - Refinement Template: refinement_template.md + - Hardware: + - CPU: cpu.md + - RAM: + - ram.md + - ECC RAM: + - ecc.md + - rasdaemon: rasdaemon.md + - Power Supply Unit: psu.md + - GPU: gpu.md + - Pedal PC: pedal_pc.md + - Pentesting: pentesting.md + - Operating Systems: + - Linux: + - linux.md + - Linux Snippets: linux_snippets.md + - Distros: + - Libreelec: libreelec.md + - Tails: tails.md + - Recovery tools: + - finnix: finnix.md + - Security tools: + - fail2ban: linux/fail2ban.md + - pass: pass.md + - Wireshark: wireshark.md + - Canary tokens: canary_tokens.md&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Sysadmin tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;brew: linux/brew.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;detox: detox.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Docker: docker.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Watchtower: watchtower.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Dynamic DNS: dynamicdns.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;goaccess: goaccess.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Gotify: gotify.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;HAProxy: linux/haproxy.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;journald: journald.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;LUKS: linux/luks/luks.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Outrun: outrun.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;rm: linux/rm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;sed: sed.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Syncthing: linux/syncthing.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Tahoe-LAFS: tahoe.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wake on Lan: wake_on_lan.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wireguard:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;linux/wireguard.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;wg-easy: wg-easy.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;yq: yq.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;zip: linux/zip.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Window manager tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;dunst: dunst.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;ferdium: ferdium.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;i3wm: i3wm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;rofi: rofi.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;User tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Browsers:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;google chrome: linux/google_chrome.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Chromium: chromium.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Hushboard: husboard.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Peek: peek.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Terminals:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;terminal_comparison.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Alacritty: alacritty.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wezterm: wezterm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Kitty: kitty.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Instant messaging apps:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Delta Chat: deltachat.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Simplex Chat: simplexchat.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Sysadmin tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;brew: linux/brew.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;detox: detox.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Docker: docker.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Watchtower: watchtower.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Dynamic DNS: dynamicdns.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;goaccess: goaccess.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Gotify: gotify.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;HAProxy: linux/haproxy.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;journald: journald.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;LUKS: linux/luks/luks.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Outrun: outrun.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;rm: linux/rm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;sed: sed.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Syncthing: linux/syncthing.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Tahoe-LAFS: tahoe.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wake on Lan: wake_on_lan.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wireguard:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;linux/wireguard.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;wg-easy: wg-easy.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;yq: yq.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;zip: linux/zip.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Window manager tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;dunst: dunst.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;ferdium: ferdium.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;i3wm: i3wm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;rofi: rofi.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;User tools:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Browsers:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;google chrome: linux/google_chrome.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Chromium: chromium.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Hushboard: husboard.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Peek: peek.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Terminals:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;terminal_comparison.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Alacritty: alacritty.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Wezterm: wezterm.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Kitty: kitty.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Instant messaging apps:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Delta Chat: deltachat.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Simplex Chat: simplexchat.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android Tips: android_tips.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;OS:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;GrapheneOS: grapheneos.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;FuriOS: furios.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Apps:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Cone: cone.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;GadgetBridge: gadgetbridge.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;LibreTube: libretube.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;HappyCow: happycow.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;ICSx5: icsx5.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Orgzly: orgzly.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;OsmAnd: osmand.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Seedvault: seedvault.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android SDK Platform tools: android_sdk.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android Tips: android_tips.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;OS:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;GrapheneOS: grapheneos.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;FuriOS: furios.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Apps:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Cone: cone.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;GadgetBridge: gadgetbridge.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;LibreTube: libretube.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;HappyCow: happycow.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;ICSx5: icsx5.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Orgzly: orgzly.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;OsmAnd: osmand.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Seedvault: seedvault.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Android SDK Platform tools: android_sdk.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Hardware:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Redox: redox.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Vial: vial.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Rock64: rock64.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Filosofía:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;filosofía.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Amor: amor.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Arts:&lt;ul&gt; &lt;li&gt;Writing:&lt;ul&gt; &lt;li&gt;writing/writing.md @@ -746,9 +755,6 @@ nav:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Calistenia: calistenia.md&lt;/li&gt; &lt;li&gt;Aerial Silk: aerial_silk.md&lt;/li&gt; &lt;li&gt;Meditation: meditation.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Maker:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Redox: redox.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Vial: vial.md&lt;/li&gt; &lt;li&gt;Sudokus: sudokus.md&lt;/li&gt; &lt;li&gt;Drawing:&lt;ul&gt; &lt;li&gt;drawing/drawing.md @@ -811,6 +817,7 @@ nav:&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Board Games:&lt;ul&gt; &lt;li&gt;board_games.md&lt;/li&gt; &lt;li&gt;Regicide: regicide.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;Monologues: monologues.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Projects: projects.md&lt;/li&gt; &lt;li&gt;Contact: contact.md&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;hardware&#34;&gt;Hardware&lt;/h3&gt; &lt;h4 id=&#34;rock64&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rock64/&#34;&gt;Rock64&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Install Debian in a rock64.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://wiki.pine64.org/wiki/ROCK64_Software_Releases#Debian&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Go to &lt;a href=&#34;https://wiki.pine64.org/wiki/ROCK64_Software_Releases#Debian&#34;&gt;the rock64 wiki page&lt;/a&gt; to get the download directory for the debian version you want to install&lt;/li&gt; &lt;li&gt;Download &lt;code&gt;firmware.rock64-rk3328.img.gz&lt;/code&gt; and &lt;code&gt;partition.img.gz&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Combine the 2 parts into 1 image file: &lt;code&gt;zcat firmware.rock64-rk3328.img.gz partition.img.gz &amp;gt; debian-installer.img&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Write the created .img file to microSD card or eMMC Module using dd: &lt;code&gt;dd if=debian-installer.img of=/dev/sda bs=4M&lt;/code&gt;. Replace &lt;code&gt;/dev/sda&lt;/code&gt; with your target drive.&lt;/li&gt; &lt;li&gt;Plug the microSD/eMMC card in the Rock64 (and connect a serial console, or keyboard and monitor) and boot up to start the Debian Installer&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Notes:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;An Ethernet connection is required for the above installer&lt;/li&gt; &lt;li&gt;Remember to leave some space before your first partition for u-boot! You can do this by creating a 32M size unused partition at the start of the device.&lt;/li&gt; &lt;li&gt;Auto creating all partitions does not work. You can use the following manual partition scheme:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; #1 - 34MB  Unused/Free Space
 #2 - 512MB ext2 /boot           (Remember to set the bootable flag)
 #3 - xxGB  ext4 /               (This can be as large as you want. You can also create separate partitions for /home /var /tmp)
 #4 - 1GB   swap                 (May not be a good idea if using an SD card)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;software-tools&#34;&gt;Software tools&lt;/h3&gt; &lt;h4 id=&#34;liberaforms&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/liberaforms/&#34;&gt;Liberaforms&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Usage of liberaforms.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Marked true&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you are a forms admin you can mark the answers which can be used to for example state that those have been checked and are not trolls, the user can then edit the answers through the magic link but it&#39;s not very probable that it becomes a trollo&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Send edit email&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want the users to receive an email with the magic link so that they can edit their answers you need to add a &#34;Short text&#34; field of type &#34;Email&#34; and then in the Options you need to enable the setting to send the users the magic link&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Extract the results through API&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Each form at the bottom of the Options tab has a section of API endpoints, once enabled you can extract them with curl:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;BASE_URL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://forms.komun.org
&lt;span class=&#34;nv&#34;&gt;form_id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;478&lt;/span&gt;
curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-sqH&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Authorization: Bearer &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;JWT_TOKEN&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;BASE_URL&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/api/form/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;form_id&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/answers&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;That will give you an answer similar to:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;answers&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;created&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2025-04-25T15:05:02.384121&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;data&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1712945984567&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Hitzaldia--Charla--Xerrada&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1713092876455&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;55&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1713373271313&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Castellano_1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1713382758036&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Si_1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;radio-group-1744968040362-0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;d8b35c755d9d41e2a844a344ae2494d6&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1712945594310&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Historia de la criptograf\u00eda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1712945631444&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1712945663611&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;user&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1712947404812&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;user@sindominio.net&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1744967213162-0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Divulgativa&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;text-1744967571620-0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Ninguno&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1712945646944&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Aproximaci\u00f3n hist\u00f3rica a la criptograf\u00eda, desde la Antig\u00fcedad a d\u00eda de hoy&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1712945755946&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1712945806547&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;HDMI&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1712945865865&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Privacidad, criptograf\u00eda, matem\u00e1ticas, historia&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;textarea-1713380502724&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;form&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;478&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;id&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;36148&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;marked&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;meta&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;err&#34;&gt;``&lt;/span&gt;

&lt;span class=&#34;err&#34;&gt;As&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;you&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ca&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;see&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;he&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ields&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;have&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;weird&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;na&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;mes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ge&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;he&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;de&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;ta&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ils&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;each&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ield&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;you&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;ca&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;do&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;he&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;same&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;reques&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;bu&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;`$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;BASE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/api/&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;orm/$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;orm_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nstea&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;d&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;o&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;`$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;BASE_URL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/api/&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;orm/$&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;orm_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;/a&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;ns&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;wers`&lt;/span&gt;

&lt;span class=&#34;err&#34;&gt;```jso&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;n&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;form&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;created&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;2025-04-25T11:45:43.633038&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;introduction_md&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;# Call4Nodes Hackmeeting 2025&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;slug&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;call4nodes-hackmeeting-2025-cas&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;structure&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;className&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;form-control&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;label&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;T\u00edtulo&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;text-1712945594310&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;required&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;subtype&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;text&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;type&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;text&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;className&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;form-control&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;label&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Descripci\u00f3n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;textarea-1712945646944&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;required&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;type&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;textarea&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;filosofia&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/&#34;&gt;Filosofía&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/filosof%C3%ADa/#pensamientos-sueltos&#34;&gt;Pensamientos sueltos.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;En el episodio de &lt;a href=&#34;https://www.ivoox.com/en/ver-al-otro-narrativa-democracia-audios-mp3_rf_146744850_1.html&#34;&gt;Ver al otro: narrativa y democracia&lt;/a&gt; de punzadas sonoras hacen un análisis muy interesante sobre cómo la literatura puede ser un mecanismo muy potente de transformación social.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;amor&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/amor/&#34;&gt;Amor&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/amor/#amor-no-correspondido&#34;&gt;Amor no correspondido.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;En el episodio &lt;a href=&#34;https://www.ivoox.com/en/amor-no-correspondido-por-que-audios-mp3_rf_145889043_1.html&#34;&gt;Amor no correspondido: ¿Por qué?&lt;/a&gt; de punzadas sonoras hacen un análisis muy interesante. Puedes escucharlo directamente desde &lt;a href=&#34;https://traffic.megaphone.fm/PMSL2043145084.mp3?updated=1745962804&#34;&gt;aquí&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;cooking&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking/&#34;&gt;Cooking&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking/#instrumentos-de-cocina&#34;&gt;Instrumentos de cocina.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=cBnIIHEtjQM&#34;&gt;cómo usar las sartenes de acero inoxidable&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;cooking-basics&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking_basics/&#34;&gt;Cooking Basics&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/cooking_basics/#cortar-una-cebolla&#34;&gt;Todos los cortes para una cebolla.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Picada&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dividir la cebolla por la raiz&lt;/li&gt; &lt;li&gt;apoyar cada mitad en la tabla con la raiz en perpendicular a ti&lt;/li&gt; &lt;li&gt;cortes grandes perpendicular a la raiz&lt;/li&gt; &lt;li&gt;poner la raiz en tu dirección&lt;/li&gt; &lt;li&gt;cortes grandes paralelos a la tabla&lt;/li&gt; &lt;li&gt;cortes grandes perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Juliana&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dividir la cebolla por la raiz&lt;/li&gt; &lt;li&gt;apoyar cada mitad en la tabla con la raiz en paralelo a ti&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Media luna&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dividir la cebolla por la raiz&lt;/li&gt; &lt;li&gt;apoyar cada mitad en la tabla con la raiz en perpendicular a ti&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Brunoise&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dividir la cebolla por la raiz&lt;/li&gt; &lt;li&gt;apoyar cada mitad en la tabla con la raiz en paralelo a ti&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla sin llegar hasta el final&lt;/li&gt; &lt;li&gt;poner la raiz en perpendicular&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor paralelos a la tabla sin llegar hasta el final&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Discos&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Sin dividir la cebolla, poner la raiz paralela a la tabla y en perpendicular a ti&lt;/li&gt; &lt;li&gt;cortes al gusto de grosor perpendiculares a la tabla&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Aros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Corte de discos&lt;/li&gt; &lt;li&gt;desmontar los discos&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;relevant-content&#34;&gt;Relevant content&lt;/h2&gt; &lt;h3 id=&#34;videogames&#34;&gt;Videogames&lt;/h3&gt; &lt;h4 id=&#34;age-of-empires&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/age_of_empires/&#34;&gt;Age of Empires&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: New teutons vs portuguese video.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://piped.video/watch?v=XECeghut_5U&amp;amp;t=0&#34;&gt;Teutons vs Portuguese | 1v1 Arabia | Hera vs MbL&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;monologues&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/monologues/&#34;&gt;Monologues&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add Sammy Obeid.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/@SammyObeidComedy&#34;&gt;Sammy Obeid&lt;/a&gt;: Antizionist comedian&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;May 28, 2025 06:52:38 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-05-28T06:52:38+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;May 28, 2025 06:52:38 UTC&#34;&gt;2025-05-28&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_05_27/</link>
      <pubDate>2025-05-28 06:52:38+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_05_27/</guid>
      
    </item>
    
    <item><title>29th April 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;activism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anticolonialism/&#34;&gt;Activism&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anticolonialism/#anticolonialism-in-technology&#34;&gt;Anticolonialism in technology.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Art&lt;/strong&gt; - &lt;a href=&#34;https://ail.angewandte.at/explore/decolonizing-technology/&#34;&gt;Decolonizing technology&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Articles&lt;/strong&gt; - &lt;a href=&#34;https://jipel.law.nyu.edu/shanzhai-an-opportunity-to-decolonize-technology/&#34;&gt;Shanzhai: An Opportunity to Decolonize Technology? by Sherry Liao&lt;/a&gt; - &lt;a href=&#34;https://alasbarricadas.org/forums/viewtopic.php?t=9654&#34;&gt;Técnicas autoritarias y técnicas democráticas by Lewis Mumford&lt;/a&gt; (&lt;a href=&#34;https://istas.net/descargas/escorial04/material/dc05.pdf&#34;&gt;pdf&lt;/a&gt;)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Books&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.ruhabenjamin.com/race-after-technology&#34;&gt;Race after technology by Ruha Benjamin&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/62790909-the-palestine-laboratory&#34;&gt;The Palestine Laboratory: How Israel Exports the Technology of Occupation Around the World by Antony Loewenstein&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Frantz_Fanon&#34;&gt;Frantz Fanon books&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.agenziax.it/hacking-del-se&#34;&gt;Hacking del sé by Ippolita&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.eleuthera.it/materiale.php?op=2699&#34;&gt;Tecnologie conviviali by Carlo Milani&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vision.centroculturadigital.mx/media/done/descolonizarYD.pdf&#34;&gt;Descolonizar y despatriarcalizar las tecnologías by Paola Ricaurte Quijano&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Research&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://researchmethodscommunity.sagepub.com/blog/decolonization-indigenous-methods-technology&#34;&gt;Decolonization, Technology, and Online Research by Janet Salmons&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Talks&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://re-publica.com/de/session/decolonize-tech-how-design-all&#34;&gt;re:publica 2024: Christoph Hassler - Decolonize Tech&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=R10Dwgxt_mg&#34;&gt;video&lt;/a&gt;)&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;feminism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/&#34;&gt;Feminism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/feminism/#references&#34;&gt;New References.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;palestine&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/palestine/&#34;&gt;Palestine&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/palestine/#al-jazeera-documenaries&#34;&gt;Add Al Jazeera documenaries.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A la luz de los acontecimientos actuales en Palestina, un gran número de cineastas han puesto sus películas sobre Palestina a disposición en línea de forma gratuita.&lt;/p&gt; &lt;p&gt;Están en árabe y no tienen subtítulos así que no se puede bajar, pero si se pueden ver directamente en youtube con los subtítulos autogenerados.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Una colección de documentales publicada por Al Jazeera Documentary: &lt;a href=&#34;https://bit.ly/3yp2nBI&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://bit.ly/2SSpMeC&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://bit.ly/3f0KK3P&#34;&gt;3&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/eywuYeflWzg&#34;&gt;El documental &#34;Guardián de la memoria&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/an4hRFWOSQQ&#34;&gt;El documental &#34;Un asiento vacío&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/wqSmdZy-Xcg&#34;&gt;El documental &#34;El piloto de la resistencia&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/499672067&#34;&gt;El documental &#34;Jenin&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/432062498&#34;&gt;El documental &#34;El olivo&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/1JlIwmnYnlE&#34;&gt;El documental &#34;Escenas de la ocupación en Gaza 1973&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/HnZSaKYmP2s&#34;&gt;El documental &#34;Gaza lucha por la libertad&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/cQZiHgbBBcI&#34;&gt;El documental &#34;Los hijos de Arna&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/209189656/e5510a6064&#34;&gt;El cortometraje &#34;Strawberry&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/fgcIVhNvsII&#34;&gt;El cortometraje &#34;The Place&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/aDvOnhssTcc&#34;&gt;El documental &#34;El alcalde&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/Bwy-Rf15UIs&#34;&gt;El documental &#34;La creación y la Nakba 1948&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/C56QcWOGSKk&#34;&gt;El documental &#34;Ocupación 101&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/220119035&#34;&gt;El documental &#34;La sombra de la ausencia&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/2WZ_7Z6vbsg&#34;&gt;El documental &#34;Los que no existen&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/220116068&#34;&gt;El documental &#34;Como dijo el poeta&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/TZU9hYIgXZw&#34;&gt;El documental &#34;Cinco cámaras rotas&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/510883804&#34;&gt;El largometraje &#34;Paradise Now&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/I--r85cOoXM&#34;&gt;El cortometraje &#34;Abnadam&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/dYMQw7hQI1U&#34;&gt;El largometraje &#34;Bodas de Galilea&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/780695653&#34;&gt;El largometraje &#34;Kofia&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/hHFlWE3N9Ik&#34;&gt;El largometraje documental &#34;Slingshot Hip Hop&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/Ma8H3sEbqtI&#34;&gt;El largometraje documental &#34;Tel Al-Zaatar&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/Ma8H3sEbqtI&#34;&gt;El largometraje documental &#34;Tal al-Zaatar - Detrás de la batalla&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/htJ10ACWQJM&#34;&gt;El documental &#34;In the Grip of the Resistance&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/gMk-Zi9vTGs&#34;&gt;El documental &#34;Swings&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/Y31yUi4WVsU&#34;&gt;El documental &#34;Naji al-Ali es un artista visionario&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/433362585&#34;&gt;El documental &#34;La puerta superior&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://vimeo.com/184213685?1&#34;&gt;El largometraje documental &#34;En busca de Palestina&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bit.ly/3c10G3Z&#34;&gt;El largometraje &#34;La sal de este mar&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://youtu.be/wdkoxBjKM1Q&#34;&gt;El largometraje documental &#34;Hakki Ya Bird&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bit.ly/3bXNAVp&#34;&gt;La serie &#34;Palestina Al-Taghriba&#34;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bit.ly/3hG8sDV&#34;&gt;La serie &#34;Yo soy Jerusalén&#34;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;conflicto&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/conflicto/&#34;&gt;Conflicto&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Añadir notas sobre el conflicto desde un punto de vista antipunitivista.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pensamientos sueltos sobre la visión del conflicto desde un punto de vista antipunitivista&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Dejar de ver los conflictos como una batalla, es una oportunidad de transformación&lt;/li&gt; &lt;li&gt;Los conflictos deben de ser resueltos en colectivo siempre que se pueda&lt;/li&gt; &lt;li&gt;Si se veta a un pavo por comportamientos machistas sólo estás trasladando el problema. Seguirá pululando por diferentes colectivos hasta que arraigue en uno más débil y lo torpedeará&lt;/li&gt; &lt;li&gt;Es difícil de ver el límite entre lo terapéutico y lo transformativo&lt;/li&gt; &lt;li&gt;Cuál es la responsabilidad colectiva de la transformación de una persona?&lt;/li&gt; &lt;li&gt;Nos faltan herramientas para:&lt;/li&gt; &lt;li&gt;la gestión de conflictos en general&lt;/li&gt; &lt;li&gt;la gestión de conflictos físicos en particular&lt;/li&gt; &lt;li&gt;el acompañamiento a ambas partes de un conflicto&lt;/li&gt; &lt;li&gt;el acompañamiento a una persona agresora&lt;/li&gt; &lt;li&gt;es todo lo que me produce malestar violencia?&lt;/li&gt; &lt;li&gt;Cada situación es tan particular que los protocolos no sirven. Es mucho mejor someternos en colectivo y a menudo a situaciones de conflicto y generar desde esa práctica las herramientas que nos puedan servir, de manera que en el momento de la verdad salgan de manera intuitiva.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Películas&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Women_Talking_(film)&#34;&gt;Ellas hablan&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=pD0mFhMqDCE&#34;&gt;trailer&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/How_to_Have_Sex&#34;&gt;How to Have Sex&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=52b7s-diPk8&#34;&gt;trailer&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://es.wikipedia.org/wiki/Promising_Young_Woman&#34;&gt;Promising young woman&lt;/a&gt; (&lt;a href=&#34;https://www.youtube.com/watch?v=7i5kiFDunk8&#34;&gt;trailer&lt;/a&gt;)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Libros&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://traficantes.net/sites/default/files/pdfs/Micropol%C3%ADticas%20de%20los%20grupos-TdS.pdf&#34;&gt;Micropolítica de los grupos&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://hamacaonline.net/media/publicacio/Conflicto-no-es-lo-mismo_dig2024.pdf&#34;&gt;Conflicto no es lo mismo que abuso&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://maryread.es/producto/ofendiditos&#34;&gt;Ofendiditos&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Series&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://dai.ly/x91qoeq&#34;&gt;La Fièvre&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Podcast&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.primaverasound.com/es/radio/shows/ciberlocutorio/ciberlocutorio-el-marido&#34;&gt;El marido (Ciberlocutorio)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.primaverasound.com/es/radio/shows/ciberlocutorio/ciberlocutorio-el-cancelado&#34;&gt;El cancelado (Ciberlocutorio)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=p_frBHfk7cc&#34;&gt;Antipunitivismo con Laura Macaya (Sabor a Queer)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://soundcloud.com/traficantesdesue-os/s5-procesos-restaurativos-feministas-y-sistemicos-con-anna-gali-fil-a-lagulla?in=traficantesdesue-os/sets/curso-me-cuidan-mis-amigas&#34;&gt;Procesos restaurativos, feministas y sistémicos (Fil a l´agulla en el curso de Nociones Comunes &#34;Me cuidan mis amigas&#34;)&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Artículos&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://ctxt.es/es/20220401/Firmas/39365/feminismo-autoorganizacion-barrio-antipunitivismo-comunidades-violencia-machista.htm&#34;&gt;Con penas y sin glorias: reflexiones desde un feminismo antipunitivo y comunitario:&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://ctxt.es/es/20250301/Firmas/48798/Colectivo-Cantoneras-expulsar-agresores-violencia-de-genero-feminismos-justicia-restaurativa-antipunitivismo.htm&#34;&gt;Expulsar a los agresores no reduce necesariamente la violencia:&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.pikaramagazine.com/2024/10/antipunitivismo-remasterizado/&#34;&gt;Antipunitivismo remasterizado&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.pikaramagazine.com/2021/12/reflexiones-sobre-antipunitivismo-en-tiempos-de-violencias/&#34;&gt;Reflexiones sobre antipunitivismo en tiempos de violencias&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/palabras-en-movimiento/indispuestas-cuando-nadie-quiere-poner-vida-ello&#34;&gt;Indispuestas. Cuando nadie quiere poner la vida en ello&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lavillana.org/la-deriva-neoliberal-de-los-cuidados/&#34;&gt;La deriva neoliberal de los cuidados&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://zonaestrategia.net/justicia-transformativa-del-dicho-al-hecho/&#34;&gt;Justicia transformativa: del dicho al hecho&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/la-antinorma/malas-victimas-responden&#34;&gt;Las malas víctimas responden&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Otras herramientas&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lacinetika.wordpress.com/comissio-de-genere/&#34;&gt;Guía para la prevención y actuación frente a las violencias patriarcales de la Cinètika.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.cooperativestreball.coop/sites/default/files/materials/guia_per_a_la_gestio_de_conflictes.pdf&#34;&gt;Guía Fil a l´agulla per a la gestió de conflictes a les cooperatives (en catalan)&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;conference-organisation&#34;&gt;Conference organisation&lt;/h3&gt; &lt;h4 id=&#34;pretalx&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/&#34;&gt;pretalx&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/#install&#34;&gt;Install.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;NOTE: it&#39;s probably too much for a small event.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/pretalx/pretalx-docker&#34;&gt;Docker compose&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pretalx/pretalx-docker/issues/75&#34;&gt;The default docker compose doesn&#39;t work&lt;/a&gt; as it still uses &lt;a href=&#34;https://pretalx.com/p/news/releasing-pretalx-2024-3-0/&#34;&gt;mysql which was dropped&lt;/a&gt;. If you want to use sqlite just remove the database configuration.&lt;/p&gt;  &lt;p&gt;I was not able to find the default admin user so I had to create it manually. Get into the docker:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-it&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pretalx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When you run the commands by default it uses another database file &lt;code&gt;/pretalx/src/data/db.sqlite3&lt;/code&gt;, so I removed it and created a symbolic link to the actual place of the database &lt;code&gt;/data/db.sqlite&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pretalxuser@82f886a58c57:/$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/pretalx/src/data/db.sqlite3
pretalxuser@82f886a58c57:/$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ln&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/data/db.sqlite3&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/pretalx/src/data/db.sqlite3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then you can create the admin user:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pretalx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;createsuperuser
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-navigation&#34;&gt;Life navigation&lt;/h2&gt; &lt;h3 id=&#34;content-management&#34;&gt;Content Management&lt;/h3&gt; &lt;h4 id=&#34;moonlight&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/moonlight/&#34;&gt;moonlight&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add note on apollo.&lt;/p&gt; &lt;p&gt;Also checkout &lt;a href=&#34;https://github.com/ClassicOldSong/Apollo&#34;&gt;apollo&lt;/a&gt; a sunshine fork.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;book-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ombi/&#34;&gt;Book Management&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/book_management/#convert-pdf-to-epub&#34;&gt;Convert images based pdf to epub.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;NOTE: before proceeding inspect the next tools that use AI so it will probably give a better output:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/opendatalab/MinerU&#34;&gt;MinerU&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/VikParuchuri/marker&#34;&gt;marker&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/docling-project/docling&#34;&gt;docling&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://olmocr.allenai.org/&#34;&gt;olmocr&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If the pdf is based on images&lt;/p&gt; &lt;p&gt;Then you need to use OCR to extract the text.&lt;/p&gt; &lt;p&gt;First, convert the PDF to images:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pdftoppm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-png&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;page
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Apply OCR to your PDF&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;tesseract&lt;/code&gt; to extract text from each image:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;img&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;page-*.png&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;tesseract&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$img&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;%.png&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;eng
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This produces &lt;code&gt;page-1.txt&lt;/code&gt;, &lt;code&gt;page-2.txt&lt;/code&gt;, etc.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ombi/#protect-ombi-behind-authentik&#34;&gt;Protect ombi behind authentik.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This option allows the user to select a HTTP header value that contains the desired login username.&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Note that if the header value is present and matches an existing user, default authentication is bypassed - use with caution.&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;This is most commonly utilized when Ombi is behind a reverse proxy which handles authentication. For example, if using Authentik, the X-authentik-username HTTP header which contains the logged in user&#39;s username is set by Authentik&#39;s proxy outpost.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;languages&#34;&gt;Languages&lt;/h3&gt; &lt;h4 id=&#34;pipx&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pipx/&#34;&gt;pipx&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pipx/#upgrading-python-version-of-all-your-pipx-packages&#34;&gt;Upgrading python version of all your pipx packages.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you upgrade the main python version and remove the old one (a dist upgrade) then you won&#39;t be able to use the installed packages.&lt;/p&gt; &lt;p&gt;If you&#39;re lucky enough to have the old one you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pipx reinstall-all --python &amp;lt;the Python executable file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Otherwise you need to export all the packages with &lt;code&gt;pipx list --json &amp;gt; ~/pipx.json&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Then reinstall one by one:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-ux
&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/pipx.json&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/pipx.json&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.venvs[].metadata.main_package.package_or_url&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;pipx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$p&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The problem is that this method does not respect the version constrains nor the injects, so you may need to debug each package a bit.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;configure-docker-to-host-the-application&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/&#34;&gt;Configure Docker to host the application&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/docker/#limit-the-access-of-a-docker-on-a-server-to-the-access-on-the-docker-of-another-server&#34;&gt;Limit the access of a docker on a server to the access on the docker of another server.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;WARNING: I had issues with this path and I ended up not using docker swarm networks.&lt;/p&gt; &lt;p&gt;If you want to restrict access to a docker (running on server 1) so that only another specific docker container running on another server (server 2) can access it. You need more than just IP-based filtering between hosts. The solution is then to:&lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;Create a Docker network that spans both hosts using Docker Swarm or a custom overlay network.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;Use Docker&#39;s built-in DNS resolution&lt;/strong&gt; to allow specific container-to-container communication.&lt;/p&gt; &lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Here&#39;s a step-by-step approach:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. Set up Docker Swarm (if not already done)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On server 1:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;swarm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;init&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--advertise-addr&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;ip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;of&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;server&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will output a command to join the swarm. Run that command on server 2.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2. Create an overlay network&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;network&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--driver&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;overlay&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--attachable&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;of&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;network&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;3. Update the docker compose on server 1&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;magine for example that we want to deploy &lt;a href=&#34;https://lyz-code.github.io/blue-book/wg-easy/&#34;&gt;wg-easy&lt;/a&gt;.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;wg-easy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;ghcr.io/wg-easy/wg-easy:latest&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;wg-easy&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;wg&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;&amp;lt;name of the network&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Add the overlay network&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;wireguard:/etc/wireguard&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/lib/modules:/lib/modules:ro&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;51820:51820/udp&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# - &#34;127.0.0.1:51821:51821/tcp&#34; # Don&#39;t expose the http interface, it will be accessed from within the docker network&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;unless-stopped&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cap_add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;NET_ADMIN&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SYS_MODULE&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;sysctls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;net.ipv4.ip_forward=1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;net.ipv4.conf.all.src_valid_mark=1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;net.ipv6.conf.all.disable_ipv6=1&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;wg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Your existing network config&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;name of the network&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Reference the overlay network created above&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;4. On server 2, create a Docker Compose file for your client container&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;wg-client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;your-client-image&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;wg-client&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;&amp;lt;name of the network&amp;gt;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Other configuration for your client container&lt;/span&gt;

&lt;span class=&#34;nt&#34;&gt;networks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;lt;name of the network&amp;gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;external&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Reference the same overlay network&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;5. Access the WireGuard interface from the client container&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Now, from within the client container on server 2, you can access the WireGuard interface using the container name:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;http://wg-easy:51821
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This approach ensures that:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The WireGuard web interface is not exposed to the public (not even localhost on server 1)&lt;/li&gt; &lt;li&gt;Only containers on the shared overlay network can access it&lt;/li&gt; &lt;li&gt;The specific container on server 2 can access it using Docker&#39;s internal DNS&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Testing the network is well set&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You may be confused if the new network is not shown on server 2 when running &lt;code&gt;docker network ls&lt;/code&gt; but that&#39;s normal. Server 2 is a swarm worker node. The issue with not seeing the overlay network on server 2 is actually expected behavior - worker nodes cannot list or manage networks directly. However, even though you can&#39;t see them, containers on the server 2 can still connect to the overlay network when properly configured.&lt;/p&gt; &lt;p&gt;To see that the swarm is well set you can use &lt;code&gt;docker node ls&lt;/code&gt; on server 1 (you&#39;ll see an error on server 2 as it&#39;s a worker node)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Weird network issues with swarm overlays&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I&#39;ve seen cases where after a server reboot you need to remove the overlay network from the docker compose and then add it again.&lt;/p&gt; &lt;p&gt;After many hours of debugging I came with the patch of removing the overlay network from the docker-compose and attaching it with the systemd service&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[Unit]
Description=wg-easy
Requires=docker.service
After=docker.service

[Service]
Restart=always
User=root
Group=docker
WorkingDirectory=/data/apps/wg-easy
TimeoutStartSec=100
RestartSec=2s
ExecStart=/usr/bin/docker compose -f docker-compose.yaml up

ExecStartPost=/bin/bash -c &#39;\
    sleep 30; \
    /usr/bin/docker network connect wg-easy wg-easy; \
&#39;
ExecStop=/usr/bin/docker compose -f docker-compose.yaml down

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;plugin-system&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_plugin_system/&#34;&gt;Plugin System&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;Correction: Write python plugins with entrypoints.&lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/&#34;&gt;Python Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#download-book-previews-from-google-books&#34;&gt;Download book previews from google books.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You will only get some of the pages but it can help in the ending pdf&lt;/p&gt; &lt;p&gt;This first script gets the images data:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;json&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;re&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;urllib.parse&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;urlparse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_qs&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;playwright.async_api&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;async_playwright&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiohttp&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiofiles&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;download_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;session&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Download image from URL and save to specified path&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
       &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;User-Agent&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Mozilla/5.0 (Windows NT 10.0; rv:128.0) Gecko/20100101 Firefox/128.0&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Accept&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;*/*&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Accept-Language&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;en-US,en;q=0.5&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Referer&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;https://books.google.es/&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;DNT&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Sec-GPC&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;Connection&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;keep-alive&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

        &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;session&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;raise_for_status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiofiles&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;wb&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;

        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Downloaded: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_path&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error downloading &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;extract_page_number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Extract numeric page number from page ID&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;match&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PA(\d+)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;match&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;match&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PA&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PP&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;9999&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;# Create output directory&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;book_images&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;makedirs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Keep track of all pages found&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;page_counter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Create HTTP session for downloads&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiohttp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ClientSession&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;session&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;async_playwright&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;firefox&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;launch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headless&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;user_agent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Mozilla/5.0 (Windows NT 10.0; rv:128.0) Gecko/20100101 Firefox/128.0&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Create a page and set up response handling&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new_page&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Store seen URLs to avoid duplicates&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;seen_urls&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Set up response handling for JSON data&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;handle_response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;nonlocal&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_counter&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;

                &lt;span class=&#34;c1&#34;&gt;# Only process URLs with jscmd=click3&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;jscmd=click3&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_urls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                        &lt;span class=&#34;c1&#34;&gt;# Try to parse as JSON&lt;/span&gt;
                        &lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
                        &lt;span class=&#34;n&#34;&gt;seen_urls&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                       &lt;span class=&#34;c1&#34;&gt;# Process and download page data immediately&lt;/span&gt;
                        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;page&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;page&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                            &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;json_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;page&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
                                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;src&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;pid&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                                    &lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;pid&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
                                    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                       &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;src&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;

                                        &lt;span class=&#34;c1&#34;&gt;# Create filename with sequential numbering&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;formatted_index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                                            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;replace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;PA&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;03d&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
                                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;output_file&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                                            &lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;page-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;formatted_index&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.png&#34;&lt;/span&gt;
                                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;page_counter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;

                                        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                                            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Found new page: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pid&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;, scheduling download&#34;&lt;/span&gt;
                                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                                        &lt;span class=&#34;c1&#34;&gt;# Start download immediately&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;task&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;create_task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                                            &lt;span class=&#34;n&#34;&gt;download_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;session&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;output_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                                        &lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                   &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error processing response from &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Register response handler&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;response&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;handle_response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Navigate to the starting URL&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;book_url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;s2&#34;&gt;&#34;https://books.google.es/books?id=412loEMJA9sC&amp;amp;lpg=PP1&amp;amp;hl=es&amp;amp;pg=PA5&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;goto&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;book_url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Wait for initial page load&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wait_for_load_state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;networkidle&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Scroll loop variables&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;max_scroll_attempts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;500&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Safety limit&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;pages_before_scroll&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;

            &lt;span class=&#34;c1&#34;&gt;# Continue scrolling until we find no new pages for several consecutive attempts&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;max_scroll_attempts&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                &lt;span class=&#34;c1&#34;&gt;# Get current page count before scrolling&lt;/span&gt;
               &lt;span class=&#34;n&#34;&gt;pages_before_scroll&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                &lt;span class=&#34;c1&#34;&gt;# Use PageDown key to scroll&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;page&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keyboard&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;press&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PageDown&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;

                &lt;span class=&#34;c1&#34;&gt;# Wait for network activity&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

                &lt;span class=&#34;c1&#34;&gt;# Check if we found new pages after scrolling&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pages_before_scroll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;
                    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                        &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scroll &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: Found &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pages_before_scroll&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; new pages&#34;&lt;/span&gt;
                    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
                    &lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
                    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                       &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scroll &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;scroll_count&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: No new pages found (&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;consecutive_no_new_pages&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/5)&#34;&lt;/span&gt;
                    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scrolling complete. Found &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seen_pids&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; pages total.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;browser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;# Wait for any remaining downloads to complete&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Waiting for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; downloads to complete...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gather&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;download_tasks&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Download complete! Downloaded &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;page_counter&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; images.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#send-keystrokes-to-an-active-window&#34;&gt;Send keystrokes to an active window.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;subprocess&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;type&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Hello world!&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Return&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# press enter&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;key&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;ctrl+c&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;window_id&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;getactivewindow&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;xdotool&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;windowactivate&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;window_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#make-temporal-file&#34;&gt;Make temporal file.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;tempfile&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tempfile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;NamedTemporaryFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.tmp&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;w+&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;utf-8&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;# Enter commit message body. Lines starting with &#39;#&#39; will be ignored.&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;# Leave file empty to skip the body.&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;flush&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;call&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;editor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;seek&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;lines&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;temp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;readlines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gitpython&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/gitpython/&#34;&gt;GitPython&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/gitpython/#checking-out-an-existing-branch&#34;&gt;Checking out an existing branch.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;heads&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;heads&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;develop&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;heads&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;develop&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;repo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reference&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;develop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;elasticsearch&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/&#34;&gt;Elasticsearch&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/elasticsearch/#delete-documents-from-all-indices-in-an-elasticsearch-cluster&#34;&gt;Delete documents from all indices in an elasticsearch cluster.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;ES_HOST&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;:-&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;://localhost:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;9200&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;DEFAULT_SETTING&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;5&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Target default value (5%)&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;INDICES&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XGET&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_cat/indices?h=index&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INDEX&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDICES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Processing index: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Close the index to modify static settings&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_close&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Update expunge_deletes_allowed to 1%&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPUT&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_settings&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-H&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;    &#34;index.merge.policy.expunge_deletes_allowed&#34;: &#34;0&#34;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  }&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Reopen the index&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_open&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Trigger forcemerge (async)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# curl -s -XPOST &#34;$ES_HOST/$INDEX/_forcemerge?only_expunge_deletes=true&amp;amp;wait_for_completion=false&#34; &amp;gt; /dev/null&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Forcemerge triggered for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_forcemerge?only_expunge_deletes=true&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Waiting until all forcemerge tasks are done&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;/_cat/tasks&lt;span class=&#34;se&#34;&gt;\?&lt;/span&gt;v&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;forcemerge&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;/_cat/indices&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;sleep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Close the index again&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_close&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Update to the new default (5%)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPUT&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_settings&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-H&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Content-Type: application/json&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  {&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;    &#34;index.merge.policy.expunge_deletes_allowed&#34;: &#34;&#39;&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$DEFAULT_SETTING&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&#34;&lt;/span&gt;
&lt;span class=&#34;s1&#34;&gt;  }&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# Reopen the index&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-XPOST&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$ES_HOST&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$INDEX&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/_open&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Done! All indices updated.&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;coding-tools&#34;&gt;Coding tools&lt;/h3&gt; &lt;h4 id=&#34;gitea&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/&#34;&gt;Gitea&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#configure-triggers-not-to-push-to-a-branch&#34;&gt;Configure triggers not to push to a branch.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There is now a branches-ignore option:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;push&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;branches-ignore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#not-there-yet&#34;&gt;Not there yet.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/go-gitea/gitea/issues/32662&#34;&gt;Being able to run two jobs on the same branch&lt;/a&gt;: It will be implemented with &lt;a href=&#34;https://github.com/go-gitea/gitea/issues/24769&#34;&gt;concurrency&lt;/a&gt; with &lt;a href=&#34;https://github.com/go-gitea/gitea/pull/32751&#34;&gt;this pr&lt;/a&gt;. This behavior &lt;a href=&#34;https://github.com/go-gitea/gitea/pull/25716&#34;&gt;didn&#39;t happen before 2023-07-25&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h2&gt; &lt;h3 id=&#34;storage&#34;&gt;Storage&lt;/h3&gt; &lt;h4 id=&#34;openzfs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;OpenZFS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#list-all-datasets-that-have-zfs-native-encryption-&#34;&gt;List all datasets that have zfs native encryption.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;```bash ROOT_FS=&#34;main&#34; is_encryption_enabled() { zfs get -H -o value encryption $1 | grep -q &#39;aes&#39; }&lt;/p&gt; &lt;p&gt;list_datasets_with_encryption() {&lt;/p&gt; &lt;pre&gt;&lt;code&gt;# Initialize an array to hold dataset names
datasets=()

# List and iterate over all datasets starting from the root filesystem
for dataset in $(zfs list -H -o name | grep -E &#39;^&#39;$ROOT_FS&#39;/&#39;); do
    if is_encryption_enabled &#34;$dataset&#34;; then
        datasets+=(&#34;$dataset&#34;)
    fi
done

# Output the results
echo &#34;ZFS datasets with encryption enabled:&#34;
printf &#39;%s\n&#39; &#34;${datasets[@]}&#34;
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;list_datasets_with_encryption&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#cannot-destroy-dataset:-dataset-is-busy&#34;&gt;Troubleshoot cannot destroy dataset: dataset is busy.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re experiencing this error and can reproduce the next traces:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cannot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;destroy&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;zroot/2013-10-15T065955229209&#39;&lt;/span&gt;:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dataset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;busy

cannot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unmount&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;zroot/2013-10-15T065955229209&#39;&lt;/span&gt;:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;not&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;currently&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mounted

zroot/2013-10-15T065955229209&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;.86G&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;25&lt;/span&gt;.0G&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;.0G&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;/var/lib/heaver/instances/2013-10-15T065955229209

umount:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/lib/heaver/instances/2013-10-15T065955229209:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;not&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mounted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can &lt;code&gt;grep zroot/2013-10-15T065955229209 /proc/*/mounts&lt;/code&gt; to see which process is still using the dataset.&lt;/p&gt; &lt;p&gt;Another possible culprit are snapshots, you can then run:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;holds&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$snapshotname&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To see if it has any holds, and if so, &lt;code&gt;zfs release&lt;/code&gt; to remove the hold.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#upgrading-zfs-storage-pools&#34;&gt;Upgrading ZFS Storage Pools.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you have ZFS storage pools from a previous zfs release you can upgrade your pools with the &lt;code&gt;zpool upgrade&lt;/code&gt; command to take advantage of the pool features in the current release. In addition, the zpool status command has been modified to notify you when your pools are running older versions. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status

&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;pool:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;state:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ONLINE
status:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;The&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;formatted&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;an&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;older&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;on-disk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;format.&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;The&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;can
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;still&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;be&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;used,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;but&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;some&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;features&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;are&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;unavailable.
action:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;zpool upgrade&#39;&lt;/span&gt;.&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Once&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;this&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;will&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;no&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;longer&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;be&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;accessible&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;on&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;older&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;software&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;versions.
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scrub:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;none&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;requested
config:
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;NAME&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;STATE&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;READ&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;WRITE&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;CKSUM
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;tank&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;mirror-0&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;c1t0d0&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;c1t1d0&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;ONLINE&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
errors:&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;No&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;known&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;errors
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can use the following syntax to identify additional information about a particular version and supported releases:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v

This&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;system&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;is&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;currently&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;running&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ZFS&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;version&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;22&lt;/span&gt;.

The&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;following&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;versions&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;are&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;supported:

VER&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;DESCRIPTION
---&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;--------------------------------------------------------
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Initial&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ZFS&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;version
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Ditto&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blocks&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;replicated&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;metadata&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Hot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;spares&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;and&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;double&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;parity&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;RAID-Z
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;history&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Compression&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;gzip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;algorithm
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;bootfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;property
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Separate&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;intent&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devices
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;Delegated&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;administration
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;refquota&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;and&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;refreservation&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;properties
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Cache&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;devices
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Improved&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;scrub&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;performance
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;properties
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;13&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;snapused&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;property
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;passthrough-x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aclinherit
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;user/group&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;space&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;accounting
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;16&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;stmf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;property&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;support
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;17&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Triple-parity&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;RAID-Z
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;holds
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;19&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Log&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;device&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;removal
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Compression&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;using&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zle&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;zero-length&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;encoding&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Reserved
&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;22&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;Received&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;properties

For&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;more&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;information&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;on&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;particular&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;version,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;including&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;supported&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;releases,
see&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;the&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ZFS&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Administration&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Guide.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then, you can run the zpool upgrade command to upgrade all of your pools. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;Linux&lt;/h3&gt; &lt;h4 id=&#34;dunst&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dunst/&#34;&gt;dunst&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Tweak installation steps.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libdbus-1-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libx11-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxinerama-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxrandr-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxss-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libglib2.0-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;libpango1.0-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libgtk-3-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libxdg-basedir-dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;libgdk-pixbuf-2.0-dev

make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;WAYLAND&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;make&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;WAYLAND&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; If it didn&#39;t create the systemd service you can &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#create-a-systemd-service-for-a-non-root-user&#34;&gt;create it yourself&lt;/a&gt; with this service file&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Dunst notification daemon&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Documentation&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;man:dunst(1)&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;PartOf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;dbus&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;BusName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;org.freedesktop.Notifications&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/local/bin/dunst&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Slice&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;session.slice&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;default.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You may need to add more paths to PATH.&lt;/p&gt; &lt;p&gt;To see the logs of the service use &lt;code&gt;journalctl --user -u dunst.service -f --since &#34;15 minutes ago&#34;&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/dunst/#configuration&#34;&gt;Configuration.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Read and tweak the &lt;code&gt;~/.dunst/dunstrc&lt;/code&gt; file to your liking. You have the &lt;a href=&#34;https://github.com/dunst-project/dunst/blob/master/dunstrc&#34;&gt;default one here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You&#39;ll also need to configure the actions in your window manager. In my case &lt;a href=&#34;https://lyz-code.github.io/blue-book/i3wm/&#34;&gt;i3wm&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bindsym $mod+b exec dunstctl close-all
bindsym $mod+v exec dunstctl context
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/dunst/#configure-each-application-notification&#34;&gt;Configure each application notification.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can look at &lt;a href=&#34;https://gist.github.com/rosoau/fdfa7b3e37e3c5c67b7dad1b7257236e&#34;&gt;rosoau config&lt;/a&gt; for inspiration&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; * &lt;a href=&#34;https://github.com/dunst-project/dunst/issues/826&#34;&gt;Some dunst configs&lt;/a&gt; * Smarttech101 tutorials (&lt;a href=&#34;https://smarttech101.com/how-to-configure-dunst-notifications-in-linux-with-images&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://smarttech101.com/how-to-send-notifications-in-linux-using-dunstify-notify-send#Taking_Actions_on_notifications_using_dunstifynotify-send&#34;&gt;2&lt;/a&gt;) * &lt;a href=&#34;https://wiki.archlinux.org/title/Dunst&#34;&gt;Archwiki page on dunst&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#use-lftp&#34;&gt;Use lftp.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Connect with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;lftp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;port&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user@host
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Navigate with &lt;code&gt;ls&lt;/code&gt; and &lt;code&gt;cd&lt;/code&gt;. Get with &lt;code&gt;mget&lt;/code&gt; for multiple things&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#difference-between-apt-get-upgrate-and-apt-get-full-upgrade&#34;&gt;Difference between apt-get upgrate and apt-get full-upgrade.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The difference between &lt;code&gt;upgrade&lt;/code&gt; and &lt;code&gt;full-upgrade&lt;/code&gt; is that the later will remove the installed packages if that is needed to upgrade the whole system. Be extra careful when using this command&lt;/p&gt; &lt;p&gt;I will more frequently use &lt;code&gt;autoremove&lt;/code&gt; to remove old packages and then just use &lt;code&gt;upgrade&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#upgrade-debian&#34;&gt;Upgrade debian.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;full-upgrade

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vi&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/sources.list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/apt/sources.list.d/*

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;clean
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;full-upgrade

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;autoremove

sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;shutdown&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;now
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-a-list-of-extensions-by-file-type&#34;&gt;Get a list of extensions by file type.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There are community made lists such as &lt;a href=&#34;https://github.com/dyne/file-extension-list/&#34;&gt;dyne&#39;s file extension list&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#upgrade-ubuntu&#34;&gt;Upgrade ubuntu.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Upgrade your system:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;update
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;upgrade
reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You must install ubuntu-release-upgrader-core package:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ubuntu-release-upgrader-core
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Ensure the Prompt line in &lt;code&gt;/etc/update-manager/release-upgrades&lt;/code&gt; is set to ‘lts‘ using the “grep” or “cat”&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;lts&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/update-manager/release-upgrades
cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/update-manager/release-upgrades
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Opening up TCP port 1022&lt;/p&gt; &lt;p&gt;For those using ssh-based sessions, open an additional SSH port using the ufw command, starting at port 1022. This is the default port set by the upgrade procedure as a fallback if the default SSH port dies during upgrades.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sbin/iptables&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-I&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;INPUT&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tcp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--dport&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1022&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-j&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ACCEPT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Finally, start the upgrade from Ubuntu 22.04 to 24.04 LTS version. Type:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;-release-upgrade&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;i3wm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/i3wm/&#34;&gt;i3wm&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add i3wm python actions.&lt;/p&gt; &lt;p&gt;You can also use it &lt;a href=&#34;https://i3ipc-python.readthedocs.io/en/latest/&#34;&gt;with async&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Create the connection object&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;i3ipc&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Event&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Focus on a window by it&#39;s class&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;i3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_tree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ff&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tree&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;find_classed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Firefox&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;ff&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;focus&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;wireguard&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/&#34;&gt;Wireguard&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#39;../../linux/wireguard/#failed-to-resolve-interface-&#34;tun&#34;:-no-such-device&#39;&gt;Troubleshoot Failed to resolve interface &#34;tun&#34;: No such device.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;purge&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;resolvconf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;calistenia&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/calistenia/&#34;&gt;Calistenia&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce calistenia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Técnica básica&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dominadas&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=3nSaIugxv7Y&#34;&gt;Video tutorial de jéssica martín&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Vídeos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;+- &lt;a href=&#34;https://www.youtube.com/@jessmartinm&#34;&gt;Jéssica Martín Moreno&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;science&#34;&gt;Science&lt;/h2&gt; &lt;h3 id=&#34;artificial-intelligence&#34;&gt;Artificial Intelligence&lt;/h3&gt; &lt;h4 id=&#34;ocr&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ocr/&#34;&gt;OCR&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add ocr references.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.reddit.com/r/LocalLLaMA/comments/1javx8d/what_is_the_best_llm_based_ocr_open_source/&#34;&gt;What is the best LLM based OCR open source available now? &lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;birding&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/birding/&#34;&gt;Birding&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce android apps for birding.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;whoBIRD&lt;/li&gt; &lt;li&gt;Merlin Bird ID: I&#39;ve seen it working and it&#39;s amazing, I&#39;m however trying first whoBIRD as it&#39;s in F-droid&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;April 30, 2025 06:50:49 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-04-30T06:50:49+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;April 30, 2025 06:50:49 UTC&#34;&gt;2025-04-30&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_04_29/</link>
      <pubDate>2025-04-30 06:50:49+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_04_29/</guid>
      
    </item>
    
    <item><title>18th March 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;activism&#34;&gt;Activism&lt;/h2&gt; &lt;h3 id=&#34;hacktivism&#34;&gt;Hacktivism&lt;/h3&gt; &lt;h4 id=&#34;mobile-verification-toolkit&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mobile_verification_toolkit/&#34;&gt;Mobile Verification Toolkit&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mobile_verification_toolkit/#other-tools-for-similar-purpose&#34;&gt;Other tools for similar purpose.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.eff.org/deeplinks/2025/03/meet-rayhunter-new-open-source-tool-eff-detect-cellular-spying&#34;&gt;Rayhunter&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;deteccion-de-estupas&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/estupas/&#34;&gt;Detección de estupas&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Malditos estupas.&lt;/p&gt; &lt;p&gt;Los estupas (o infiltrados) son de los peores cuerpos de represión del estado. No sólo porque extraen información de los colectivos sino porque generan un ambiente de desconfianza y miedo que muchas veces es paralizante o incluso desarticula los propios colectivos. De la peor escoria de la sociedad...&lt;/p&gt; &lt;p&gt;Por desgracia, en el estado español &lt;a href=&#34;https://www.elsaltodiario.com/montajes-policiales&#34;&gt;está bastante de moda&lt;/a&gt;. Por suerte no estamos desamparadas, varias compañeras están generando materiales para familiarizarnos con este problema. Desde el documental &lt;a href=&#34;https://www.3cat.cat/3cat/infiltrats/video/6319194/&#34;&gt;Infiltrats&lt;/a&gt; hasta el &lt;a href=&#34;https://doscuadrados.es/colaboraciones.html&#34;&gt;Manual para destapar a un infiltrado&lt;/a&gt; (puedes ver &lt;a href=&#34;https://www.elsaltodiario.com/represion/manual-infiltrado-policial-espionaje-policia-directa&#34;&gt;el artículo del salto sobre el manual&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;Probablemente estos desgraciados adaptarán sus modos de hacer para pasar estas detecciones, pero al menos los movimientos sociales ya tenemos una base formal sobre la que trabajar.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://doscuadrados.es/colaboraciones.html&#34;&gt;Manual para destapar a un infiltrado&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;conference-organisation&#34;&gt;Conference organisation&lt;/h3&gt; &lt;h4 id=&#34;pretalx&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/&#34;&gt;pretalx&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/#references&#34;&gt;Add references for pretalx.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://pretalx.com/p/about/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pretalx/pretalx&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-navigation&#34;&gt;Life navigation&lt;/h2&gt; &lt;h3 id=&#34;time-navigation&#34;&gt;Time navigation&lt;/h3&gt; &lt;h4 id=&#34;identities&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/identities/&#34;&gt;Identities&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the time navigation abstract identity concept.&lt;/p&gt; &lt;p&gt;An &lt;a href=&#34;https://en.m.wikipedia.org/wiki/Identity_%28social_science%29&#34;&gt;identity&lt;/a&gt; is the set of qualities, beliefs, personality traits, appearance, and/or expressions that characterize a person or a group.&lt;/p&gt; &lt;p&gt;Identity serves multiple functions, acting as a &#34;self-regulatory structure&#34; that provides meaning, direction, and a sense of self-control. It fosters internal harmony and serves as a behavioral compass, enabling individuals to orient themselves towards the future and establish long-term goals. As an active process, it profoundly influences an individual&#39;s capacity to adapt to life events and achieve a state of well-being. However, identity originates from traits or attributes that you may have little or no control over, such as their family background or ethnicity.&lt;/p&gt; &lt;p&gt;Identities then will be the guide of my life. I&#39;ve tried setting essential goals, answering big questions with no success so far. This approach however looks more interesting because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;I can split myself in many identities each with it&#39;s definition and analyse life through the different lenses, identify identity conflicts, priorize identities...&lt;/li&gt; &lt;li&gt;I can analyse each identity on it&#39;s own, decide how to change my roadmap to integrate the ones I want to adopt and get away from the ones I want to leave behind.&lt;/li&gt; &lt;li&gt;It reminds me of the RPG character building and although it may seem silly, that motivates me.&lt;/li&gt; &lt;li&gt;It fits quite well with what I&#39;ve learnt regarding &lt;a href=&#34;https://lyz-code.github.io/blue-book/habit_management/&#34;&gt;habit management&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;The identities archive&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I&#39;m using a new notebook page called &lt;code&gt;identities.org&lt;/code&gt; where I plan to analyze, build and evolve my identities.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;An identity section&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Each identity may have the next sections. A simple heading with the name of the identity is just fine. You&#39;ll create the sections as long as you need them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Analysis of the identity&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here we can develop our thoughts on what does the identity mean and what do you see yourself embodying the identity&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Identity characteristics&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;List the values, habits, abilities, knowledge, capabilities and experiences that define the identity, and analyse each of them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Identity plan&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Here is where we can sketch the plan we want to follow to grow or shrink this identity. It contains a list of &lt;a href=&#34;https://lyz-code.github.io/blue-book/axis/&#34;&gt;identity axis&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Children identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Sometimes an identity can be refined in smaller more specific identities, here we&#39;ll add sections for each of them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Identity analysis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dump your thoughts on your identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Before we get tainted with our past analysis imagine a fresh canvas and start painting yourself.&lt;/p&gt; &lt;p&gt;You can add a section in &lt;code&gt;think.org&lt;/code&gt; to record your findings. I found that I needed some time to do this dump, working on the section through days before the actual analysis.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Do an initial list of values&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I first created a &lt;code&gt;global values or principles&lt;/code&gt; headline and listed all core principles such as:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All creatures are beautiful&lt;/li&gt; &lt;li&gt;Be excellent to each other&lt;/li&gt; &lt;li&gt;Better done than perfect&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You may refactor them into the identities once you start building them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Do an initial list of identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Empty your mind of the different identities that define you or that you want to be defined by. Create headlines for each using the sections defined above as you need them.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Do an initial list of axis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Dream of what &lt;a href=&#34;https://lyz-code.github.io/blue-book/axis/&#34;&gt;axis&lt;/a&gt; you&#39;ll want to address. If you can order them into identities.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Do the identity analysis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Refactor the gathered thoughts into the &lt;code&gt;identities.org&lt;/code&gt; file&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Select the identities you want to prioritise in the year&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Skim over all identities and for the ones you want to focus in the year:&lt;/li&gt; &lt;li&gt;add the &lt;code&gt;identity&lt;/code&gt; tag&lt;/li&gt; &lt;li&gt;assign a priority&lt;/li&gt; &lt;li&gt;do not add a TODO keyword, we&#39;ll reserve them for the identity axis.&lt;/li&gt; &lt;li&gt;Use the year custom agenda &lt;code&gt;identities&lt;/code&gt; section to adjust the priority of the different identities following the next guides:&lt;/li&gt; &lt;li&gt;Spread the identities over the different priorities so that each has more less the same number of elements.&lt;/li&gt; &lt;li&gt;Compare an identity with the ones that are above or below and decide if you promote or demote it&lt;/li&gt; &lt;li&gt;If you don&#39;t want one identity to bien the list add the &lt;code&gt;backlog&lt;/code&gt; tag if you don&#39;t want that identity and it&#39;s subidentities to appear. Add the &lt;code&gt;hide&lt;/code&gt; tag in case you want any of the subidentities&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Refine the identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Following the priority order of identities go one by one until you run out of time and:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Read the identity analysis and the different &lt;a href=&#34;https://lyz-code.github.io/blue-book/axis/&#34;&gt;axis&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;Order the different axis by the impact they can have in the identity&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/axis/&#34;&gt;Refine the projects of each axis&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;axis&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/axis/&#34;&gt;Axis&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the axis time navigation concept.&lt;/p&gt; &lt;p&gt;An identity axis is an abstract guide for action with an indefinite scope or a timeframe longer than one year. It serves as a high-level directional tool to materialise changes in your &lt;a href=&#34;https://lyz-code.github.io/blue-book/identities/&#34;&gt;identities&lt;/a&gt;, helping to outline a general course without specifying exact destinations.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Limitations of an axis&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It is not suitable as a final destination on a roadmap because it is too ambiguous.&lt;/li&gt; &lt;li&gt;Even minor progress could be considered sufficient, leading to a lack of clear endpoints.&lt;/li&gt; &lt;li&gt;One could continue indefinitely without a sense of completion, such as continuously striving for improvement.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Axis orgmode representation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;An axis is a headline or TODO headline (depending whether it&#39;s active or not) that is part of the &lt;code&gt;plan&lt;/code&gt; section of an &lt;a href=&#34;https://lyz-code.github.io/blue-book/identities/&#34;&gt;identity&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;It can have none or many of the next sections:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Axis analysis section&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To gather the thoughts regarding the study of the axis&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Axis plan section&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To gather the axis projects that will materialise the direction of the axis.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Axis projects&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To prevent endless pursuit, an axis should be broken down into projects with defined scopes that indicate when to stop advancing in that direction.&lt;/p&gt; &lt;p&gt;Axis projects shall:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Have a scope shorter than 11 months so they can be managed in the life stage review.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Depending on whether the axis projects will be acted upon in the current quarter they will have two possible representations:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If you don&#39;t plan to it will be a project section with the análisis, and steps&lt;/li&gt; &lt;li&gt;If you do, then it will be a link to the project section either in &lt;code&gt;projects.org&lt;/code&gt; or in &lt;code&gt;backlog.org&lt;/code&gt;. You can leave the analysis section below the link in &lt;code&gt;identities.org&lt;/code&gt; that way it won&#39;t use precious space in your &lt;code&gt;projects.org&lt;/code&gt; file.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;roadmap-adjustment&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/&#34;&gt;Roadmap Adjustment&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#life-stage-roadmap-adjustment&#34;&gt;Life stage roadmap adjustment adjustments.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Review what you&#39;ve done the last year&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Read your &lt;code&gt;logbook.org&lt;/code&gt; (o &lt;code&gt;bitácora.org&lt;/code&gt;) adjusting the priorities of the áreas, projects and actions thinking of the impact the element has meant in your live.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Review what you&#39;ve learn the last year&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It&#39;s always interesting to look back and see what you&#39;ve learned throughout the year. I have these sources of data:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;#digital-garden&#34;&gt;Digital garden&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you happen to have a &lt;a href=&#34;https://lyz-code.github.io/blue-book/digital_garden/&#34;&gt;digital garden&lt;/a&gt; you can look at your git history to know what has changed since the last year. That&#39;s cumbersome and ugly though, it&#39;s better to review &lt;a href=&#34;https://lyz-code.github.io/blue-book/newsletter/0_newsletter_index/&#34;&gt;your newsletters&lt;/a&gt;, although you may need to use something like &lt;a href=&#34;https://lyz-code.github.io/mkdocs-newsletter/&#34;&gt;&lt;code&gt;mkdocs-newsletter&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;While you skim through the newsletters you can add to the analysis report the highlights of what you&#39;ve learned.&lt;/p&gt; &lt;p&gt;You can also check &lt;a href=&#34;https://lyz-code.github.io/blue-book/git/#get-interesting-stats-of-the-repo&#34;&gt;your repository insights&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;#anki&#34;&gt;Anki&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I use &lt;a href=&#34;https://lyz-code.github.io/blue-book/anki/&#34;&gt;&lt;code&gt;anki&lt;/code&gt;&lt;/a&gt; to record the knowledge that I need to have in my mind. The program has a &#34;Stats&#34; tab where you can see your insights of the last years to understand how are you learning. You can also go to the &#34;Browse&#34; tab to sort the cards by created and get an idea of which ones have been the most used decks.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Review what programs you have developed&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Update your identities&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Follow the steps of &lt;a href=&#34;https://lyz-code.github.io/blue-book/identities/#identity-management&#34;&gt;identity management&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;content-management&#34;&gt;Content Management&lt;/h3&gt; &lt;h4 id=&#34;book-drm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/book_drm/&#34;&gt;Book DRM&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: How to remove DRM from ebooks.&lt;/p&gt; &lt;p&gt;To remove the DRM from ebooks you can use &lt;a href=&#34;https://github.com/noDRM/DeDRM_tools&#34;&gt;DeDRM_tools&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You need to download &lt;a href=&#34;https://github.com/noDRM/DeDRM_tools/releases&#34;&gt;the latest release&lt;/a&gt;, and follow the instructions of the README.md of the zip file.o&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Once the plugin is installed, you can import the books you want to remove the DRM from. In theory the plugin only works on import and not on convert, but I&#39;ve also used the convert tool to make sure it&#39;s a different file.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;health&#34;&gt;Health&lt;/h2&gt; &lt;h3 id=&#34;silence&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/silence/&#34;&gt;Silence&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/silence/#resources&#34;&gt;Introduce the Right to quiet collective.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://quiet.org/&#34;&gt;Right to quiet&lt;/a&gt;: The Right to Quiet Society for Soundscape Awareness and Protection was founded in Vancouver, British Columbia in 1982 as a charitable organization with the mission of raising public awareness of the detrimental effects of noise on health; promoting awareness of noise pollution and the dangers of noise to our physical, emotional, and spiritual wellbeing; working for noise reduction through better regulation and enforcement; encouraging responsible behaviour regarding noise; advocating for manufacturing quieter products; and fostering recognition of the right to quiet as a basic human right, rather than as an amenity for the affluent.&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://quiet.org/resources/&#34;&gt;Right to quiet resources&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;coding-tools&#34;&gt;Coding tools&lt;/h3&gt; &lt;h4 id=&#34;vim-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_snippets/&#34;&gt;Vim Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_snippets/#search-for-different-strings-in-the-same-search-query&#34;&gt;Search for different strings in the same search query.&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gitea&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/&#34;&gt;Gitea&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#configuration&#34;&gt;Configure gitea.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Check the &lt;a href=&#34;https://docs.gitea.com/administration/config-cheat-sheet&#34;&gt;configuration sheet&lt;/a&gt; or the &lt;a href=&#34;https://github.com/go-gitea/gitea/blob/release/v1.23/custom/conf/app.example.ini&#34;&gt;default values&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#upgrade-the-gitea-actions-runner&#34;&gt;Upgrade the gitea actions runner.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check in &lt;a href=&#34;https://gitea.com/gitea/act_runner/releases&#34;&gt;the releases&lt;/a&gt; the last version and the changelog&lt;/li&gt; &lt;li&gt;Deploy the new version&lt;/li&gt; &lt;li&gt;Restart the service&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gitea/#upgrade&#34;&gt;Upgrade gitea.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check the Changelog for breaking changes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To make Gitea better, some breaking changes are unavoidable, especially for big milestone releases. Before upgrading, please read the &lt;a href=&#34;https://blog.gitea.com/&#34;&gt;Changelog on Gitea blog&lt;/a&gt; and check whether the breaking changes affect your Gitea instance.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Verify there are no deprecated configuration options&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;New versions of Gitea often come with changed configuration syntax or options which are usually displayed for at least one release cycle inside at the top of the Site Administration panel. If these warnings are not resolved, Gitea may refuse to start in the following version.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Make a backup&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.gitea.com/installation/upgrade-from-gitea#upgrade-with-docker&#34;&gt;Upgrade from docker&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;docker pull the latest Gitea release.&lt;/li&gt; &lt;li&gt;Stop the running instance, backup data.&lt;/li&gt; &lt;li&gt;Use docker or docker-compose to start the newer Gitea Docker container.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.gitea.com/installation/upgrade-from-gitea#upgrade-from-binary&#34;&gt;Upgrade from binary&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A script automating the following steps for a deployment on Linux can be found at &lt;a href=&#34;https://raw.githubusercontent.com/go-gitea/gitea/refs/heads/release/v1.23/contrib/upgrade.sh&#34;&gt;contrib/upgrade.sh&lt;/a&gt; in Gitea&#39;s source tree.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Download the latest Gitea binary to a temporary directory.&lt;/li&gt; &lt;li&gt;Stop the running instance, backup data.&lt;/li&gt; &lt;li&gt;Replace the installed Gitea binary with the downloaded one.&lt;/li&gt; &lt;li&gt;Start the Gitea instance.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Read the script to see what it&#39;s going to do. To upgrade to &lt;code&gt;1.20.5&lt;/code&gt; you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./update.sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;.20.5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you have a different home directory for gitea you can set&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;giteahome&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/var/gitea&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;./update.sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;.20.5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h2&gt; &lt;h3 id=&#34;infrastructure-solutions&#34;&gt;Infrastructure Solutions&lt;/h3&gt; &lt;h4 id=&#34;kubernetes&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/&#34;&gt;Kubernetes&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubernetes/kubernetes/#optimizing-kubernetes-cluster-node-count:-a-strategic-approach&#34;&gt;Optimizing Kubernetes Cluster Node Count: A Strategic Approach.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Reducing the number of nodes in a Kubernetes cluster is a critical strategy for controlling cloud infrastructure costs without compromising system reliability. Here are key best practices to help organizations right-size their Kubernetes deployments:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1. Availability Zone Consolidation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Carefully evaluate the number of availability zones (AZs) used in your cluster. While multi-AZ deployments provide redundancy, using too many zones can: - Increase infrastructure complexity - Raise management overhead - Unnecessarily distribute resources - Increase cost without proportional benefit&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;: Aim for a balanced approach, typically 3 AZs, which provides robust redundancy while allowing more efficient resource consolidation.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2. Intelligent Node Sizing and Management&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Implement sophisticated node management strategies:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Node Provisioning Optimization&lt;/strong&gt; - Use tools like Karpenter to dynamically manage node sizing - Continuously analyze and adjust node types based on actual workload requirements - Consolidate smaller nodes into fewer, more efficiently sized instances&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Overhead Calculation&lt;/strong&gt; Regularly assess system and Kubernetes overhead: - Calculate total system resource consumption - Identify underutilized resources - Understand the overhead percentage for different node types - Make data-driven decisions about node scaling&lt;/p&gt; &lt;p&gt;&lt;strong&gt;3. Advanced Pod Autoscaling Techniques&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Horizontal Pod Autoscaling (HPA)&lt;/strong&gt; - Implement HPA for workloads with variable load - Automatically adjust pod count based on CPU/memory utilization - Ensure efficient resource distribution across existing nodes&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Vertical Pod Autoscaling (VPA)&lt;/strong&gt; - Use VPA in recommendation mode initially - Carefully evaluate automated resource adjustments - Manually apply recommendations to prevent potential service disruptions&lt;/p&gt; &lt;p&gt;&lt;strong&gt;4. Workload Optimization Strategies&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;High Availability Considerations&lt;/strong&gt; - Ensure critical workloads have robust high availability configurations - Design applications to tolerate node failures gracefully - Implement pod disruption budgets to maintain service reliability&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Resource Right-Sizing&lt;/strong&gt; - Conduct thorough analysis of actual resource utilization - Avoid over-provisioning by matching resource requests to actual usage - Use monitoring tools to gain insights into workload characteristics&lt;/p&gt; &lt;p&gt;&lt;strong&gt;5. Continuous Monitoring and Refinement&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Implement comprehensive monitoring of cluster performance&lt;/li&gt; &lt;li&gt;Regularly review node utilization metrics&lt;/li&gt; &lt;li&gt;Create feedback loops for continuous optimization&lt;/li&gt; &lt;li&gt;Develop scripts or use tools to collect and analyze resource usage data&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;continuous-deployment&#34;&gt;Continuous Deployment&lt;/h3&gt; &lt;h4 id=&#34;argocd&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/&#34;&gt;ArgoCD&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#argocd-commandline-installation&#34;&gt;ArgoCD commandline installation.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-sSL&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;argocd-linux-amd64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-m&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;555&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;argocd-linux-amd64&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.local/bin/argocd
rm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;argocd-linux-amd64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#argocd-commandline-usage&#34;&gt;ArgoCD commandline usage.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://codefresh.io/learn/argo-cd/argo-cd-cli-commands-and-best-practices/&#34;&gt;Login into the server&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;argocd login&lt;/code&gt; command is the first step in interacting with the Argo CD API. This command allows you to authenticate yourself, setting up a secure connection between your terminal and the Argo CD server. You’ll need to provide your server’s URL and your credentials. There are three different ways to login, I found that the &lt;code&gt;--core&lt;/code&gt; is the most useful as it will use your kubernetes credentials.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;login&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;your.argocd.url.com&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--core&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;production
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Be careful thought that you can&#39;t set different &lt;code&gt;argocd context&lt;/code&gt; for different clusters using the &lt;code&gt;--core&lt;/code&gt; even though &lt;a href=&#34;https://github.com/argoproj/argo-cd/issues/12883&#34;&gt;you set the &lt;code&gt;--kube-context&lt;/code&gt; flag&lt;/a&gt;. The config file &lt;code&gt;~/.config/argocd/config&lt;/code&gt; shows that it&#39;s using whatever kubernetes context you&#39;re using. So be careful that you&#39;re applying it in the correct one!&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Set an argocd context&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;argocd context&lt;/code&gt; command is used to manage your Argo CD contexts. A context is a configuration that represents a Kubernetes cluster, user, and namespace. You can use this command to switch Argo CD between different contexts, allowing you to manage multiple Kubernetes namespaces and clusters from a single terminal.&lt;/p&gt; &lt;p&gt;You can see the different contexts with &lt;code&gt;argocd context&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Get the list of applications&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Refresh an application&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app_name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--refresh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Show the diff of an application&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;diff&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app_name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Sync an application&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;argocd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sync&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;app_name
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#not-there-yet&#34;&gt;More not there yet features.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Python library: I have found none&lt;/li&gt; &lt;li&gt;Argocd TUI: I have found none that is updated&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;automating-processes&#34;&gt;Automating Processes&lt;/h3&gt; &lt;h4 id=&#34;renovate&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/&#34;&gt;renovate&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/#configuration&#34;&gt;Configure renovate.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.renovatebot.com/configuration-options/#automerge&#34;&gt;automerge&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;By default, Renovate raises PRs but leaves them to someone or something else to merge them. By configuring this setting, you allow Renovate to automerge PRs or even branches. Using automerge reduces the amount of human intervention required.&lt;/p&gt; &lt;p&gt;Usually you won&#39;t want to automerge all PRs, for example most people would want to leave major dependency updates to a human to review first. You could configure Renovate to automerge all but major this way:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;packageRules&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;matchUpdateTypes&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;minor&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;patch&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;pin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;digest&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;automerge&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Also note that this option can be combined with other nested settings, such as dependency type. So for example you could choose to automerge all (passing) devDependencies only this way:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;packageRules&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;matchDepTypes&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;devDependencies&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;automerge&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configure docker version extraction&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/renovatebot/renovate/discussions/18190&#34;&gt;Ansible Manager Docker-type dependency extraction · renovatebot/renovate · Discussion #18190 · GitHub&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.renovatebot.com/modules/manager/ansible/&#34;&gt;Automated Dependency Updates for Ansible - Renovate Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/renovatebot/renovate/issues/3720&#34;&gt;Pin packages in ansible roles · Issue #3720 · renovatebot/renovate&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/renovatebot/renovate/issues/4635&#34;&gt;Support default environment variable values in docker-compose · Issue #4635 · renovatebot/renovate&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/renovatebot/renovate/issues/31685&#34;&gt;Support docker-compose.yml versions from .env files · Issue #31685 · renovatebot/renovate&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Combine all updates to one branch/PR&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.renovatebot.com/presets-group/#groupallnonmajor&#34;&gt;Group Presets - Renovate Docs group all non major&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://docs.renovatebot.com/presets-group/#groupall&#34;&gt;Group Presets - Renovate Docs group all&lt;/a&gt;&lt;/li&gt; &lt;li&gt; &lt;h3 id=&#34;config-renovate-combine-all-updates-to-one-branchpr-stack-overflow&#34;&gt;&lt;a href=&#34;https://stackoverflow.com/questions/66471226/renovate-combine-all-updates-to-one-branch-pr&#34;&gt;config - Renovate: Combine all updates to one branch/PR - Stack Overflow&lt;/a&gt;&lt;/h3&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/#references&#34;&gt;Add upgrade notes.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.renovatebot.com/release-notes-for-major-versions/&#34;&gt;Upgrade notes&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;storage&#34;&gt;Storage&lt;/h3&gt; &lt;h4 id=&#34;openzfs-storage-planning&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_storage_planning/&#34;&gt;OpenZFS storage planning&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add link tot he backblaze disk reports.&lt;/p&gt; &lt;p&gt;If you have some time take a look at &lt;a href=&#34;https://www.backblaze.com/cloud-storage/resources/hard-drive-test-data&#34;&gt;backblaze disk reports&lt;/a&gt; they do quarterly analysis on their infra (around 300k disks).&lt;/p&gt; &lt;p&gt;@@ -26,6 +26,7 @@ nav: - Feminism: - Privileges: feminism/privileges.md - Palestine: palestine.md + - Detección de estupas: estupas.md - Anarchism: anarchism.md - Memoria histórica: memoria_historica.md - Anti-Tourism: antitourism.md @@ -33,19 +34,22 @@ nav: - Free Knowledge: free_knowledge.md - Free Software: free_software.md - Environmentalism: environmentalism.md - - Laboral: - - laboral.md - - Trabajadoras del hogar: trabajadoras_del_hogar.md + - Laboral: + - laboral.md + - Trabajadoras del hogar: trabajadoras_del_hogar.md - Collaborating tools: collaborating_tools.md - Conference organisation: - conference_organisation.md - pretalx: pretalx.md - - Ludditest: luddites.md - - Life Management: + - Luddites: luddites.md + - Life navigation: - life_management.md - - Time management: + - Time navigation: - time_management.md - - Time management abstraction levels: time_management_abstraction_levels.md + - Time navigation abstraction levels: + - time_management_abstraction_levels.md + - Identities: identities.md + - Axis: axis.md - Action Management: action_management.md - Roadmap Adjustment: - roadmap_adjustment.md @@ -134,6 +138,7 @@ nav: - Book Management: - book_management.md - Bookwyrm: bookwyrm.md + - Book DRM: book_drm.md - Movies Management: - Jellyfin: jellyfin.md - Ombi: ombi.md @@ -196,6 +201,7 @@ nav: - Teeth: - teeth.md - Deep cleaning: teeth_deep_cleaning.md + - Silence: silence.md - Remote Working: remote_work.md - Fitness Tracker: - fitness_band.md @@ -649,6 +655,8 @@ nav: - fail2ban: linux/fail2ban.md - pass: pass.md - Wireshark: wireshark.md + - Canary tokens: canary_tokens.md + - Sysadmin tools: - brew: linux/brew.md - detox: detox.md @@ -753,6 +761,7 @@ nav: - Speech to text: - Whisper: whisper.md - Speech recognition: speech_recognition.md + - Text to speech: text_to_speech.md - Coding by Voice: coding_by_voice.md - Data Analysis: - data_analysis.md&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;openzfs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;OpenZFS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#replacing-a-disk-in-the-pool&#34;&gt;Replacing a disk in the pool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;If the pool is not DEGRADED&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you want to do operations on your pool and want to prevent it from being DEGRADED you need to attach a new disk to the server and use the replace command&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zfs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;replace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ata-WDC_WD2003FZEX-00SRLA0_WD-xxxxxxxxxxxx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdX
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Where &lt;code&gt;/dev/sdX&lt;/code&gt; is your temporal disk. Once the original disk is removed from the vdev you can do the operations you need.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#removing-a-disk-from-the-pool&#34;&gt;Removing a disk from the pool.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remove&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will trigger the data evacuation from the disk. Check &lt;code&gt;zpool status&lt;/code&gt; to see when it finishes.&lt;/p&gt; &lt;p&gt;Sometimes zfs won&#39;t allow you to remove a disk if it will put at risk the pool. In that case try to replace a disk in the pool as explained above.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;Linux&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#download-videos-from-rtve.es&#34;&gt;Download videos from rtve.es.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;a href=&#34;https://www.descargavideos.tv/&#34;&gt;descargavideos.tv&lt;/a&gt; (&lt;a href=&#34;https://github.com/forestrf/Descargavideos&#34;&gt;source&lt;/a&gt;)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#check-if-a-domain-is-in-a-list-of-known-disposable-email-domains&#34;&gt;Check if a domain is in a list of known disposable email domains.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can check in known lists &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://raw.githubusercontent.com/andreis/disposable-email-domains/master/domains.txt
grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;homapin.com&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;domains.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;Or using web services that either use the IPs (obtained by whois/dig)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://www.blocklist.de/en/search.html?ip=142.132.166.12&amp;amp;action=search&amp;amp;send=start+search 👍
https://www.blocklist.de/en/search.html?ip=188.166.111.252&amp;amp;action=search&amp;amp;send=start+search 👍
https://www.blocklist.de/en/search.html?ip=46.101.111.206&amp;amp;action=search&amp;amp;send=start+search 👍
https://www.blocklist.de/en/search.html?ip=116.202.9.167&amp;amp;action=search&amp;amp;send=start+search 👍
https://check.spamhaus.org/results/?query=homapin.com 👍
https://verifymail.io/domain/homapin.com 👎
https://www.ipqualityscore.com/domain-reputation/homapin.com 👎
https://quickemailverification.com/tools/disposable-email-address-detector for
  - homapin.com 👎
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#mount-a-cdrom-or-dvd&#34;&gt;Mount a cdrom or dvd.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;TL;DR: The syntax is as follows for the mount command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mount&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;iso9660&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ro&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/deviceName&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/path/to/mount/point
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Use the following command to find out the name Of DVD / CD-ROM / Writer / Blu-ray device on a Linux based system:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;lsblk
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;OR use the combination of the dmesg command and grep/egrep as follow to print your CD/DVD device name. For example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dmesg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-E&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--color&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;cdrom|dvd|cd/rw|writer&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Sample outputs indicating that the /dev/sr0 is my device name:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[    5.437164] sr0: scsi3-mmc drive: 24x/24x writer dvd-ram cd/rw xa/form2 cdda tray
[    5.437307] cdrom: Uniform CD-ROM driver Revision: 3.20
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Create a mount point, type mkdir command as follows:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/mnt/cdrom
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Mount the /dev/cdrom or /dev/sr0 as follows:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mount&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;iso9660&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ro&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/cdrom&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/mnt/cdrom
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;canary-tokens&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/canary_tokens/&#34;&gt;Canary tokens&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce Canary tokens.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.canarytokens.org/nest/&#34;&gt;Canary tokens&lt;/a&gt; are like motion sensors for your networks, computers and clouds. You can put them in folders, on network devices and on your phones.&lt;/p&gt; &lt;p&gt;Place them where nobody should be poking around and get a clear alarm if they are accessed. They are designed to look juicy to attackers to increase the likelihood that they are opened (and they are completely free).&lt;/p&gt; &lt;p&gt;Our Canarytokens are easy to sprinkle all over and forget about, until you get the notification that matters. They are super lightweight and don’t require installing software or running more background processes that can slow down your PC.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.canarytokens.org/guide/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.canarytokens.org/nest/&#34;&gt;Home&lt;/a&gt; feat(kubernetes#Move a pvc between AZ in aws): Move a pvc between AZ in aws&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Usage: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &amp;lt;pv-name&amp;gt; &amp;lt;new-az&amp;gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;PV_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;NEW_AZ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$2&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Volume&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ID&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;from&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;PV
&lt;span class=&#34;nv&#34;&gt;VOLUME_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;{.spec.csi.volumeHandle}&#39;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-z&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;then&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to get volume ID for PV &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;fi&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;PVC_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{.spec.claimRef.name}&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;NAMESPACE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;jsonpath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{.spec.claimRef.namespace}&#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;PVC Name: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Namespace: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NAMESPACE&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Found volume: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create-snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--description&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Migration for &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;SnapshotId&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;text&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Snapshot created: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Waiting for snapshot to be ready...&#34;&lt;/span&gt;
aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;snapshot-completed&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--snapshot-ids&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Snapshot &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; is ready&#34;&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;VOLUME_TYPE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;describe-volumes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-ids&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Volumes[0].VolumeType&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;text&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nv&#34;&gt;NEW_VOLUME_ID&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create-volume&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--snapshot-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--availability-zone&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_AZ&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-type&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_TYPE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--query&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;VolumeId&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;text&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New volume created: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Waiting for new volume to be available...&#34;&lt;/span&gt;
aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;volume-available&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-ids&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_VOLUME_ID&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New volume &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; is ready&#34;&lt;/span&gt;

&lt;span class=&#34;nv&#34;&gt;NEW_PV_NAME&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PV_NAME&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;-migrated
cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt;EOF &amp;gt; new-pv.yaml&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;apiVersion: v1&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;kind: PersistentVolume&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;metadata:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  name: $NEW_PV_NAME&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;spec:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  capacity:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    storage: $(kubectl get pv $PV_NAME -o jsonpath=&#39;{.spec.capacity.storage}&#39;)&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  volumeMode: Filesystem&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  accessModes:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    - ReadWriteOnce&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  persistentVolumeReclaimPolicy: Retain&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  storageClassName: $(kubectl get pv $PV_NAME -o jsonpath=&#39;{.spec.storageClassName}&#39;)&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  csi:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    driver: ebs.csi.aws.com&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    volumeHandle: $NEW_VOLUME_ID&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    fsType: ext4&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  nodeAffinity:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    required:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;      nodeSelectorTerms:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;      - matchExpressions:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;        - key: topology.ebs.csi.aws.com/zone&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;          operator: In&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;          values:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;          - $NEW_AZ&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;EOF&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New PV manifest generated: new-pv.yaml&#34;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apply&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new-pv.yaml
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New PV &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; created&#34;&lt;/span&gt;
kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pvc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NAMESPACE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;PVC_NAME&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;-backup.yaml

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;If you haven&#39;t size to 0 the statefulset, it is the time to kill the pod to rebind the PVC&#34;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pvc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NAMESPACE&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Old PVC deleted&#34;&lt;/span&gt;
cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt;EOF &amp;gt; new-pvc.yaml&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;apiVersion: v1&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;kind: PersistentVolumeClaim&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;metadata:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  name: $PVC_NAME&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  namespace: $NAMESPACE&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;spec:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  accessModes:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    - ReadWriteOnce&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  resources:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;    requests:&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;      storage: $(kubectl get pv $NEW_PV_NAME -o jsonpath=&#39;{.spec.capacity.storage}&#39;)&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  storageClassName: $(kubectl get pv $NEW_PV_NAME -o jsonpath=&#39;{.spec.storageClassName}&#39;)&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;  volumeName: $NEW_PV_NAME&lt;/span&gt;
&lt;span class=&#34;s&#34;&gt;EOF&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New PVC manifest generated: new-pvc.yaml&#34;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apply&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;new-pvc.yaml
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;New PVC &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; created and bound to new PV&#34;&lt;/span&gt;

kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to delete PV &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;, probably was not retained&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Old PV &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; deleted&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Deleting old volume &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete-volume&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--volume-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to delete volume &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$VOLUME_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;, probably was not retained&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Old volume deleted&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Deleting snapshot &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aws&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ec2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete-snapshot&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--snapshot-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$SNAPSHOT_ID&lt;/span&gt;
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Snapshot deleted&#34;&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Migration complete.\nNew PV: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$NEW_PV_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;\nNew PVC: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$PVC_NAME&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;wireguard&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/wg-easy/&#34;&gt;Wireguard&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#user-management&#34;&gt;User management.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Wireguard&#39;s default user management is not very user friendly as it&#39;s difficult to know which key belongs to what user.&lt;/p&gt; &lt;p&gt;I&#39;ve been looking for WireGuard admin interface UI that is actively maintained but also isn&#39;t cloud-based and &lt;a href=&#34;https://www.reddit.com/r/selfhosted/comments/18nrbnf/wireguard_admin_interface_ui_that_is_actively/&#34;&gt;between all solutions&lt;/a&gt; I found &lt;a href=&#34;https://lyz-code.github.io/blue-book/wg-easy/&#34;&gt;wg-easy&lt;/a&gt; the best candidate because:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It has just the features I need:&lt;/li&gt; &lt;li&gt;Clean User management: add, remove, disable&lt;/li&gt; &lt;li&gt;Clean UI interface&lt;/li&gt; &lt;li&gt;Actively maintained: last commit 7h ago&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master&#34;&gt;Really popular: 17.7k stars, 1.7k forks&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It&#39;s installable either with docker or &lt;a href=&#34;https://github.com/wg-easy/wg-easy/blob/production/docker-compose.yml&#34;&gt;docker-compose&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It exports &lt;a href=&#34;https://github.com/wg-easy/wg-easy/issues/1510&#34;&gt;prometheus metrics&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It has &lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki&#34;&gt;good documentation&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;It has &lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki/Using-WireGuard-Easy-with-Ansible&#34;&gt;an ansible playbook&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It has &lt;a href=&#34;https://grafana.com/grafana/dashboards/21733-wireguard/&#34;&gt;a grafana dashboard&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It has &lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master&#34;&gt;a clean release process&lt;/a&gt;&lt;/li&gt; &lt;li&gt;It&#39;s a stable project: 3 years and 10 months old&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If &lt;code&gt;wg-easy&lt;/code&gt; doesn&#39;t work, I&#39;d look at the next projects:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/donaldzou/WGDashboard?tab=readme-ov-file&#34;&gt;WGDashboard&lt;/a&gt; (&lt;a href=&#34;https://donaldzou.dev/WGDashboard-Documentation/index_topic.html&#34;&gt;Docs&lt;/a&gt;)&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/burghardt/easy-wg-quick&#34;&gt;easy-wg-quick&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/ngoduykhanh/wireguard-ui&#34;&gt;wireguard-ui&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/gene-git/wg_tool&#34;&gt;wg-tool&lt;/a&gt; and &lt;a href=&#34;https://github.com/gene-git/wg-client&#34;&gt;wg-client&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#rosenpass&#34;&gt;Introduce Rosenpass.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Rosenpass is free and open-source software based on the latest research in the field of cryptography. It is intended to be used with WireGuard VPN, but can work with all software that uses pre-shared keys. It uses two cryptographic methods (Classic McEliece and Kyber) to secure systems against attacks with quantum computers.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/rosenpass/rosenpass&#34;&gt;Source code&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://rosenpass.eu/docs/&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#references&#34;&gt;Add awesome wireguard link.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/cedrickchee/awesome-wireguard&#34;&gt;Awesome wireguard&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce wg-easy.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master&#34;&gt;&lt;code&gt;wg-easy&lt;/code&gt;&lt;/a&gt; is the easiest way to install &amp;amp; manage WireGuard on any Linux hostthe easiest way to install &amp;amp; manage WireGuard on any Linux host&lt;/p&gt; &lt;p&gt;Features:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;All-in-one: WireGuard + Web UI.&lt;/li&gt; &lt;li&gt;Easy installation, simple to use.&lt;/li&gt; &lt;li&gt;List, create, edit, delete, enable &amp;amp; disable clients.&lt;/li&gt; &lt;li&gt;Show a client&#39;s QR code.&lt;/li&gt; &lt;li&gt;Download a client&#39;s configuration file.&lt;/li&gt; &lt;li&gt;Statistics for which clients are connected.&lt;/li&gt; &lt;li&gt;Tx/Rx charts for each connected client.&lt;/li&gt; &lt;li&gt;Gravatar support.&lt;/li&gt; &lt;li&gt;Automatic Light / Dark Mode&lt;/li&gt; &lt;li&gt;Multilanguage Support&lt;/li&gt; &lt;li&gt;One Time Links&lt;/li&gt; &lt;li&gt;Client Expiration&lt;/li&gt; &lt;li&gt;Prometheus metrics support&lt;/li&gt; &lt;li&gt;IPv6 support&lt;/li&gt; &lt;li&gt;CIDR support&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master?tab=readme-ov-file#installation&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki/Using-WireGuard-Easy-with-Ansible&#34;&gt;With ansible&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/tree/master&#34;&gt;Source&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/wg-easy/wg-easy/wiki&#34;&gt;Docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;science&#34;&gt;Science&lt;/h2&gt; &lt;h3 id=&#34;artificial-intelligence&#34;&gt;Artificial Intelligence&lt;/h3&gt; &lt;h4 id=&#34;text-to-speech&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/text_to_speech/&#34;&gt;Text to speech&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/text_to_speech/#references&#34;&gt;Add link to Exploring the World of Open-Source Text-to-Speech Models article.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.bentoml.com/blog/exploring-the-world-of-open-source-text-to-speech-models&#34;&gt;Exploring the World of Open-Source Text-to-Speech Models&lt;/a&gt; diff --git a/docs/vim_plugin_development.md b/docs/vim_plugin_development.md index 8b70311a61..1fa882233a 100644 --- a/docs/vim_plugin_development.md +++ b/docs/vim_plugin_development.md feat(vim_plugin_development): Explain how to load a plugin in a local directory with lazy&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can manually edit those files to develop new feature or fix issues on the plugins. Or if you&#39;re developing them in a directory you can specify the &lt;code&gt;dir&lt;/code&gt; directive in the lazy loading.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;March 19, 2025 06:48:26 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-03-19T06:48:26+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;March 19, 2025 06:48:26 UTC&#34;&gt;2025-03-19&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_03_18/</link>
      <pubDate>2025-03-19 06:48:26+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_03_18/</guid>
      
    </item>
    
    <item><title>24th February 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;activism&#34;&gt;Activism&lt;/h2&gt; &lt;h3 id=&#34;hacktivism&#34;&gt;Hacktivism&lt;/h3&gt; &lt;h4 id=&#34;collectives&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/hacktivist_collectives/&#34;&gt;Collectives&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add critical switch.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://critical-switch.org/&#34;&gt;Critical Switch&lt;/a&gt;: una colectiva transhackfeminista no mixta1 interesades en la cultura libre, la privacidad y la seguridad digital. Promovemos la cultura de la seguridad para generar espacios más seguros en los movimientos sociales y activistas.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add méxico collectives.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://sursiendo.org/quienes-somos/&#34;&gt;Sursiendo&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://tecnoafecciones.net&#34;&gt;Tecnoafecciones&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;laboral&#34;&gt;Laboral&lt;/h3&gt; &lt;h4 id=&#34;trabajadoras-del-hogar&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/trabajadoras_del_hogar/&#34;&gt;Trabajadoras del hogar&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introducir investigación sobre las trabajadoras del hogar.&lt;/p&gt; &lt;p&gt;Nota: para nada soy un experto en este tema, estas son las claves que he ido deduciendo a través de hablar del tema con trabajadoras y gestoras. Así que verificar todo antes de tomarlo por verdad!&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cuidado de personas mayores dependientes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;El cuidado de las personas mayores es una movida, especialmente cuando empiezan a ser dependientes. Normalmente necesitan cuidados la mayor parte del tiempo del día. Actualmente existen las siguientes opciones para impartir dichos cuidados:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;La red cercana (normalmente las mujeres de la familia) se encargan de dichos cuidados.&lt;/li&gt; &lt;li&gt;Parte o todos los cuidados se externalizan ya sea a una residencia de ancianos, centros de día o contratando a trabajadoras que acuden al hogar.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;En este mundo podrido donde los servicios públicos están siendo desmantelados, la oferta pública de centros de día o residencias es insuficiente y generalmente en manos de políticas incompetentes (nunca olvidemos &lt;a href=&#34;https://www.elsaltodiario.com/residencias-mayores/7291-muertes-explicacion-familiares-residencias-denuncian-ayuso-sigue-bloqueando-verdad&#34;&gt;las 7291 muertes&lt;/a&gt; que pesan sobre los hombros de Ayuso &lt;a href=&#34;https://www.youtube.com/@quietotodoelmundo&#34;&gt;{hija de puta!}&lt;/a&gt;).&lt;/p&gt; &lt;p&gt;Esto sumado a que las mujeres de la familia ahora trabajan y la precarización del sector de las empleadas del hogar hace que (sobre todo peña que tiene pasta) recurra a contratar trabajadoras en régimen de interna.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Trabajo del hogar en régimen de interna&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En realidad este trabajo es esclavismo encubierto bajo una pátina legal. Aprovechandose de que la profesión está feminizada y generalmente por personas migrantes, se imponen unas condiciones laborales que no cumplen el estatuto de las trabajadoras.&lt;/p&gt; &lt;p&gt;Con un salario que normalmente no supera el mínimo estas trabajadoras:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Trabajan muchas más horas que las 40 a la semana&lt;/li&gt; &lt;li&gt;Hacen trabajos por fuera de su contrato como limpiar la casa o servir la comida.&lt;/li&gt; &lt;li&gt;Se encuentran encerradas en su lugar de trabajo. Incluso cuando &#34;dejan de trabajar&#34; están dentro del control de sus empleadores.&lt;/li&gt; &lt;li&gt;Al encontrarse solas con las personas a las que cuidan, 24 horas al día, es común encontrarse casos de violencia de género. Muchas cuentan testimonios de atrancar la puerta de su cuarto por la noche.&lt;/li&gt; &lt;li&gt;Los espacios que se les ceden (habitaciones o cuartos de baño) no se respetan y generalmente son usados por otras personas de la familia cuando lo desean, arrebatándoles incluso su cuarto propio.&lt;/li&gt; &lt;li&gt;Generalmente tienen unas dos horas al día para librar. Pero generalmente trabajan en barrios muy lejanos de su hogar, con precios y oferta de ocio muy lejana a sus posibilidades, así que normalmente usan esas horas para pasear. En invierno se pone más complicado con el frío y la lluvia.&lt;/li&gt; &lt;li&gt;Las que libran los fines de semana tienen que pagar una habitación o piso que sólo pueden disfrutar unos pocos días a la semana.&lt;/li&gt; &lt;li&gt;Tienen que soportar el maltrato y la tiranía propia de las personas mayores que ya empiezan a perder la cabeza. A esas edades se exacerban el clasismo y el racismo a la vez que desaparecen los mecanismos de control propio y filtro. Lo que genera situaciones muy desagradables que muchas veces desembocan en maltrato psicológico y físico.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Y aunque esto es harto conocido por la sociedad, es un modelo que se sigue usando con frecuencia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Horario de trabajo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En algunos casos las trabajadoras libran el fin de semana, 36 horas consecutivas según la ley, lo que podría ser de sábado a las 9:00 hasta el domingo a las 21:00, además de 2 horas al día (no remuneradas) en los días de entre semana. Esto hace un total de 122 horas trabajadas a la semana, mucho mayor de las 40 horas establecidas.&lt;/p&gt; &lt;p&gt;Y aunque en teoría &lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/justicia-europea-tira-orejas-espana-obliga-registrar-jornada-trabajadoras-del-hogar&#34;&gt;los empleadores están obligados a implementar un sistema para registrar la jornada de sus trabajadoras&lt;/a&gt; se torna &lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/registrar-jornada-laboral-empleo-hogar&#34;&gt;difícil en la práctica&lt;/a&gt;&lt;/p&gt; &lt;p&gt;La ley además establece que además de las 40 horas semanales se pueden tener 20 horas extras de presencia. Las horas de presencia se pagan a precio de hora normal porque el régimen de empleadas de hogar lo establece así. No es como otros convenios.&lt;/p&gt; &lt;p&gt;La mayor parte de las trabajadoras no conoce que tienen derecho a estas 20 horas adicionales. Esas horas de presencia se pueden reclamar por los últimos 12 meses, las anteriores prescriben. Esto pueden ser unos 18.000 euros a reclamar. Para ello hacen falta pruebas de que la trabajadora está haciendo esa jornada. Una manera de pelearlo es pedir al empleador que justifique qué otras personas tiene contratadas para cuidar a la persona dependiente. Porque la prueba dentro de un domicilio es muy difícil. Si en el contrato no figura ningún horario se puede asumir que es 24h. También se puede preguntar a vecinos o si está empadronada.&lt;/p&gt; &lt;p&gt;Lo que si es claro es que la empresa tiene que definir el horario de trabajo en el contrato, lo que no siempre hacen.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Pernocta&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En el contrato tiene que figurar si la trabajadora duerme en el lugar de trabajo.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/registrar-jornada-laboral-empleo-hogar&#34;&gt;Es muy difícil de regular las veces que se despiertan en la noche, así que pelear eso es aún complicado.&lt;/a&gt; Aunque se van haciendo avances.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Violencia y acoso en el empleo doméstico&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Según el &lt;a href=&#34;https://www.boe.es/buscar/act.php?id=BOE-A-2024-18182&#34;&gt;Real Decreto 893/2024&lt;/a&gt; a ojos de &lt;a href=&#34;https://noticias.juridicas.com/actualidad/noticias/19543-real-decreto-893-2024:-nuevos-derechos-laborales-para-las-empleadas-de-hogar-y-de-ayuda-a-domicilio-/&#34;&gt;noticias.juridicas.com&lt;/a&gt;:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;El abandono del domicilio ante una situación de violencia o acoso sufrida por la persona trabajadora no podrá considerarse dimisión ni podrá ser causa de despido, sin perjuicio de la posibilidad de la persona trabajadora de solicitar la extinción del contrato en virtud del artículo 50 ET y de la solicitud de medidas cautelares en caso de formulación de demandas, de conformidad con la LRJS.&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;&lt;strong&gt;Salario&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Lo normal es que se pague el salario mínimo, aunque &lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/empleadas-hogar-internas-trabajan-maximo-60-horas-semanales&#34;&gt;Cuatro de cada diez ni llegan a eso&lt;/a&gt;. Hay que tener en cuenta que el salario mínimo ha sido actualizado desde enero de 2025 a 1383 euros. Es probable que a muchas ni se lo suban.&lt;/p&gt; &lt;p&gt;Si se cuentan las 20 horas de presencia, el salario serían aproximadamente 2000 euros al mes (2094 según la &lt;a href=&#34;https://www.sendadecuidados.org/cuidados-en-el-hogar/tablas-salariales/&#34;&gt;tabla salarial de senda de cuidados de 2024&lt;/a&gt; para un régimen de 6 noches a la semana).&lt;/p&gt; &lt;p&gt;&lt;em&gt;Pelear por sus derechos*&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Normalmente aunque les cuentes todos los derechos que tienen, las trabajadoras no quieren reclamar ni ejercer sus derechos porque no se atreven. Por miedo a perder el trabajo u otras represalias.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Datos personales&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Las asesorías pueden sacar el número de la seguridad social con un nombre y un DNI. Esto se hace para facilitar los trámites. Pero si no lo sabes puede rayarte.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Forma de pago&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;El empleador es el encargado de hacer la transferencia al trabajador como una nómina, no como una transferencia regular. Ya que si no el trabajador no obtiene las bonificaciones de tener domiciliada la nómina.&lt;/p&gt; &lt;p&gt;Aunque haya agencias de por medio, estas generalmente hacen de intermediarias y sólo un trabajo de asesoría, por lo tanto el contrato se suele hacer con la familia de la persona que es cuidada, y esta es la que ha de hacer el ingreso a la trabajadora. A no ser que la agencia sea una ETT de empleadas del hogar, que en ese caso es la agencia la que las contrata directamente.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Denuncias de inspección de trabajo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Las denuncias de inspección de trabajo en este régimen tienen un recorrido diferente dependiendo de a qué inspector le toque, porque como inspección de trabajo no puede entrar en los domicilios particulares por sorpresa aunque sea una empresa. Entonces hay inspectores que las denuncias por maltrato de las empleadas del hogar las meten en el cajón. Otros no, requieren y de más.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Impuestos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En las nóminas de las empleadas del hogar no hay IRPF. Normalmente el salario y la prorrata se desglosa, si está junto es una nómina cutre.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Papeleos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Una vez firmado el contrato, la empresa ha de entregar a la trabajadora la huella digital de su contrato comunicado al servicio público de empleo. Cuando haces un alta de una trabajadora hay que mandar dos ficheros, uno a la tesorería general con el alta y otro al servicio público de empleo estatal con el contrato. Si no lo hacen es un defecto formal, no es gravísimo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Empresas decentes: No todo es horrendo, existen cooperativas de trabajadoras que ofrecen estos servicios bajo unas condiciones que ellas han decidido:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.sendadecuidados.org/&#34;&gt;Senda de cuidados&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.lacomala.org/&#34;&gt;La Comala&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Senda de cuidados publica su &lt;a href=&#34;https://www.sendadecuidados.org/cuidados-en-el-hogar/tablas-salariales/&#34;&gt;tabla salarial&lt;/a&gt; en la que te puedes hacer una idea del salario y de los diferentes tipos de régimen de trabajo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mejoras legales&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.boe.es/buscar/act.php?id=BOE-A-2024-18182&#34;&gt;Real Decreto 893/2024, de 10 de septiembre, por el que se regula la protección de la seguridad y la salud en el ámbito del servicio del hogar familiar.&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.boe.es/diario_boe/txt.php?id=BOE-A-2022-14680&#34;&gt;Real Decreto-ley 16/2022, de 6 de septiembre, para la mejora de las condiciones de trabajo y de Seguridad Social de las personas trabajadoras al servicio del hogar.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Artículos sobre el trabajo interno&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/empleadas-hogar-internas-trabajan-maximo-60-horas-semanales&#34;&gt; Trabajo doméstico Dos de cada tres empleadas del hogar internas trabajan más del máximo de 60 horas semanales &lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/justicia-europea-tira-orejas-espana-obliga-registrar-jornada-trabajadoras-del-hogar&#34;&gt;La justicia europea tira de las orejas a España y obliga a registrar la jornada de las trabajadoras del hogar&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/trabajo-domestico/registrar-jornada-laboral-empleo-hogar&#34;&gt;Registrar la jornada laboral en el empleo de hogar&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;conference-organisation&#34;&gt;Conference organisation&lt;/h3&gt; &lt;h4 id=&#34;pretalx&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/&#34;&gt;pretalx&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/pretalx/#import-a-pretalx-calendar-in-giggity&#34;&gt;Import a pretalx calendar in giggity.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Search the url similar to &lt;a href=&#34;https://pretalx.com/&#34;&gt;https://pretalx.com/&lt;/a&gt;&lt;conference-name&gt;/schedule/export/schedule.xml&lt;/conference-name&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;time-management&#34;&gt;Time management&lt;/h3&gt; &lt;h4 id=&#34;org-mode&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/&#34;&gt;Org Mode&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#footnotes&#34;&gt;Footnotes.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;A footnote is started by a footnote marker in square brackets in column 0, no indentation allowed. It ends at the next footnote definition, headline, or after two consecutive empty lines. The footnote reference is simply the marker in square brackets, inside text. Markers always start with ‘fn:’. For example:&lt;/p&gt;  &lt;p&gt;Nvim-orgmode has &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/4f62b7f#diff-fa091537281e07e5e58902b6484b097442300c98e115ab29f4374abbe98b8d3d&#34;&gt;some basic support for footnotes&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#custom-agendas&#34;&gt;Custom agendas.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You an use &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/blob/d62fd3cdb2958e2e76fb0af4ea64d6209703fbe0/DOCS.md#org_agenda_custom_commands&#34;&gt;custom agenda commands&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Define custom agenda views that are available through the &lt;code&gt;org_agenda&lt;/code&gt; mapping. It is possible to combine multiple agenda types into single view. An example: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;orgmode&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;~/org/**/*&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;org_agenda_custom_commands&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- &#34;c&#34; is the shortcut that will be used in the prompt&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;c&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Combined view&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Description shown in the prompt for the shortcut&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;types&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;tags_todo&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Type can be agenda | tags | tags_todo&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;match&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;+PRIORITY=&#34;A&#34;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;--Same as providing a &#34;Match:&#34; for tags view &amp;lt;leader&amp;gt;oa + m, See: https://orgmode.org/manual/Matching-tags-and-properties.html&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;High priority todos&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_todo_ignore_deadlines&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;far&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Ignore all deadlines that are too far in future (over org_deadline_warning_days). Possible values: all | near | far | past | future&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;My daily agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_span&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;day&#39;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- can be any value as org_agenda_span&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;tags&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;match&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;WORK&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;--Same as providing a &#34;Match:&#34; for tags view &amp;lt;leader&amp;gt;oa + m, See: https://orgmode.org/manual/Matching-tags-and-properties.html&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;My work todos&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_todo_ignore_scheduled&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;all&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Ignore all headlines that are scheduled. Possible values: past | future | all&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Whole week overview&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_span&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;week&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- &#39;week&#39; is default, so it&#39;s not necessary here, just an example&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_start_on_weekday&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Start on Monday&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_remove_tags&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Do not show tags only for this view&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Personal agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;types&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;tags_todo&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;My personal todos&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_category_filter_preset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;todos&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Show only headlines from `todos` category. Same value providad as when pressing `/` in the Agenda view&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_sorting_strategy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;todo-state-up&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;priority-down&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- See all options available on org_agenda_sorting_strategy&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Personal projects agenda&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;~/my-projects/**/*&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Can define files outside of the default org_agenda_files&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;tags&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_overriding_header&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;Personal projects notes&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_files&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;~/my-projects/**/*&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;org_agenda_tag_filter_preset&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;NOTES-REFACTOR&#39;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Show only headlines with NOTES tag that does not have a REFACTOR tag. Same value providad as when pressing `/` in the Agenda view&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;You can also define the &lt;code&gt;org_agenda_sorting_strategy&lt;/code&gt;. The default value is &lt;code&gt;{ agenda = {&#39;time-up&#39;, &#39;priority-down&#39;, &#39;category-keep&#39;}, todo = {&#39;priority-down&#39;, &#39;category-keep&#39;}, tags = {&#39;priority-down&#39;, &#39;category-keep&#39;}}&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;The available list of sorting strategies to apply to a given view are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;time-up&lt;/code&gt;: Sort entries by time of day. Applicable only in agenda view&lt;/li&gt; &lt;li&gt;&lt;code&gt;time-down&lt;/code&gt;: Opposite of time-up&lt;/li&gt; &lt;li&gt;&lt;code&gt;priority-down&lt;/code&gt;: Sort by priority, from highest to lowest&lt;/li&gt; &lt;li&gt;&lt;code&gt;priority-up&lt;/code&gt;: Sort by priority, from lowest to highest&lt;/li&gt; &lt;li&gt;&lt;code&gt;tag-up&lt;/code&gt;: Sort by sorted tags string, ascending&lt;/li&gt; &lt;li&gt;&lt;code&gt;tag-down&lt;/code&gt;: Sort by sorted tags string, descending&lt;/li&gt; &lt;li&gt;&lt;code&gt;todo-state-up&lt;/code&gt;: Sort by todo keyword by position (example: &#39;TODO, PROGRESS, DONE&#39; has a sort value of 1, 2 and 3), ascending&lt;/li&gt; &lt;li&gt;&lt;code&gt;todo-state-down&lt;/code&gt;: Sort by todo keyword, descending&lt;/li&gt; &lt;li&gt;&lt;code&gt;clocked-up&lt;/code&gt;: Show clocked in headlines first&lt;/li&gt; &lt;li&gt;&lt;code&gt;clocked-down&lt;/code&gt;: Show clocked in headines last&lt;/li&gt; &lt;li&gt;&lt;code&gt;category-up&lt;/code&gt;: Sort by category name, ascending&lt;/li&gt; &lt;li&gt;&lt;code&gt;category-down&lt;/code&gt;: Sort by category name, descending&lt;/li&gt; &lt;li&gt;&lt;code&gt;category-keep&lt;/code&gt;: Keep default category sorting, as it appears in org-agenda-files&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;You can open the custom agendas with the API too. For example to open the agenda stored under &lt;code&gt;t&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;     &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
       &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;gt&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
         &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Opening today&#39;s agenda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.api.agenda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open_by_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;t&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Open orgmode agenda for today&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In that case I&#39;m configuring the &lt;code&gt;keys&lt;/code&gt; section of the lazyvim plugin. Through the API you can also configure these options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;org_agenda_files&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;org_agenda_sorting_strategy&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;org_agenda_category_filter_preset&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;org_agenda_todo_ignore_deadlines&lt;/code&gt;: Ignore all deadlines that are too far in future (over org_deadline_warning_days). Possible values: all | near | far | past | future&lt;/li&gt; &lt;li&gt;&lt;code&gt;org_agenda_todo_ignore_scheduled&lt;/code&gt;: Ignore all headlines that are scheduled. Possible values: past | future | all&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#load-different-agendas-with-the-same-binding-depending-on-the-time&#34;&gt;Load different agendas with the same binding depending on the time.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I find it useful to bind &lt;code&gt;gt&lt;/code&gt; to Today&#39;s agenda, but what today means is different between week days. Imagine that you want to load an agenda if you&#39;re from monday to friday before 18:00 (a work agenda) versus a personal agenda the rest of the time.&lt;/p&gt; &lt;p&gt;You could then configure this function:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
     &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;s2&#34;&gt;&#34;gt&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_time&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;os.date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*t&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;wday&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- 1 = Sunday, 2 = Monday, etc.&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;

          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;agenda_key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;t&#34;&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;agenda_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Today&#39;s&#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- default&lt;/span&gt;

          &lt;span class=&#34;c1&#34;&gt;-- Monday (2) through Friday (6)&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;17&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;agenda_key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;w&#34;&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;agenda_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Today + Work&#34;&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Opening &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;agenda_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34; agenda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.api.agenda&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open_by_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;agenda_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Open orgmode agenda for today&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#better-handle-indentations&#34;&gt;Better handle indentations.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There is something called &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/blob/master/docs/configuration.org#org_startup_indented&#34;&gt;virtual indents&lt;/a&gt; that will prevent you from many indentation headaches. To enable them set the &lt;code&gt;org_startup_indented = true&lt;/code&gt; configuration.&lt;/p&gt; &lt;p&gt;If you need to adjust the indentation of your document (for example after enabling the option on existent orgmode code), visually select the lines to correct the indentation (&lt;code&gt;V&lt;/code&gt;) and then press &lt;code&gt;=&lt;/code&gt;. You can do this with the whole file &lt;code&gt;(╥﹏╥)&lt;/code&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#remove-some-tags-when-the-state-has-changed-so-done&#34;&gt;Remove some tags when the state has changed so DONE.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;For example if you want to remove them for recurrent tasks&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;      &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;remove_specific_tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tagsToRemove&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;t&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;q&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;y&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;currentTags&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;newTags&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
        &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;needsUpdate&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;

        &lt;span class=&#34;c1&#34;&gt;-- Build new tags list excluding t, w, m&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;ipairs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;currentTags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;do&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shouldKeep&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;removeTag&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;ipairs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tagsToRemove&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;do&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;removeTag&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;shouldKeep&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;needsUpdate&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
              &lt;span class=&#34;kr&#34;&gt;break&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shouldKeep&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;nb&#34;&gt;table.insert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newTags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;-- Only update if we actually removed something&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;needsUpdate&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set_tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;table.concat&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;newTags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;refresh&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

      &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.events&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TodoChanged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;---@cast event OrgTodoChangedEvent&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;DONE&#34;&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;remove_specific_tags&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#register-the-todo-changes-in-the-logbook&#34;&gt;Register the todo changes in the logbook.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can now register the changes with events. Add this to your plugin config. If you&#39;re using lazyvim:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;nvim-orgmode/orgmode&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({...})&lt;/span&gt;

      &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.events&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
      &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Date&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;orgmode.objects.date&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

      &lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EventManager&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TodoChanged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;c1&#34;&gt;---@cast event OrgTodoChangedEvent&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
         &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_todo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_todo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;now&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

          &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;headline&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_note&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
            &lt;span class=&#34;s1&#34;&gt;&#39;State &#34;&#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_todo&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#34; from &#34;&#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;old_todo_state&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&#34;  [&#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;to_string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;]&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgmode/#api-usage&#34;&gt;API usage.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/2c806ca&#34;&gt;Get the headline under the cursor&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/500004ff315475033e3a9247b61addd922d1f5da&#34;&gt;Read and write files&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You have information on how to do it in &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/500004ff315475033e3a9247b61addd922d1f5da&#34;&gt;this pr&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/commit/8cdfc8d34bd9c5993ea8f933b5f5c306081ffb97&#34;&gt;Create custom hyperlink types&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Custom types can trigger functionality such as opening the terminal and pings the provided URL .&lt;/p&gt; &lt;p&gt;To add your own custom hyperlink type, provide a custom handler to &lt;code&gt;hyperlinks.sources&lt;/code&gt; setting. Each handler needs to have a &lt;code&gt;get_name()&lt;/code&gt; method that returns a name for the handler. Additionally, &lt;code&gt;follow(link)&lt;/code&gt; and &lt;code&gt;autocomplete(link)&lt;/code&gt; optional methods are available to open the link and provide the autocompletion. ## &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/471#event-16071077147&#34;&gt;Refile a headline to another destination&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/issues/471#event-16071077147&#34;&gt;Refile a headline to another destination&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can do this &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/blob/master/doc/orgmode_api.txt#L27&#34;&gt;with the API&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Assuming you are in the filewhere your TODOs are:&lt;/p&gt; &lt;p&gt;local api = require(&#39;orgmode.api&#39;) local closest_headline = api.current():get_closest_headline() local destination_file = api.load(&#39;~/org/journal.org&#39;) ocal destination_headline = vim.tbl_filter(function(headline) return headline.title == &#39;My journal&#39; end, destination_file.headlines)[1]&lt;/p&gt; &lt;p&gt;api.refile({ source = closest_headline, destination = destination_headline })&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/tree/master/lua/orgmode/events&#34;&gt;Use events&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;orgzly&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/&#34;&gt;Orgzly&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/#not-adding-a-todo-state-when-creating-a-new-element-by-default&#34;&gt;Not adding a todo state when creating a new element by default.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The default state &lt;code&gt;NOTE&lt;/code&gt; doesn&#39;t add any state.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;roadmap-adjustment&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/&#34;&gt;Roadmap Adjustment&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Adjust the month review process.&lt;/p&gt; &lt;p&gt;To record the results of the review create the section in &lt;code&gt;pages/reviews.org&lt;/code&gt; with the following template:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;* winter
** january review
*** work
*** personal
**** month review
***** mental dump
****** What worries you right now?
****** What drained your energy or brought you down emotionally this last month?
****** What are the little things that burden you or slow you down?
****** What do you desire right now?
****** Where is your mind these days?
****** What did you enjoy most this last month?
****** What did help you most this last month?
****** What things would you want to finish throughout the month so you can carry them to the next?
****** What things do you feel you need to do?
****** What are you most proud of this month?
***** month checks
***** analyze
***** decide
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;I&#39;m assuming it&#39;s the january&#39;s review and that you have two kinds of reviews, one personal and one for work.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dump your mind&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The first thing we want to do in the review is to dump all that&#39;s in our mind into our system to free up mental load.&lt;/p&gt; &lt;p&gt;Try not to, but if you think of decisions you want to make that address the elements you&#39;re discovering, write them down in the &lt;code&gt;Decide&lt;/code&gt; section of your review document.&lt;/p&gt; &lt;p&gt;There are different paths to discover actionable items:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Analyze what is in your mind: Take 10 minutes to answer to the questions of the template under the &#34;mental dump&#34; section (you don&#39;t need to answer them all). Notice that we do not need to review our life logging tools (diary, action manager, ...) to answer these questions. This means that we&#39;re doing an analysis of what is in our minds right now, not throughout the month. It&#39;s flawed but as we do this analysis often, it&#39;s probably fine. We add more importance to the latest events in our life anyway.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Clean your notebook&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Empty the elements you added to the &lt;code&gt;review box&lt;/code&gt;. I have them in my inbox with the tag &lt;code&gt;:review:&lt;/code&gt; (you have it in the month agenda view &lt;code&gt;gM&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;Clean your life notebook by:&lt;/li&gt; &lt;li&gt;Iterate over the areas of &lt;code&gt;proyects.org&lt;/code&gt; only checking the first level of projects, don&#39;t go deeper and for each element:&lt;ul&gt; &lt;li&gt;Move the done elements either to &lt;code&gt;archive.org&lt;/code&gt; or &lt;code&gt;logbook.org&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Move to &lt;code&gt;backlog.org&lt;/code&gt; the elements that don&#39;t make sense to be active anymore&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;Check if you have any &lt;code&gt;DONE&lt;/code&gt; element in &lt;code&gt;calendar.org&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Empty the &lt;code&gt;inbox.org&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Empty the &lt;code&gt;DONE&lt;/code&gt; elements of &lt;code&gt;talk.org&lt;/code&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Clean the elements that don&#39;t make sense anymore from &lt;code&gt;think.org&lt;/code&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Process your &lt;code&gt;month checks&lt;/code&gt;. For each of them:&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;If you need, add action elements in the &lt;code&gt;mental dump&lt;/code&gt; section of the review.&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Think of whether you&#39;ve met the check.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Refresh your idea of how the month go&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Open your &lt;code&gt;bitácora.org&lt;/code&gt; agenda view to see what has been completed in the last month &lt;code&gt;match = &#39;CLOSED&amp;gt;&#34;&amp;lt;-30d&amp;gt;&#34;-work-steps-done&#39;,&lt;/code&gt; ordered by name &lt;code&gt;org_agenda_sorting_strategy = { &#34;category-keep&#34; },&lt;/code&gt; and change the priority of the elements according to the impact. Open your &lt;code&gt;recurrent.org&lt;/code&gt; agenda view to see what has been done the last month &lt;code&gt;match = &#39;LAST_REPEAT&amp;gt;&#34;&amp;lt;-30d&amp;gt;&#34;-work&#39;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Check what has been left of your month objectives &lt;code&gt;+m&lt;/code&gt; and refile the elements that don&#39;t make sense anymore.&lt;/li&gt; &lt;li&gt;Check the reports of your weekly reviews of the month in the &lt;code&gt;reviews.org&lt;/code&gt; document.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Check your close compromises&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Check all your action management tools (in my case &lt;code&gt;orgmode&lt;/code&gt; and &lt;code&gt;ikhal&lt;/code&gt;) to identify: - Arranged compromises - trips&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#life-roadmap-adjustment&#34;&gt;Life roadmap adjustment.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Create next stage&#39;s life notebook&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;After reading &#34;The Bulletproof Journal&#34;, I was drawn to the idea of changing notebooks each year, carrying over only the necessary things.&lt;/p&gt; &lt;p&gt;I find this to be a powerful concept since you start each stage with a clean canvas. This brings you closer to desire versus duty as it removes the commitments you made to yourself, freeing up significant mental load. From this point, it&#39;s much easier to allow yourself to dream about what you want to do in this new stage.&lt;/p&gt; &lt;p&gt;I want to apply this concept to my digital life notebook as I see the following advantages:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It lightens my files making them easier to manage and faster to process with orgmode&lt;/li&gt; &lt;li&gt;It&#39;s a very easy way to clean up&lt;/li&gt; &lt;li&gt;It&#39;s an elegant way to preserve what you&#39;ve recorded without it becoming a hindrance&lt;/li&gt; &lt;li&gt;In each stage, you can start with a different notebook structure, meaning new axes, tools, and structures. This helps avoid falling into the rigidity of a constrained system or artifacts defined by inertia rather than conscious decision&lt;/li&gt; &lt;li&gt;It allows you to avoid maintaining files that follow an old scheme or having to migrate them to the new system&lt;/li&gt; &lt;li&gt;Additionally, you get rid of all those actions you&#39;ve been reluctant to delete in one fell swoop&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The notebook change can be done in two phases:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Notebook Construction&lt;/li&gt; &lt;li&gt;Stage Closure&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Notebook Construction&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This phase spans from when you start making stage adjustments until you finally close the current stage. You can follow these steps:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create a directory with the name of the new stage. In my case, it&#39;s the number of my predominant age during the stage&lt;/li&gt; &lt;li&gt;Create a directory for the current stage&#39;s notebook within &#34;notebooks&#34; in your references. Here we&#39;ll move everything that doesn&#39;t make sense to maintain. It&#39;s important that this directory isn&#39;t within your agenda files&lt;/li&gt; &lt;li&gt;Quickly review the improvements you&#39;ve noted that you want to implement in next year&#39;s notebook to keep them in mind. You can note the references in the &#34;Create new notebook&#34; action&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;As you review the stage, decide if it makes sense for the file you&#39;re viewing to exist as-is in the new notebook. Remember that the idea is to migrate minimal structure and data.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If it makes sense:&lt;/li&gt; &lt;li&gt;Create a symbolic link in the new notebook. When closing the stage, we&#39;ll replace the link with the file&#39;s final state&lt;/li&gt; &lt;li&gt;If the file no longer makes sense, move it to &lt;code&gt;references/notebooks&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;year-reviews&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/year_reviews/&#34;&gt;Year reviews&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/year_reviews/#2025&#34;&gt;Cositas del 2025.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Fascismo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En el acto de toma de posesión del cargo de trump, elon musk hace el saludo nazi.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;elon nazi&#34; src=&#34;x.mp4&#34;/&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Feminismo&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.usnews.com/news/business/articles/2025-01-20/trump-orders-reflect-his-promises-to-roll-back-transgender-protections-and-end-dei-programs&#34;&gt;trump nada más llegar al poder restablece el género de nacimiento a las personas trans y amenaza con terminar los programas de diversidad, inclusión e igualdad&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;himalaya&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/&#34;&gt;himalaya&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#configure-gpg&#34;&gt;Configure GPG.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Himalaya relies on cargo features to enable gpg. You can see the default enabled features in the &lt;a href=&#34;https://github.com/pimalaya/himalaya/blob/master/Cargo.toml#L18&#34;&gt;Cargo.toml&lt;/a&gt; file. As of 2025-01-27 the &lt;code&gt;pgp-commands&lt;/code&gt; is enabled.&lt;/p&gt; &lt;p&gt;You only need to add the next section to your config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;na&#34;&gt;pgp.type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;commands&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;And then you can use both the cli and the vim plugin with gpg. Super easy&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;instant-messages-management&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/k9/&#34;&gt;Instant Messages Management&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add interesting article to merge all protocols under matrix.&lt;/p&gt; &lt;p&gt;You can &lt;a href=&#34;https://technicallyrural.ca/2021/04/05/unify-signal-whatsapp-and-sms-in-a-personal-matrix-server-part-1-matrix/&#34;&gt;use bridges to merge all into matrix&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/k9/#how-to-set-a-master-password&#34;&gt;How to set a master password.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can&#39;t, it&#39;s not supported and it doesn&#39;t look that it will (&lt;a href=&#34;https://forum.k9mail.app/t/password-protection-for-launch-of-k9/6871/11&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://forum.k9mail.app/t/can-i-password-protect-app-on-startup/6755/6&#34;&gt;2&lt;/a&gt;)&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;languages&#34;&gt;Languages&lt;/h3&gt; &lt;h4 id=&#34;pdm&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/pdm/&#34;&gt;PDM&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Suggest to check uv.&lt;/p&gt; &lt;p&gt;Maybe use &lt;a href=&#34;https://astral.sh/blog/uv&#34;&gt;uv&lt;/a&gt; instead (although so far I&#39;m still using &lt;code&gt;pdm&lt;/code&gt;)&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;coding-tools&#34;&gt;Coding tools&lt;/h3&gt; &lt;h4 id=&#34;file-management-configuration&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/fzf_nvim/&#34;&gt;File management configuration&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/fzf_nvim/#how-to-exclude-some-files-from-the-search&#34;&gt;How to exclude some files from the search.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If anyone else comes here in the future and have the following setup&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Using &lt;code&gt;fd&lt;/code&gt; as default command: &lt;code&gt;export FZF_DEFAULT_COMMAND=&#39;fd --type file --hidden --follow&#39;&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Using &lt;code&gt;:Rg&lt;/code&gt; to grep in files&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;And want to exclude a specific path in a git project say &lt;code&gt;path/to/exclude&lt;/code&gt; (but that should not be included in &lt;code&gt;.gitignore&lt;/code&gt;) from both &lt;code&gt;fd&lt;/code&gt; and &lt;code&gt;rg&lt;/code&gt; as used by &lt;code&gt;fzf.vim&lt;/code&gt;, then the easiest way I found to solve to create ignore files for the respective tool then ignore this file in the local git clone (as they are only used by me)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;git_proj/
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;path/to/exclude&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.rgignore
&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;path/to/exclude&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.fdignore
&lt;span class=&#34;nb&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.rgignore\n.fdignore&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.git/info/exclude
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h2&gt; &lt;h3 id=&#34;infrastructure-solutions&#34;&gt;Infrastructure Solutions&lt;/h3&gt; &lt;h4 id=&#34;kubectl-commands&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/&#34;&gt;Kubectl Commands&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/#get-the-node-architecture-of-the-pods-of-a-deployment&#34;&gt;Get the node architecture of the pods of a deployment.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Here are a few ways to check the node architecture of pods in a deployment:&lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;Get the nodes where the pods are running: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pods&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-deployment-label&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wide
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; This will show which nodes are running your pods.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Then check the architecture of those nodes: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nodes&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;custom-columns&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;NAME:.metadata.name,ARCH:.status.nodeInfo.architecture
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Or you can combine this into a single command: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pods&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-deployment-label&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;json&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jq&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-r&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;.items[].spec.nodeName&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;xargs&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-I&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;custom-columns&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;NAME:.metadata.name,ARCH:.status.nodeInfo.architecture
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;You can also check if your deployment is explicitly targeting specific architectures through node selectors or affinity rules: &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;deployment&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;your-deployment-name&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;yaml&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nodeSelector
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;automating-processes&#34;&gt;Automating Processes&lt;/h3&gt; &lt;h4 id=&#34;renovate&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/&#34;&gt;renovate&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/renovate/#installation&#34;&gt;Installation in gitea actions.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create Renovate Bot Account and generate a token for the Gitea Action secret&lt;/li&gt; &lt;li&gt;Add the renovate bot account as collaborator with write permissions to the repository you want to update.&lt;/li&gt; &lt;li&gt;Create a repository to store our Renovate bot configurations, assuming called renovate-config.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In renovate-config, create a file config.js to configure Renovate:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;err&#34;&gt;module.expor&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;ts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;endpoint&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://gitea.com/api/v1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// replace it with your actual endpoint&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;gitAuthor&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Renovate Bot &amp;lt;renovate-bot@yourhost.com&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;platform&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;gitea&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;onboardingConfigFileName&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;renovate.json&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;autodiscover&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;optimizeForDisabled&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If you&#39;re using mysql or you see errors like &lt;code&gt;.../repository/pulls 500 internal error&lt;/code&gt; you &lt;a href=&#34;https://github.com/renovatebot/renovate/issues/10264&#34;&gt;may need to set &lt;code&gt;unicodeEmoji: false&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;storage&#34;&gt;Storage&lt;/h3&gt; &lt;h4 id=&#34;nas&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_storage_planning/&#34;&gt;NAS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Suggest to look at the slimbook.&lt;/p&gt; &lt;p&gt;I built a server pretty much the same as the &lt;a href=&#34;https://slimbook.com/en/shop/product/nas-cube-1510?category=10&#34;&gt;slimbook&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce smartctl.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology&#34;&gt;Self-Monitoring, Analysis, and Reporting Technology (S.M.A.R.T. or SMART)&lt;/a&gt; is a monitoring system included in computer hard disk drives (HDDs) and solid-state drives (SSDs). Its primary function is to detect and report various indicators of drive reliability, or how long a drive can function while anticipating imminent hardware failures.&lt;/p&gt; &lt;p&gt;When S.M.A.R.T. data indicates a possible imminent drive failure, software running on the host system may notify the user so action can be taken to prevent data loss, and the failing drive can be replaced and no data is lost.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;General information&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Accuracy&#34;&gt;Accuracy&lt;/a&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;A field study at Google covering over 100,000 consumer-grade drives from December 2005 to August 2006 found correlations between certain S.M.A.R.T. information and annualized failure rates:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;In the 60 days following the first uncorrectable error on a drive (S.M.A.R.T. attribute 0xC6 or 198) detected as a result of an offline scan, the drive was, on average, 39 times more likely to fail than a similar drive for which no such error occurred.&lt;/li&gt; &lt;li&gt;First errors in reallocations, offline reallocations (S.M.A.R.T. attributes 0xC4 and 0x05 or 196 and 5) and probational counts (S.M.A.R.T. attribute 0xC5 or 197) were also strongly correlated to higher probabilities of failure.&lt;/li&gt; &lt;li&gt;Conversely, little correlation was found for increased temperature and no correlation for usage level. However, the research showed that a large proportion (56%) of the failed drives failed without recording any count in the &#34;four strong S.M.A.R.T. warnings&#34; identified as scan errors, reallocation count, offline reallocation, and probational count.&lt;/li&gt; &lt;li&gt;Further, 36% of failed drives did so without recording any S.M.A.R.T. error at all, except the temperature, meaning that S.M.A.R.T. data alone was of limited usefulness in anticipating failures.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://blog.shadypixel.com/monitoring-hard-drive-health-on-linux-with-smartmontools/&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;On Debian systems:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;apt-get&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartmontools
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;By default when you install it all your drives are checked periodically with the &lt;code&gt;smartd&lt;/code&gt; daemon under the &lt;code&gt;smartmontools&lt;/code&gt; systemd service.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Running the tests&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Self-tests&#34;&gt;Test types&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;S.M.A.R.T. drives may offer a number of self-tests:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Short: Checks the electrical and mechanical performance as well as the read performance of the disk. Electrical tests might include a test of buffer RAM, a read/write circuitry test, or a test of the read/write head elements. Mechanical test includes seeking and servo on data tracks. Scans small parts of the drive&#39;s surface (area is vendor-specific and there is a time limit on the test). Checks the list of pending sectors that may have read errors, and it usually takes under two minutes.&lt;/li&gt; &lt;li&gt;Long/extended: A longer and more thorough version of the short self-test, scanning the entire disk surface with no time limit. This test usually takes several hours, depending on the read/write speed of the drive and its size. It is possible for the long test to pass even if the short test fails.&lt;/li&gt; &lt;li&gt;Conveyance: Intended as a quick test to identify damage incurred during transporting of the device from the drive manufacturer to the computer manufacturer. Only available on ATA drives, and it usually takes several minutes.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Drives remain operable during self-test, unless a &#34;captive&#34; option (ATA only) is requested.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Long test&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Start with a long self test with &lt;code&gt;smartctl&lt;/code&gt;. Assuming the disk to test is &lt;code&gt;/dev/sdd&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;long&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The command will respond with an estimate of how long it thinks the test will take to complete.&lt;/p&gt; &lt;p&gt;To check progress use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;martctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-A&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remaining
smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remaining
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Don&#39;t check too often because it can abort the test with some drives. If you receive an empty output, examine the reported status with:&lt;/p&gt; &lt;p&gt;&lt;code&gt;`bash smartctl -l selftest /dev/sdd&lt;/code&gt;&lt;/p&gt; &lt;p&gt;If errors are shown, check the &lt;code&gt;dmesg&lt;/code&gt; as there are usually useful traces of the error.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/smartctl/#understanding-the-tests&#34;&gt;Understanding the tests.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The output of a &lt;code&gt;smartctl&lt;/code&gt; command is difficult to read:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;smartctl 5.40 2010-03-16 r3077 [x86_64-unknown-linux-gnu] (local build)
Copyright (C) 2002-10 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF INFORMATION SECTION ===
Model Family:     SAMSUNG SpinPoint F2 EG series
Device Model:     SAMSUNG HD502HI
Serial Number:    S1VZJ9CS712490
Firmware Version: 1AG01118
User Capacity:    500,107,862,016 bytes
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   8
ATA Standard is:  ATA-8-ACS revision 3b
Local Time is:    Wed Feb  9 15:30:42 2011 CET
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

General SMART Values:
Offline data collection status:  (0x00)    Offline data collection activity
                    was never started.
                    Auto Offline Data Collection: Disabled.
Self-test execution status:      (   0)    The previous self-test routine completed
                    without error or no self-test has ever
                    been run.
Total time to complete Offline
data collection:          (6312) seconds.
Offline data collection
capabilities:              (0x7b) SMART execute Offline immediate.
                    Auto Offline data collection on/off support.
                    Suspend Offline collection upon new
                    command.
                    Offline surface scan supported.
                    Self-test supported.
                    Conveyance Self-test supported.
                    Selective Self-test supported.
SMART capabilities:            (0x0003)    Saves SMART data before entering
                    power-saving mode.
                    Supports SMART auto save timer.
Error logging capability:        (0x01)    Error logging supported.
                    General Purpose Logging supported.
Short self-test routine
recommended polling time:      (   2) minutes.
Extended self-test routine
recommended polling time:      ( 106) minutes.
Conveyance self-test routine
recommended polling time:      (  12) minutes.
SCT capabilities:            (0x003f)    SCT Status supported.
                    SCT Error Recovery Control supported.
                    SCT Feature Control supported.
                    SCT Data Table supported.

SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000f   099   099   051    Pre-fail  Always       -       2376
  3 Spin_Up_Time            0x0007   091   091   011    Pre-fail  Always       -       3620
  4 Start_Stop_Count        0x0032   100   100   000    Old_age   Always       -       405
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x000f   253   253   051    Pre-fail  Always       -       0
  8 Seek_Time_Performance   0x0025   100   100   015    Pre-fail  Offline      -       0
  9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       717
 10 Spin_Retry_Count        0x0033   100   100   051    Pre-fail  Always       -       0
 11 Calibration_Retry_Count 0x0012   100   100   000    Old_age   Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       405
 13 Read_Soft_Error_Rate    0x000e   099   099   000    Old_age   Always       -       2375
183 Runtime_Bad_Block       0x0032   100   100   000    Old_age   Always       -       0
84 End-to-End_Error        0x0033   100   100   000    Pre-fail  Always       -       0
187 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       2375
188 Command_Timeout         0x0032   100   100   000    Old_age   Always       -       0
190 Airflow_Temperature_Cel 0x0022   084   074   000    Old_age   Always       -       16 (Lifetime Min/Max 16/16)
194 Temperature_Celsius     0x0022   084   071   000    Old_age   Always       -       16 (Lifetime Min/Max 16/16)
195 Hardware_ECC_Recovered  0x001a   100   100   000    Old_age   Always       -       3558
196 Reallocated_Event_Count 0x0032   100   100   000    Old_age   Always       -       0
197 Current_Pending_Sector  0x0012   098   098   000    Old_age   Always       -       81
198 Offline_Uncorrectable   0x0030   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x003e   100   100   000    Old_age   Always       -       1
200 Multi_Zone_Error_Rate   0x000a   100   100   000    Old_age   Always       -       0
201 Soft_Read_Error_Rate    0x000a   253   253   000    Old_age   Always       -       0

MART Error Log Version: 1
No Errors Logged

SMART Self-test log structure revision number 1
No self-tests have been logged.  [To run self-tests, use: smartctl -t]

SMART Selective self-test log data structure revision number 1
 SPAN  MIN_LBA  MAX_LBA  CURRENT_TEST_STATUS
    1        0        0  Not_testing
    2        0        0  Not_testing
    3        0        0  Not_testing
    4        0        0  Not_testing
    5        0        0  Not_testing
Selective self-test flags (0x0):
  After scanning selected spans, do NOT read-scan remainder of disk.
If Selective self-test is pending on power-up, resume after 0 minute delay.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Checking overall health&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Somewhere in your report you&#39;ll see something like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If it doesn’t return PASSED, you should immediately backup all your data. Your hard drive is probably failing.&lt;/p&gt; &lt;p&gt;That message can also be shown with &lt;code&gt;smartctl -H /dev/sda&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Known_ATA_S.M.A.R.T._attributes&#34;&gt;Checking the SMART attributes&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Each drive manufacturer defines a set of attributes, and sets threshold values beyond which attributes should not pass under normal operation. But they do not agree on precise attribute definitions and measurement units, the following list of attributes is a general guide only.&lt;/p&gt; &lt;p&gt;If one or more attribute have the &#34;prefailure&#34; flag, and the &#34;current value&#34; of such prefailure attribute is smaller than or equal to its &#34;threshold value&#34; (unless the &#34;threshold value&#34; is 0), that will be reported as a &#34;drive failure&#34;. In addition, a utility software can send SMART RETURN STATUS command to the ATA drive, it may report three status: &#34;drive OK&#34;, &#34;drive warning&#34; or &#34;drive failure&#34;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://ma.juii.net/blog/interpret-smart-attributes&#34;&gt;SMART attributes columns&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Every of the SMART attributes has several columns as shown by “smartctl -a &lt;device&gt;”:&lt;/device&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ID: The ID number of the attribute, good for comparing with other lists like &lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Known_ATA_S.M.A.R.T._attributes&#34;&gt;Wikipedia: S.M.A.R.T.: Known ATA S.M.A.R.T. attributes&lt;/a&gt; because the attribute names sometimes differ. Name: The name of the SMART attribute.&lt;/li&gt; &lt;li&gt;Value: The current, normalized value of the attribute. Higher values are always better (except for temperature for hard disks of some manufacturers). The range is normally 0-100, for some attributes 0-255 (so that 100 resp. 255 is best, 0 is worst). There is no standard on how manufacturers convert their raw value to this normalized one: when the normalized value approaches threshold, it can do linearily, exponentially, logarithmically or any other way, meaning that a doubled normalized value does not necessarily mean “twice as good”.&lt;/li&gt; &lt;li&gt;Worst: The worst (normalized) value that this attribute had at any point of time where SMART was enabled. There seems to be no mechanism to reset current SMART attribute values, but this still makes sense as some SMART attributes, for some manufacturers, fluctuate over time so that keeping the worst one ever is meaningful.&lt;/li&gt; &lt;li&gt;Threshold: The threshold below which the normalized value will be considered “exceeding specifications”. If the attribute type is “Pre-fail”, this means that SMART thinks the hard disk is just before failure. This will “trigger” SMART: setting it from “SMART test passed” to “SMART impending failure” or similar status.&lt;/li&gt; &lt;li&gt;Type: The type of the attribute. Either “Pre-fail” for attributes that are said to indicate impending failure, or “Old_age” for attributes that just indicate wear and tear. Note that one and the same attribute can be classified as “Pre-fail” by one manufacturer or for one model and as “Old_age” by another or for another model. This is the case for example for attribute Seek_Error_Rate (ID 7), which is a widespread phenomenon on many disks and not considered critical by some manufacturers, but Seagate has it as “Pre-fail”.&lt;/li&gt; &lt;li&gt;Raw value: The current raw value that was converted to the normalized value above. smartctl shows all as decimal values, but some attribute values of some manufacturers cannot be reasonably interpreted that way&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/smartctl/#reacting-to-smart-values&#34;&gt;Reacting to SMART Values.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;It is said that a drive that starts getting bad sectors (attribute ID 5) or “pending” bad sectors (attribute ID 197; they most likely are bad, too) will usually be trash in 6 months or less. The only exception would be if this does not happen: that is, bad sector count increases, but then stays stable for a long time, like a year or more. For that reason, one normally needs a diagramming / journaling tool for SMART. Many admins will exchange the hard drive if it gets reallocated sectors (ID 5) or sectors “under investigation” (ID 197)&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology#Known_ATA_S.M.A.R.T._attributes&#34;&gt;Critical SMART attributes&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Of all the attributes I&#39;m going to analyse only the critical ones&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Read Error Rate&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 01 (0x01) deal: Low +Correlation with probability of failure: not clear&lt;/p&gt; &lt;p&gt;(Vendor specific raw value.) Stores data related to the rate of hardware read errors that occurred when reading data from a disk surface. The raw value has different structure for different vendors and is often not meaningful as a decimal number. For some drives, this number may increase during normal operation without necessarily signifying errors.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reallocated Sectors Count&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 05 (0x05) Ideal: Low Correlation with probability of failure: Strong&lt;/p&gt; &lt;p&gt;Count of reallocated sectors. The raw value represents a count of the bad sectors that have been found and remapped. Thus, the higher the attribute value, the more sectors the drive has had to reallocate. This value is primarily used as a metric of the life expectancy of the drive; a drive which has had any reallocations at all is significantly more likely to fail in the immediate months. If Raw value of 0x05 attribute is higher than its Threshold value, that will reported as &#34;drive warning&#34;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Spin Retry Count&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 10 (0x0A) Ideal: Low Correlation with probability of failure: Strong&lt;/p&gt; &lt;p&gt;Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the condition that the first attempt was unsuccessful). An increase of this attribute value is a sign of problems in the hard disk mechanical subsystem.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Current Pending Sector Count&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 197 (0xC5) Ideal: Low Correlation with probability of failure: Strong&lt;/p&gt; &lt;p&gt;Count of &#34;unstable&#34; sectors (waiting to be remapped, because of unrecoverable read errors). If an unstable sector is subsequently read successfully, the sector is remapped and this value is decreased. Read errors on a sector will not remap the sector immediately (since the correct value cannot be read and so the value to remap is not known, and also it might become readable later); instead, the drive firmware remembers that the sector needs to be remapped, and will remap it the next time it has been successfully read.[76]&lt;/p&gt; &lt;p&gt;However, some drives will not immediately remap such sectors when successfully read; instead the drive will first attempt to write to the problem sector, and if the write operation is successful the sector will then be marked as good (in this case, the &#34;Reallocation Event Count&#34; (0xC4) will not be increased). This is a serious shortcoming, for if such a drive contains marginal sectors that consistently fail only after some time has passed following a successful write operation, then the drive will never remap these problem sectors. If Raw value of 0xC5 attribute is higher than its Threshold value, that will reported as &#34;drive warning&#34;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;(Offline) Uncorrectable Sector Count&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 198 (0xC6) Ideal: Low Correlation with probability of failure: Strong&lt;/p&gt; &lt;p&gt;The total count of uncorrectable errors when reading/writing a sector. A rise in the value of this attribute indicates defects of the disk surface and/or problems in the mechanical subsystem.&lt;/p&gt; &lt;p&gt;In the 60 days following the first uncorrectable error on a drive (S.M.A.R.T. attribute 0xC6 or 198) detected as a result of an offline scan, the drive was, on average, 39 times more likely to fail than a similar drive for which no such error occurred.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Non critical SMART attributes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The next attributes appear to change in the logs but that doesn&#39;t mean that there is anything going wrong&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Hardware ECC Recovered&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;ID: 195 (0xC3) Ideal: Varies Correlation with probability of failure: Low&lt;/p&gt; &lt;p&gt;(Vendor-specific raw value.) The raw value has different structure for different vendors and is often not meaningful as a decimal number. For some drives, this number may increase during normal operation without necessarily signifying errors.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/smartctl/#monitorization&#34;&gt;Monitorization.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To monitor your drive health you can use &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/prometheus/&#34;&gt;prometheus&lt;/a&gt; with &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/prometheus/alertmanager/&#34;&gt;alertmanager&lt;/a&gt; for alerts and &lt;a href=&#34;https://lyz-code.github.io/blue-book/grafana/&#34;&gt;grafana&lt;/a&gt; for dashboards.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installing the exporter&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The prometheus community has it&#39;s own &lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter&#34;&gt;smartctl exporter&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Using the binary&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can download the latest binary from the repository &lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter/releases&#34;&gt;releases&lt;/a&gt; and configure the &lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter/blob/master/systemd/smartctl_exporter.service&#34;&gt;systemd service&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;unp&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl_exporter-0.13.0.linux-amd64.tar.gz
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl_exporter-0.13.0.linux-amd64/smartctl_exporter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Add the &lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter/blob/master/systemd/smartctl_exporter.service&#34;&gt;service&lt;/a&gt; to &lt;code&gt;/etc/systemd/system/smartctl-exporter.service&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;smartctl exporter service&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;network-online.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;simple&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;PIDFile&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/run/smartctl_exporter.pid&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/bin/smartctl_exporter&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;root&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Group&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;root&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;SyslogIdentifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;smartctl_exporter&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on-failure&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;RemainAfterExit&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;no&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;RestartSec&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;100ms&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardOutput&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;hen enable it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl-exporter
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl-exporter&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/prometheus-community/smartctl_exporter?tab=readme-ov-file#example-of-running-in-docker&#34;&gt;Using docker&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;smartctl-exporter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl-exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;prometheuscommunity/smartctl-exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;privileged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;root&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;9633:9633&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configuring prometheus&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Add the next scraping metrics:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;job_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;metrics_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/metrics&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;scrape_timeout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;60s&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static_configs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;targets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;smartctl-exporter&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;9633&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;your-hostname&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configuring the alerts&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Taking as a reference the &lt;a href=&#34;https://samber.github.io/awesome-prometheus-alerts/rules#s.m.a.r.t-device-monitoring&#34;&gt;awesome prometheus rules&lt;/a&gt; and &lt;a href=&#34;https://www.wirewd.com/hacks/blog/monitoring_a_mixed_fleet_of_flash_hdd_and_nvme_devices_with_node_exporter_and_prometheus&#34;&gt;this wired post&lt;/a&gt; I&#39;m using the next rules:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nn&#34;&gt;---&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl exporter&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartDeviceTemperatureWarning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_temperature &amp;gt; 60&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;2m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart device temperature warning (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;temperature&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartDeviceTemperatureCritical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_temperature &amp;gt; 80&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;2m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart device temperature critical (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;temperature&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;critical&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartCriticalWarning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_critical_warning &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart critical warning (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;critical&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;warning&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartNvmeWearoutIndicator&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_available_spare{device=~&#34;nvme.*&#34;} &amp;lt; smartctl_device_available_spare_threshold{device=~&#34;nvme.*&#34;}&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart NVME Wearout Indicator (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;NVMe&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;wearing&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartNvmeMediaError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_media_errors &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart NVME Media errors (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;Contains&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;number&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;occurrences&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;where&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;controller&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;detected&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;an&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;unrecovered&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;integrity&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;error.&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Errors&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;such&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;uncorrectable&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;ECC,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;CRC&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;checksum&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;failure,&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;or&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LBA&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;tag&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;mismatch&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;are&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;included&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;field&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;SmartSmartStatusError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_smart_status &amp;lt; 1&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;15m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;critical&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;Smart general status error (instance {{ $labels.hostname }})&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DiskReallocatedSectorsIncreased&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_attribute{attribute_id=&#34;5&#34;, attribute_value_type=&#34;raw&#34;} &amp;gt; max_over_time(smartctl_device_attribute{attribute_id=&#34;5&#34;, attribute_value_type=&#34;raw&#34;}[1h])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Reallocated&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sectors&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Increased&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(Reallocated&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sectors&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;increased&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;w w-Error&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DiskSpinRetryCountIncreased&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_attribute{attribute_id=&#34;10&#34;, attribute_value_type=&#34;raw&#34;} &amp;gt; max_over_time(smartctl_device_attribute{attribute_id=&#34;10&#34;, attribute_value_type=&#34;raw&#34;}[1h])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Spin&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Retry&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Increased&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(Spin&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Retry&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;increased&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DiskCurrentPendingSectorCountIncreased&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_attribute{attribute_id=&#34;197&#34;, attribute_value_type=&#34;raw&#34;} &amp;gt; max_over_time(smartctl_device_attribute{attribute_id=&#34;197&#34;, attribute_value_type=&#34;raw&#34;}[1h])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Current&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Pending&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sector&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Increased&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;197&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(Current&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Pending&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sector&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;increased&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;DiskUncorrectableSectorCountIncreased&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;smartctl_device_attribute{attribute_id=&#34;198&#34;, attribute_value_type=&#34;raw&#34;} &amp;gt; max_over_time(smartctl_device_attribute{attribute_id=&#34;198&#34;, attribute_value_type=&#34;raw&#34;}[1h])&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Uncorrectable&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sector&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Increased&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;SMART&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;attribute&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;198&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(Uncorrectable&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Sector&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Count)&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;increased&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.device&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;(instance&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}})\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;VALUE&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$value&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}\n&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;LABELS&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configuring the grafana dashboards&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Of the different grafana dashboards (&lt;a href=&#34;https://grafana.com/grafana/dashboards/22604-smartctl-exporter-dashboard/&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://grafana.com/grafana/dashboards/20204-smart-hdd/&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://grafana.com/grafana/dashboards/22381-smartctl-exporter/&#34;&gt;3&lt;/a&gt;) I went for the first one.&lt;/p&gt; &lt;p&gt;Import it with the UI of grafana, make it work and then export the json to store it in your infra as code respository.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Self-Monitoring,_Analysis_and_Reporting_Technology&#34;&gt;Wikipedia&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://sourceforge.net/projects/smartmontools/&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.smartmontools.org/wiki/TocDoc&#34;&gt;Documentation&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_storage_planning/#thoughts-on-adding-new-disks-to-zfs&#34;&gt;Thoughts on adding new disks to ZFS.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;When it comes to expanding an existing ZFS storage system, careful consideration is crucial. In my case, I faced a decision point with my storage cluster: after two years of reliable service from my 8TB drives, I needed more capacity. This led me to investigate the best way to integrate newly acquired refurbished 12TB drives into the system. Here&#39;s my journey through this decision-making process and the insights gained along the way.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;The Starting Point&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;My existing setup consisted of 8TB drives purchased new, which had been running smoothly for two years. The need for expansion led me to consider refurbished 12TB drives as a cost-effective solution. However, mixing new and refurbished drives, especially of different capacities, raised several important considerations that needed careful analysis.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Initial Drive Assessment&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The first step was to evaluate the reliability of all drives. Using &lt;code&gt;smartctl&lt;/code&gt;, I analyzed the SMART data across both the existing and new drives:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;b&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;c&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;e&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;g&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;h&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;i&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;do&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;/dev/sd&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$disk&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: old &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sd&lt;span class=&#34;nv&#34;&gt;$disk&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Old&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; pre-fail: &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sd&lt;span class=&#34;nv&#34;&gt;$disk&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;Pre-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wc&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-l&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The results showed similar values across all drives, with &#34;Old_Age&#34; attributes ranging from 14-17 and &#34;Pre-fail&#34; attributes between 3-6. While this indicated all drives were aging, they were still functioning with acceptable parameters. However, raw SMART data doesn&#39;t tell the whole story, especially when comparing new versus refurbished drives.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Drive Reliability Considerations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;After careful evaluation, I found myself trusting the existing 8TB drives more than the newer refurbished 12TB ones. This conclusion was based on several factors:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The 8TB drives had a proven track record in my specific environment&lt;/li&gt; &lt;li&gt;Their smaller size meant faster resilver times, reducing the window of vulnerability during recovery&lt;/li&gt; &lt;li&gt;One of the refurbished 12TB drives was already showing concerning symptoms (8 reallocated sectors, although a badblocks didn&#39;t increase that number), which reduced confidence in the entire batch&lt;/li&gt; &lt;li&gt;The existing drives were purchased new, while the 12TB drives were refurbished, adding an extra layer of uncertainty&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Layout Options Analysis&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;When expanding a ZFS system, there&#39;s always the temptation to simply add more vdevs to the existing pool. However, I investigated two main approaches:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Creating a new separate ZFS pool with the new disks&lt;/li&gt; &lt;li&gt;Add another vdev to the existent pool&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Resilver time&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Adding the 12TB drives to the pool and redistributing the data across all 8 drives will help reduce the resilver time. Here&#39;s a detailed breakdown:&lt;/p&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;Current Situation&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;4x 8TB drives at 95% capacity means each drive is heavily packed&lt;/p&gt; &lt;/li&gt; &lt;li&gt;High data density means longer resilver times&lt;/li&gt; &lt;li&gt; &lt;p&gt;Limited free space for data movement and reconstruction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;After Adding 12TB Drives&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Total pool capacity increases significantly&lt;/p&gt; &lt;/li&gt; &lt;li&gt;ZFS will automatically start rebalancing data across all 8 drives&lt;/li&gt; &lt;li&gt;This process (sometimes called &#34;data shuffling&#34; or &#34;data redistribution&#34;) has several benefits:&lt;/li&gt; &lt;li&gt;Reduces data density per drive&lt;/li&gt; &lt;li&gt;Creates more free space&lt;/li&gt; &lt;li&gt;Improves overall pool performance&lt;/li&gt; &lt;li&gt; &lt;p&gt;Potentially reduces future resilver times&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;Resilver Time Reduction Mechanism&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;With data spread across more drives, each individual drive has less data to resilver&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Less data per drive = faster resilver process&lt;/li&gt; &lt;li&gt;The redistribution happens gradually and in the background&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Understanding Failure Scenarios&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The key differentiator between these approaches came down to failure scenarios:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Single Drive Failure&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Both configurations handle single drive failures similarly, though the 12TB drives&#39; longer resilver time creates a longer window of vulnerability in the two-vdev configuration if the data load is evenly shared between the disks. This is particularly concerning with refurbished drives, where the failure probability might be higher.&lt;/p&gt; &lt;p&gt;However if as soon as you add the other vdev to the pool you defragment the data inside zfs, the 8TB drives will be less filled, so until more data is added you may reduce the resilver time as they have less data.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Double Drive Failure&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This is where the configurations differ significantly:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;In a two-vdev pool, losing two drives from the same vdev would cause complete pool failure&lt;/li&gt; &lt;li&gt;With separate pools, a double drive failure would only affect one pool, allowing the other to continue operating. This way you can store the critical data on the pool you trust more.&lt;/li&gt; &lt;li&gt;Given the mixed drive origins (new vs refurbished), isolating potential failures becomes more critical&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Performance Considerations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;While investigating performance implications, I found several interesting points about IOPS and throughput:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ZFS stripes data across vdevs, meaning more vdevs generally means better IOPS&lt;/li&gt; &lt;li&gt;In RAIDZ configurations, IOPS are limited by the slowest drive in the vdev&lt;/li&gt; &lt;li&gt;Multiple mirrored vdevs provide the best combined IOPS performance&lt;/li&gt; &lt;li&gt;Streaming speeds scale with the number of data disks in a RAIDZ vdev&lt;/li&gt; &lt;li&gt;When mixing drive sizes, ZFS tends to favor larger vdevs, which could lead to uneven wear&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Easiness of configuration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cache and log&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you already have a zpool with a cache and logs in nvme, then if you were to use two pools, you&#39;d need to reformat your nvme drives to create space for the new partitions needed for the new zpool.&lt;/p&gt; &lt;p&gt;This would allow you to specify different cache sizes for each pool. But it comes at the cost of a more complex operation.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;New pool creation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Adding a vdev to an existing pool is quicker and easier than to create a zpool. You need to make sure that you initialise it with the correct configuration.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Storage management&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Having two pools doubles the operation tasks. One of the pools are to be filled soon, so you may need to manually move files and directories around to rebalance it.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Final Decision&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;After weighing all factors, if you favour reliability over easiness of your life implement two separate ZFS pools. This statement is primarily driven by:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Enhanced Reliability&lt;/strong&gt;: By separating the pools, we can maintain service availability even if one pool fails completely&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Data Prioritization&lt;/strong&gt;: This allows placing critical application data on the more reliable pool (8TB drives), while using the refurbished drives for less critical data like media files&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Risk Isolation&lt;/strong&gt;: Keeping the proven, new-purchased drives separate from the refurbished ones minimizes the impact of potential issues with the refurbished drives&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Consistent Performance&lt;/strong&gt;: Following the best practice of keeping same-sized drives together in pools&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;However I&#39;m currently favouring easiness of life and trust my backup solution (I hope not to read this line in the future with regret :P), so I&#39;ll go with two vdevs.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Through this investigation, I learned several important lessons about ZFS storage design:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Raw parity drive count isn&#39;t the only reliability metric - configuration matters more than simple redundancy numbers&lt;/li&gt; &lt;li&gt;Pool layout significantly impacts both performance and failure scenarios&lt;/li&gt; &lt;li&gt;Sometimes simpler configurations (like separate pools) can provide better overall reliability than more complex ones&lt;/li&gt; &lt;li&gt;Consider the full lifecycle of the storage, including maintenance operations like resilver times&lt;/li&gt; &lt;li&gt;When expanding storage, don&#39;t underestimate the value of isolating different generations or sources of hardware&lt;/li&gt; &lt;li&gt;The history and source of drives (new vs refurbished) should influence your pool design decisions&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;This investigation reinforced that storage design isn&#39;t just about maximizing space or performance - it&#39;s about finding the right balance of reliability, performance, and manageability for your specific needs. When dealing with mixed drive sources and different capacities, this balance becomes even more critical.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References and further reading&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.truenas.com/blog/zfs-pool-performance-2/&#34;&gt;Truenas post&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://forums.freebsd.org/threads/when-does-it-make-more-sense-to-use-multiple-vdevs-in-a-zfs-pool.83586/&#34;&gt;Freebsd post&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://klarasystems.com/articles/choosing-the-right-zfs-pool-layout/&#34;&gt;Klarasystems post&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;diff --git a/mkdocs.yml b/mkdocs.yml index 74292dd717..596f1506e8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -103,6 +103,8 @@ nav: - Email clients: - himalaya: himalaya.md - alot: alot.md + - k9: k9.md + - Email protocols: - Maildir: maildir.md - Instant Messages Management: @@ -371,6 +373,7 @@ nav: - File management configuration: - NeoTree: neotree.md - Telescope: telescope.md + - fzf.nvim: fzf_nvim.md - Editing specific configuration: - vim_editor_plugins.md - Vim formatters: vim_formatters.md @@ -566,7 +569,10 @@ nav: - OpenZFS storage planning: zfs_storage_planning.md - Sanoid: sanoid.md - ZFS Prometheus exporter: zfs_exporter.md - - Hard drive health: hard_drive_health.md + - Hard drive health: + - hard_drive_health.md + - Smartctl: smartctl.md + - badblocks: badblocks.md - Resilience: - linux_resilience.md - Memtest: memtest.md @@ -768,7 +774,8 @@ nav: # - Streaming channels: streaming_channels.md - Music: - Sister Rosetta Tharpe: sister_rosetta_tharpe.md - - Video Gaming: + - Videogames: + - DragonSweeper: dragonsweeper.md - King Arthur Gold: kag.md - The Battle for Wesnoth: - The Battle for Wesnoth: wesnoth.md&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;badblocks&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;badblocks&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/badblocks/#check-the-health-of-a-disk-with-badblocks&#34;&gt;Check the health of a disk with badblocks.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;badblocks&lt;/code&gt; command will write and read the disk with different patterns, thus overwriting the whole disk, so you will loose all the data in the disk.&lt;/p&gt; &lt;p&gt;This test is good for rotational disks as there is no disk degradation on massive writes, do not use it on SSD though.&lt;/p&gt; &lt;p&gt;WARNING: be sure that you specify the correct disk!!&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;badblocks&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-wsv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-b&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4096&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sde&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tee&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;disk_analysis_log.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If errors are shown is that all of the spare sectors of the disk are used, so you must not use this disk anymore. Again, check &lt;code&gt;dmesg&lt;/code&gt; for traces of disk errors.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#removing-a-disk-from-the-pool&#34;&gt;Removing a disk from the pool.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;remove&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank0&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will trigger the data evacuation from the disk. Check &lt;code&gt;zpool status&lt;/code&gt; to see when it finishes.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#encrypting-zfs-drives-with-luks&#34;&gt;Encrypting ZFS Drives with LUKS.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Warning: Proceed with Extreme Caution&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;IMPORTANT SAFETY NOTICE:&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;These instructions will COMPLETELY WIPE the target drive&lt;/li&gt; &lt;li&gt;Do NOT attempt on production servers&lt;/li&gt; &lt;li&gt;Experiment only on drives with no valuable data&lt;/li&gt; &lt;li&gt;Seek professional help if anything is unclear&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A drive you want to encrypt (will be referred to as &lt;code&gt;/dev/sdx&lt;/code&gt;)&lt;/li&gt; &lt;li&gt;Root access&lt;/li&gt; &lt;li&gt;Basic understanding of Linux command line&lt;/li&gt; &lt;li&gt;Backup of all important data&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Step 1: Create LUKS Encryption Layer&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;First, format the drive with LUKS encryption:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cryptsetup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;luksFormat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;You&#39;ll be prompted for a sudo password&lt;/li&gt; &lt;li&gt;Create a strong encryption password (mix of uppercase, lowercase, numbers, symbols)&lt;/li&gt; &lt;li&gt;Note the precise capitalization in commands&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Step 2: Open the Encrypted Disk&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Open the newly encrypted disk:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cryptsetup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;luksOpen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sdx_crypt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This creates a mapped device at &lt;code&gt;/dev/mapper/sdx_crypt&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Step 3: Create ZFS Pool or the vdev&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;For example to create a ZFS pool on the encrypted device:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;create&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ashift&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;-O&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;compression&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;lz4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\&lt;/span&gt;
+&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/mapper/sdx_crypt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Check the &lt;a href=&#34;#create-your-pool&#34;&gt;create zpool section&lt;/a&gt; to know which configuration flags to use.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Step 4: Set Up Automatic Unlocking&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Generate a Keyfile&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Create a random binary keyfile:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1024&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/urandom&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/etc/zfs/keys/sdx.key
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0400&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/zfs/keys/sdx.key
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;em&gt;Add Keyfile to LUKS&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Add the keyfile to the LUKS disk:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cryptsetup&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;luksAddKey&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdx&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/zfs/keys/sdx.key
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;You&#39;ll be asked to enter the original encryption password&lt;/li&gt; &lt;li&gt;This adds the binary file to the LUKS disk header&lt;/li&gt; &lt;li&gt;Now you can unlock the drive using either the password or the keyfile&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Step 5: Configure Automatic Mounting&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Find Drive UUID&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Get the drive&#39;s UUID:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blkid
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Look for the line with &lt;code&gt;TYPE=&#34;crypto_LUKS&#34;&lt;/code&gt;. Copy the UUID.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Update Crypttab&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Edit the crypttab file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;vim&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/crypttab
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Add an entry like:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sdx_crypt UUID=your-uuid-here /etc/zfs/keys/sdx.key luks,discard
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Final Step: Reboot&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Reboot your system&lt;/li&gt; &lt;li&gt;The drive will be automatically decrypted and imported&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;+- Keep your keyfile and encryption password secure - Store keyfiles with restricted permissions - Consider backing up the LUKS header&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Double-check UUIDs&lt;/li&gt; &lt;li&gt;Verify keyfile permissions&lt;/li&gt; &lt;li&gt;Ensure cryptsetup and ZFS are installed&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Security Notes&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;This method provides full-disk encryption at rest&lt;/li&gt; &lt;li&gt;Data is inaccessible without the key or password&lt;/li&gt; &lt;li&gt;Protects against physical drive theft&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;While these instructions are comprehensive, they come with inherent risks. Always:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Have backups&lt;/li&gt; &lt;li&gt;Test in non-critical environments first&lt;/li&gt; &lt;li&gt;Understand each step before executing&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Further reading&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://wiki.alpinelinux.org/wiki/Setting_up_ZFS_on_LUKS&#34;&gt;Setting up ZFS on LUKS - Alpine Linux Wiki&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.malachisoord.com/2023/11/04/decrypt-additiona-luks-encrypted-volumes-on-boot/&#34;&gt;Decrypt Additional LUKS Encrypted Volumes on Boot&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://dradis.com/support/guides/customization/auto-unlock-luks-encrypted-drive.html&#34;&gt;Auto-Unlock LUKS Encrypted Drive - Dradis Support Guide&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://askubuntu.com/questions/996155/how-do-i-automatically-decrypt-an-encrypted-filesystem-on-the-next-reboot&#34;&gt;How do I automatically decrypt an encrypted filesystem on the next reboot? - Ask Ubuntu&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#add-a-disk-to-an-existing-vdev&#34;&gt;Add a disk to an existing vdev.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;add&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tank&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#add-a-vdev-to-an-existing-pool&#34;&gt;Add a vdev to an existing pool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;``bash zpool add main raidz1-1 /dev/disk-1 /dev/disk-2 /dev/disk-3 /dev/disk-4 ```&lt;/p&gt; &lt;p&gt;You don&#39;t need to specify the &lt;code&gt;ashift&lt;/code&gt; or the &lt;code&gt;autoexpand&lt;/code&gt; as they are set on zpool creation.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#books&#34;&gt;Add zfs book.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://mwl.io/nonfiction/os#fmzfs&#34;&gt;FreeBSD Mastery: ZFS by Michael W Lucas and Allan Jude&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;authentication&#34;&gt;Authentication&lt;/h3&gt; &lt;h4 id=&#34;authentik&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/authentik/&#34;&gt;Authentik&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add api and library docs.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.goauthentik.io/docs/developer-docs/api/&#34;&gt;Using the API&lt;/a&gt;&lt;/p&gt; &lt;p&gt;There is a &lt;a href=&#34;https://pypi.org/project/authentik-client/&#34;&gt;python library&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;Linux&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#record-the-audio-from-your-computer&#34;&gt;Record the audio from your computer.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can record audio being played in a browser using &lt;code&gt;ffmpeg&lt;/code&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Check your default audio source:&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pactl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;list&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sources&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-E&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;Name|Description&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;Record using &lt;code&gt;ffmpeg&lt;/code&gt;:&lt;/li&gt; &lt;/ol&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pulse&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;your_monitor_source&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.wav
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Example:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pulse&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;alsa_output.pci-0000_00_1b.0.analog-stereo.monitor&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.wav
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;Stop recording with &lt;strong&gt;Ctrl+C&lt;/strong&gt;.&lt;/li&gt; &lt;/ol&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;relevant-content&#34;&gt;Relevant content&lt;/h2&gt; &lt;h3 id=&#34;videogames&#34;&gt;Videogames&lt;/h3&gt; &lt;h4 id=&#34;dragonsweeper&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/dragonsweeper/&#34;&gt;DragonSweeper&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce dragonsweeper.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://danielben.itch.io/dragonsweeper&#34;&gt;DragonSweeper&lt;/a&gt; is an addictive simple RPG-tinged take on the Minesweeper formula. You can &lt;a href=&#34;https://danielben.itch.io/dragonsweeper&#34;&gt;play it for free&lt;/a&gt; in your browser.&lt;/p&gt; &lt;p&gt;If you&#39;re lost at the beginning start reading the &lt;a href=&#34;https://arstechnica.com/gaming/2025/02/dragonsweeper-is-my-favorite-game-of-2025-so-far&#34;&gt;ArsTechnica blog post&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tips&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Use &lt;code&gt;Shift&lt;/code&gt; to mark numbers you already know.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://danielben.itch.io/dragonsweeper&#34;&gt;Play&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://danielben.itch.io/dragonsweeper&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://arstechnica.com/gaming/2025/02/dragonsweeper-is-my-favorite-game-of-2025-so-far&#34;&gt;ArsTechnica blog post&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;February 25, 2025 00:11:50 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-02-25T00:11:50+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;February 25, 2025 00:11:50 UTC&#34;&gt;2025-02-25&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_02_24/</link>
      <pubDate>2025-02-25 00:11:50+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_02_24/</guid>
      
    </item>
    
    <item><title>15th January 2025</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;activism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/&#34;&gt;Activism&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/activism/#references&#34;&gt;Add 38c3 talk on state of surveillance.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://media.ccc.de/v/38c3-state-of-surveillance-a-year-of-digital-threats-to-civil-society&#34;&gt;38C3 Talk: State of Surveillance: A year of digital threats to civil society&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;hacktivism&#34;&gt;Hacktivism&lt;/h3&gt; &lt;h4 id=&#34;gatherings&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mobile_verification_toolkit/&#34;&gt;Gatherings&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Chaos feminist convention.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;events.haecksen.org/cfc25&#34;&gt;Chaos feminist convention&lt;/a&gt; (looks like it will be mostly in german)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Add 38C3 talk from pegasus to predator.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://media.ccc.de/v/38c3-from-pegasus-to-predator-the-evolution-of-commercial-spyware-on-ios&#34;&gt;38C3 talk: From Pegasus to Predator - The evolution of Commercial Spyware on iOS&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;chaos-communication-congress&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/&#34;&gt;Chaos Communication Congress&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/#remember-these-useful-things&#34;&gt;Remember these useful things.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Use c3lingo for german talks&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There are many talks in german, this may deter you from attending them, but don&#39;t worry, if they are hosted in the main tracks you can hear the translation in english live.&lt;/p&gt; &lt;p&gt;You can access them &lt;a href=&#34;https://c3lingo.org/&#34;&gt;here&lt;/a&gt;, they work best with the ccc wifi.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://events.ccc.de/congress/2024/infos/mentors.html&#34;&gt;Chaos mentors&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;At Chaos Mentors, they connect experienced mentors with first-time visitors of Congress. Their goal is to make Congress more inclusive by supporting those who might not usually attend, including people with special needs.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/#first-time-angel-tips&#34;&gt;First time angel tips.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If you&#39;re lost on what shifts you might want to take here is the ones I&#39;ve found easy to do: - Talk access shifts: You will be on the access of the talks making sure that the doors are opened and closed when it should and that people do not linger in the corridors, whenever you want to see a talk in one of the main tracks take these shifts as you&#39;ll be able to watch it fine and also help the organisation. If you know for sure you&#39;ll be attending one of these talks, reserve the shift the day before as they usually fly away soon. - Standby angel: You just stay in heaven for a couple of hours waiting for someone to tell you what you need to do. It&#39;s a good shift to know people and to find your place in heaven. If you know for sure you&#39;ll have a free slot between talks and workshops, reserve the shift the day before as they usually fly away soon. - At teardown: If you can stay after the congress has ended, help in the tear down, I first go to the assemblies that have attracted me the most and then go to heaven to see what else is needed.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;anarchism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/anarchism/&#34;&gt;Anarchism&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/anarchism/#anarchism-in-belarus&#34;&gt;Anarchism in Belarus.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://abc-belarus.org/en/main-page/&#34;&gt;Anarchist black cross Belarus&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://bsky.app/profile/bad-immigrant.bsky.social&#34;&gt;Bad immigrant bluesky&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://pramen.io/en/&#34;&gt;Pramen website&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://kolektiva.media/c/pramenby/videos?s=1&#34;&gt;Pramen videos&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;time-management&#34;&gt;Time management&lt;/h3&gt; &lt;h4 id=&#34;roadmap-adjustment&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/&#34;&gt;Roadmap Adjustment&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Small annotations throughout the document.&lt;/p&gt; &lt;p&gt;The idea of each adjustment is that it&#39;s not cumbersome, so I&#39;ve decided to set a fixed time for each one, I assume that I&#39;ll do my best on both processes and wherever I reach is just fine (remember, better done than perfect).&lt;/p&gt; &lt;p&gt;I believe on the power of constant small changes, so the next review will be built on top of the current one, and thus it will be done better and faster.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#year-review&#34;&gt;Do the first sketch of the year review.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As the year comes to an end it can be a good idea to review stuff that has a year cadence of change and that people are reviewing, for example:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;#how-the-world-has-changed&#34;&gt;How the world has changed&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Relevant content stuff&lt;/li&gt; &lt;li&gt;Life experiences&lt;/li&gt; &lt;li&gt;Your toolset&lt;/li&gt; &lt;li&gt;Your economical year review&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;I&#39;m not going to review the year roadmap or how I&#39;ve changed or my tactics or strategies right now as I feel it makes more sense to do it in the &lt;a href=&#34;#life-review&#34;&gt;life review&lt;/a&gt; just before spring comes. In fact, we&#39;ll be able to do a better life review once we have the output of the review of the year.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Year review timeline&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;As you can see the amount of stuff to review is not something that can be done in a day, my current plan is to prepare the review of the year throughout December and carry it out on the first two weeks of January.&lt;/p&gt; &lt;p&gt;So I&#39;ve scheduled an action each 1&lt;sup&gt;st&lt;/sup&gt; of December with deadline on the 31&lt;sup&gt;st&lt;/sup&gt; to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create a new entry in &lt;code&gt;think.org&lt;/code&gt; with the next format: &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Then I created another action from the 1&lt;sup&gt;st&lt;/sup&gt; of January to the 15&lt;sup&gt;th&lt;/sup&gt; to actually do the review.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Year review phases&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How the world has changed&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You don&#39;t live alone in a bubble, your life is affected by what is going on around you, so if you can it&#39;s always good to analyse it so that you can adjust your roadmap accordingly.&lt;/p&gt; &lt;p&gt;Doing this on January makes a lot of sense because most newspapers and important people do a year review which synthesizes the most important year events and how it has changed throughout the year.&lt;/p&gt; &lt;p&gt;I&#39;m usually gathering the analysis on the &lt;a href=&#34;https://lyz-code.github.io/blue-book/year_reviews/&#34;&gt;Year reviews&lt;/a&gt; article.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;How did my economy change this year&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I take the chance to do a last review of the year through the lenses of my accounting system (&lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/&#34;&gt;beancount&lt;/a&gt;). I&#39;ve made some fava dashboards that gather the most interesting information.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Review the relevant content I&#39;ve consumed&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;With the use of &lt;a href=&#34;https://lyz-code.github.io/blue-book/mediatracker/&#34;&gt;mediatracker&lt;/a&gt; and other life logging tools I take a look at what content I&#39;ve enjoyed the most. I want to share it also with all of you through these articles:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/books/&#34;&gt;Books&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;movies.md&#34;&gt;Movies&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;tv_shows.md&#34;&gt;TV shows&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/podcasts/&#34;&gt;Podcasts&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;streaming_channels.md&#34;&gt;Streaming channels&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;music.md&#34;&gt;Music&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;videogames.md&#34;&gt;Videogames&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;boardgames.md&#34;&gt;Boardgames&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/roadmap_adjustment/#life-review&#34;&gt;First sketch of the life review.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Life reviews are meant to give you an idea of:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;How much have you and your workflows evolved&lt;/li&gt; &lt;li&gt;What roadmap decisions were right, which ones were wrong&lt;/li&gt; &lt;li&gt;With the context you have now, you can think of how you could have avoided the bad decisions.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you have the year&#39;s planning you can analyze it against your task management tools and life logs and create a review document analyzing all.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Life review timeline&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;As you can see the amount of stuff to review is not something that can be done in a day, my current plan is to prepare the review from the 15&lt;sup&gt;th&lt;/sup&gt; of December till the 15&lt;sup&gt;th&lt;/sup&gt; of January and then carry it out until the 23&lt;sup&gt;rd&lt;/sup&gt; of February, to leave space to do the spring quarter and March month reviews.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;year-reviews&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/year_reviews/&#34;&gt;Year reviews&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Primera versión de la revisión del 2024.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Fuentes&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/boletin/balance-2024-socias&#34;&gt;Boletín de socias de El Salto 2024&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/fotografia/imagenes-un-ano-no-se-pudo-parar-genocidio&#34;&gt;Fotografías de un año en el que no se pudo parar el genocidio&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/boletin/diciembre-2024&#34;&gt;Boletín de diciembre de El Salto 2024&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/feminismos/siete-palabras-entender-feminismos-2024&#34;&gt;Siete palabras para entender feminismos 2024&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Fascismo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En 2024, a nivel estatal la extrema derecha avanzó posiciones y cuotas de poder, pero las movilizaciones masivas por la vivienda, contra el modelo turístico y la gestión de la dana desafiaron abiertamente su relato del mundo y su reparto de culpas.&lt;/p&gt; &lt;p&gt;A nivel mundial la cosa va incluso peor:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;estados unidos, la principal potencia económica y militar del mundo ha vuelto a caer en manos de Trump, un multimillonario sádico, que ha conseguido todo su poder a través de su gigantesco poder mediático y un ejército de trolls, bulos y paramilitares supremacistas vestidos con pasamontañas y fusiles de asalto. Los principales países del mundo ya han caído o están a punto de caer en las redes de esta internacional de la desinformación, respaldada y promocionada a su vez por cuatro de los cinco hombres más ricos del mundo.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Uno de ellos es elon musk, un ser despreciable que tras cargarse twitter está haciendo campaña por las ultraderechas como la alemana afd. - &lt;a href=&#34;https://es.wikipedia.org/wiki/Presidencia_de_Javier_Milei&#34;&gt;en argentina ha estado gobernando javier milei&lt;/a&gt; desde el 10 de diciembre de 2023, básicamente se está cargando el estado de derecho y todos los avances en políticas feministas que se consiguieron con tanto esfuerzo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Antifascismo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Las resistencias a las ideas que propugna esta coalición mundial neofascista, que culpa a la migración y a los pobres de todos los males, que niega el cambio climático, los derechos LGTBIQ+ y de las mujeres, pasan por otro lado.&lt;/p&gt; &lt;p&gt;Desde El Salto tenemos la convicción de que el resultado de esta contienda se dirimirá en gran parte en el campo de la información, de los medios y las redes sociales. Por eso creemos que es tan importante, ahora más que nunca, contar con medios propios, que no dependan de grandes poderes económicos o intereses partidarios.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Byron Maher&#34; src=&#34;../../img/2024-antifa.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Manifestación antiracista en las calles de Londres.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Vivienda&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Las gigantescas movilizaciones por la vivienda y contra el modelo depredador del turismo que recorrieron 2024 desde las Islas Canarias, pasando por Baleares, Madrid, Barcelona y casi todas las grandes capitales españolas, son una buena demostración de que el final de esta película está abierto. Después de estas demostraciones de fuerza y significado, la vivienda no es más barata, pero son menos las personas que piensan que el problema de fondo son los “inquiokupas”.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Luz Sosa&#34; src=&#34;../../img/2024-vivienda.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Canarias se plantó en el mes de abril ante el turismo de masas en una movilización histórica simultánea en las ocho islas.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Álvaro Minguito&#34; src=&#34;../../img/2024-vivienda-1.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Manifestación contra la especulación inmobiliaria y por el derecho a la vivienda en octubre.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Alberto Astudillo&#34; src=&#34;../../img/2024-vivienda-2.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Los desahucios han continuado durante el 2024, al amparo de la cobertura jurídica ofrecida a los especuladores que trafican con el derecho a la vivienda digna, en contra de lo que establece la Constitución Española.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Álvaro Minguito&#34; src=&#34;../../img/2024-vivienda-3.jpg&#34;/&gt; Un amanecer en el barrio de Lavapiés, mientras el vecindario espera un nuevo desahucio en su calle, que finalmente se ejecutó, dejando a otra familia en la calle.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cambio climático&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;La Dana&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Similar lucha por el discurso y reparto de culpas se produjo tras la dana en València, donde los intentos de la ultraderecha de dirigir el debate hacia los saqueos realizados supuestamente por migrantes fueron frustrados por la emocionante respuesta popular para hacer llegar una ayuda que ninguna institución, ni local ni estatal, estaba proporcionando.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Jaime Pérez Rivero&#34; src=&#34;../../img/2025-01-05-dana.jpg&#34;/&gt; Una senyera del Pais Valencià en una ventana de Paiporta, tras el paso de la dana.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Pedro Armestre&#34; src=&#34;../../img/2024-dana-2.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;El cuerpo de un perro flota junto a los restos de cañizo y arboles arrastrados por la Dana a la playa de Pinedo. La pérdida de biodiversidad, víctima y a la vez solución de esta crisis, también está detrás de lo que está ocurriendo. Restaurar la naturaleza es clave para protegernos frente a eventos extremos a la vez que es una oportunidad transformadora para tener unos entornos resilientes y sanos para la biodiversidad y las personas. Para esto se necesitan medidas desde el nivel local hasta el global.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Jose Ángel Sánchez Rocamora&#34; src=&#34;../../img/2024-dana-3.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;No obstante la población valenciana (y la del resto del estado) ha hecho ver el descontento con la mala gestión que hizo el gobierno del PP en la comunidad como se puede ver en la manifestación multitudinaria del 30 de noviembre para pedir la dimisión del president Carlos Mazón.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Feminismo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este 2024 también ha estado marcado por las luchas feministas: el terremoto mediático y social provocado por las denuncias anónimas de violencia sexual en redes ha trastocado el panorama político, ha revuelto el mundo del cine y del teatro, y sobre todo, ha resquebrajado el armazón de impunidad que recubre las agresiones machistas. Más allá de dónde acabe todo esto, el movimiento feminista ha vuelto a demostrar su enorme potencia de cambio en un sentido opuesto a la agenda de la extrema derecha.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Elisa González&#34; src=&#34;../../img/2024-feminismo.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;El 25 de noviembre, Día Internacional de la Eliminación de la Violencia contra la Mujer, se celebró en medio de una intensa conversación en torno a las violencias sexuales.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Caso Pelicot&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Martin Barzilai&#34; src=&#34;../../img/2025-01-05-dana.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;El 19 de diciembre de 2024 conocimos la sentencia del caso Pelicot. Dominique fue condenado a 20 años, la pena máxima. El Tribunal de Aviñón (Francia) que lo juzgaba lo consideró culpable de un delito de violación agravada contra ahora ya exesposa Gisèle Pelicot. Desde julio de 2011 y hasta octubre de 2020, el hombre utilizó webs de citas para invitar a desconocidos a agredir sexualmente a su entonces esposa, a la que previamente había suministrado una cantidad de ansiolíticos suficiente como para acercarla “al estado de coma”. Los otros casi cincuenta acusados han sido declarados culpables de violación con penas de entre tres y 15 años.&lt;/p&gt; &lt;p&gt;Gisèle también ha hecho alusión a la vergüenza cuando ha explicado por qué todo el mundo la conoce por el apellido de su exmarido y agresor: “Tengo nietos y no quiero que se avergüencen de usar ese apellido. Quiero que estén orgullosos de su abuela. A partir de hoy se recordará a la señora Pelicot y cada vez menos al señor Pelicot”, explicó esta mujer que aunque ha recuperado su apellido tras divorciarse no quiere regalarle el nombre de sus nietos a un violador.&lt;/p&gt; &lt;p&gt;La consigna “la vergüenza debe cambiar de bando” se ha repetido más allá de Francia y tuvo un lugar destacado en las convocatorias del 25 de noviembre, Día por la Eliminación de la Violencia contra las Mujeres.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Caso Errejón&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;El 23 de octubre, el testimonio de una mujer, publicado en la cuenta de la periodista Cristina Fallarás en Instagram corre por las redes. La mujer señala a “un político de Madrid” como un “maltratador psicológico”. En pocas horas, las redes identifican a Íñigo Errejón. El jueves 25 de octubre, Errejón anuncia que abandona la política y esa misma tarde la actriz Elisa Mouliaá presenta una denuncia ante la Policía en la que relata una agresión sexual.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Migración&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;El fin de año además nos arroja otra cifra, no por esperada menos demoledora: la estimación de más de diez mil personas muertas tratando de llegar a nuestro país. Personas que, por mucho que se empeñe una extrema derecha en auge mediático, solo buscaban mejorar en algo sus vidas y que la perdieron por un sistema cruel que denomina a este otro genocidio “crisis migratoria”.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Manuel del Valle&#34; src=&#34;../../img/2024-migracion.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Las fronteras españolas han marcado este 2024 un récord de la vergüenza: 10.457 personas han muerto tratando de alcanzar las costas de la península. Imagen de la manifestación antirracista el pasado 9 de noviembre, Madrid.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Movimientos sociales&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este año ha sido duro para las okupas en la ciudad de madríd. Se desalojaron el CSO La Ferroviaria y el CSO La Atalaya&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;David F. Sabadell&#34; src=&#34;../../img/2024-atalaya.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Integrantes del CSO La Atalaya sacan materiales que formaban parte de las decenas de actividades que ofrecía el centro social, mientras la zona se encuentra acordonada por agentes de Policía Nacional.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Servicios públicos&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Edu León&#34; src=&#34;../../img/2024-servicios-publicos.jpg&#34;/&gt; Las asambleas de estudiantes piden seguir la reivindicación de tener unos presupuestos que permitan la supervivencia de la universidad pública en una autonomía donde se impulsa más a la enseñanza privada. &lt;strong&gt;Internacional&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Palestina&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;En diciembre, Israel ha enfocado sus ataques sobre los hospitales del norte de Gaza.&lt;/p&gt; &lt;p&gt;ejército que ha llevado a cabo un genocidio que dura ya más de 440 días.&lt;/p&gt; &lt;p&gt;Comenzamos el año con los ojos puestos en Gaza y Cisjordania y pendientes de la vida de cientos de miles de palestinos amenazados en todo el mundo por el estado sionista de Israel. La cosa no ha ido a mejor en estos 12 meses y a este genocidio calculado le han acompañado otras desgracias, como la creciente crisis ambiental con efectos cada vez más recurrentes en todo el planeta, incluida nuestra españita. En Valencia 231 personas han perdido la vida y 4 más permanecen desaparecidas a causa de una dana que arrasó en pocas horas la comunidad, muertes que quizá pudieron haberse evitado si los responsables políticos hubieran actuado con algo de los que se les presupone, vocación de servicio público, en vez de esconder sus miserias y tratar a toda costa judicial de evitar responsabilidades.&lt;/p&gt; &lt;p&gt;Tras la elección de trump el panorama de palestina no ha hecho más que empeorar (aunque harris tampoco tenía pinta que se fuese a mojar lo más mínimo).&lt;/p&gt; &lt;p&gt;No obstante la sociedad está respondiendo como buenamente puede para presionar a sus gobiernos a que paren el genocidio.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Montecruz foto&#34; src=&#34;../../img/2025-01-05-gaza.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;En el mes de mayo, cientos de estudiantes tomaron la Universidad Humboldt de Berlín en apoyo a Gaza.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Dani Gago&#34; src=&#34;../../img/2024-palestina.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;La batalla naval de Vallecas en 2024, con especial recuerdo para Palestina.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Siria&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Laurent Perpigna Iban&#34; src=&#34;../../img/2024-siria.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Miembros árabes de las Fuerzas Democráticas Sirias en el interior del estadio de Rakka, que el Estado Islámico había convertido en prisión. &lt;strong&gt;Honduras&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Edu León&#34; src=&#34;../../img/2024-honduras.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Honduras heredó del narcogobierno de Juan Orlando Hernández la violencia que ejercen de forma estructural la Policía, el Ejército, las maras y los sicarios contratados por las empresas para matar a líderes ambientales. &lt;strong&gt;Corrupción&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;República&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este año la monarquía ha caído algo en el ideario popular, aunque no lo suficiente.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Sou Harris&#34; src=&#34;../../img/2024-republica.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Momentos de tensión en la visita de los reyes y representantes políticos 5 días después del paso de la Dana en Valencia. La liaron parda porque impidieron que llegase ayuda voluntaria para que pasase l séquito real. No sentó nada bien, por lo que sea.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;beancount&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/&#34;&gt;beancount&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/beancount/#writing-an-importer&#34;&gt;Writing an importer.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;NOTE: since 3.0.0 the importers need to be done with &lt;a href=&#34;https://github.com/beancount/beangulp?tab=readme-ov-file&#34;&gt;&lt;code&gt;beangulp&lt;/code&gt;&lt;/a&gt;. I&#39;ve tried using it but found it confusing so I fell back to 2.x e&lt;/p&gt; &lt;p&gt;Check a list of already existing importers &lt;a href=&#34;https://tariochbctools.readthedocs.io/en/latest/importers.html#&#34;&gt;here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Once you have your importer built up you might want to spice it up with &lt;a href=&#34;https://github.com/beancount/smart_importer/?tab=readme-ov-file&#34;&gt;smart_importer&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;signal&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/signal/&#34;&gt;Signal&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/signal/#signal-bots&#34;&gt;Signal bots.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To write signal bots you can use &lt;a href=&#34;https://github.com/JeremyGDiamond/signal-info-bot&#34;&gt;this library&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;languages&#34;&gt;Languages&lt;/h3&gt; &lt;h4 id=&#34;lua&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/lua/&#34;&gt;lua&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/lua/#syntax&#34;&gt;Syntax rules.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Boolean operations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Not equal operation&lt;/strong&gt; In Lua, you can perform a &#34;not equal&#34; comparison using the &lt;code&gt;~=&lt;/code&gt; operator:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;~=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;-- true if a is not equal to b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;List operations&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Length of a list&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;current_slide&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;current_slide&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- code&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;python-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/&#34;&gt;Python Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/python_snippets/#convert-a-datetime-into-a-date&#34;&gt;Convert a datetime into a date.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;pandas&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pandas/&#34;&gt;Pandas&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Try FireDuck!.&lt;/p&gt; &lt;p&gt;NOTE: you might as well use &lt;a href=&#34;https://fireducks-dev.github.io/&#34;&gt;FireDucks&lt;/a&gt; as it has the same API interface and is &lt;a href=&#34;https://fireducks-dev.github.io/docs/benchmarks/&#34;&gt;waaay faster&lt;/a&gt;. The good thing is that you only need to add to the top of your code &lt;code&gt;import fireducks.pandas as pd&lt;/code&gt; and everything should work (I haven&#39;t tried myself).&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;coding-tools&#34;&gt;Coding tools&lt;/h3&gt; &lt;h4 id=&#34;lazyvim&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/&#34;&gt;LazyVim&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/lazyvim/#load-a-plugin-on-startup&#34;&gt;Load a plugin on startup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can &lt;a href=&#34;https://lazy.folke.io/spec/examples&#34;&gt;define the &lt;code&gt;lazy = false&lt;/code&gt; in your plugin spec&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- the colorscheme should be available when starting Neovim&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;folke/tokyonight.nvim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;lazy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- make sure we load this during startup if it is your main colorscheme&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;diff --git a/docs/linux/wireguard.md b/docs/linux/wireguard.md index d69f315a8e..6ccbaa011c 100644 --- a/docs/linux/wireguard.md +++ b/docs/linux/wireguard.md @@ -16,41 +16,42 @@ VPN solution in the industry.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;radicle&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_plugin_development/&#34;&gt;Radicle&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce radicle.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;radicle.xyz&#34;&gt;Radicle&lt;/a&gt; is an open source, peer-to-peer code collaboration stack built on Git. Unlike centralized code hosting platforms, there is no single entity controlling the network. Repositories are replicated across peers in a decentralized manner, and users are in full control of their data and workflow.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;radicle.xyz&#34;&gt;Home&lt;/a&gt; - &lt;a href=&#34;radicle.zulipchat.com&#34;&gt;Support&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Sum up the notes of the vim plugin development tutorial.&lt;/p&gt; &lt;p&gt;For the repository name, plugins usually finish with the &lt;code&gt;.nvim&lt;/code&gt; extension. I&#39;m going to call mine &lt;code&gt;org-misc.nvim&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Let&#39;s go with the second, add to your &lt;code&gt;init.lua&lt;/code&gt; the next code:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Hello from our plugin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=VGid4aN25iI&#34;&gt;How to load our extension&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We can have the code of our extension wherever we want in our filesystem, but we need to tell Neovim where our plugin’s code is, so it can load the files correctly. Since I use lazy.nvim this is the way to load a plugin from a local folder:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;~/projects/org-misc&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Your path&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now if you restart your neovim you won&#39;t see anything until you load it with &lt;code&gt;:lua require &#34;org-misc&#34;&lt;/code&gt; you&#39;ll see the message &lt;code&gt;Hello from our plugin&lt;/code&gt; in the command line.&lt;/p&gt; &lt;p&gt;To automatically load the plugin when you open nvim, use the next lazy config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;~/projects/org-misc&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;-- Your path&lt;/span&gt;
  &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;org-misc&#34;&lt;/span&gt;
  &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=VGid4aN25iI&#34;&gt;The plugin file structure&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Usually &lt;code&gt;init.lua&lt;/code&gt; starts with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- nothing yet&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where: - &lt;code&gt;M&lt;/code&gt; stands for module, and we&#39;ll start adding it methods. - &lt;code&gt;M.setup&lt;/code&gt; will be the method we use to configure the plugin.&lt;/p&gt; &lt;p&gt;Let&#39;s start with a basic functionality to print some slides:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- nothing yet&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;---@class present.Slides&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;---@fields slides string[]: The slides of the file&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;--- Takes some lines and parses them&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;--- @param lines string&lt;/span&gt;
&lt;span class=&#34;c1&#34;&gt;--- @return present.Slides&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_slides&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;slides&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;slides&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;ipairs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;do&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;slides&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_slides&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;# Hello&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;this is something else&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;# world&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;this is something else&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}))&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You &lt;a href=&#34;https://vi.stackexchange.com/questions/44902/how-can-i-execute-lua-code-from-a-buffer&#34;&gt;can run the code in the current buffer&lt;/a&gt; with &lt;code&gt;:%lua&lt;/code&gt;. For quick access, I&#39;ve defined the next binding:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;X&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:%lua&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Run the lua code in the current buffer&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The &lt;code&gt;print(parse_slides..&lt;/code&gt; part it&#39;s temporal code so that you can debug your code easily. Once it&#39;s ready you&#39;ll remove them&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Call a method of a module&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To run the method of a module:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;c1&#34;&gt;-- nothing yet&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can do &lt;code&gt;require(&#39;org-misc&#39;).setup()&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Set keymaps&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Inside the code of the plugin&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can set keymaps into your plugins by using:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- code&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The problem is that it will override the &lt;code&gt;n&lt;/code&gt; key everywhere which is not a good idea, that&#39;s why we normally limit it to the current buffer.&lt;/p&gt; &lt;p&gt;You can get the current buffer with &lt;code&gt;buffer = true&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- code&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;buffer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Continue till the end&lt;/strong&gt; If you want to stop capturing the traffic flow and go to the end ignoring all breakpoints, remove all breakpoints and do &lt;code&gt;.c&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.reddit.com/r/neovim/comments/170jkzh/how_to_reload_plugin_when_developing_them/&#34;&gt;Reload the plugin without exiting nvim&lt;/a&gt;&lt;/strong&gt; If you are using lazy.nvim, there is a feature that lazy.nvim provides for this purpose:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;Lazy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;reload&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_plugin&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_plugin2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Neovim plugin testing&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We&#39;re going to test it with &lt;code&gt;plenary&lt;/code&gt;. We&#39;ll add a &lt;code&gt;tests&lt;/code&gt; directory at the root of our repository.&lt;/p&gt; &lt;p&gt;Each of the test files need to end in &lt;code&gt;_spec.lua&lt;/code&gt;, so if we want to test a &lt;code&gt;parse_lines&lt;/code&gt; it will be called &lt;code&gt;parse_lines_spec.lua&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Each test file has the following structure&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clockin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;org-misc&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;clockin&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;describe&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;org-misc.clockin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;it&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;should do clockin&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;assert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;clock_in&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; These are all the tests for the &lt;code&gt;clockin&lt;/code&gt; method,&lt;/p&gt; &lt;p&gt;Now you can run the test with &lt;code&gt;:PlenaryBustedFile %&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuring neotest to run the tests&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Using &lt;code&gt;:PlenaryBustedFile %&lt;/code&gt; is not comfortable, that&#39;s why we&#39;re going to use &lt;a href=&#34;https://github.com/nvim-neotest/neotest?tab=readme-ov-file&#34;&gt;&lt;code&gt;neotest&lt;/code&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Configure it with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;nvim-neotest/neotest&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;dependencies&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;s2&#34;&gt;&#34;nvim-neotest/neotest-plenary&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;neotest&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;adapters&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;nb&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;neotest-plenary&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Now you can do:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;tT&lt;/code&gt; to run all test files&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;tt&lt;/code&gt; to run the whole file&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;tl&lt;/code&gt; to run the last test&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;to&lt;/code&gt; to show the output&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;tr&lt;/code&gt; to run the nearest&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;leader&amp;gt;ts&lt;/code&gt; to show the summary&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.reddit.com/r/neovim/comments/18pe4f4/plenarynvim_undefined_global_describe_it_etc_not/&#34;&gt;Remove the Undefined global describe linter warnings&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Add to the root of your repository a &lt;code&gt;.luarc.json&lt;/code&gt; file with &lt;a href=&#34;https://github.com/nvim-orgmode/orgmode/blob/master/.luarc.json&#34;&gt;the next contents&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;$schema&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;diagnostics&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;globals&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;hint&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;enable&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;runtime&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;path&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;?.lua&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;?/init.lua&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;pathStrict&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;version&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;LuaJIT&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;telemetry&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;enable&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;workspace&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;checkThirdParty&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Disable&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;ignoreDir&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;.git&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&#34;library&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;./lua&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;$VIMRUNTIME/lua&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;${3rd}/luv/library&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;./tests/.deps/plugins/plenary&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Testing internal functions&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you have a function &lt;code&gt;parse_lines&lt;/code&gt; in your module that you want to test, you can export it as an internal method&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kd&#34;&gt;local&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_lines&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
  &lt;span class=&#34;c1&#34;&gt;-- code&lt;/span&gt;
&lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;M&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_parse_lines&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_lines&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vim_plugin_development/#control-an-existing-nvim-instance&#34;&gt;Control an existing nvim instance with dap.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Once you have all set up and assuming you&#39;re using the lazyvim keybindings for &lt;code&gt;nvim-dap&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;ds&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;osv&#34;.launch({port = 8086})&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;n&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;&amp;lt;leader&amp;gt;dq&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[[:lua require&#34;osv&#34;.stop()&amp;lt;CR&amp;gt;]]&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You will debug the plugin by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Launch the server in the nvim instance where you&#39;re going to run the actions using &lt;code&gt;&amp;lt;leader&amp;gt;ds&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Open another Neovim instance with the source file (the debugger).&lt;/li&gt; &lt;li&gt;Place breakpoint with &lt;code&gt;&amp;lt;leader&amp;gt;db&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;On the debugger connect to the DAP client with &lt;code&gt;&amp;lt;leader&amp;gt;dc&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Optionally open the &lt;code&gt;nvim-dap-ui&lt;/code&gt; with &lt;code&gt;&amp;lt;leader&amp;gt;B&lt;/code&gt; in the debugger.&lt;/li&gt; &lt;li&gt;Run your script/plugin in the debuggee&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Now you can interact with the debugger in the window below the code. You have the next commands:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;help&lt;/code&gt;: Show all commands&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;enter&amp;gt;&lt;/code&gt;: run the same action as the previous one. For example if you do &lt;code&gt;.n&lt;/code&gt; and then &lt;code&gt;&amp;lt;enter&amp;gt;&lt;/code&gt; it will run &lt;code&gt;.n&lt;/code&gt; again.&lt;/li&gt; &lt;li&gt;&lt;code&gt;.n&lt;/code&gt; or &lt;code&gt;.next&lt;/code&gt;: next step&lt;/li&gt; &lt;li&gt;&lt;code&gt;.b&lt;/code&gt; or &lt;code&gt;.back&lt;/code&gt;: previous step (if the debugger supports it)&lt;/li&gt; &lt;li&gt;&lt;code&gt;.c&lt;/code&gt; or &lt;code&gt;.continue&lt;/code&gt;: Continue to the next breakpoint.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h2&gt; &lt;h3 id=&#34;infrastructure-as-code&#34;&gt;Infrastructure as Code&lt;/h3&gt; &lt;h4 id=&#34;nix&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/nix/&#34;&gt;Nix&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add mention to sixos.&lt;/p&gt; &lt;p&gt;Think about using &lt;a href=&#34;https://media.ccc.de/v/38c3-sixos-a-nix-os-without-systemd&#34;&gt;sixos&lt;/a&gt; instead, a nixos without systemd&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;continuous-deployment&#34;&gt;Continuous Deployment&lt;/h3&gt; &lt;h4 id=&#34;argocd&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/&#34;&gt;ArgoCD&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/argocd/#difference-between-sync-and-refresh&#34;&gt;Difference between sync and refresh.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Sync: Reconciles the current cluster state with the target state in git.&lt;/li&gt; &lt;li&gt;Refresh: Fetches the latest manifests from git and compares the diff with the live state.&lt;/li&gt; &lt;li&gt;Hard Refresh: Clears any caches and does a refresh.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For more information read &lt;a href=&#34;https://argo-cd.readthedocs.io/en/stable/core_concepts/&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://github.com/argoproj/argo-cd/discussions/8260&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;https://github.com/argoproj/argo-cd/discussions/12237&#34;&gt;3&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;storage&#34;&gt;Storage&lt;/h3&gt; &lt;h4 id=&#34;openzfs-storage-planning&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/zfs_storage_planning/&#34;&gt;OpenZFS storage planning&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Add the stats of the Enterprise Capacity seagate disk.&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th&gt;Specs&lt;/th&gt; &lt;th&gt;IronWolf&lt;/th&gt; &lt;th&gt;IronWolf Pro&lt;/th&gt; &lt;th&gt;Exos 7E8 8TB&lt;/th&gt; &lt;th&gt;Exos 7E10 8TB&lt;/th&gt; &lt;th&gt;Exos X18 16TB&lt;/th&gt; &lt;th&gt;Enterpri. Capacity&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Bays&lt;/td&gt; &lt;td&gt;1-8&lt;/td&gt; &lt;td&gt;1-24&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Capacity&lt;/td&gt; &lt;td&gt;1-12TB&lt;/td&gt; &lt;td&gt;2-20TB&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;8TB&lt;/td&gt; &lt;td&gt;16 TB&lt;/td&gt; &lt;td&gt;10 TB&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RPM&lt;/td&gt; &lt;td&gt;5,400 RPM (3-6TB)&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RPM&lt;/td&gt; &lt;td&gt;5,900 RPM (1-3TB)&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;RPM&lt;/td&gt; &lt;td&gt;7,200 RPM (8-12TB)&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;td&gt;7200 RPM&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Speed&lt;/td&gt; &lt;td&gt;180MB/s (1-12TB)&lt;/td&gt; &lt;td&gt;214-260MB/s (4-18TB)&lt;/td&gt; &lt;td&gt;249 MB/s&lt;/td&gt; &lt;td&gt;255 MB/s&lt;/td&gt; &lt;td&gt;258 MB/s&lt;/td&gt; &lt;td&gt;254 MB/s&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Cache&lt;/td&gt; &lt;td&gt;64MB (1-4TB)&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Cache&lt;/td&gt; &lt;td&gt;256MB (3-12TB)&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;td&gt;256 MB&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Power Consumption&lt;/td&gt; &lt;td&gt;10.1 W&lt;/td&gt; &lt;td&gt;10.1 W&lt;/td&gt; &lt;td&gt;12.81 W&lt;/td&gt; &lt;td&gt;11.03 W&lt;/td&gt; &lt;td&gt;9.31 W&lt;/td&gt; &lt;td&gt;8 W&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Power Consumption Rest&lt;/td&gt; &lt;td&gt;7.8 W&lt;/td&gt; &lt;td&gt;7.8 W&lt;/td&gt; &lt;td&gt;7.64 W&lt;/td&gt; &lt;td&gt;7.06 W&lt;/td&gt; &lt;td&gt;5.08 W&lt;/td&gt; &lt;td&gt;4.5 W&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Workload&lt;/td&gt; &lt;td&gt;180TB/yr&lt;/td&gt; &lt;td&gt;300TB/yr&lt;/td&gt; &lt;td&gt;550TB/yr&lt;/td&gt; &lt;td&gt;550TB/yr&lt;/td&gt; &lt;td&gt;550TB/yr&lt;/td&gt; &lt;td&gt;&amp;lt; 550TB/yr&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;MTBF&lt;/td&gt; &lt;td&gt;1 million&lt;/td&gt; &lt;td&gt;1 million&lt;/td&gt; &lt;td&gt;2 millions&lt;/td&gt; &lt;td&gt;2 millions&lt;/td&gt; &lt;td&gt;2.5 millions&lt;/td&gt; &lt;td&gt;2.5 millions&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Noise idle&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;3.0 bels max&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Noise performance seek&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;?&lt;/td&gt; &lt;td&gt;3.4 bels max&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;diff --git a/mkdocs.yml b/mkdocs.yml index 7d0201801c..ade48234b0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,19 +5,18 @@ site_author: Lyz site_url: &lt;a href=&#34;https://lyz-code.github.io/blue-book&#34;&gt;https://lyz-code.github.io/blue-book&lt;/a&gt; nav: - Introduction: index.md - - Projects: projects.md - Activism: - activism.md - Antifascism: - antifascism.md - Antifascist Actions: antifascist_actions.md - Hacktivism: - - Gatherings: - - hacktivist_gatherings.md - - Chaos Communication Congress: ccc.md - - Collectives: hacktivist_collectives.md - - Tools: - - Mobile Verification Toolkit: mobile_verification_toolkit.md + - Gatherings: + - hacktivist_gatherings.md + - Chaos Communication Congress: ccc.md + - Collectives: hacktivist_collectives.md + - Tools: + - Mobile Verification Toolkit: mobile_verification_toolkit.md - Anti-Colonialism: anticolonialism.md - Anti-Transphobia: antitransphobia.md - Anti-Racism: antiracism.md @@ -27,6 +26,7 @@ nav: - Feminism: - Privileges: feminism/privileges.md - Palestine: palestine.md + - Anarchism: anarchism.md - Memoria histórica: memoria_historica.md - Anti-Tourism: antitourism.md - Mentoring: mentoring.md @@ -36,153 +36,154 @@ nav: - Laboral: laboral.md - Collaborating tools: collaborating_tools.md - Conference organisation: conference_organisation.md - - Ludditest: luddites.md + - Ludditest: luddites.md - Life Management: - life_management.md - Time management: - - time_management.md - - Time management abstraction levels: time_management_abstraction_levels.md - - Action Management: action_management.md - - Roadmap Adjustment: - - roadmap_adjustment.md - - Strategy: strategy.md - - Systems Thinking: systems_thinking.md - - Roadmap Management Tools: - - roadmap_tools.md - - Org Mode: - - orgmode.md - - Org-rw: org_rw.md - - Orgzly: orgzly.md - - OpenProject: openproject.md - - Habit management: habit_management.md - - Interruption management: - - interruption_management.md - - Interruption Management Analysis: - - Work Interruption Analysis: work_interruption_analysis.md - - Personal Interruption Analysis: personal_interruption_analysis.md - - Week management: week_management.md - - Calendar management: - - calendar_management.md - - Calendar automation: - - vdirsyncer: vdirsyncer.md - - Calendar clients: - - Khal: khal.md - - Gancio: gancio.md - - Time management theories: - - Getting Things Done: gtd.md + - time_management.md + - Time management abstraction levels: time_management_abstraction_levels.md + - Action Management: action_management.md + - Roadmap Adjustment: + - roadmap_adjustment.md + - Strategy: strategy.md + - Systems Thinking: systems_thinking.md + - Roadmap Management Tools: + - roadmap_tools.md + - Org Mode: + - orgmode.md + - Org-rw: org_rw.md + - Orgzly: orgzly.md + - OpenProject: openproject.md + - Habit management: habit_management.md + - Interruption management: + - interruption_management.md + - Interruption Management Analysis: + - Work Interruption Analysis: work_interruption_analysis.md + - Personal Interruption Analysis: personal_interruption_analysis.md + - Week management: week_management.md + - Calendar management: + - calendar_management.md + - Calendar automation: + - vdirsyncer: vdirsyncer.md + - Calendar clients: + - Khal: khal.md + - Gancio: gancio.md + - Time management theories: + - Getting Things Done: gtd.md - Life chores management: - - Trip management: - - Route management: route_management.md - - Map management: map_management.md - - Food management: food_management.md - - Stock management: - - Grocy: grocy_management.md - - Money management: - - money_management.md - - beancount: - - beancount.md - - bean-sql: bean_sql.md - - Fava Dashboards: fava_dashboards.md - - Tools management: - - tool_management.md - - Email management: - - email_management.md - - Email automation: - - email_automation.md - - Email automation tools: - - mbsync: mbsync.md - - mirador: mirador.md - - afew: afew.md - - notmuch: notmuch.md - - Email automation libraries: - - mailbox: mailbox.md - - IMAP: - - IMAP library comparison: python_imap.md - - imap-tools: imap_tools.md - - Email clients: - - himalaya: himalaya.md - - alot: alot.md - - Email protocols: - - Maildir: maildir.md - - Instant Messages Management: - - instant_messages_management.md - - XMPP/Jabber: - - Dino: dino.md - - Gajim: gajim.md - - Profanity: profanity.md - - Matrix: - - matrix.md - - Matrix Highlight: matrix_highlight.md - - Rocketchat: rocketchat.md - - Computer configuration management: configuration_management.md + - Trip management: + - Route management: route_management.md + - Map management: map_management.md + - Food management: food_management.md + - Stock management: + - Grocy: grocy_management.md + - Money management: + - money_management.md + - beancount: + - beancount.md + - bean-sql: bean_sql.md + - Fava Dashboards: fava_dashboards.md + - Tools management: + - tool_management.md + - Email management: + - email_management.md + - Email automation: + - email_automation.md + - Email automation tools: + - mbsync: mbsync.md + - mirador: mirador.md + - afew: afew.md + - notmuch: notmuch.md + - Email automation libraries: + - mailbox: mailbox.md + - IMAP: + - IMAP library comparison: python_imap.md + - imap-tools: imap_tools.md + - Email clients: + - himalaya: himalaya.md + - alot: alot.md + - Email protocols: + - Maildir: maildir.md + - Instant Messages Management: + - instant_messages_management.md + - XMPP/Jabber: + - Dino: dino.md + - Gajim: gajim.md + - Profanity: profanity.md + - Matrix: + - matrix.md + - Matrix Highlight: matrix_highlight.md + - Signal: signal.md + - Rocketchat: rocketchat.md + - Computer configuration management: configuration_management.md - Content Management: - - Music Management: - - music_management.md - - MusicBrainz: musicbrainz.md - - Mopidy: mopidy.md - - Beets: beets.md - - Koel: koel.md - - yt-dlp: yt-dlp.md - - Book Management: - - book_management.md - - Bookwyrm: bookwyrm.md - - Movies Management: - - Jellyfin: jellyfin.md - - Ombi: ombi.md - - Mediatracker: mediatracker.md - - ffmpeg: ffmpeg.md - - transcoding: - - transcoding.md - - unmanic: unmanic.md - - Kodi: kodi.md - - News Management: - - news_management.md - - RSS: rss.md - - Wallabag: wallabag.md - - Photo management: - - photo_self_hosted.md - - Immich: immich.md - - Video management: video_management.md - - Videogames management: - - moonlight: moonlight.md - - retroarch: retroarch.md + - Music Management: + - music_management.md + - MusicBrainz: musicbrainz.md + - Mopidy: mopidy.md + - Beets: beets.md + - Koel: koel.md + - yt-dlp: yt-dlp.md + - Book Management: + - book_management.md + - Bookwyrm: bookwyrm.md + - Movies Management: + - Jellyfin: jellyfin.md + - Ombi: ombi.md + - Mediatracker: mediatracker.md + - ffmpeg: ffmpeg.md + - transcoding: + - transcoding.md + - unmanic: unmanic.md + - Kodi: kodi.md + - News Management: + - news_management.md + - RSS: rss.md + - Wallabag: wallabag.md + - Photo management: + - photo_self_hosted.md + - Immich: immich.md + - Video management: video_management.md + - Videogames management: + - moonlight: moonlight.md + - retroarch: retroarch.md - Knowledge Management: - - knowledge_management.md - - Spaced Repetition: - - spaced_repetition.md - - Anki: anki.md - - Mochi: mochi.md - - Analytical web reading: - - analytical_web_reading.md - - Hypothesis: linux/hypothesis.md - - Digital Gardens: - - digital_garden.md - - mkdocs: linux/mkdocs.md - - Build your own Digital Garden: writing/build_your_own_wiki.md - - Forking this garden: forking_this_wiki.md - - Aleph: aleph.md - - Wordpress: wordpress.md - - Relationship Management: - - relationship_management.md - - monica: linux/monica.md + - knowledge_management.md + - Spaced Repetition: + - spaced_repetition.md + - Anki: anki.md + - Mochi: mochi.md + - Analytical web reading: + - analytical_web_reading.md + - Hypothesis: linux/hypothesis.md + - Digital Gardens: + - digital_garden.md + - mkdocs: linux/mkdocs.md + - Build your own Digital Garden: writing/build_your_own_wiki.md + - Forking this garden: forking_this_wiki.md + - Aleph: aleph.md + - Wordpress: wordpress.md + - Relationship Management: + - relationship_management.md + - monica: linux/monica.md - Process Automation: - - process_automation.md - - AI: - - Open WebUI: openwebui.md - - NLP: - - spacy: spacy.md - - Virtual Assistant: virtual_assistant.md - - Monitor web changes: - - Changedetection.io: changedetection.md - - Monitorizar billetes de renfe: renfe.md + - process_automation.md + - AI: + - Open WebUI: openwebui.md + - NLP: + - spacy: spacy.md + - Virtual Assistant: virtual_assistant.md + - Monitor web changes: + - Changedetection.io: changedetection.md + - Monitorizar billetes de renfe: renfe.md - Torrent management: - - torrents.md - - qBittorrent: qbittorrent.md - - Rtorrent: rtorrent.md - - Unpackerr: unpackerr.md - - Life logging: - - life_logging.md - - ActivityWatch: activitywatch.md + - torrents.md + - qBittorrent: qbittorrent.md + - Rtorrent: rtorrent.md + - Unpackerr: unpackerr.md + - Life logging: + - life_logging.md + - ActivityWatch: activitywatch.md - Health: - Sleep: sleep.md - Teeth: @@ -213,7 +214,8 @@ nav: - Create the documentation repository: &amp;gt;- coding/python/python_project_template/python_docs.md - Load config from YAML: coding/python/python_config_yaml.md - - Configure SQLAlchemy to use the MariaDB/Mysql backend: &amp;gt;- + - Configure SQLAlchemy to use the MariaDB/Mysql backend: + &amp;gt;- coding/python/python_project_template/python_sqlalchemy_mariadb.md - Configure Docker to host the application: &amp;gt;- coding/python/python_project_template/python_docker.md @@ -269,9 +271,9 @@ nav: - Python Mysql: python_mysql.md - pythonping: pythonping.md - Python Prometheus: python-prometheus.md - - Python Telegram: - - python-telegram.md - - pytelegrambotapi: pytelegrambotapi.md + - Python Telegram: + - python-telegram.md + - pytelegrambotapi: pytelegrambotapi.md - Python VLC: python_vlc.md - Playwright: playwright.md - Plotly: coding/python/plotly.md @@ -299,13 +301,13 @@ nav: - Code Styling: coding/python/python_code_styling.md - Docstrings: coding/python/docstrings.md - Properties: python_properties.md - - Protocols: python_protocols.md + - Protocols: python_protocols.md - Package Management: - - python_package_management.md - - PDM: pdm.md - - pipx: pipx.md - - Pipenv: pipenv.md - - Poetry: python_poetry.md + - python_package_management.md + - PDM: pdm.md + - pipx: pipx.md + - Pipenv: pipenv.md + - Poetry: python_poetry.md - Lazy loading: lazy_loading.md - Plugin System: python_plugin_system.md - Profiling: python_profiling.md @@ -351,65 +353,66 @@ nav: - JWT: devops/jwt.md - React: coding/react/react.md - Coding tools: - - IDES: - - Vim: - - vim.md - - Vim configuration: - - vim_config.md - - Vim Keymaps: vim_keymaps.md - - Vim Package Manager: - - vim_plugin_managers.md - - LazyVim: lazyvim.md - - Packer: vim_packer.md - - UI management configuration: - - Vim foldings: vim_foldings.md - - Vim movement: vim_movement.md - - Tabs vs Buffers: vim_tabs.md - - File management configuration: - - NeoTree: neotree.md - - Telescope: telescope.md - - Editing specific configuration: - - vim_editor_plugins.md - - Vim formatters: vim_formatters.md - - Vim autocomplete: vim_completion.md - - Vim markdown: vim_markdown.md - - Vim spelling: vim_spelling.md - - Vim autosave: vim_autosave.md - - Coding specific configuration: - - vim_coding_plugins.md - - Treesitter: vim_treesitter.md - - LSP: vim_lsp.md - - Snippets: luasnip.md - - DAP: vim_dap.md - - Git management configuration: - - vim_git.md - - Diffview: diffview.md - - gitsigns: gitsigns.md - - Testing management configuration: vim_testing.md - - Email management: vim_email.md - - Other Vim Plugins: - - linux/vim/vim_plugins.md - - Vim Snippets: vim_snippets.md - - Vim Troubleshooting: vim_troubleshooting.md - - Neovim Plugin Development: vim_plugin_development.md - - Vi vs Vim vs Neovim: vim_vs_neovim.md - - Tridactyl: tridactyl.md - - VSCodium: vscodium.md - - Coding with AI: ai_coding.md - - Git: - - git.md - - Github cli: gh.md - - Forgejo: forgejo.md - - Gitea: gitea.md - - Data orchestrators: - - data_orchestrators.md - - Kestra: kestra.md - - memorious: memorious.md - - Scrapers: - - morph.io: morph_io.md - - ETL: - - Singer: singer.md - - Espanso: espanso.md + - IDES: + - Vim: + - vim.md + - Vim configuration: + - vim_config.md + - Vim Keymaps: vim_keymaps.md + - Vim Package Manager: + - vim_plugin_managers.md + - LazyVim: lazyvim.md + - Packer: vim_packer.md + - UI management configuration: + - Vim foldings: vim_foldings.md + - Vim movement: vim_movement.md + - Tabs vs Buffers: vim_tabs.md + - File management configuration: + - NeoTree: neotree.md + - Telescope: telescope.md + - Editing specific configuration: + - vim_editor_plugins.md + - Vim formatters: vim_formatters.md + - Vim autocomplete: vim_completion.md + - Vim markdown: vim_markdown.md + - Vim spelling: vim_spelling.md + - Vim autosave: vim_autosave.md + - Coding specific configuration: + - vim_coding_plugins.md + - Treesitter: vim_treesitter.md + - LSP: vim_lsp.md + - Snippets: luasnip.md + - DAP: vim_dap.md + - Git management configuration: + - vim_git.md + - Diffview: diffview.md + - gitsigns: gitsigns.md + - Testing management configuration: vim_testing.md + - Email management: vim_email.md + - Other Vim Plugins: + - linux/vim/vim_plugins.md + - Vim Snippets: vim_snippets.md + - Vim Troubleshooting: vim_troubleshooting.md + - Neovim Plugin Development: vim_plugin_development.md + - Vi vs Vim vs Neovim: vim_vs_neovim.md + - Tridactyl: tridactyl.md + - VSCodium: vscodium.md + - Coding with AI: ai_coding.md + - Git: + - git.md + - Github cli: gh.md + - Forgejo: forgejo.md + - Gitea: gitea.md + - Radicle: radicle.md + - Data orchestrators: + - data_orchestrators.md + - Kestra: kestra.md + - memorious: memorious.md + - Scrapers: + - morph.io: morph_io.md + - ETL: + - Singer: singer.md + - Espanso: espanso.md - Generic Coding Practices: - How to code: how_to_code.md - Program Versioning: @@ -435,8 +438,8 @@ nav: - Microservices: architecture/microservices.md - Restful APIS: architecture/restful_apis.md - OCR: - - Table parsing: - - Camelot: camelot.md + - Table parsing: + - Camelot: camelot.md - Frontend Development: frontend_development.md - Park programming: park_programming.md - Sponsor: sponsor.md @@ -453,8 +456,8 @@ nav: - Helmfile: devops/helmfile.md - Terraform: terraform.md - Ansible: - - Ansible Snippets: ansible_snippets.md - - Molecule: molecule.md + - Ansible Snippets: ansible_snippets.md + - Molecule: molecule.md - Nix: nix.md - Dotfiles: - dotfiles.md @@ -517,8 +520,8 @@ nav: - S3: devops/aws/s3.md - WAF: aws_waf.md - Databases: - - Redis: architecture/redis.md - - RabbitMQ: rabbitmq.md + - Redis: architecture/redis.md + - RabbitMQ: rabbitmq.md - Continuous Deployment: - ArgoCD: argocd.md - Continuous Integration: @@ -553,21 +556,21 @@ nav: - renovate: renovate.md - letsencrypt: letsencrypt.md - Threat modeling: - - Privacy threat modeling: privacy_threat_modeling.md + - Privacy threat modeling: privacy_threat_modeling.md - Storage: - - storage.md - - NAS: nas.md - - OpenZFS: - - linux/zfs.md - - OpenZFS storage planning: zfs_storage_planning.md - - Sanoid: sanoid.md - - ZFS Prometheus exporter: zfs_exporter.md - - Hard drive health: hard_drive_health.md - - Resilience: - - linux_resilience.md - - Memtest: memtest.md - - watchdog: watchdog.md - - Magic keys: magic_keys.md + - storage.md + - NAS: nas.md + - OpenZFS: + - linux/zfs.md + - OpenZFS storage planning: zfs_storage_planning.md + - Sanoid: sanoid.md + - ZFS Prometheus exporter: zfs_exporter.md + - Hard drive health: hard_drive_health.md + - Resilience: + - linux_resilience.md + - Memtest: memtest.md + - watchdog: watchdog.md + - Magic keys: magic_keys.md - Monitoring: - Monitoring Comparison: monitoring_comparison.md - Prometheus: @@ -587,21 +590,21 @@ nav: devops/prometheus/prometheus_troubleshooting.md - Grafana: grafana.md - Log analysis: - - Loki: - - loki.md - - Logcli: logcli.md - - Promtail: promtail.md - - Graylog: graylog.md - - Elastic Security: elastic_security.md + - Loki: + - loki.md + - Logcli: logcli.md + - Promtail: promtail.md + - Graylog: graylog.md + - Elastic Security: elastic_security.md - SIEM: siem.md - Databases: - - PostgreSQL: - - postgres.md - - Postgres operators: - - postgres_operators.md - - Zalando Postgres operator: zalando_postgres_operator.md - - elasticsearch: linux/elasticsearch.md - - Oracle Database: oracle_database.md + - PostgreSQL: + - postgres.md + - Postgres operators: + - postgres_operators.md + - Zalando Postgres operator: zalando_postgres_operator.md + - elasticsearch: linux/elasticsearch.md + - Oracle Database: oracle_database.md - Authentication: - Authentik: authentik.md - API Management: @@ -613,11 +616,11 @@ nav: - Refinement Template: refinement_template.md - Hardware: - CPU: cpu.md - - RAM: - - ram.md - - ECC RAM: - - ecc.md - - rasdaemon: rasdaemon.md + - RAM: + - ram.md + - ECC RAM: + - ecc.md + - rasdaemon: rasdaemon.md - Power Supply Unit: psu.md - GPU: gpu.md - Pedal PC: pedal_pc.md @@ -627,52 +630,54 @@ nav: - linux.md - Linux Snippets: linux_snippets.md - Distros: - - Libreelec: libreelec.md - - Tails: tails.md + - Libreelec: libreelec.md + - Tails: tails.md - Recovery tools: - - finnix: finnix.md + - finnix: finnix.md - Security tools: - - fail2ban: linux/fail2ban.md - - pass: pass.md - - Wireshark: wireshark.md + - fail2ban: linux/fail2ban.md + - pass: pass.md + - Wireshark: wireshark.md - Sysadmin tools: - - brew: linux/brew.md - - detox: detox.md - - Docker: docker.md - - Watchtower: watchtower.md - - Dynamic DNS: dynamicdns.md - - goaccess: goaccess.md - - Gotify: gotify.md - - HAProxy: linux/haproxy.md - - journald: journald.md - - LUKS: linux/luks/luks.md - - Outrun: outrun.md - - rm: linux/rm.md - - sed: sed.md - - Syncthing: linux/syncthing.md - - Tahoe-LAFS: tahoe.md - - Wake on Lan: wake_on_lan.md - - Wireguard: linux/wireguard.md - - yq: yq.md - - zip: linux/zip.md + - brew: linux/brew.md + - detox: detox.md + - Docker: docker.md + - Watchtower: watchtower.md + - Dynamic DNS: dynamicdns.md + - goaccess: goaccess.md + - Gotify: gotify.md + - HAProxy: linux/haproxy.md + - journald: journald.md + - LUKS: linux/luks/luks.md + - Outrun: outrun.md + - rm: linux/rm.md + - sed: sed.md + - Syncthing: linux/syncthing.md + - Tahoe-LAFS: tahoe.md + - Wake on Lan: wake_on_lan.md + - Wireguard: linux/wireguard.md + - yq: yq.md + - zip: linux/zip.md - Window manager tools: - - dunst: dunst.md - - ferdium: ferdium.md - - i3wm: i3wm.md - - rofi: rofi.md + - dunst: dunst.md + - ferdium: ferdium.md + - i3wm: i3wm.md + - rofi: rofi.md - User tools: - - Browsers: - - google chrome: linux/google_chrome.md - - Chromium: chromium.md - - Hushboard: husboard.md - - Peek: peek.md - - Terminals: - - terminal_comparison.md - - Alacritty: alacritty.md - - Wezterm: wezterm.md - - Kitty: kitty.md - - Instant messaging apps: - - Delta Chat: deltachat.md + - Browsers: + - google chrome: linux/google_chrome.md + - Chromium: chromium.md + - Hushboard: husboard.md + - Peek: peek.md + - Terminals: + - terminal_comparison.md + - Alacritty: alacritty.md + - Wezterm: wezterm.md + - Kitty: kitty.md + - Instant messaging apps: + - Delta Chat: deltachat.md + - Simplex Chat: simplexchat.md + - Android: - Android Tips: android_tips.md - OS: @@ -687,7 +692,6 @@ nav: - Orgzly: orgzly.md - OsmAnd: osmand.md - Seedvault: seedvault.md - - Signal: signal.md - Android SDK Platform tools: android_sdk.md - Arts: - Writing: @@ -703,8 +707,8 @@ nav: - Dancing: - Rave Dances: dancing/rave_dances.md - Swing: - - Shag: shag.md - - Lindy Hop: lindy.md + - Shag: shag.md + - Lindy Hop: lindy.md - Shuffle: - Basics: dancing/shuffle_basics.md - Kicks: dancing/shuffle_kicks.md @@ -729,7 +733,7 @@ nav: - board_games.md - Regicide: regicide.md - Music: - - Sister Rosetta Tharpe: sister_rosetta_tharpe.md + - Sister Rosetta Tharpe: sister_rosetta_tharpe.md - Sudokus: sudokus.md - Drawing: - drawing/drawing.md @@ -741,23 +745,24 @@ nav: - Emojis: emojis.md - Languages: - Castellano: castellano.md - - Galego: + - Galego: - galego.md - Diccionario galego-castelan: diccionario_galego.md + - Esperanto: esperanto.md - Science: - - Artificial Intelligence: - - ai.md - - Speech to text: - - Whisper: whisper.md - - Speech recognition: speech_recognition.md - - Coding by Voice: coding_by_voice.md - - Data Analysis: + - Artificial Intelligence: + - ai.md + - Speech to text: + - Whisper: whisper.md + - Speech recognition: speech_recognition.md + - Coding by Voice: coding_by_voice.md + - Data Analysis: - data_analysis.md - Recommender Systems: &amp;gt;- data_analysis/recommender_systems/recommender_systems.md - Parsers: parsers.md - CSV exploring: - - csvlens: csvlens.md + - csvlens: csvlens.md - Psychology: - psychology.md - The XY Problem: psychology/the_xy_problem.md @@ -765,6 +770,18 @@ nav: - Botany: - Trees: botany/trees.md - Math: math.md + - Reviews: + - Year reviews: year_reviews.md + - Content reviews: + - Books: books.md + # - Movies: movies.md + # - Music: music.md + # - TV Shows: tv_shows.md + - Podcasts: podcasts.md + # - Videogames: videogames.md + # - Boardgames: boardgames.md + # - Streaming channels: streaming_channels.md + - Projects: projects.md - Contact: contact.md&lt;/p&gt; &lt;p&gt;plugins: @@ -825,7 +842,7 @@ theme:&lt;/p&gt; &lt;p&gt;palette: # Light mode - - media: &#39;(prefers-color-scheme: light)&#39; + - media: &#34;(prefers-color-scheme: light)&#34; scheme: default primary: blue grey accent: light blue @@ -834,7 +851,7 @@ theme: name: Switch to dark mode&lt;/p&gt; &lt;pre&gt;&lt;code&gt; # Dark mode
&lt;/code&gt;&lt;/pre&gt; &lt;ul&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;media: &#39;(prefers-color-scheme: dark)&#39;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;ul&gt; &lt;li&gt;media: &#34;(prefers-color-scheme: dark)&#34; scheme: slate primary: blue grey accent: light blue&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;Linux&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/simplexchat/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#prevent-the-screen-from-turning-off&#34;&gt;Prevent the screen from turning off.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;VESA Display Power Management Signaling (DPMS) enables power saving behaviour of monitors when the computer is not in use. The time of inactivity before the monitor enters into a given saving power level—standby, suspend or off—can be set as described in DPMSSetTimeouts(3).&lt;/p&gt; &lt;p&gt;It is possible to turn off your monitor with the xset command&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;off&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-dpms
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; It will disable DPMS and prevent screen from blanking&lt;/p&gt; &lt;p&gt;To query the current settings:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;xset&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;q
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If that doesn&#39;t work you can use the &lt;a href=&#34;https://github.com/carrot69/keep-presence/&#34;&gt;keep-presence&lt;/a&gt; program&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;keep-presence
keep-presence&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;That will move the cursor one pixel in circles each 300s, if you need to move it more often use the &lt;code&gt;-s&lt;/code&gt; flag.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#protect-the-edition-of-a-pdf-with-a-password&#34;&gt;Protect the edition of a pdf with a password.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Use &lt;code&gt;pdftk&lt;/code&gt;. From its man page:&lt;/p&gt; &lt;p&gt;Encrypt a PDF using 128-Bit Strength (the Default) and Withhold All Permissions (the Default)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pdftk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc.128&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;owner_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;foopass&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Same as Above, Except a Password is Required to Open the PDF&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pdftk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc.128&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;owner_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;foo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;baz&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Same as Above, Except Printing is Allowed (after the PDF is Open)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pdftk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;mydoc.128&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;.pdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;owner_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;foo&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;user_pw&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;baz&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;allow&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pri
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;To check if it has set the password correctly you &lt;a href=&#34;https://stackoverflow.com/questions/4039659/is-it-possible-to-check-if-pdf-is-password-protected-using-ghostscript&#34;&gt;can run&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pdftk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;input.pdf&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dump_data&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/null&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dont_ask
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#reduce-the-size-of-an-image&#34;&gt;Reduce the size of an image.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The simplest way of reducing the size of the image is by degrading the quality of the image.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;convert&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;INPUT_FILE&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-quality&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;%&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;OUTPUT_FILE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The main difference between &lt;code&gt;convert&lt;/code&gt; and &lt;code&gt;mogrify&lt;/code&gt; command is that &lt;code&gt;mogrify&lt;/code&gt; command applies the operations on the original image file, whereas convert does not.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mogrify&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-quality&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;*.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#change-the-default-shell-of-a-user-using-the-command-line&#34;&gt;Change the default shell of a user using the command line.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;chsh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-s&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/usr/bin/zsh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;lyz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce simplex chat.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://simplex.chat/&#34;&gt;Simplex chat&lt;/a&gt; is the first messenger without user IDs&lt;/p&gt; &lt;p&gt;I went to a talk in the &lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/&#34;&gt;38c3&lt;/a&gt; (december 2024), and even though the project looked good there were some stuff that pushed me away:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The cypher has not been tested&lt;/li&gt; &lt;li&gt;It&#39;s not fully open sourced&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;wireguard&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/&#34;&gt;Wireguard&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/wireguard/#configure-the-kill-switch&#34;&gt;Configure the kill switch.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can configure a kill-switch in order to prevent the flow of unencrypted packets through the non-WireGuard interfaces, by adding the following two lines ‘PostUp‘ and ‘PreDown‘ lines to the ‘[Interface]‘ section:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;The ‘PostUp’ and ‘PreDown’ fields have been added to specify an iptables command which, when used with interfaces that have a peer that specifies 0.0.0.0/0 as part of the ‘AllowedIPs’, works together with wg-quick’s fwmark usage in order to drop all packets that are either not coming out of the tunnel encrypted or not going through the tunnel itself. Note that this continues to allow most DHCP traffic through, since most DHCP clients make use of PF_PACKET sockets, which bypass Netfilter. When IPv6 is in use, additional similar lines could be added using ip6tables.&lt;/p&gt; &lt;p&gt;If you want to allow the traffic to your LAN while keeping your kill-switch you can use:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT &amp;amp;&amp;amp; iptables -I OUTPUT -p tcp -d 192.168.0.0/24 -j ACCEPT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT &amp;amp;&amp;amp; iptables -D OUTPUT -p tcp -d 192.168.0.0/24 -j ACCEPT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Here I&#39;m assuming that your LAN is defined by &lt;code&gt;192.168.0.0/24&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://www.ivpn.net/knowledgebase/linux/linux-wireguard-kill-switch/&#34;&gt;One way to test if the kill switch works&lt;/a&gt; is by deleting the IP address from the wireguard interface&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;del&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;IP&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;address&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;dev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;interface&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where the &lt;code&gt;[IP address]&lt;/code&gt; can be seen using the &lt;code&gt;ip a&lt;/code&gt; command.&lt;/p&gt; &lt;p&gt;To gracefully recover from this, you will likely have to use the wg-quick command to take the connection down, then bring it back up.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;languages_1&#34;&gt;Languages&lt;/h2&gt; &lt;h3 id=&#34;esperanto&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/esperanto/&#34;&gt;Esperanto&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce esperanto.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Personal notes on the 38C3 Esperanto gathering&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The language has 130 years&lt;/li&gt; &lt;li&gt;It&#39;s difficult to reform: There is no defined process to change the language and they don&#39;t like newbies to propose changes although there is an academy of esperanto&lt;/li&gt; &lt;li&gt;There are no different past, conditional tenses&lt;/li&gt; &lt;li&gt;There is no conjugation, they always use the pronouns&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Anki decks&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;There is &lt;a href=&#34;https://esperanto.cards/&#34;&gt;this nice deck&lt;/a&gt; also available from the &lt;a href=&#34;https://ankiweb.net/shared/info/353142617&#34;&gt;ankiweb site&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/c3esperanto/kurseto&#34;&gt;38c3 workshop slides&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;science&#34;&gt;Science&lt;/h2&gt; &lt;h3 id=&#34;artificial-intelligence&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ai/&#34;&gt;Artificial Intelligence&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ai/#ai-and-ecologism&#34;&gt;Add 38C3 talk on AI and ecologism.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://media.ccc.de/v/38c3-resource-consumption-of-ai-degrow-or-die&#34;&gt;38C3 talk: Resource Consumption of AI - Degrow or Die&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;relevant-content&#34;&gt;Relevant content&lt;/h2&gt; &lt;h3 id=&#34;books&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/books/&#34;&gt;Books&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/books/#mejores-libros-del-2024&#34;&gt;Mejores libros del 2024.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;2024 ha sido un año muy potente para mi en cuanto a lectura se refiere,&lt;/p&gt; &lt;p&gt;La mayor parte de los 23 libros que me he terminado han tenido buena puntuación.&lt;/p&gt; &lt;p&gt;5: 8 4: 7 3: 6 2: 1 1: 1&lt;/p&gt; &lt;p&gt;6 se han quedado por el camino y sólamente recuerdo uno que se me haya hecho pesado de leer y me he forzado a terminar de leerlo.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Política&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.todostuslibros.com/libros/mano-dura_978-84-19158-52-9#synopsis&#34;&gt;The global police state by William I. Robinson&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;William ha puesto palabras bonitas y claras a mis pensamientos como no lo hacia un libro desde el manifiesto comunista hace muchos años. Un análisis impoluto sobre la crisis del capitalismo y el mundo al que nos estamos dirigiendo. A la vez que dando una dirección a la que apuntar para combatirlo. Ambiciosa y difícil, pero la que más me cuadra. Me encantaría debatirlo con la gente y lo regalaré allá donde vaya. Da un poco de yuyu porque hasta el final final final no da atisbo de luz al final del túnel tan necesaria en estos tiempos oscuros, pero aguantad, que merece la pena (✿◠‿◠).&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/the_global_police_state.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;A muchos nos aterra el nuevo auge del fascismo. Solo en Europa, la extrema derecha integra cinco gobiernos y tiene representación parlamentaria destacada en veintisiete países. Pero esto es apenas la punta del iceberg de un proceso bastante más complejo: el auge del Estado policial global como respuesta a la profunda crisis del sistema capitalista actual. A medida que el neoliberalismo dispara las desigualdades hasta límites insospechados (los veintiséis millonarios más importantes del mundo poseen hoy más de la mitad de la riqueza mundial mientras dos mil millones de personas viven en situación de pobreza), los individuos se vuelven «desechables». Una población excedente que supone una amenaza de rebelión para la clase capitalista. Para refrenarla, se hacen ubicuos todo tipo de sistemas de control, rastreos biométricos, encarcelamientos generalizados, barcos‐prisión, violencia policial, persecución de migrantes, represión contra activistas medioambientales, eliminación de prestaciones sociales, desahucios, precarización de las clases medias, guerras estratégicas sustentadas por capital privado... Así, el Estado policial global no remite ya a un mecanismo policial y militar, sino a la propia economía global como totalidad represiva, cuya lógica es tan mercantil como política y cultural. Y, mientras la codicia infinita de la clase dominante hunde al capitalismo en una crisis sin precedentes (llevando la degradación ecológica y el deterioro social a su límite absoluto), el neofascismo afianza su posición en ese Estado policial global cuyo objetivo es la exclusión coercitiva de la humanidad excedente. Basándose en datos estremecedores y argumentos incontrovertibles, William I. Robinson demuestra hasta qué punto el capitalismo del siglo XXI se ha convertido en un sistema absoluto de represión como único método para mantenerse en pie más allá de sus contradicciones terminales, y defiende la urgencia de crear un movimiento que trascienda los meros llamados a la justicia social y ataque a la yugular.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://joyfulmilitancy.com/&#34;&gt;Joyful militancy by carla bergman and Nick Montgomery&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un libro muy interesante desde todas las perspectivas. Por cómo debió de ser el proceso creativo, por el cuidado y respeto a todos los distintos movimientos que representa, por las personas entrevistadas y las ideas que transmiten... Para mi ha sido un libro clave para una de las transformaciones más importantes de concepto de vida que he dado este año, entrar más en contacto con mi deseo y dejar que este fluya sobre las rigideces autoimpuestas entre otras cosas por el concepto del deber. Esto aplicado a mi vida en general y a mi militancia en particular.&lt;/p&gt; &lt;p&gt;Es cierto que la mayor parte de los conceptos transgresores son heredados del feminismo, pero el libro los refleja muy bien y puede ser un buen punto de entrada para los que no nos hemos zambullido aún muy profundamente en leer teoría feminista.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/joyful.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;Why do radical movements and spaces sometimes feel laden with fear, anxiety, suspicion, self-righteousness and competition? The authors call this phenomenon rigid radicalism: congealed and toxic ways of relating that have seeped into radical movements, posing as the ‘correct’ way of being radical. In conversation with organizers and intellectuals from a wide variety of currents, the authors explore how rigid radicalism smuggles itself into radical spaces, and how it is being undone. Rather than proposing ready-made solutions, they amplify the questions that are already being asked among movements. Fusing together movement-based perspectives and contemporary affect theory, they trace emergent forms of trust, care and responsibility in a wide variety of radical currents today, including indigenous resurgence, anarchism, transformative justice, and youth liberation. Joyful Militancy foregrounds forms of life in the cracks of Empire, revealing the ways that fierceness, tenderness, curiosity, and commitment can be intertwined.&lt;/p&gt; &lt;p&gt;Interviewees include Silvia Federici, adrienne maree brown, Marina Sitrin, Gustavo Esteva, Tasnim Nathoo, Kian Cham, Leanne Betasamosake Simpson, Sebastian Touza, Walidah Imarisha, Margaret Killjoy, Glen Coulthard, Richard Day, Melanie Matining, Zainab Amadahy and Mik Turje.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://piedrapapellibros.com/producto/verano-sin-vacaciones-las-hijas-de-la-costa-del-sol/&#34;&gt;Verano sin vacaciones. Las hijas de la Costa del Sol por Ana geranios&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Libro que dolorosamente me quitó la venda de los ojos en cuanto al turismo y la restauración. Tiene un formato perfecto, la primera parte (Verano sin vacaciones) te llega a la patata haciéndote vivir en las entrañas lo podrido que está el sector y luego en la segunda (Las hijas de la Costa del Sol) le da forma de ensayo y te llega al coco.&lt;/p&gt; &lt;p&gt;Lo leímos en un club de lectura muy chulo organizado por la Escuela de las Periferias, que junto a Estuve aquí y me acordé de nosotros de Anna Pacheco, nos ayudó a tener unas discusiones super interesantes que terminaron de definir mi nuevo concepto sobre el turismo. Además tuve la suerte de asistir a una mesa redonda impresionante con Ana, Valeria del Sindicato de Inquilinas y dos compas de la PAH que le dieron distintos matices a la problemática de la vivienda que tenemos que sufrir. Y para colmo luego estuvimos rajando en un parque con Ana y luego dimos un paseo por el barrio. Un final maravilloso para un libro fantástico.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/Verano-sin-vacaciones.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;¿Cómo sería un mundo sin hostelería? ¿Es posible pensar en una sociedad en la que ninguna persona tuviera que servir ni ser servida, donde las bandejas no tuvieran ninguna utilidad?&lt;/p&gt; &lt;p&gt;Este libro no va de eso. Es justo lo contrario: el análisis de un sector económico que se enriquece gracias al trabajo de quienes se dedican a servir a un público que puede permitírselo.&lt;/p&gt; &lt;p&gt;Verano sin vacaciones es el diario de una trabajadora del sector hostelero de la costa malagueña; un relato al que se suma Las hijas de la Costa del Sol, un ensayo situado que nos interpela como turistas, pero también nos hace comprender qué hay detrás de una industria que descansa sobre la explotación laboral, el servilismo político y la voracidad ecológica.&lt;/p&gt; &lt;p&gt;El leitmotiv es hacernos preguntas, dialogar, pensar, compartir; imaginarnos, ahora sí, cómo sería un mundo sin hostelería.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://donellameadows.org/systems-thinking-book-sale/&#34;&gt;Thinking in systems by Donella H. Meadows&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Me ha encantado. Al principio dudaba de la autora por no saber de que pie cojeaba pero al final es un libro que abre mentes. Muchas ganas de resumirlo. Al principio del año descubrí el concepto de &lt;a href=&#34;https://en.wikipedia.org/wiki/Systems_thinking&#34;&gt;systems thinking&lt;/a&gt; a way of making sense of the complexity of the world by looking at it in terms of wholes and relationships rather than by splitting it down into its parts. It has been used as a way of exploring and developing effective action in complex contexts, enabling systems change. Systems thinking draws on and contributes to systems theory and the system sciences.&lt;/p&gt; &lt;p&gt;Me maravilló la idea de tener un sistema nuevo y sistemático de analizar el mundo, me encantan los modelos y creo que systems thinking puede llegar a ser muy potente. De los cuatro libros que me leí del tema este es sin duda el mejor.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;&#34;/&gt; This is a primer that brings you to a tangible world where anyone can understand systems and engage with them in meaningful ways. The problems we face – war, hunger, poverty, climate change, racism, gender-based violence cannot be solved by quick fixes in isolation. We need to see the whole system and reach deeper to the structures and mindsets that are at play. Written with a hopeful and visionary tone, Thinking in Systems helps readers overcome confusion and helplessness, which is a first step in the work of change.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Novela&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://edurneportela.com/mejor-la-ausencia/&#34;&gt;Mejor la ausencia de Edurne Portela&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Lo empecé el 6 de marzo y esa noche me leí 209 páginas. A las 5:35 dije que ya era suficiente, aunque me fuese rabia no terminarmelo en un día. Hoy ha caído en la madrugada del 7 al 8 de marzo. Muy icónico todo, ya no me da rabia haberlo acabado hoy. Me ha maravillado, cómo escribe Edurne, es una pasada. Te coje con la primera frase y es tu cuerpo el que suplica que dejes de leer. No hay piedad. El cambio de lenguaje a medida que va avanzando la vida de Amaia es alucinante . Cómo le da un repaso a todo el conflicto de Euskadi visto desde alguien que sin estar dentro está salpicada. No se si tuvo miedo al publicarlo, es bastante crítica con toda la movida. Me sorprende porque ella si que está politizada. He pensado que me gustaría preguntarle su opinión respecto a lo que pasó y como ella lo vivió. He pensado varias veces a lo largo de la novela si es autobiográfica. Es impresionante que sea su primera novela.&lt;/p&gt; &lt;p&gt;Ha sido un año del (no estoy seguro de si bien llamado) conflicto vasco, ya que también leí Las fieras de Clara Usón que también me gustó mucho.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/mejor_la_ausencia.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;Crecer siempre implica alguna forma de violencia, contra uno mismo o contra aquellos que quieren imponer su autoridad. Cuando además la vida trascurre en un pueblo de la margen izquierda del Nervión durante los años 80 y 90, y todo es heroína, paro, detritus medioambiental, cuando en las calles silban cada semana las pelotas de goma y los gases lacrimógenos y las paredes están llenas de consignas asesinas, la violencia no es sólo un problema personal. Mejor la ausencia nos presenta una familia destruida, atravesada por la violencia de su entorno. Amaia, la pequeña de cuatro hermanos, narra ese entorno brutal desde su mirada de niña y adolescente. Compartimos con ella su miedo, su perplejidad, su rabia, ante un padre que hiere, una madre que se esconde, tres hermanos que, como ella, sólo buscan salir adelante.&lt;/p&gt; &lt;p&gt;Amaia es la joven que se enfrenta, hasta alcanzar sus propios límites, a este mundo hostil. Amaia es también la mujer que años después vuelve a su pueblo para encontrarse con un pasado irresuelto. En ese camino de ida y vuelta, en sus huidas y regresos, descubrirá, a su pesar, que nadie escapa del entorno en el que se cría, de la familia que le toca en suerte. Y que reconocerlo es la única manera de sobrevivir.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;To kill a mockingbird de Harper Lee&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Inglés muy dificil. La historia muy bien contada, es como que todo el pueblo es de la familia. Engancha bastante.&lt;/p&gt; &lt;p&gt;One of the best-loved stories of all time, To Kill a Mockingbird has been translated into more than 40 languages, sold more than 30 million copies worldwide, served as the basis for an enormously popular motion picture, and voted one of the best novels of the 20&lt;sup&gt;th&lt;/sup&gt; century by librarians across the United States. A gripping, heart-wrenching, and wholly remarkable tale of coming-of-age in a South poisoned by virulent prejudice, it views a world of great beauty and savage inequities through the eyes of a young girl, as her father -- a crusading local lawyer -- risks everything to defend a black man unjustly accused of a terrible crime.&lt;/p&gt; &lt;p&gt;Lawyer Atticus Finch defends Tom Robinson -- a black man charged with the rape of a white girl. Writing through the young eyes of Finch&#39;s children Scout and Jem, Harper Lee explores with rich humor and unswerving honesty the irrationality of adult attitudes toward race and class in small-town Alabama during the mid-1930s Depression years. The conscience of a town steeped in prejudice, violence, and hypocrisy is pricked by the stamina and quiet heroism of one man&#39;s struggle for justice. But the weight of history will only tolerate so much.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Gestión del tiempo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.oliverburkeman.com/fourthousandweeks&#34;&gt;Four thousand weeks by Oliver Burkeman&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Me ha encantado. Me flipa encontrar un libro de auto ayuda y time management con una perspectiva bastante anticapitalista. Probablemente es el mejor libro de gestión de tiempo que conozco, ha generado en mi esos momentos preciosos en los que surgen ideas fuera de los límites mentales que tenía antes. Ha sido bastante liberador y ha influido mucho en crear mi nueva manera de entender el tiempo y cómo navegarlo. Lo he utilizado mucho este año para rediseñar todos mis &lt;a href=&#34;roadmap_adjustments.md&#34;&gt;roadmap adjustments&lt;/a&gt;, en especial el trimestral y el anual. Muy muy recomendable.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/4000_weeks.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;The average human lifespan is absurdly, outrageously, insultingly brief: if you live to 80, you have about four thousand weeks on earth. How should we use them best?&lt;/p&gt; &lt;p&gt;Of course, nobody needs telling that there isn&#39;t enough time. We&#39;re obsessed by our lengthening to-do lists, our overfilled inboxes, the struggle against distraction, and the sense that our attention spans are shrivelling. Yet we rarely make the conscious connection that these problems only trouble us in the first place thanks to the ultimate time-management problem: the challenge of how best to use our four thousand weeks.&lt;/p&gt; &lt;p&gt;Four Thousand Weeks is an uplifting, engrossing and deeply realistic exploration of this problem. Rejecting the futile modern obsession with &#39;getting everything done,&#39; it introduces readers to tools for constructing a meaningful life, showing how the unhelpful ways we&#39;ve come to think about time aren&#39;t inescapable, unchanging truths, but choices we&#39;ve made, as individuals and as a society - and its many revelations will transform the reader&#39;s worldview.&lt;/p&gt; &lt;p&gt;Drawing on the insights of both ancient and contemporary philosophers, psychologists, and spiritual teachers, Oliver Burkeman sets out to realign our relationship with time - and in doing so, to liberate us from its grasp.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://gregmckeown.com/books/essentialism/&#34;&gt;Essentialism: The disciplined pursuit of less&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Me apesta su tono emprendedor de sueño americano y su falta de perspectiva de clase. Eso sumado a su prepotencia mandaloriana de &#34;this is the way&#34;&#34; con el essentialist path y non essentialist path hace que la lectura sea bastante horrenda. Dicho esto, si consigues abstraerte de toda esa mierda, el author aporta conceptos interesantes que me han ayudado mucho a diseñar las revisiones trimestrales y anuales del &lt;a href=&#34;roadmap_adjustments.md&#34;&gt;roadmap adjustments&lt;/a&gt;. Es especialmente interesante para aquellas personas que no sabemos decir que no y acabamos enfrascados en mil movidas.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/essentialism.webp&#34;/&gt;&lt;/p&gt; &lt;p&gt;Essentialism isn&#39;t about getting more done in less time. It&#39;s about getting only the right things done. Have you ever found yourself stretched too thin? Do you simultaneously feel overworked and underutilized? Are you often busy but not productive? Do you feel like your time is constantly being hijacked by other people&#39;s agendas? If you answered yes to any of these, the way out is the Way of the Essentialist. Essentialism is more than a time-management strategy or a productivity technique. It is a systematic discipline for discerning what is absolutely essential, then eliminating everything that is not, so we can make the highest possible contribution toward the things that really matter. By forcing us to apply more selective criteria for what is Essential, the disciplined pursuit of less empowers us to reclaim control of our own choices about where to spend our precious time and energy -- instead of giving others the implicit permission to choose for us. Essentialism is not one more thing. It&#39;s a whole new way of doing everything. It&#39;s about doing less, but better, in every area of our lives.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Ensayo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.librosdelasteroide.com/libro/la-novia-grulla&#34;&gt;La novia grulla de CJ Hauser&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Me ha encantado cómo trata temas tan complicados, su filosofía de vida y lo bien que está escrito. Una ventana a todo tipo de &#34;amor&#34; desde la &#34;nueva&#34; perspectiva feminista. Me entraron muchas ganas de leerlo ya que no paraban de mencionarlo en &lt;a href=&#34;https://lyz-code.github.io/blue-book/podcasts/#punzadas_sonoras&#34;&gt;Punzadas sonoras&lt;/a&gt;, me parece que Paula e Inés me van a dar muy buen material de lectura, aunque no pueda seguirlas el ritmo ni de lejos xD.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/grulla.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Una mirada franca y divertida sobre el amor, la intimidad y la identidad en el siglo XXI.&lt;/p&gt; &lt;p&gt;Diez días después de cancelar su boda, CJ Hauser se embarcó en una expedición a Texas para estudiar a la grulla trompetera. Tras una semana chapoteando en las marismas del golfo comprendió que había estado a punto de firmar un contrato para vivir la vida de otra persona.&lt;/p&gt; &lt;p&gt;¿Qué pasaría si decidiéramos liberarnos de la idea tradicional de felicidad y nos abriéramos a lo inesperado? Hauser se sirve de su propia experiencia para explorar las relaciones sentimentales, los fracasos amorosos, la intimidad y la identidad en el siglo XXI. Disecciona la personalidad de los protagonistas de Expediente X mientras intenta entender qué es el amor, rememora sus peores citas de Tinder, chatea con desconocidos que conversan como robots y analiza a Katharine Hepburn en Historias de Filadelfia para aprender a no perderse en una relación.&lt;/p&gt; &lt;p&gt;Divertido, inclasificable y brutalmente sincero, este libro trata de cómo modelamos nuestra vida sentimental y nuestra comprensión de los demás a través de los relatos; una lectura para aquellos que aprenden a encontrar la alegría en el no saber e intentan, aunque a veces fracasen, construir particulares formas de vida, familia y hogar.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Las dos amigas de Tony Morrison&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Un libro breve, inquietante y curioso que te hace cuestionarte a ti mismo. Me gustaría dar una reflexión más larga pero es imposible no meter spoilers. Cuando te lo leas lo hablamos :P&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;podcasts&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/podcasts/&#34;&gt;Podcasts&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/podcasts/#mejores-podcasts-de-2024&#34;&gt;Mejores podcasts de 2024.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Estoy muy contento porque este año he descubierto podcast muy buenos, hasta el punto de considerar unidireccionalmente a varias de ellas ya parte de mi familia.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.ivoox.com/podcast-quieto-todo-mundo_sq_f11778903_1.html&#34;&gt;Quieto todo el mundo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Facu Díaz y Miguel Maldonado han conseguido alegrarme las horas de cocina de los lunes con la manera más amable de acercarme desde la comedia a la actualidad política.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/quieto_todo_el_mundo.jpeg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Con un tono divertido y relajado, en el programa van comentando desde la ignorancia, la improvisación y, en ocasiones, la desidia las noticias más importantes de la semana.&lt;/p&gt; &lt;p&gt;Esta misa roja ha creado una verdadera religión a lo largo de los programas, no sólo por el lore sino por el vacío existencial que dejan esa semana que no publican programa. Especialmente cuando es porque los nazis les ocupan los espacios, asco de pais...&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://punzadas.com/punzadas-sonoras/&#34;&gt;Punzadas sonoras&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Paula Ducay e Inés García me han recordado la importancia de la Filosofía como nadie. Gracias a ellas he descubierto nuevas maneras de ver, me han regado palabras que describen a la percepción pensamientos y sensaciones que tengo y gracias con ellas he conseguido esclarecer un poco más mi entendimiento del mundo y de mi mismo. En especial han sido la base para desenterrar pilares imprescindibles de mi vida como son el deambular creativo y la solitud.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/punzadas_sonoras.jpeg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Siento que mi camino con ellas ha sido perfecto, me enamoré de ellas en los derroteros de &lt;a href=&#34;#carne-cruda&#34;&gt;Carne cruda&lt;/a&gt; de la temporada pasada (una pena enorme que no las hayan renovado). Son episodios de 20 minutos muy accesibles, y una vez que ya me enganché a ellas, los programas de una hora se hacen cortos.&lt;/p&gt; &lt;p&gt;Escucharlas es un absoluto placer.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://es.wikipedia.org/wiki/No_hay_negros_en_el_T%C3%ADbet&#34;&gt;No hay negros en el Tibet&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Asaari Bibang, Lamine Thior y Frank T nos regalan un par de veces al mes una ventana a la realidad de ser una persona afrodescendiente en España. Es un podcast muy amable de escuchar, te partes con las puyas que se echan, además de ser super interesante ver el salto generacional que hay entre Frank y (Asaari y Lamine). Eso si, tienes que aprender a vivir con que se interrumpan continuamente. Al principio esto me rayó bastante ya que es especialmente irritante cuando se lo hacen a Asaari. Luego ves que no tienen filtro y no sólo se cortan entre ellas, también lo hacen con las personas invitadas.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;no_hay_negros_en_el_tibet.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Una manera muy fácil de introducir el antiracismo en tu vida ya que con sus relatos eres capaz de verlo, identificártelo, aprender y corregir elementos racistas que tenemos inculcados por este sistema asqueroso. Y creo que como material divulgativo es perfecto ya que lo abordan desde un punto de vista antipunitivista nada agresivo, sin que por ello se dejen títere sin cabeza.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.eldiario.es/carnecruda/&#34;&gt;Carne cruda&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Violeta Muñoz y Javier Gallego han sido la voz seria de la actualidad para mi este año.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;cover&#34; src=&#34;../../img/carne_cruda.jpg&#34;/&gt;&lt;/p&gt; &lt;p&gt;Si es cierto que esta temporada estoy un poco más desencantado con el equipo ya que:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Ya no cuentan con Punzadas Sonoras para los derroteros y a Santiago Alba Rico nunca le he tragado.&lt;/li&gt; &lt;li&gt;Hace tiempo que no llaman a Pablo Elorduy del Salto, me encantaba oírle y le echo de menos :(.&lt;/li&gt; &lt;li&gt;Han cambiado el Nido de rojos de la temporada pasada por &#34;A diestra y siniestra&#34; en el que incluyen a peña de derechas en los debates para darle otro punto de vista. Ya se van regulando pero los primeros programas tuve que dejar de escucharlo con cabreo porque tenía que escuchar cosas como que el genocidio de palestina estaba justificado y lindezas similares. Entiendo que puede darle color al debate, pero para eso ya me voy a los medios tradicionales la verdad...&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Aun así sigue siendo el referente para mi para saber qué está pasando tanto en el mundo en general como en el mundo activista.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Muriendo porque saquen más&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Este año hay unos cuantos podcast que no han continuado y que me encantarían que volviesen como:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://deesonosehabla.com/&#34;&gt;(de eso no se habla)&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://www.soynuriaperez.com/podcast&#34;&gt;Gabinete de curiosidades&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;January 16, 2025 06:42:28 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2025-01-16T06:42:28+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;January 16, 2025 06:42:28 UTC&#34;&gt;2025-01-16&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2025_01_15/</link>
      <pubDate>2025-01-16 06:42:28+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2025_01_15/</guid>
      
    </item>
    
    <item><title>23rd December 2024</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;activism&#34;&gt;Activism&lt;/h2&gt; &lt;h3 id=&#34;hacktivism&#34;&gt;Hacktivism&lt;/h3&gt; &lt;h4 id=&#34;chaos-communication-congress&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/&#34;&gt;Chaos Communication Congress&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce the CCC.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://events.ccc.de/en/&#34;&gt;Chaos Communication Congress&lt;/a&gt; is the best gathering of hacktivism in europe.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Prepare yourself for the congress&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can follow &lt;a href=&#34;https://github.com/MacLemon/CongressChecklist&#34;&gt;MacLemon&#39;s checklist&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://events.ccc.de/congress/2024/hub/de/wiki/apps/&#34;&gt;Install the useful apps&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;The schedule app&lt;/em&gt;&lt;/p&gt; &lt;p&gt;You can use either the Fahrplan app or giggity, I&#39;ve been using the second for a while, so is the one I use&lt;/p&gt; &lt;p&gt;&lt;em&gt;The navigation app&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;c3nav&lt;/code&gt; is an application to get around the congress. The official F-droid is outdated, so add &lt;a href=&#34;https://f-droid.c3nav.de/fdroid/repo/?fingerprint=C1EC2D062F67A43F87CCF95B8096630285E1B2577DC803A0826539DF6FB4C95D&#34;&gt;their repository&lt;/a&gt; to get the latest version.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Reference&lt;/strong&gt; - [Home](&lt;a href=&#34;https://events.ccc.de/en/&#34;&gt;https://events.ccc.de/en/&lt;/a&gt; - &lt;a href=&#34;https://engel.events.ccc.de/&#34;&gt;Engelsystem&lt;/a&gt; - &lt;a href=&#34;https://engel.events.ccc.de/faq&#34;&gt;Angel FAQ&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/ccc/#angel&#39;s-system&#34;&gt;Introduce the Angel&#39;s system.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/&#34;&gt;Angels&lt;/a&gt; are participants who volunteer to make the event happen. They are neither getting paid for their work nor do they get free admission.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/#_expectations&#34;&gt;Expectation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Helping at our events also comes with some simple, but important expectations of you:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Be on time for your shift or give Heaven early notice.&lt;/li&gt; &lt;li&gt;Be well rested, sober and not hungry.&lt;/li&gt; &lt;li&gt;Be open-minded and friendly in attitude.&lt;/li&gt; &lt;li&gt;Live our moral values:&lt;/li&gt; &lt;li&gt;Be excellent to each other.&lt;/li&gt; &lt;li&gt;All creatures are welcome.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/#_quick_start&#34;&gt;Quickstart&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Create yourself an &lt;a href=&#34;https://engel.events.ccc.de/&#34;&gt;Engelsystem account&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Arrive at the venue&lt;/li&gt; &lt;li&gt;Find &lt;a href=&#34;https://c3nav.de/&#34;&gt;the Heaven&lt;/a&gt; and go there.&lt;/li&gt; &lt;li&gt;Talk to a welcome angel or a shift coordinator to get your angel badge and get marked as arrived.&lt;/li&gt; &lt;li&gt;If you have any questions, you can always ask the shift coordinators behind the counter.&lt;/li&gt; &lt;li&gt;Attend an angel meeting&lt;/li&gt; &lt;li&gt;Announced in the Engelsystem news&lt;/li&gt; &lt;li&gt;Click yourself an interesting shift&lt;/li&gt; &lt;li&gt;Read shift descriptions first&lt;/li&gt; &lt;li&gt;Participate in your shift&lt;/li&gt; &lt;li&gt;Use the navigation to find the right place.&lt;/li&gt; &lt;li&gt;Arrive a little bit early at the meeting point&lt;/li&gt; &lt;li&gt;Rest for at least one hour&lt;/li&gt; &lt;li&gt;Repeat from step 5&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;And always, have a lot of fun.&lt;/p&gt; &lt;p&gt;To get more insights read &lt;a href=&#34;https://jascha.wtf/angels-at-chaos-about-volunteering-and-fitting-in/&#34;&gt;this article&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/#_the_engelsystem&#34;&gt;The engelsystem&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;a href=&#34;https://engel.events.ccc.de/&#34;&gt;Engelsystem&lt;/a&gt; is the central place to distribute the work to all the helping angels. It can be a bit overwhelming at the beginning but you will get used to it and find your way around.&lt;/p&gt; &lt;p&gt;As you might have seen there are many different shifts and roles for angels — some sounding more appealing than others. There are shifts where you need to have some knowledge before you can take them. This knowledge is given in introduction meetings or by taking an unrestricted shift in the team and getting trained on the job. These introduction meetings are announced in the Engelsystem under the tab &#34;Meetings&#34;. Heaven and the teams try to make sure that there are only restrictions for shifts in place where they are absolutely needed.&lt;/p&gt; &lt;p&gt;Most restrictions really only need a meeting or some unrestricted shifts at the team to get lifted. Harder restrictions are in place where volunteers need to have special certification, get access to certain systems with a huge amount of data (e.g. mail-queues with emails from participants) or handling big piles of money. Usually the requirements for joining an angeltype are included in the description of the angeltype.&lt;/p&gt; &lt;p&gt;Especially the restricted shifts are tempting because after all we want to get the event running, aren’t we? From our personal experience what gets the event running are the most common things: Guarding a door, collecting bottle/trash, washing dishes in the angel kitchen, being on standby to hop in when spontaneous help is needed or check the wrist band at the entrance.&lt;/p&gt; &lt;p&gt;If there are any further questions about angeltypes, the description of the angeltype usually includes contact data such as a DECT number or an e-mail address that can be used. Alternatively, you can also ask one of the persons of the respective angeltype mentioned under &#34;Supporter&#34;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://angelguide.c3heaven.de/#_teams&#34;&gt;Teams&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Congress is organized from different teams, each with its own area of expertise.&lt;/p&gt; &lt;p&gt;All teams are self-organized and provide their own set of services to the event.&lt;/p&gt; &lt;p&gt;Teams spawn into existence by a need not fulfilled. They are seldom created by an authority.&lt;/p&gt; &lt;p&gt;Check out the &lt;a href=&#34;https://angelguide.c3heaven.de/#_teams&#34;&gt;different teams&lt;/a&gt; to see which one suits you best.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://jascha.wtf/angels-at-chaos-about-volunteering-and-fitting-in/&#34;&gt;Some poeple&lt;/a&gt; suggest not to try to fit into special roles at your first event. The roles will find you – not the other way around. Our com­mu­ni­ty is not about per­so­nal gro­wing but about con­tri­bu­ting to each other and gro­wing by doing this.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Perks&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Being an angel also comes with some perks. While we hope that participation is reward enough, here is a list of things that are exclusive to angels:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Community acknowledgement&lt;/li&gt; &lt;li&gt;Hanging out in Heaven and the angel hack center with its chill out area&lt;/li&gt; &lt;li&gt;Free coffee and (sparkling) water&lt;/li&gt; &lt;li&gt;Warm drinks or similar to make the cold night shifts more bearable&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Rewards&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you have contributed a certain amount of time, you may receive access to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Fantastic hot vegan and vegetarian meals&lt;/li&gt; &lt;li&gt;The famous limited™ angel T-shirt in Congress design&lt;/li&gt; &lt;li&gt;Maybe some other perks&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;time-management&#34;&gt;Time management&lt;/h3&gt; &lt;h4 id=&#34;orgzly&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/orgzly/&#34;&gt;Orgzly&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: Migrate from Orgzly to Orgzly Revived.&lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;himalaya&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/&#34;&gt;himalaya&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Tweak the bindings.&lt;/p&gt; &lt;p&gt;Move forward and backwards in the history of emails:&lt;/p&gt; &lt;p&gt; Better bindings for the email list view:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;          &lt;span class=&#34;c1&#34;&gt;-- Refresh emails&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;r&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:lua FetchEmails()&amp;lt;CR&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Email list view bindings&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;b&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select-previous-page)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;f&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select-next-page)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;R&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-reply-all)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;F&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-forward)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;m&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-folder-select)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;M&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-move)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(himalaya#Searching emails): Searching emails&lt;/p&gt; &lt;p&gt;You can use the &lt;code&gt;g/&lt;/code&gt; binding from within nvim to search for emails. The query syntax supports filtering and sorting query.&lt;/p&gt; &lt;p&gt;I&#39;ve tried changing it to &lt;code&gt;/&lt;/code&gt; without success :&#39;(&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Filters&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A filter query is composed of operators and conditions. There is 3 operators and 8 conditions:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;not &amp;lt;condition&amp;gt;&lt;/code&gt;: filter envelopes that do not match the condition&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;condition&amp;gt; and &amp;lt;condition&amp;gt;&lt;/code&gt;: filter envelopes that match both conditions&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;condition&amp;gt; or &amp;lt;condition&amp;gt;&lt;/code&gt;: filter envelopes that match one of the conditions&lt;/li&gt; &lt;li&gt;&lt;code&gt;date &amp;lt;yyyy-mm-dd&amp;gt;&lt;/code&gt;: filter envelopes that match the given date&lt;/li&gt; &lt;li&gt;&lt;code&gt;before &amp;lt;yyyy-mm-dd&amp;gt;&lt;/code&gt;: filter envelopes with date strictly before the given one&lt;/li&gt; &lt;li&gt;&lt;code&gt;after &amp;lt;yyyy-mm-dd&amp;gt;&lt;/code&gt;: filter envelopes with date stricly after the given one&lt;/li&gt; &lt;li&gt;&lt;code&gt;from &amp;lt;pattern&amp;gt;&lt;/code&gt;: filter envelopes with senders matching the given pattern&lt;/li&gt; &lt;li&gt;&lt;code&gt;to &amp;lt;pattern&amp;gt;&lt;/code&gt;: filter envelopes with recipients matching the given pattern&lt;/li&gt; &lt;li&gt;&lt;code&gt;subject &amp;lt;pattern&amp;gt;&lt;/code&gt;: filter envelopes with subject matching the given pattern&lt;/li&gt; &lt;li&gt;&lt;code&gt;body &amp;lt;pattern&amp;gt;&lt;/code&gt;: filter envelopes with text bodies matching the given pattern&lt;/li&gt; &lt;li&gt;&lt;code&gt;flag &amp;lt;flag&amp;gt;&lt;/code&gt;: filter envelopes matching the given flag&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Sorting&lt;/strong&gt; A sort query starts by &#34;order by&#34;, and is composed of kinds and orders. There is 4 kinds and 2 orders:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;date [order]&lt;/code&gt;: sort envelopes by date&lt;/li&gt; &lt;li&gt;&lt;code&gt;from [order]&lt;/code&gt;: sort envelopes by sender&lt;/li&gt; &lt;li&gt;&lt;code&gt;to [order]&lt;/code&gt;: sort envelopes by recipient&lt;/li&gt; &lt;li&gt;&lt;code&gt;subject [order]&lt;/code&gt;: sort envelopes by subject&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;kind&amp;gt; asc&lt;/code&gt;: sort envelopes by the given kind in ascending order&lt;/li&gt; &lt;li&gt;&lt;code&gt;&amp;lt;kind&amp;gt; desc&lt;/code&gt;: sort envelopes by the given kind in descending order&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Examples&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;subject foo and body bar&lt;/code&gt;: filter envelopes containing &#34;foo&#34; in their subject and &#34;bar&#34; in their text bodies &lt;code&gt;order by date desc subject&lt;/code&gt;: sort envelopes by descending date (most recent first), then by ascending subject &lt;code&gt;subject foo and body bar order by date desc subject&lt;/code&gt;: combination of the 2 previous examples&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#not-there-yet&#34;&gt;List more detected issues.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/14&#34;&gt;Replying an email doesn&#39;t mark it as replied&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#cannot-install&#34;&gt;Troubleshoot cannot install the program.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Sometimes &lt;a href=&#34;https://github.com/pimalaya/himalaya/issues/513&#34;&gt;the installation steps fail&lt;/a&gt; as it&#39;s still not in stable. A workaround is to download the binary created by the &lt;a href=&#34;https://github.com/pimalaya/himalaya/actions/workflows/pre-releases.yml&#34;&gt;pre-release CI&lt;/a&gt;. You can do it by:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Click on the latest job&lt;/li&gt; &lt;li&gt;Click on jobs&lt;/li&gt; &lt;li&gt;Click on the job of your architecture&lt;/li&gt; &lt;li&gt;Click on &#34;Upload release&#34;&lt;/li&gt; &lt;li&gt;Search for &#34;Artifact download URL&#34; and download the file&lt;/li&gt; &lt;li&gt;Unpack it and add it somewhere in your &lt;code&gt;$PATH&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;content-management&#34;&gt;Content Management&lt;/h3&gt; &lt;h4 id=&#34;jellyfin&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/&#34;&gt;Jellyfin&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/jellyfin/#enable-hardware-transcoding&#34;&gt;Enable hardware transcoding.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://jellyfin.org/docs/general/administration/hardware-acceleration/nvidia&#34;&gt;Enable NVIDIA hardware transcoding&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;Remove the artificial limit of concurrent NVENC transcodings&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Consumer targeted &lt;a href=&#34;https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new&#34;&gt;Geforce and some entry-level Quadro cards&lt;/a&gt; have an artificial limit on the number of concurrent NVENC encoding sessions (max of 8 on most modern ones). This restriction can be circumvented by applying an unofficial patch to the NVIDIA Linux and Windows driver.&lt;/p&gt; &lt;p&gt;To apply the patch:&lt;/p&gt; &lt;p&gt;First check that your current version is supported &lt;code&gt;nvidia-smi&lt;/code&gt;, if it&#39;s not try to upgrade the drivers to a supported one, or think if you need more than 8 transcodings. &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wget&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://raw.githubusercontent.com/keylase/nvidia-patch/refs/heads/master/patch.sh
chmod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;+x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;patch.sh
./patch.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt; &lt;p&gt;If you need to rollback the changes run &lt;code&gt;./patch.sh -r&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;You can also patch it &lt;a href=&#34;https://github.com/keylase/nvidia-patch?tab=readme-ov-file#docker-support&#34;&gt;within the docker itself&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;jellyfin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;jellyfin/jellyfin&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;user&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;1000:1000&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;network_mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#39;host&#39;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/path/to/config:/config&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/path/to/cache:/cache&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;/path/to/media:/media&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;runtime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;nvidia&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;deploy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;resources&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;reservations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;devices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;driver&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;nvidia&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;all&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;capabilities&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;gpu&lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Restart the docker and then check that you can access the graphics card with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-it&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;jellyfin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;nvidia-smi
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Enable NVENC in Jellyfin and uncheck the unsupported codecs.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Tweak the docker-compose&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The official Docker image doesn&#39;t include any NVIDIA proprietary driver.&lt;/p&gt; &lt;p&gt;You have to install the NVIDIA driver and NVIDIA Container Toolkit on the host system to allow Docker access to your GPU.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;knowledge-management&#34;&gt;Knowledge Management&lt;/h3&gt; &lt;h4 id=&#34;aleph&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/&#34;&gt;Aleph&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#available-datasets&#34;&gt;Available datasets.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;OpenSanctions helps investigators find leads, allows companies to manage risk and enables technologists to build data-driven products.&lt;/p&gt; &lt;p&gt;You can check &lt;a href=&#34;https://www.opensanctions.org/datasets/&#34;&gt;their datasets&lt;/a&gt;.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#offshore-graph&#34;&gt;Offshore-graph.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/opensanctions/offshore-graph&#34;&gt;offshore-graph&lt;/a&gt; contains scripts that will merge the OpenSanctions Due Diligence dataset with the ICIJ OffshoreLeaks database in order create a combined graph for analysis.&lt;/p&gt; &lt;p&gt;The result is a Cypher script to load the full graph into the Neo4J database and then browse it using the Linkurious investigation platform.&lt;/p&gt; &lt;p&gt;Based on name-based entity matching between the datasets, an analyst can use this graph to find offshore holdings linked to politically exposed and sanctioned individuals.&lt;/p&gt; &lt;p&gt;As a general alternative, you can easily export and convert entities from an Aleph instance to visualize them in Neo4j or Gephi using the ftm CLI: &lt;a href=&#34;https://docs.aleph.occrp.org/developers/how-to/data/export-network-graphs/&#34;&gt;https://docs.aleph.occrp.org/developers/how-to/data/export-network-graphs/&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;languages&#34;&gt;Languages&lt;/h3&gt; &lt;h4 id=&#34;nodejs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/nodejs/&#34;&gt;nodejs&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/nodejs/#using-nvm&#34;&gt;Install using nvm.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;bash

nvm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;22&lt;/span&gt;

node&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# should print `v22.12.0`&lt;/span&gt;

npm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-v&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;# should print `10.9.0`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h2&gt; &lt;h3 id=&#34;infrastructure-solutions&#34;&gt;Infrastructure Solutions&lt;/h3&gt; &lt;h4 id=&#34;kubectl-commands&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/&#34;&gt;Kubectl Commands&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/devops/kubectl/kubectl_commands/#delete-pods-that-are-stuck-in-terminating-state-for-a-while&#34;&gt;Delete pods that are stuck in terminating state for a while.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;kubectl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;delete&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;pod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pod-name&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--grace-period&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;Linux&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#convert-an-html-to-a-pdf&#34;&gt;Convert an html to a pdf.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Using weasyprint&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Install it with &lt;code&gt;pip install weasyprint PyMuPDF&lt;/code&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;weasyprint&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.html&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.pdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It gave me better result than &lt;code&gt;wkhtmltopdf&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Using wkhtmltopdf&lt;/strong&gt; To convert the given HTML into a PDF with proper styling and formatting using a simple method on Linux, you can use &lt;code&gt;wkhtmltopdf&lt;/code&gt; with some custom options.&lt;/p&gt; &lt;p&gt;First, ensure that you have &lt;code&gt;wkhtmltopdf&lt;/code&gt; installed on your system. If not, install it using your package manager (e.g., Debian: &lt;code&gt;sudo apt-get install wkhtmltopdf&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;Then, convert the HTML to PDF using &lt;code&gt;wkhtmltopdf&lt;/code&gt; with the following command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;wkhtmltopdf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--page-size&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;A4&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--margin-top&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;15mm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--margin-bottom&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;15mm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--encoding&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;utf8&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;input.html&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;output.pdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;In this command: - &lt;code&gt;--page-size A4&lt;/code&gt;: Sets the paper size to A4. - &lt;code&gt;--margin-top 15mm&lt;/code&gt; and &lt;code&gt;--margin-bottom 15mm&lt;/code&gt;: Adds top and bottom margins of 15 mm to the PDF.&lt;/p&gt; &lt;p&gt;After running the command, you should have a nicely formatted &lt;code&gt;output.pdf&lt;/code&gt; file in your current directory. This method preserves most of the original HTML styling while providing a simple way to export it as a PDF on Linux.&lt;/p&gt; &lt;p&gt;If you need to zoom in, you can use the &lt;code&gt;--zoom 1.2&lt;/code&gt; flag. For this to work you need your css to be using the &lt;code&gt;em&lt;/code&gt; sizes.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#format-a-drive-to-use-a-fat32-system&#34;&gt;Format a drive to use a FAT32 system.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mkfs.vfat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-F&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;32&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdX
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Replace /dev/sdX with your actual drive identifier&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#get-the-newest-file-of-a-directory-with-nested-directories-and-files&#34;&gt;Get the newest file of a directory with nested directories and files.&lt;/a&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;.&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-type&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-printf&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;%T@ %p\n&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sort&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-n&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-1&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cut&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f2-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;s2&#34;&gt;&#34; &#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#how-to-debug-a-cpu-throttling-high-alert&#34;&gt;How to debug a CPU Throttling high alert.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If the docker is using less resources than the limits but they are still small (for example 0.1 CPUs) the issue may be that the CPU spikes are being throttle before they are shown in the CPU usage, the solution is then to increase the CPU limits&lt;/p&gt; &lt;p&gt;# Create a systemd service for a non-root user&lt;/p&gt; &lt;p&gt;To set up a systemd service as a &lt;strong&gt;non-root user&lt;/strong&gt;, you can create a user-specific service file under your home directory. User services are defined in &lt;code&gt;~/.config/systemd/user/&lt;/code&gt; and can be managed without root privileges.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Check the docker images sorted by size.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;docker&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;images&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--format&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;{{.Repository}}:{{.Tag}}\t{{.Size}}&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;sort&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-k2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can also use the builtin &lt;code&gt;docker system df -v&lt;/code&gt; to get a better understanding of the usage of disk space.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt; &lt;ul&gt; &lt;li&gt;Reorganization: Into roadmap_adjustment.&lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;December 24, 2024 06:45:10 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2024-12-24T06:45:10+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;December 24, 2024 06:45:10 UTC&#34;&gt;2024-12-24&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2024_12_23/</link>
      <pubDate>2024-12-24 06:45:10+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2024_12_23/</guid>
      
    </item>
    
    <item><title>27th November 2024</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;activism&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/antitourism/&#34;&gt;Activism&lt;/a&gt;&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/antitourism/#artículos&#34;&gt;Nuevo artículo contra el turismo.&lt;/a&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://www.elsaltodiario.com/turismo/abolir-turismo&#34;&gt;Abolir el turismo - Escuela de las periferias&lt;/a&gt;: Lleguemos a donde lleguemos, no puede ser que sea más fácil imaginar el fin del capitalismo que el fin del turismo.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;himalaya&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/&#34;&gt;himalaya&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#configure-navigation-bindings&#34;&gt;Configure navigation bindings.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The default bindings conflict with my git bindings, and to make them similar to orgmode agenda I&#39;m changing the next and previous page:&lt;/p&gt;  &lt;/li&gt; &lt;li&gt; &lt;p&gt;Correction: &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/#configure-the-account-bindings&#34;&gt;Configure the account bindings.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;android&#34;&gt;Android&lt;/h3&gt; &lt;h4 id=&#34;android-sdk-platform-tools&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/android_sdk/&#34;&gt;Android SDK Platform tools&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce android_sdk.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://developer.android.com/tools/releases/platform-tools&#34;&gt;Android SDK Platform tools&lt;/a&gt; is a component for the Android SDK. It includes tools that interface with the Android platform, primarily adb and fastboot.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://developer.android.com/tools/releases/platform-tools&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;While many Linux distributions already package Android Platform Tools (for example &lt;code&gt;android-platform-tools-base&lt;/code&gt; on Debian), it is preferable to install the most recent version from the official website. Packaged versions might be outdated and incompatible with most recent Android handsets.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Download &lt;a href=&#34;https://dl.google.com/android/repository/platform-tools-latest-linux.zip&#34;&gt;the latest toolset&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Extract it somewhere in your filesystem&lt;/li&gt; &lt;li&gt;Create links to the programs you want to use in your &lt;code&gt;$PATH&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Next you will need to enable debugging on the Android device you are testing. &lt;a href=&#34;https://developer.android.com/studio/command-line/adb&#34;&gt;Please follow the official instructions on how to do so.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Connecting over USB&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To use &lt;code&gt;adb&lt;/code&gt; with a device connected over USB, you must enable USB debugging in the device system settings, under Developer options. On Android 4.2 (API level 17) and higher, the Developer options screen is hidden by default.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Enable the Developer options&lt;/em&gt;&lt;/p&gt; &lt;p&gt;To make it visible, &lt;a href=&#34;https://developer.android.com/studio/debug/dev-options#enable&#34;&gt;enable Developer options&lt;/a&gt;. On Android 4.1 and lower, the Developer options screen is available by default. On Android 4.2 and higher, you must enable this screen.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;On your device, find the Build number option (Settings &amp;gt; About phone &amp;gt; Build number)&lt;/li&gt; &lt;li&gt;Tap the Build Number option seven times until you see the message You are now a developer! This enables developer options on your device.&lt;/li&gt; &lt;li&gt;Return to the previous screen to find Developer options at the bottom.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;em&gt;Enable USB debugging&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Before you can use the debugger and other tools, you need to enable USB debugging, which allows Android Studio and other SDK tools to recognize your device when connected via USB.&lt;/p&gt; &lt;p&gt;Enable USB debugging in the device system settings under Developer options. You can find this option in one of the following locations, depending on your Android version:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Android 9 (API level 28) and higher: Settings &amp;gt; System &amp;gt; Advanced &amp;gt; Developer Options &amp;gt; USB debugging&lt;/li&gt; &lt;li&gt;Android 8.0.0 (API level 26) and Android 8.1.0 (API level 27): Settings &amp;gt; System &amp;gt; Developer Options &amp;gt; USB debugging&lt;/li&gt; &lt;li&gt;Android 7.1 (API level 25) and lower: Settings &amp;gt; Developer Options &amp;gt; USB debugging&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;em&gt;Test it works&lt;/em&gt;&lt;/p&gt; &lt;p&gt;If everything is configured appropriately you should see your device when launching the command &lt;code&gt;adb devices&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;em&gt;Create udev rules if it fails&lt;/em&gt;&lt;/p&gt; &lt;p&gt;If you see the next error:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;failed to open device: Access denied (insufficient permissions)

* failed to start daemon
adb: failed to check server version: cannot connect to daemon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;It indicates an issue with permissions when &lt;code&gt;adb&lt;/code&gt; tries to communicate with the device via USB. Here are some steps you can take to resolve this issue:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Check USB permissions&lt;/li&gt; &lt;li&gt;Ensure that you have the necessary permissions to access the USB device. If you&#39;re running on Linux, check if the device has appropriate udev rules.&lt;/li&gt; &lt;li&gt; &lt;p&gt;You can try adding your user to the &lt;code&gt;plugdev&lt;/code&gt; group:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;usermod&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-aG&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;plugdev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$USER&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Make sure you have a &lt;code&gt;udev&lt;/code&gt; rule for Android devices in &lt;code&gt;/etc/udev/rules.d/&lt;/code&gt;. If not, you can create one by adding a file like &lt;code&gt;51-android.rules&lt;/code&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;touch&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/etc/udev/rules.d/51-android.rules
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Add this line to the file to grant access to Android devices:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nv&#34;&gt;SUBSYSTEM&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;usb&#34;&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;ATTR&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;idVendor&lt;span class=&#34;o&#34;&gt;}==&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;18d1&#34;&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;MODE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;0666&#34;&lt;/span&gt;,&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;GROUP&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;plugdev&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reload the &lt;code&gt;udev&lt;/code&gt; rules:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;udevadm&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;control&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--reload-rules
sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;udev&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Unplug and reconnect the USB device. &lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://developer.android.com/tools/releases/platform-tools&#34;&gt;Home&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;other&#34;&gt;Other&lt;/h2&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate not-by-ai.&lt;/p&gt; &lt;p&gt;As they have introduced pricing, which makes no sense, and we had a discussion that using that badge it&#39;s a nice way to tell the AI which content to use and which not to&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;November 28, 2024 06:46:58 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2024-11-28T06:46:58+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;November 28, 2024 06:46:58 UTC&#34;&gt;2024-11-28&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2024_11_27/</link>
      <pubDate>2024-11-28 06:46:58+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2024_11_27/</guid>
      
    </item>
    
    <item><title>19th November 2024</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;time-management&#34;&gt;Time management&lt;/h3&gt; &lt;h4 id=&#34;vdirsyncer&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/&#34;&gt;vdirsyncer&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/#sync-to-a-read-only-ics&#34;&gt;Sync to a read-only ics.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;```ini [pair calendar_name] a = &#34;calendar_name_local&#34; b = &#34;calendar_name_remote&#34; collections = null conflict_resolution = [&#34;command&#34;, &#34;vimdiff&#34;] metadata = [&#34;displayname&#34;, &#34;color&#34;]&lt;/p&gt; &lt;p&gt;[storage calendar_name_local] type = &#34;filesystem&#34; path = &#34;~/.calendars/calendar_name&#34; fileext = &#34;.ics&#34;&lt;/p&gt; &lt;p&gt;[storage calendar_name_remote] type = &#34;http&#34; url = &#34;&lt;a href=&#34;https://example.org/calendar.ics&#34;&gt;https://example.org/calendar.ics&lt;/a&gt;&#34;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/vdirsyncer/#automatically-sync-calendars&#34;&gt;Automatically sync calendars.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;You can use the script shown in the &lt;a href=&#34;#script-to-sync-emails-and-calendars-with-different-frequencies&#34;&gt;automatically sync emails&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;gancio&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/gancio/&#34;&gt;Gancio&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/gancio/#wordpress-plugin&#34;&gt;Wordpress plugin.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This plugin allows you to embed a list of events or a single event from your Gancio website using a shortcode. It also allows you to connects a Gancio instance to a your wordpress website to automatically push events published on WordPress: for this to work an event manager plugin is required, Event Organiser and The Events Calendar are supported. Adding another plugin it’s an easy task and you have a guide available in the repo that shows you how to do it.&lt;/p&gt; &lt;p&gt;The source code of the plugin is &lt;a href=&#34;https://framagit.org/les/gancio/-/tree/master/wp-plugin?ref_type=heads&#34;&gt;in the wp-plugin&lt;/a&gt; directory of the official repo&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h3 id=&#34;life-chores-management&#34;&gt;Life chores management&lt;/h3&gt; &lt;h4 id=&#34;himalaya&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/mbsync/&#34;&gt;himalaya&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce himalaya.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya&#34;&gt;himalaya&lt;/a&gt; is a Rust CLI to manage emails.&lt;/p&gt; &lt;p&gt;Features:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Multi-accounting&lt;/li&gt; &lt;li&gt;Interactive configuration via &lt;strong&gt;wizard&lt;/strong&gt; (requires &lt;code&gt;wizard&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Mailbox, envelope, message and flag management&lt;/li&gt; &lt;li&gt;Message composition based on &lt;code&gt;$EDITOR&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;IMAP&lt;/strong&gt; backend (requires &lt;code&gt;imap&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Maildir&lt;/strong&gt; backend (requires &lt;code&gt;maildir&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Notmuch&lt;/strong&gt; backend (requires &lt;code&gt;notmuch&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;SMTP&lt;/strong&gt; backend (requires &lt;code&gt;smtp&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Sendmail&lt;/strong&gt; backend (requires &lt;code&gt;sendmail&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Global system &lt;strong&gt;keyring&lt;/strong&gt; for managing secrets (requires &lt;code&gt;keyring&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;OAuth 2.0&lt;/strong&gt; authorization (requires &lt;code&gt;oauth2&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;&lt;strong&gt;JSON&lt;/strong&gt; output via &lt;code&gt;--output json&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;strong&gt;PGP&lt;/strong&gt; encryption:&lt;/li&gt; &lt;li&gt;via shell commands (requires &lt;code&gt;pgp-commands&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;via &lt;a href=&#34;https://www.gnupg.org/&#34;&gt;GPG&lt;/a&gt; bindings (requires &lt;code&gt;pgp-gpg&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;via native implementation (requires &lt;code&gt;pgp-native&lt;/code&gt; feature)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Documentation is inexistent, you have to dive into the &lt;code&gt;--help&lt;/code&gt; to understand stuff.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;em&gt;The &lt;code&gt;v1.0.0&lt;/code&gt; is currently being tested on the &lt;code&gt;master&lt;/code&gt; branch, and is the prefered version to use. Previous versions (including GitHub beta releases and repositories published versions) are not recommended.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Himalaya CLI &lt;code&gt;v1.0.0&lt;/code&gt; can be installed with a pre-built binary. Find the latest &lt;a href=&#34;https://github.com/pimalaya/himalaya/actions/workflows/pre-release.yml&#34;&gt;&lt;code&gt;pre-release&lt;/code&gt;&lt;/a&gt; GitHub workflow and look for the &lt;em&gt;Artifacts&lt;/em&gt; section. You should find a pre-built binary matching your OS.&lt;/p&gt; &lt;p&gt;Himalaya CLI &lt;code&gt;v1.0.0&lt;/code&gt; can also be installed with &lt;a href=&#34;https://doc.rust-lang.org/cargo/&#34;&gt;cargo&lt;/a&gt;:&lt;/p&gt; &lt;p&gt; &lt;strong&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya?tab=readme-ov-file#configuration&#34;&gt;Configuration&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Just run &lt;code&gt;himalaya&lt;/code&gt;, the wizard will help you to configure your default account.&lt;/p&gt; &lt;p&gt;You can also manually edit your own configuration, from scratch:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Copy the content of the documented &lt;a href=&#34;https://github.com/pimalaya/himalaya/blob/master/config.sample.toml&#34;&gt;&lt;code&gt;./config.sample.toml&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Paste it in a new file &lt;code&gt;~/.config/himalaya/config.toml&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Edit, then comment or uncomment the options you want&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;If using mbrsync&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;My generic configuration for an mbrsync account is:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[accounts.account_name]

email = &#34;lyz@example.org&#34;
display-name = &#34;lyz&#34;
envelope.list.table.unseen-char = &#34;u&#34;
envelope.list.table.replied-char = &#34;r&#34;
backend.type = &#34;maildir&#34;
backend.root-dir = &#34;/home/lyz/.local/share/mail/lyz-example&#34;
backend.maildirpp = false
message.send.backend.type = &#34;smtp&#34;
message.send.backend.host = &#34;example.org&#34;
message.send.backend.port = 587
message.send.backend.encryption = &#34;start-tls&#34;
message.send.backend.login = &#34;lyz&#34;
message.send.backend.auth.type = &#34;password&#34;
message.send.backend.auth.command = &#34;pass show mail/lyz.example&#34;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Once you&#39;ve set it then you need to &lt;a href=&#34;#cannot-find-maildir-matching-name-inbox&#34;&gt;fix the INBOX directory&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Then you can check if it works by running &lt;code&gt;himalaya envelopes list -a lyz-example&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Vim plugin installation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Using lazy:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;pimalaya/himalaya-vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can then run &lt;code&gt;:Himalaya account_name&lt;/code&gt; and it will open himalaya in your editor.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configure the account bindings&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;To avoid typing &lt;code&gt;:Himalaya account_name&lt;/code&gt; each time you want to check the email you can set some bindings:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;pimalaya/himalaya-vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;ma&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;cmd&amp;gt;Himalaya account_name&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Open account_name@example.org&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;ml&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;cmd&amp;gt;Himalaya lyz&amp;lt;cr&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Open lyz@example.org&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Setting the description is useful to see the configured accounts with which-key by typing &lt;code&gt;&amp;lt;leader&amp;gt;m&lt;/code&gt; and waiting.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configure extra bindings&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The default plugin doesn&#39;t yet have all the bindings I&#39;d like so I&#39;ve added the next ones:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;In the list of emails view:&lt;/li&gt; &lt;li&gt;&lt;code&gt;dd&lt;/code&gt; in normal mode or &lt;code&gt;d&lt;/code&gt; in visual: Delete emails&lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;code&gt;q&lt;/code&gt;: exit the program&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;In the email view:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;&lt;code&gt;d&lt;/code&gt;: Delete email&lt;/li&gt; &lt;li&gt;&lt;code&gt;q&lt;/code&gt;: Return to the list of emails view&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If you want them too set the next config:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;pimalaya/himalaya-vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_augroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;HimalayaCustomBindings&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clear&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;FileType&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;HimalayaCustomBindings&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;himalaya-email-listing&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Bindings to delete emails&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;dd&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-delete)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;x&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;d&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-delete)&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Bind `q` to close the window&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;q&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:bd&amp;lt;CR&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;

      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_augroup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;HimalayaEmailCustomBindings&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clear&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
      &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_create_autocmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;FileType&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;HimalayaEmailCustomBindings&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;pattern&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;mail&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;callback&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Bind `q` to close the window&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;q&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;:q&amp;lt;CR&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
          &lt;span class=&#34;c1&#34;&gt;-- Bind `d` to delete the email and close the window&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nvim_buf_set_keymap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;d&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;plug&amp;gt;(himalaya-email-delete):q&amp;lt;CR&amp;gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;noremap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;silent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
          &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Configure email fetching from within vim&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/13&#34;&gt;Fetching emails from within vim&lt;/a&gt; is not yet supported, so I&#39;m manually refreshing by account:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kr&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;pimalaya/himalaya-vim&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
      &lt;span class=&#34;c1&#34;&gt;-- Email refreshing bindings&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;&amp;lt;leader&amp;gt;rj&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&#39;:lua FetchEmails(&#34;lyz&#34;)&amp;lt;CR&amp;gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;desc&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;Fetch lyz@example.org&#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;FetchEmails&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Fetching emails for &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;, please wait...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cmd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;redraw&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fn&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jobstart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;mbsync &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;n&#34;&gt;on_exit&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exit_code&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exit_code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;then&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Emails for &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34; fetched successfully!&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;else&lt;/span&gt;
              &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Failed to fetch emails for &#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;..&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;. Check the logs.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ERROR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
          &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
      &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;
    &lt;span class=&#34;kr&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
  &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You still need to open again &lt;code&gt;:Himalaya account_name&lt;/code&gt; as the plugin does not reload if there are new emails.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Show notifications when emails arrive&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can set up &lt;a href=&#34;https://lyz-code.github.io/blue-book/mirador/&#34;&gt;mirador&lt;/a&gt; to get those notifications.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Not there yet&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/8&#34;&gt;With the vim plugin you can&#39;t switch accounts&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/12&#34;&gt;Let the user delete emails without confirmation&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya-vim/issues/13&#34;&gt;Fetching emails from within vim&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/pimalaya/himalaya/issues/490&#34;&gt;Cannot find maildir matching name INBOX&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;mbrsync&lt;/code&gt; uses &lt;code&gt;Inbox&lt;/code&gt; instead of the default &lt;code&gt;INBOX&lt;/code&gt; so it doesn&#39;t find it. In theory you can use &lt;code&gt;folder.alias.inbox = &#34;Inbox&#34;&lt;/code&gt; but it didn&#39;t work with me, so I finally ended up doing a symbolic link from &lt;code&gt;INBOX&lt;/code&gt; to &lt;code&gt;Inbox&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cannot find maildir matching name Trash&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;That&#39;s because the &lt;code&gt;Trash&lt;/code&gt; directory does not follow the Maildir structure. I had to create the &lt;code&gt;cur&lt;/code&gt; &lt;code&gt;tmp&lt;/code&gt; and &lt;code&gt;new&lt;/code&gt; directories.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://github.com/pimalaya/himalaya&#34;&gt;Source&lt;/a&gt; - &lt;a href=&#34;https://github.com/pimalaya/himalaya-vim&#34;&gt;Vim plugin source&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce mailbox.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://docs.python.org/3/library/mailbox.html&#34;&gt;&lt;code&gt;mailbox&lt;/code&gt;&lt;/a&gt; is a python library to work with MailDir and mbox local mailboxes.&lt;/p&gt; &lt;p&gt;It&#39;s part of the core python libraries, so you don&#39;t need to install anything.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The docs are not very pleasant to read, so I got most of the usage knowledge from these sources:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://pymotw.com/2/mailbox/&#34;&gt;pymowt docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://cr-net.be/posts/maildir_cleanup_with_python/&#34;&gt;Cleanup maildir directories&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://gist.github.com/tyndyll/6f6145f8b1e82d8b0ad8&#34;&gt;Parsing maildir directories&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;One thing to keep in mind is that an account can have many mailboxes (INBOX, Sent, ...), there is no &#34;root mailbox&#34; that contains all of the other&lt;/p&gt; &lt;p&gt;&lt;strong&gt;initialise a mailbox&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;n&#34;&gt;mbox&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mailbox&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Maildir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;path/to/your/mailbox&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where the &lt;code&gt;path/to/your/mailbox&lt;/code&gt; is the directory that contains the &lt;code&gt;cur&lt;/code&gt;, &lt;code&gt;new&lt;/code&gt;, and &lt;code&gt;tmp&lt;/code&gt; directories.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Working with mailboxes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It&#39;s not very clear how to work with them, the Maildir mailbox contains the emails in iterators &lt;code&gt;[m for m in mbox]&lt;/code&gt;, it acts kind of a dictionary, you can get the keys of the emails with &lt;code&gt;[k for k in mbox.iterkeys]&lt;/code&gt;, and then you can &lt;code&gt;mbox[key]&lt;/code&gt; to get an email, you cannot modify those emails (flags, subdir, ...) directly in the &lt;code&gt;mbox&lt;/code&gt; object (for example &lt;code&gt;mbox[key].set_flags(&#39;P&#39;)&lt;/code&gt; doesn&#39;t work). You need to &lt;code&gt;mail = mbox.pop(key)&lt;/code&gt;, do the changes in the &lt;code&gt;mail&lt;/code&gt; object and then &lt;code&gt;mbox.add(mail)&lt;/code&gt; it again, with the downside that after you added it again, the &lt;code&gt;key&lt;/code&gt; has changed! But it&#39;s the return value of the &lt;code&gt;add&lt;/code&gt; method.&lt;/p&gt; &lt;p&gt;If the program gets interrupted between the &lt;code&gt;pop&lt;/code&gt; and the &lt;code&gt;add&lt;/code&gt; then you&#39;ll loose the email. The best way to work with it would be then:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;mail = mbox.get(key)&lt;/code&gt; the email&lt;/li&gt; &lt;li&gt;Do all the process you need to do with the email&lt;/li&gt; &lt;li&gt;&lt;code&gt;mbox.pop(key)&lt;/code&gt; and &lt;code&gt;key = mbox.add(mail)&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;In theory &lt;code&gt;mbox&lt;/code&gt; has an &lt;code&gt;update&lt;/code&gt; method that does this, but I don&#39;t understand it and it doesn&#39;t work as expected :S.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Moving emails around&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can&#39;t just move the files between directories like you&#39;d do with python as each directory contains it&#39;s own identifiers.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Moving a message between the maildir directories&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;Message&lt;/code&gt; has a &lt;code&gt;set_subdir&lt;/code&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://pymotw.com/2/mailbox/#maildir-folders&#34;&gt;Creating folders&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Even though you can create folders with &lt;code&gt;mailbox&lt;/code&gt; it creates them in a way that mbsync doesn&#39;t understand it. It&#39;s easier to manually create the &lt;code&gt;cur&lt;/code&gt;, &lt;code&gt;tmp&lt;/code&gt;, and &lt;code&gt;new&lt;/code&gt; directories. I&#39;m using the next function:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailbox_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;cur&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exists&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dir&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;cur&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;tmp&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;new&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailbox_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Initialized mailbox: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailbox&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mailbox&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; already exists&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.python.org/3/library/mailbox.html&#34;&gt;Reference Docs&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&#34;https://pymotw.com/2/mailbox/&#34;&gt;Non official useful docs&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: Introduce maildir.&lt;/p&gt; &lt;p&gt;The &lt;a href=&#34;https://en.wikipedia.org/wiki/Maildir&#34;&gt;Maildir&lt;/a&gt; e-mail format is a common way of storing email messages on a file system, rather than in a database. Each message is assigned a file with a unique name, and each mail folder is a file system directory containing these files.&lt;/p&gt; &lt;p&gt;A Maildir directory (often named Maildir) usually has three subdirectories named &lt;code&gt;tmp&lt;/code&gt;, &lt;code&gt;new&lt;/code&gt;, and &lt;code&gt;cur&lt;/code&gt;.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The &lt;code&gt;tmp&lt;/code&gt; subdirectory temporarily stores e-mail messages that are in the process of being delivered. This subdirectory may also store other kinds of temporary files.&lt;/li&gt; &lt;li&gt;The &lt;code&gt;new&lt;/code&gt; subdirectory stores messages that have been delivered, but have not yet been seen by any mail application.&lt;/li&gt; &lt;li&gt;The &lt;code&gt;cur&lt;/code&gt; subdirectory stores messages that have already been seen by mail applications.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Maildir&#34;&gt;Wikipedia&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mbsync/#my-emails-are-not-being-deleted-on-the-source-imap-server&#34;&gt;My emails are not being deleted on the source IMAP server.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;That&#39;s the default behavior of &lt;code&gt;mbsync&lt;/code&gt;, if you want it to actually delete the emails on the source you need to add:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Expunge Both
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Under your channel (close to &lt;code&gt;Sync All&lt;/code&gt;, &lt;code&gt;Create Both&lt;/code&gt;)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/mbsync/#mbsync-error:-uid-is-beyond-highest-assigned-uid&#34;&gt;Mbsync error: UID is beyond highest assigned UID.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;If during the sync you receive the following errors:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mbsync error: UID is 3 beyond highest assigned UID 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Go to the place where &lt;code&gt;mbsync&lt;/code&gt; is storing the emails and find the file that is giving the error, you need to find the files that contain &lt;code&gt;U=3&lt;/code&gt;, imagine that it&#39;s something like &lt;code&gt;1568901502.26338_1.hostname,U=3:2,S&lt;/code&gt;. You can strip off everything from the &lt;code&gt;,U=&lt;/code&gt; from that filename and resync and it should be fine, e.g.&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mv&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;1568901502.26338_1.hostname,U=3:2,S&#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;1568901502.26338_1.hostname&#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(mirador): introduce mirador&lt;/p&gt; &lt;p&gt;DEPRECATED: as of 2024-11-15 the tool has many errors (&lt;a href=&#34;https://github.com/pimalaya/mirador/issues/4&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;https://github.com/pimalaya/mirador/issues/3&#34;&gt;2&lt;/a&gt;), few stars (4) and few commits (8). use &lt;a href=&#34;https://lyz-code.github.io/blue-book/watchdog_python/&#34;&gt;watchdog&lt;/a&gt; instead and build your own solution.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pimalaya/mirador&#34;&gt;mirador&lt;/a&gt; is a CLI to watch mailbox changes made by the maintaner of &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/&#34;&gt;himalaya&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Features:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Watches and executes actions on mailbox changes&lt;/li&gt; &lt;li&gt;Interactive configuration via &lt;strong&gt;wizard&lt;/strong&gt; (requires &lt;code&gt;wizard&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Supported events: &lt;strong&gt;on message added&lt;/strong&gt;.&lt;/li&gt; &lt;li&gt;Supported actions: &lt;strong&gt;send system notification&lt;/strong&gt;, &lt;strong&gt;execute shell command&lt;/strong&gt;.&lt;/li&gt; &lt;li&gt;Supports &lt;strong&gt;IMAP&lt;/strong&gt; mailboxes (requires &lt;code&gt;imap&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Supports &lt;strong&gt;Maildir&lt;/strong&gt; folders (requires &lt;code&gt;maildir&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Supports global system &lt;strong&gt;keyring&lt;/strong&gt; to manage secrets (requires &lt;code&gt;keyring&lt;/code&gt; feature)&lt;/li&gt; &lt;li&gt;Supports &lt;strong&gt;OAuth 2.0&lt;/strong&gt; (requires &lt;code&gt;oauth2&lt;/code&gt; feature)&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;em&gt;Mirador CLI is written in &lt;a href=&#34;https://www.rust-lang.org/&#34;&gt;Rust&lt;/a&gt;, and relies on &lt;a href=&#34;https://doc.rust-lang.org/cargo/reference/features.html&#34;&gt;cargo features&lt;/a&gt; to enable or disable functionalities. Default features can be found in the &lt;code&gt;features&lt;/code&gt; section of the &lt;a href=&#34;https://github.com/pimalaya/mirador/blob/master/Cargo.toml#L18&#34;&gt;&lt;code&gt;Cargo.toml&lt;/code&gt;&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/pimalaya/mirador&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The &lt;code&gt;v1.0.0&lt;/code&gt; is currently being tested on the &lt;code&gt;master&lt;/code&gt; branch, and is the preferred version to use. Previous versions (including GitHub beta releases and repositories published versions) are not recommended.*&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Cargo (git)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Mirador CLI &lt;code&gt;v1.0.0&lt;/code&gt; can also be installed with &lt;a href=&#34;https://doc.rust-lang.org/cargo/&#34;&gt;cargo&lt;/a&gt;:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;cargo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--frozen&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--force&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--git&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;https://github.com/pimalaya/mirador.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Pre-built binary&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Mirador CLI &lt;code&gt;v1.0.0&lt;/code&gt; can be installed with a pre-built binary. Find the latest &lt;a href=&#34;https://github.com/pimalaya/mirador/actions/workflows/pre-release.yml&#34;&gt;&lt;code&gt;pre-release&lt;/code&gt;&lt;/a&gt; GitHub workflow and look for the &lt;em&gt;Artifacts&lt;/em&gt; section. You should find a pre-built binary matching your OS.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Configuration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Just run &lt;code&gt;mirador&lt;/code&gt;, the wizard will help you to configure your default account.&lt;/p&gt; &lt;p&gt;You can also manually edit your own configuration, from scratch:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Copy the content of the documented &lt;a href=&#34;https://github.com/pimalaya/mirador/blob/master/config.sample.toml&#34;&gt;&lt;code&gt;./config.sample.toml&lt;/code&gt;&lt;/a&gt;&lt;/li&gt; &lt;li&gt;Paste it in a new file &lt;code&gt;~/.config/mirador/config.toml&lt;/code&gt;&lt;/li&gt; &lt;li&gt; &lt;p&gt;Edit, then comment or uncomment the options you want&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/pimalaya/mirador&#34;&gt;Source&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;alot&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/email_automation/&#34;&gt;alot&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate in favour of himalaya.&lt;/p&gt; &lt;p&gt;DEPRECATED: Use &lt;a href=&#34;https://lyz-code.github.io/blue-book/himalaya/&#34;&gt;himalaya&lt;/a&gt; instead.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/email_automation/#automatically-sync-emails&#34;&gt;Automatically sync emails.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;I have many emails, and I want to fetch them with different frequencies, in the background and be notified if anything goes wrong.&lt;/p&gt; &lt;p&gt;For that purpose I&#39;ve created a python script, a systemd service and some loki rules to monitor it.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Script to sync emails and calendars with different frequencies&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The script iterates over the configured accounts in &lt;code&gt;accounts_config&lt;/code&gt; and runs &lt;code&gt;mbsync&lt;/code&gt; for email accounts and &lt;code&gt;vdirsyncer&lt;/code&gt; for email accounts based on some cron expressions. It logs the output in &lt;code&gt;logfmt&lt;/code&gt; format so that it&#39;s easily handled by &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;loki&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To run it you&#39;ll first need to create a virtualenv, I use &lt;code&gt;mkvirtualenv account_syncer&lt;/code&gt; which creates a virtualenv in &lt;code&gt;~/.local/share/virtualenv/account_syncer&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Then install the dependencies:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aiocron
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Then place this script somewhere, for example (&lt;code&gt;~/.local/bin/account_syncer.py&lt;/code&gt;)&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio.subprocess&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiocron&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;accounts_config&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;lyz&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/15 9-23 * * *&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;work&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/60 8-17 * * 1-5&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Monday-Friday&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;monitorization&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/5 * * * *&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
    &lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;lyz&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/15 9-23 * * *&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;work&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
          &lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;*/60 8-17 * * 1-5&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Monday-Friday&lt;/span&gt;
      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;LogfmtFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Custom formatter to output logs in logfmt style.&#34;&#34;&#34;&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;format&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LogRecord&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log_message&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;level=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;levelname&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &#34;&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;logger=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; &#34;&lt;/span&gt;
            &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;msg=&#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#34;&#39;&lt;/span&gt;
        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;log_message&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;setup_logging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Logger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Configure logging to use logfmt format.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        logging_name (str): The logger&#39;s name and identifier in the systemd journal.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    Returns:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        Logger: The configured logger.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;console_handler&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;StreamHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logfmt_formatter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LogfmtFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;console_handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logfmt_formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getLogger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;console_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;log&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;setup_logging&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;account_syncer&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;run_mbsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Run mbsync command asynchronously for email accounts.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        account_name (str): The name of the email account to sync.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;mbsync &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Syncing emails for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;process&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;create_subprocess_shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PIPE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PIPE&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;communicate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Output for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Error for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;run_vdirsyncer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Run vdirsyncer command asynchronously for calendar accounts.&lt;/span&gt;

&lt;span class=&#34;sd&#34;&gt;    Args:&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;        account_name (str): The name of the calendar account to sync.&lt;/span&gt;
&lt;span class=&#34;sd&#34;&gt;    &#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;command&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;vdirsyncer sync &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Syncing calendar for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;...&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;process&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;create_subprocess_shell&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stdout&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PIPE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subprocess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PIPE&lt;/span&gt;
    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;communicate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stderr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;decode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;error&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;critical&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Output for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;splitlines&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Output for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;command_log&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;should_i_sync_today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;&#34;&#34;&#34;Check if the current time matches the cron expression day and hour constraints.&#34;&#34;&#34;&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day_of_week&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cron_expr&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;now&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;*&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;-&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;hour&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;-&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day_of_week&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;*&#34;&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;weekday&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;day_of_week&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;,&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Starting account syncer for emails and calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]}&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Schedule email accounts&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;should_i_sync_today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run_mbsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scheduled mbsync for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; with cron expression: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;c1&#34;&gt;# Schedule calendar accounts&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;account_name&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;cron_expressions&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;should_i_sync_today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
                &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
                &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run_vdirsyncer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
            &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
                &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Scheduled vdirsyncer for &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; with cron expression: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cron_expression&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;&lt;/span&gt;
            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Running an initial fetch on today&#39;s accounts&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;emails&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;run_mbsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;accounts_to_sync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;calendars&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;run_vdirsyncer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;account_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;n&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Finished loading accounts&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;60&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;__main__&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Where:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;accounts_config&lt;/code&gt;: Holds your account configuration. Each account must contain an &lt;code&gt;account_name&lt;/code&gt; which should be the name of the &lt;code&gt;mbsync&lt;/code&gt; or &lt;code&gt;vdirsyncer&lt;/code&gt; profile, and &lt;code&gt;cron_expressions&lt;/code&gt; must be a list of cron valid expressions you want the email to be synced.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Create the systemd service&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We&#39;re using a non-root systemd service. You can follow &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#create-a-systemd-service-for-a-non-root-user&#34;&gt;these instructions&lt;/a&gt; to configure this service:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Account Sync Service for emails and calendars&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;simple&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/home/lyz/.local/share/virtualenvs/account_syncer/bin/python /home/lyz/.local/bin/&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/home/lyz/.local/bin&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on-failure&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardOutput&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;SyslogIdentifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account_syncer&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;PATH=/home/lyz/.local/share/virtualenvs/account_syncer/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&#34;&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;DISPLAY=:0&#34;&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Remember to tweak the service to match your current case and paths.&lt;/p&gt; &lt;p&gt;As we&#39;ll probably need to enter our &lt;code&gt;pass&lt;/code&gt; password we need the service to start once we&#39;ve logged into the graphical interface.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Monitor the automation&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;It&#39;s always nice to know if the system is working as expected without adding mental load. To do that I&#39;m creating the next &lt;a href=&#34;https://lyz-code.github.io/blue-book/loki/&#34;&gt;loki&lt;/a&gt; rules:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nt&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;account_sync&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;AccountSyncIsNotRunningWarning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;}[15m])) or sum by(hostname) (count_over_time({hostname=&#34;my_computer&#34;} [15m])) * 0 ) == 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;is&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;not&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;running&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;AccountSyncIsNotRunningError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;}[3h])) or sum by(hostname) (count_over_time({hostname=&#34;my_computer&#34;} [3h])) * 0 ) == 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;error&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;script&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;been&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;down&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;least&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;hours&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;AccountSyncError&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;count(rate({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;} |= `` | logfmt | level_extracted=`error` [5m])) &amp;gt; 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;warning&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;There&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;are&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;errors&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;the&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;EmailAccountIsOutOfSyncLyz&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;} | logfmt | msg=`Syncing emails for lyz...`[1h])) or sum by(hostname) (count_over_time({hostname=&#34;my_computer&#34;} [1h])) * 0 ) == 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;error&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;email&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;lyz&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;been&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;1h&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;alert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;CalendarAccountIsOutOfSyncLyz&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p p-Indicator&#34;&gt;|&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;no&#34;&gt;(sum by(hostname) (count_over_time({job=&#34;systemd-journal&#34;, syslog_identifier=&#34;account_syncer&#34;} | logfmt | msg=`Syncing calendar for lyz...`[3h])) or sum by(hostname) (count_over_time({hostname=&#34;my_computer&#34;} [3h])) * 0 ) == 0&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;0m&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;severity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l l-Scalar l-Scalar-Plain&#34;&gt;error&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;annotations&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;summary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;The&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;calendar&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;account&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;lyz&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;has&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;been&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;out&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;sync&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;3h&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;{{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$labels.hostname}}&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Where: - You need to change &lt;code&gt;my_computer&lt;/code&gt; for the hostname of the device running the service - Tweak the OutOfSync alerts to match your account (change the &lt;code&gt;lyz&lt;/code&gt; part).&lt;/p&gt; &lt;p&gt;These rules will raise: - A warning if the sync has not shown any activity in the last 15 minutes. - An error if the sync has not shown any activity in the last 3 hours. - An error if there is an error in the logs of the automation.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;rocketchat&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/rocketchat/&#34;&gt;Rocketchat&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/rocketchat/#references&#34;&gt;Add end of life link.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Warning they only support 6 months of versions! and they advice you with 12 days that you&#39;ll loose service if you don&#39;t update.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href=&#34;https://docs.rocket.chat/docs/version-durability&#34;&gt;End of life for the versions&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;languages&#34;&gt;Languages&lt;/h3&gt; &lt;h4 id=&#34;aiocron&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aiocron/&#34;&gt;aiocron&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce aiocron.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/gawel/aiocron?tab=readme-ov-file&#34;&gt;&lt;code&gt;aiocron&lt;/code&gt;&lt;/a&gt; is a python library to run cron jobs in python asyncronously.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can run it using a decorator&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiocron&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;nd&#34;&gt;@aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*/30 * * * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;attime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;     &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;run&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;
&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get_event_loop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run_forever&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Or by calling the function yourself&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cron&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;0 * * * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;yourcoroutine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;a href=&#34;https://stackoverflow.com/questions/65551736/python-3-9-scheduling-periodic-calls-of-async-function-with-different-paramete&#34;&gt;Here&#39;s a simple example&lt;/a&gt; on how to run it in a script:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;asyncio&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;aiocron&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;param&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cron_min&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;*/1 * * * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;At every minute&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cron_hour&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;0 */1 * * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;At minute 0 past every hour.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cron_day&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;0 9 */1 * *&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;At 09:00 on every day-of-month&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;cron_week&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;aiocron&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crontab&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;0 9 * * Mon&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;foo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;At 09:00 on every Monday&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;asyncio&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You have more complex examples &lt;a href=&#34;https://github.com/gawel/aiocron/tree/master/examples&#34;&gt;in the repo&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;aiocron
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://github.com/gawel/aiocron?tab=readme-ov-file&#34;&gt;Source&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;logging&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_logging/&#34;&gt;Logging&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/python_logging/#configure-the-logging-module-to-log-directly-to-systemd&#39;s-journal&#34;&gt;Configure the logging module to log directly to systemd&#39;s journal.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To use &lt;code&gt;systemd.journal&lt;/code&gt; in Python, you need to install the &lt;code&gt;systemd-python&lt;/code&gt; package. This package provides bindings for systemd functionality.&lt;/p&gt; &lt;p&gt;Install it using pip:&lt;/p&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;systemd-python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; Below is an example Python script that configures logging to send messages to the systemd journal:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;logging&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;systemd.journal&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JournalHandler&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getLogger&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;my_app&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Set the logging level&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JournalHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEBUG&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Adjust logging level if needed&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addFilter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;lambda&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;setattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;record&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;SYSLOG_IDENTIFIER&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;mbsync_syncer&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;formatter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;logging&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(asctime)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; - &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(name)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; - &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(levelname)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; - &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%(message)s&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;setFormatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;formatter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;addHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;journal_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;info&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;This is an info message.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;This is an error message.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;logger&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;debug&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;Debugging information.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;When you run the script, the log messages will be sent to the systemd journal. You can view them using the &lt;code&gt;journalctl&lt;/code&gt; command:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;journalctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This command will show the latest log entries in real time. You can filter by your application name using:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;journalctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-t&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Replace &lt;code&gt;my_app&lt;/code&gt; with the logger name you used (e.g., &lt;code&gt;&#39;my_app&#39;&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Additional Tips&lt;/strong&gt; - &lt;strong&gt;Tagging&lt;/strong&gt;: You can add a custom identifier for your logs by setting &lt;code&gt;logging.getLogger(&#39;your_tag&#39;)&lt;/code&gt;. This will allow you to filter logs using &lt;code&gt;journalctl -t your_tag&lt;/code&gt;. - &lt;strong&gt;Log Levels&lt;/strong&gt;: You can control the verbosity of the logs by setting different levels (e.g., &lt;code&gt;DEBUG&lt;/code&gt;, &lt;code&gt;INFO&lt;/code&gt;, &lt;code&gt;WARNING&lt;/code&gt;, &lt;code&gt;ERROR&lt;/code&gt;, &lt;code&gt;CRITICAL&lt;/code&gt;).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Example Output in the Systemd Journal&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You should see entries similar to the following in the systemd journal:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Nov 15 12:45:30 my_hostname my_app[12345]: 2024-11-15 12:45:30,123 - my_app - INFO - This is an info message.
Nov 15 12:45:30 my_hostname my_app[12345]: 2024-11-15 12:45:30,124 - my_app - ERROR - This is an error message.
Nov 15 12:45:30 my_hostname my_app[12345]: 2024-11-15 12:45:30,125 - my_app - DEBUG - Debugging information.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This approach ensures that your logs are accessible through standard systemd tools and are consistent with other system logs. Let me know if you have any additional requirements or questions!&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;inotify&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/python_inotify/&#34;&gt;Inotify&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;Correction: Deprecate inotify.&lt;/p&gt; &lt;p&gt;DEPRECATED: As of 2024-11-15 it&#39;s been 4 years since the last commit. &lt;a href=&#34;https://lyz-code.github.io/blue-book/watchdog_python/&#34;&gt;watchdog&lt;/a&gt; has 6.6k stars and last commit was done 2 days ago.&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h4 id=&#34;watchdog&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/watchdog_python/&#34;&gt;watchdog&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: Introduce watchdog.&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/gorakhargosh/watchdog?tab=readme-ov-file&#34;&gt;watchdog&lt;/a&gt; is a Python library and shell utilities to monitor filesystem events.&lt;/p&gt; &lt;p&gt;Cons:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The &lt;a href=&#34;https://python-watchdog.readthedocs.io/en/stable/api.html&#34;&gt;docs&lt;/a&gt; suck.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;install&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;watchdog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;Usage&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;A simple program that uses watchdog to monitor directories specified as command-line arguments and logs events generated:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;time&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;watchdog.events&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FileSystemEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FileSystemEventHandler&lt;/span&gt;
&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;watchdog.observers&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Observer&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;MyEventHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileSystemEventHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;on_any_event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FileSystemEvent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;n&#34;&gt;event_handler&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MyEventHandler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Observer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;schedule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;event_handler&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&#34;.&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;recursive&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
        &lt;span class=&#34;n&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;k&#34;&gt;finally&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
    &lt;span class=&#34;n&#34;&gt;observer&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;&lt;strong&gt;References&lt;/strong&gt; - &lt;a href=&#34;https://github.com/gorakhargosh/watchdog?tab=readme-ov-file&#34;&gt;Source&lt;/a&gt; - &lt;a href=&#34;https://python-watchdog.readthedocs.io&#34;&gt;Docs&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;devsecops&#34;&gt;DevSecOps&lt;/h2&gt; &lt;h3 id=&#34;storage&#34;&gt;Storage&lt;/h3&gt; &lt;h4 id=&#34;openzfs&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/&#34;&gt;OpenZFS&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux/zfs/#sync-an-already-created-cold-backup&#34;&gt;Sync an already created cold backup.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Mount the existent pool&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Imagine your pool is at &lt;code&gt;/dev/sdf2&lt;/code&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Connect your device&lt;/li&gt; &lt;li&gt;Check for available ZFS pools: First, check if the system detects any ZFS pools that can be imported:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This command will list all pools that are available for import, including the one stored in &lt;code&gt;/dev/sdf2&lt;/code&gt;. Look for the pool name you want to import.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Import the pool: If you see the pool listed and you know its name (let&#39;s say the pool name is &lt;code&gt;mypool&lt;/code&gt;), you can import it with:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mypool
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Import the pool from a specific device: If the pool isn&#39;t showing up or you want to specify the device directly, you can use:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdf2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This tells ZFS to look specifically at &lt;code&gt;/dev/sdf2&lt;/code&gt; for any pools. If you don&#39;t know the name of the pool this is also the command to run.&lt;/p&gt; &lt;p&gt;This should list any pools found on the device. If it shows a pool, import it using:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sdf2&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;lt;pool_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;Mount the pool: Once the pool is imported, ZFS should automatically mount any datasets associated with the pool. You can check the status of the pool with:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Additional options:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;If the pool was exported cleanly, you can use &lt;code&gt;zpool import&lt;/code&gt; without additional flags.&lt;/li&gt; &lt;li&gt;If the pool wasn’t properly exported or was interrupted, you might need to use &lt;code&gt;-f&lt;/code&gt; (force) to import it:&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;zpool&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;import&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;mypool
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; feat(linux_snippets#Create a systemd service for a non-root user): Create a systemd service for a non-root user&lt;/p&gt; &lt;p&gt;To set up a systemd service as a &lt;strong&gt;non-root user&lt;/strong&gt;, you can create a user-specific service file under your home directory. User services are defined in &lt;code&gt;~/.config/systemd/user/&lt;/code&gt; and can be managed without root privileges.&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Create the service file:&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;Open a terminal and create a new service file in &lt;code&gt;~/.config/systemd/user/&lt;/code&gt;. For example, if you want to create a service for a script named &lt;code&gt;my_script.py&lt;/code&gt;, follow these steps:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-p&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.config/systemd/user
nano&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;~/.config/systemd/user/my_script.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;Edit the service file:&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;In the &lt;code&gt;my_script.service&lt;/code&gt; file, add the following configuration:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;My Python Script Service&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;network.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;simple&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/bin/python3 /path/to/your/script/my_script.py&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/path/to/your/script/&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;SyslogIdentifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_script&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on-failure&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardOutput&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;default.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Description&lt;/strong&gt;: A short description of what the service does.&lt;/li&gt; &lt;li&gt; &lt;p&gt;&lt;strong&gt;ExecStart&lt;/strong&gt;: The command to run your script. Replace &lt;code&gt;/path/to/your/script/my_script.py&lt;/code&gt; with the full path to your Python script. If you want to run the script within a virtualenv you can use &lt;code&gt;/path/to/virtualenv/bin/python&lt;/code&gt; instead of &lt;code&gt;/usr/bin/python3&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;You&#39;ll need to add the virtualenv path to Path &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;c1&#34;&gt;# Add virtualenv&#39;s bin directory to PATH&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;PATH=/path/to/virtualenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; - &lt;strong&gt;WorkingDirectory&lt;/strong&gt;: Set the working directory to where your script is located (optional). - &lt;strong&gt;Restart&lt;/strong&gt;: Restart the service if it fails. - &lt;strong&gt;StandardOutput&lt;/strong&gt; and &lt;strong&gt;StandardError&lt;/strong&gt;: This ensures that the output is captured in the systemd journal. - &lt;strong&gt;WantedBy&lt;/strong&gt;: Specifies the target to which this service belongs. &lt;code&gt;default.target&lt;/code&gt; is commonly used for user services.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Reload systemd to recognize the new service:&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Run the following command to reload systemd&#39;s user service files:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;daemon-reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt;Enable and start the service:&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;To start the service immediately and enable it to run on boot (for your user session), use the following commands:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;start&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service
systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ol&gt; &lt;li&gt; &lt;p&gt;Check the status and logs:&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;To check if the service is running:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;status&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;To view logs specific to your service:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;journalctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-u&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ol&gt; &lt;p&gt;&lt;strong&gt;If you need to use the graphical interface&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If your script requires user interaction (like entering a GPG passphrase), it’s crucial to ensure that the service is tied to your graphical user session, which ensures that prompts can be displayed and interacted with.&lt;/p&gt; &lt;p&gt;To handle this situation, you should make a few adjustments to your systemd service:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Ensure service is bound to graphical session&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Change the &lt;code&gt;WantedBy&lt;/code&gt; target to &lt;code&gt;graphical-session.target&lt;/code&gt; instead of &lt;code&gt;default.target&lt;/code&gt;. This makes sure the service waits for the full graphical environment to be available.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Use &lt;code&gt;Type=forking&lt;/code&gt; instead of &lt;code&gt;Type=simple&lt;/code&gt; (optional)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;If you need the service to wait until the user is logged in and has a desktop session ready, you might need to tweak the service type. Usually, &lt;code&gt;Type=simple&lt;/code&gt; is fine, but you can also experiment with &lt;code&gt;Type=forking&lt;/code&gt; if you notice any issues with user prompts.&lt;/p&gt; &lt;p&gt;Here’s how you should modify your &lt;code&gt;mbsync_syncer.service&lt;/code&gt; file:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;My Python Script Service&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;After&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;simple&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/bin/python3 /path/to/your/script/my_script.py&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WorkingDirectory&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/path/to/your/script/&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;on-failure&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardOutput&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;StandardError&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;journal&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;SyslogIdentifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;my_script&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;DISPLAY=:0&#34;&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus&#34;&lt;/span&gt;

&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;graphical-session.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;After modifying the service, reload and restart it:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;daemon-reload
systemctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--user&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;restart&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;my_script.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;operating-systems&#34;&gt;Operating Systems&lt;/h2&gt; &lt;h3 id=&#34;linux&#34;&gt;Linux&lt;/h3&gt; &lt;h4 id=&#34;linux-snippets&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/&#34;&gt;Linux Snippets&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#debugging-high-iowait&#34;&gt;Debugging high IOwait.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;High I/O wait (&lt;code&gt;iowait&lt;/code&gt;) on the CPU, especially at 50%, typically indicates that your system is spending a large portion of its time waiting for I/O operations (such as disk access) to complete. This can be caused by a variety of factors, including disk bottlenecks, overloaded storage systems, or inefficient applications making disk-intensive operations.&lt;/p&gt; &lt;p&gt;Here’s a structured approach to debug and analyze high I/O wait on your server:&lt;/p&gt; &lt;p&gt;** Monitor disk I/O**&lt;/p&gt; &lt;p&gt;First, verify if disk I/O is indeed the cause. Tools like &lt;code&gt;iostat&lt;/code&gt;, &lt;code&gt;iotop&lt;/code&gt;, and &lt;code&gt;dstat&lt;/code&gt; can give you an overview of disk activity:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;iostat&lt;/code&gt;&lt;/strong&gt;: This tool reports CPU and I/O statistics. You can install it with &lt;code&gt;apt-get install sysstat&lt;/code&gt;. Run the following command to check disk I/O stats:&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;iostat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-x&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; The &lt;code&gt;-x&lt;/code&gt; flag provides extended statistics, and &lt;code&gt;1&lt;/code&gt; means it will report every second. Look for high values in the &lt;code&gt;%util&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; columns, which represent: - &lt;code&gt;%util&lt;/code&gt;: Percentage of time the disk is busy (ideally should be below 90% for most systems). - &lt;code&gt;await&lt;/code&gt;: Average time for I/O requests to complete.&lt;/p&gt; &lt;p&gt;If either of these values is unusually high, it indicates that the disk subsystem is likely overloaded.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;iotop&lt;/code&gt;&lt;/strong&gt;: If you want a more granular look at which processes are consuming disk I/O, use &lt;code&gt;iotop&lt;/code&gt;:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;iotop&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will show you the processes that are actively performing I/O operations.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;dstat&lt;/code&gt;&lt;/strong&gt;: Another useful tool for monitoring disk I/O in real-time:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dstat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-cdl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This shows CPU, disk, and load stats, refreshing every second. Pay attention to the &lt;code&gt;dsk/await&lt;/code&gt; value.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check disk health&lt;/strong&gt; Disk issues such as bad sectors or failing drives can also lead to high I/O wait times. To check the health of your disks:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Use &lt;code&gt;smartctl&lt;/code&gt;&lt;/strong&gt;: This tool can give you a health check of your disks if they support S.M.A.R.T.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;smartctl&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-a&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Check for any errors or warnings in the output. Particularly look for things like reallocated sectors or increasing &#34;pending sectors.&#34;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;dmesg&lt;/code&gt; logs&lt;/strong&gt;: Look at the system logs for disk errors or warnings:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dmesg&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;grep&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&#34;error&#34;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If there are frequent disk errors, it may be time to replace the disk or investigate hardware issues.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Look for disk saturation&lt;/strong&gt; If the disk is saturated, no matter how fast the CPU is, it will be stuck waiting for data to come back from the disk. To further investigate disk saturation:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;df -h&lt;/code&gt;&lt;/strong&gt;: Check if your disk partitions are full or close to full.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;df&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;lsblk&lt;/code&gt;&lt;/strong&gt;: Check how your disks are partitioned and how much data is written to each partition:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;lsblk&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;NAME,SIZE,TYPE,MOUNTPOINT
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;blktrace&lt;/code&gt;&lt;/strong&gt;: For advanced debugging, you can use &lt;code&gt;blktrace&lt;/code&gt;, which traces block layer events on your system.&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blktrace&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sda&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-o&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;blkparse&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-i&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will give you very detailed insights into how the system is interacting with the block device.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Check for heavy disk-intensive processes&lt;/strong&gt; Identify processes that might be using excessive disk I/O. You can use tools like &lt;code&gt;iotop&lt;/code&gt; (as mentioned earlier) or &lt;code&gt;pidstat&lt;/code&gt; to look for processes with high disk usage:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;pidstat&lt;/code&gt;&lt;/strong&gt;: Track per-process disk activity:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pidstat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-d&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This command will give you I/O statistics per process every second. Look for processes with high &lt;code&gt;I/O&lt;/code&gt; values (&lt;code&gt;r/s&lt;/code&gt; and &lt;code&gt;w/s&lt;/code&gt;).&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;&lt;code&gt;top&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;htop&lt;/code&gt;&lt;/strong&gt;: While &lt;code&gt;top&lt;/code&gt; or &lt;code&gt;htop&lt;/code&gt; can show CPU usage, they can also show process-level disk activity. Focus on processes consuming high CPU or memory, as they might also be performing heavy I/O operations.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;check file system issues&lt;/strong&gt; Sometimes the file system itself can be the source of I/O bottlenecks. Check for any file system issues that might be causing high I/O wait.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Check file system consistency&lt;/strong&gt;: If you suspect the file system is causing issues (e.g., due to corruption), run a file system check. For &lt;code&gt;ext4&lt;/code&gt;:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;fsck&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/dev/sda1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Ensure you unmount the disk first or do this in single-user mode.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Check disk scheduling&lt;/strong&gt;: Some disk schedulers (like &lt;code&gt;cfq&lt;/code&gt; or &lt;code&gt;deadline&lt;/code&gt;) might perform poorly depending on your workload. You can check the scheduler used by your disk with:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys/block/sda/queue/scheduler
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can change the scheduler with:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;deadline&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&amp;gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/sys/block/sda/queue/scheduler
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This might improve disk performance, especially for certain workloads.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Examine system logs&lt;/strong&gt; The system logs (&lt;code&gt;/var/log/syslog&lt;/code&gt; or &lt;code&gt;/var/log/messages&lt;/code&gt;) may contain additional information about hardware issues, I/O bottlenecks, or kernel-related warnings:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/log/syslog
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;or&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;tail&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-f&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/var/log/messages
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;Look for I/O or disk-related warnings or errors.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Consider hardware upgrades or tuning&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;SSD vs HDD&lt;/strong&gt;: If you&#39;re using HDDs, consider upgrading to SSDs. HDDs can be much slower in terms of I/O, especially if you have a high number of random read/write operations.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;RAID Configuration&lt;/strong&gt;: If you are using RAID, check the RAID configuration and ensure it&#39;s properly tuned for performance (e.g., using RAID-10 for a good balance of speed and redundancy).&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Memory and CPU Tuning&lt;/strong&gt;: If the server is swapping due to insufficient RAM, it can result in increased I/O wait. You might need to add more RAM or optimize the system to avoid excessive swapping.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Check for swapping issues&lt;/strong&gt; Excessive swapping can contribute to high I/O wait times. If your system is swapping (which happens when physical RAM is exhausted), I/O wait spikes as the system reads from and writes to swap space on disk.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Check swap usage&lt;/strong&gt;:&lt;/li&gt; &lt;/ul&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;free&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;-h
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;If swap usage is high, you may need to add more physical RAM or optimize applications to reduce memory pressure.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/linux_snippets/#create-a-file-with-random-data-&#34;&gt;Create a file with random data.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Of 3.5 GB&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dd&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/urandom&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;of&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;random_file.bin&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bs&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1M&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3584&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;/li&gt; &lt;/ul&gt; &lt;h2 id=&#34;arts&#34;&gt;Arts&lt;/h2&gt; &lt;h3 id=&#34;parkour&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/parkour/&#34;&gt;Parkour&lt;/a&gt;&lt;/h3&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/parkour/#warming-up&#34;&gt;Warming up.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Never do static stretches if you&#39;re cold, it&#39;s better to do dynamic stretches.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Take the joints through rotations&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Head:&lt;/li&gt; &lt;li&gt;Nod 10 times&lt;/li&gt; &lt;li&gt;Say no 10 times&lt;/li&gt; &lt;li&gt;Ear shoulder 10 times&lt;/li&gt; &lt;li&gt; &lt;p&gt;Circles 10 times each direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Shoulders&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Circles back 10 times&lt;/li&gt; &lt;li&gt; &lt;p&gt;Circles forward 10 times&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Elbows&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Circles 10 each direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Wrists:&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Circle 10 each direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Chest:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Chest out/in 10 times&lt;/li&gt; &lt;li&gt;Chest one side to the other 10 times&lt;/li&gt; &lt;li&gt; &lt;p&gt;Chest in circles&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Hips:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Circles 10 each direction&lt;/li&gt; &lt;li&gt; &lt;p&gt;Figure eight 10 times each direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Knees:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Circular rotations 10 each direction feet and knees together&lt;/li&gt; &lt;li&gt;10 ups and downs with knees together&lt;/li&gt; &lt;li&gt; &lt;p&gt;Circular rotations 10 each direction feet waist width&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;Ankles:&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Circular 10 rotations each direction&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Light exercises&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;10 steps forward of walking on your toes, 10 back&lt;/li&gt; &lt;li&gt;10 steps forward of walking on your toes feet rotated outwards, 10 back&lt;/li&gt; &lt;li&gt;10 steps forward of walking on your toes feet rotated inwards, 10 back&lt;/li&gt; &lt;li&gt;10 steps forward of walking on your heels feet rotated outwards, 10 back&lt;/li&gt; &lt;li&gt; &lt;p&gt;10 steps forward of walking on your heels feet rotated inwards, 10 back&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;2 x 10 x Side step, carry the leg up (from out to in) while you turn 180, keep on moving on that direction&lt;/p&gt; &lt;/li&gt; &lt;li&gt;2 x 10 x Front step carrying the leg up (from in to out)while you turn 45, then side step, keep on moving on that direction&lt;/li&gt; &lt;li&gt;10 light skips on one leg: while walking forward lift your knee and arms and do a slight jump&lt;/li&gt; &lt;li&gt;10 steps with high knees&lt;/li&gt; &lt;li&gt;10 steps with heel to butt&lt;/li&gt; &lt;li&gt; &lt;p&gt;10 side shuffles (like basketball defense)&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;5 lunges forward, 5 backwards&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;10 rollups and downs from standing position&lt;/p&gt; &lt;/li&gt; &lt;li&gt;5 push-ups&lt;/li&gt; &lt;li&gt;10 rotations from the pushup position on each direction with straigth arms&lt;/li&gt; &lt;li&gt;5 push-ups&lt;/li&gt; &lt;li&gt;10 rotations from the pushup position on each direction with shoulders at ankle level&lt;/li&gt; &lt;li&gt; &lt;p&gt;3 downward monkeys: from piramid do a low pushup and go to cobra, then a pushup&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;10 steps forward walking on all fours&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;&lt;strong&gt;Strengthen your knees&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Follow &lt;a href=&#34;#strengthen-your-knees&#34;&gt;there steps&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Transit to the parkour place&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Go by bike, skate, jogging to the parkour place&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;November 20, 2024 06:45:21 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2024-11-20T06:45:21+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;November 20, 2024 06:45:21 UTC&#34;&gt;2024-11-20&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2024_11_19/</link>
      <pubDate>2024-11-20 06:45:21+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2024_11_19/</guid>
      
    </item>
    
    <item><title>5th November 2024</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;coding&#34;&gt;Coding&lt;/h2&gt; &lt;h3 id=&#34;languages&#34;&gt;Languages&lt;/h3&gt; &lt;h4 id=&#34;pytest&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/&#34;&gt;Pytest&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/coding/python/pytest/#changing-the-directory-when-running-tests-but-switching-it-back-after-the-test-ends&#34;&gt;Changing the directory when running tests but switching it back after the test ends.&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;November 8, 2024 10:38:37 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2024-11-08T10:38:37+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;November 8, 2024 10:38:37 UTC&#34;&gt;2024-11-08&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2024_11_05/</link>
      <pubDate>2024-11-08 10:38:37+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2024_11_05/</guid>
      
    </item>
    
    <item><title>29th October 2024</title>
      <author>Lyz</author>
      <description>&lt;article class=&#34;md-content__inner md-typeset&#34;&gt;  &lt;h2 id=&#34;life-management&#34;&gt;Life Management&lt;/h2&gt; &lt;h3 id=&#34;knowledge-management&#34;&gt;Knowledge Management&lt;/h3&gt; &lt;h4 id=&#34;aleph&#34;&gt;&lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/&#34;&gt;Aleph&lt;/a&gt;&lt;/h4&gt; &lt;ul&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#alephclient-cli-tool&#34;&gt;Alephclient cli tool.&lt;/a&gt;&lt;/p&gt; &lt;p&gt;alephclient is a command-line client for Aleph. It can be used to bulk import structured data and files and more via the API, without direct access to the server.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.aleph.occrp.org/developers/how-to/data/install-alephclient/#how-to-install-the-alephclient-cli&#34;&gt;Installation&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You can now install &lt;code&gt;alephclient&lt;/code&gt; using pip although I recommend to use &lt;code&gt;pipx&lt;/code&gt; instead:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;alephclient&lt;/code&gt; needs to know the URL of the Aleph instance to connect to. For privileged operations (e.g. accessing private datasets or writing data), it also needs your API key. You can find your API key in your user profile in the Aleph UI.&lt;/p&gt; &lt;p&gt;Both settings can be provided by setting the environment variables &lt;code&gt;ALEPHCLIENT_HOST&lt;/code&gt; and &lt;code&gt;ALEPHCLIENT_API_KEY&lt;/code&gt;, respectively, or by passing them in with &lt;code&gt;--host&lt;/code&gt; and &lt;code&gt;--api-key&lt;/code&gt; options.&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ALEPHCLIENT_HOST&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;https://aleph.occrp.org/
&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ALEPHCLIENT_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;YOUR_SECRET_API_KEY
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;You can now start using &lt;code&gt;alephclient&lt;/code&gt; for example to upload an entire directory to Aleph.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://docs.aleph.occrp.org/developers/how-to/data/upload-directory/&#34;&gt;Upload an entire directory to Aleph&lt;/a&gt;&lt;/strong&gt; While you can upload multiple files and even entire directories at once via the Aleph UI, using the &lt;code&gt;alephclient&lt;/code&gt; CLI allows you to upload files in bulk much quicker and more reliable.&lt;/p&gt; &lt;p&gt;Run the following &lt;code&gt;alephclient&lt;/code&gt; command to upload an entire directory to Aleph:&lt;/p&gt; &lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;alephclient&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;crawldir&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;--foreign-id&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;wikileaks-cable&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;/Users/sunu/data/cable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt; &lt;p&gt;This will upload all files in the directory &lt;code&gt;/Users/sunu/data/cable&lt;/code&gt; (including its subdirectories) into an investigation with the foreign ID &lt;code&gt;wikileaks-cable&lt;/code&gt;. If no investigation with this foreign ID exists, a new investigation is created (in theory, but it didn&#39;t work for me, so manually create the investigation and then copy it&#39;s foreign ID).&lt;/p&gt; &lt;p&gt;If you’d like to import data into an existing investigation and do not know its foreign ID, you can find the foreign ID in the Aleph UI. Navigate to the investigation homepage. The foreign ID is listed in the sidebar on the right.&lt;/p&gt; &lt;/li&gt; &lt;li&gt; &lt;p&gt;New: &lt;a href=&#34;https://lyz-code.github.io/blue-book/aleph/#other-tools-for-the-ecosystem&#34;&gt;Other tools for the ecosystem.&lt;/a&gt;&lt;/p&gt; &lt;/li&gt; &lt;/ul&gt; &lt;aside class=&#34;md-source-file&#34;&gt; &lt;span class=&#34;md-source-file__fact&#34;&gt; &lt;span class=&#34;md-icon&#34; title=&#34;Last update&#34;&gt; &lt;svg viewbox=&#34;0 0 24 24&#34; xmlns=&#34;http://www.w3.org/2000/svg&#34;&gt;&lt;path d=&#34;M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z&#34;&gt;&lt;/path&gt;&lt;/svg&gt; &lt;/span&gt; &lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago&#34; title=&#34;October 30, 2024 06:44:52 UTC&#34;&gt;&lt;span class=&#34;timeago&#34; datetime=&#34;2024-10-30T06:44:52+00:00&#34; locale=&#34;en&#34;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date&#34; title=&#34;October 30, 2024 06:44:52 UTC&#34;&gt;2024-10-30&lt;/span&gt; &lt;/span&gt; &lt;/aside&gt; &lt;/article&gt;</description>
      <link>https://lyz-code.github.io/blue-book/newsletter/2024_10_29/</link>
      <pubDate>2024-10-30 06:44:52+00:00</pubDate>
      <source url="https://lyz-code.github.io/blue-book/daily.xml">The Blue Book</source>
      <guid isPermaLink="true">https://lyz-code.github.io/blue-book/newsletter/2024_10_29/</guid>
      
    </item>
    
  </channel>
</rss>