<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Linux Sin Humo</title><link>https://sergiobelkin.com/</link><description>Linux y Tecnología libres de hypes</description><atom:link href="https://sergiobelkin.com/rss.xml" rel="self" type="application/rss+xml"></atom:link><language>es</language><copyright>Contents © 2026 &lt;a href="mailto:sebelk@gmail.com"&gt;sebelk&lt;/a&gt; 
&lt;a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"&gt;
&lt;img alt="Creative Commons License BY-NC-SA"
style="border-width:0; margin-bottom:12px;"
src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png"&gt;&lt;/a&gt;
</copyright><lastBuildDate>Sat, 21 Feb 2026 19:40:50 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>3 Power Tips + Power Link I10</title><link>https://sergiobelkin.com/posts/3-power-tips-power-link-i10/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;Las herramientas de &lt;strong&gt;monitoreo&lt;/strong&gt; son fundamentales, pero una pobre &lt;strong&gt;interpretación&lt;/strong&gt; de los resultados, pueden llevar a conclusiones incorrectas. Incluso usando chatbots de IA, si hacemos &lt;strong&gt;preguntas&lt;/strong&gt; deficientes podemos terminar girando en círculos o tardar más tiempo en resolver un problema. Lo mejor es reducir el nivel de especulación con hipótesis técnica. A continuación vemos unos ejemplos bien sencillos.&lt;/p&gt;
&lt;h3 id="power-tip-1"&gt;Power Tip #1&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;No todas las métricas que parecen similares describen el mismo fenómeno.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Aplicación lenta.&lt;/li&gt;
&lt;li&gt;Load 15.&lt;/li&gt;
&lt;li&gt;CPU idle 50%.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alguien descarta CPU porque “está libre”.&lt;/p&gt;
&lt;p&gt;Pero:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Load describe tareas en ejecución o esperando.&lt;/li&gt;
&lt;li&gt;CPU usage describe tiempo ocupado.&lt;/li&gt;
&lt;li&gt;CPU pressure describe tiempo en que las tareas no pudieron progresar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Son fenómenos distintos.&lt;/p&gt;
&lt;p&gt;Antes de interpretar, mirá comportamiento:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;vmstat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
mpstat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y si necesitás otra capa:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;cat&lt;span class="w"&gt; &lt;/span&gt;/proc/pressure/cpu
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Es importante saber que “Load no es necesariamente consumo de CPU”, sin embargo, más importante es entender qué está describiendo cada señal.&lt;/p&gt;
&lt;p&gt;Interpretarlas como si hablaran de lo mismo es especulación con números.&lt;/p&gt;
&lt;h3 id="power-tip-2"&gt;Power Tip #2&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Tomar una métrica aislada de memoria en Linux no implica entender como funciona&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;free&lt;span class="w"&gt; &lt;/span&gt;-h
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Las columnas están ahí. Pero entender qué representa cada una es otra cosa.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;used&lt;/code&gt; no significa “memoria en crisis”.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;buff/cache&lt;/code&gt; no significa “desperdicio”.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;available&lt;/code&gt; no significa “memoria libre inmediata”.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Antes de reaccionar ante un número alto, mirá dinámica:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;vmstat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Linux administra memoria como recurso dinámico, no como espacio estático.&lt;/p&gt;
&lt;p&gt;Leer columnas sin entender el modelo del kernel es especulación con formato tabular.&lt;/p&gt;
&lt;h3 id="power-tip-3"&gt;Power Tip #3&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Reiniciar en muchas situaciones no hace otra cosa que restaurar un estado. No explica causas.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El servicio falla.&lt;/li&gt;
&lt;li&gt;Se reinicia.&lt;/li&gt;
&lt;li&gt;Funciona.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eso no es diagnóstico.&lt;/p&gt;
&lt;p&gt;Antes de repetir el gesto automático:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;journalctl&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;servicio-problematico&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Si no entendemos por qué se degradó, volverá a pasar.&lt;/p&gt;
&lt;p&gt;Reiniciar elimina el síntoma. No valida la hipótesis. Las herramientas no están equivocadas.&lt;/p&gt;
&lt;p&gt;La diferencia está en entender qué fenómeno describe cada señal. Está claro que en el mundo real, muchas veces determinar la causa del problema lleva más tiempo que usar un trigger que reinice un servicio. Algo que pasa muchas veces apps legacy (la falta de especialistas o la triste realidad de falta del código fuente). Sin embargo, el problema es cuando se usa esta metodologìa como primera opción...&lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;La IA terminará con las operaciones de IT. ¿En serio? Bueno, en realidad no, para sorpresa de tecno-optimistas o tecno-pesimistas, aquí hay un interesante análisis de Sebastián Martínez de SUSE sobre este tema: &lt;a href="https://www.suse.com/c/why-ai-cannot-run-linux-infrastructure-mcp-suse/"&gt;Why AI Still Cannot Run Your Linux Infrastructure (And What Must Change)&lt;/a&gt;&lt;/p&gt;</description><category>AI</category><category>IA</category><category>monitoreo</category><category>troubleshooting</category><guid>https://sergiobelkin.com/posts/3-power-tips-power-link-i10/</guid><pubDate>Sat, 21 Feb 2026 16:57:09 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I9</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i9/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;PSI (Pressure Stall Information)&lt;/strong&gt; permite observar ese tipo de situaciones y, sobre todo, cambiar la forma en que interpretamos problemas de rendimiento y estabilidad en Linux. A partir de esa señal, el foco deja de estar en métricas globales y pasa a decisiones concretas: entender dónde ocurre el problema, a quién afecta y cómo intervenir sin arrastrar todo el sistema.
Finalmente, el Power Link nos lleva a ver qué opina Gaël Duval, el creador de la distribución Mandrake, sobre uno de los hypes actuales.&lt;/p&gt;
&lt;h3 id="power-tip-1-como-se-ven-afectadas-mis-aplicaciones-por-falta-de-recursos"&gt;Power Tip #1: ¿Cómo se ven afectadas mis aplicaciones por falta de recursos?&lt;/h3&gt;
&lt;p&gt;Existe a veces una creencia basado en pensamiento mágico: que el monitoreo depende solamente de la herramienta que se utilice. Pero más que la herramienta lo importante, es &lt;em&gt;qué se mide&lt;/em&gt; y &lt;em&gt;cómo interpretar&lt;/em&gt; esos resultados. &lt;strong&gt;Las métricas más conocidas: uso de cpu, load-average, uso de memoria, uso de I/O, etc. si bien son útiles pueden darnos en muchos casos un panorama parcial&lt;/strong&gt;. Eso sucede porque están basados en los recursos, o en el scheduler.&lt;/p&gt;
&lt;p&gt;Existen sin embargo desde hace varios años métricas que están más centradas en como las aplicaciones se ven impactadas por el uso de recursos.  Con PSI (Pressure Stall Information) obtenemos un indicio del tiempo que las aplicaciones quedan detenidas porque el sistema no puede darles CPU, memoria o acceso a disco en el momento en que lo necesitan. &lt;/p&gt;
&lt;p&gt;Esto está expuesto en el sistema de archivos:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/psi-files.webp"&gt;&lt;img src="https://sergiobelkin.com/images/psi-files.thumbnail.webp" alt="Archivos de PSI"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;PSI distingue entre situaciones donde al menos una tarea queda bloqueada (&lt;code&gt;some&lt;/code&gt;) y escenarios donde todas las tareas relevantes compiten por el mismo recurso (&lt;code&gt;full&lt;/code&gt;).
Valores elevados y sostenidos en este &lt;code&gt;full&lt;/code&gt; caso suelen indicar un problema estructural: no de picos puntuales, sino de diseño, aislamiento o priorización de workloads.&lt;/p&gt;
&lt;p&gt;Vale hacer aquí tres aclaraciones:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Esta funcionalidad está presente a partir de la versión 4.20 del kernel (RHEL8 la trae como backport). En algunas distribuciones puede ser necesario habilitar PSI explícitamente en el arranque.&lt;/li&gt;
&lt;li&gt;Esta no es &lt;strong&gt;la&lt;/strong&gt; métrica definitiva, sin embargo ignorarla es perder el cuadro completo de lo que sucede tanto en el sistema como nuestras aplicaciones.&lt;/li&gt;
&lt;li&gt;Versiones recientes del kernel incluyen también la medición de la presión sobre &lt;strong&gt;irq&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="power-tip-2-las-disrupciones-se-pueden-atribuir-a-workloads-especificos"&gt;Power Tip #2: Las disrupciones se pueden atribuir a workloads específicos&lt;/h3&gt;
&lt;p&gt;Cuando el host empieza a perder capacidad de respuesta, no siempre el problema es global.
Es común que el sistema siga siendo usable mientras algunos servicios o aplicaciones comienzan a degradarse, simplemente porque no acceden a los recursos cuando los necesitan. Esa degradación suele manifestarse como lentitud, mayor latencia o pérdida de capacidad de interacción.&lt;/p&gt;
&lt;p&gt;En un Linux moderno, el kernel organiza los procesos bajo &lt;strong&gt;dominios de control definidos por cgroups&lt;/strong&gt;.
Esto permite observar de forma localizada qué tareas empiezan a quedarse esperando recursos, en lugar de razonar únicamente a partir de métricas agregadas del host.&lt;/p&gt;
&lt;p&gt;En sistemas basados en systemd, ese dominio no es abstracto: se corresponde con services, slices o scopes.
El mismo síntoma que aparece a nivel global puede observarse dentro de estos límites, lo que permite atribuir dónde se generan las esperas, incluso cuando el resto del sistema continúa funcionando con normalidad.&lt;/p&gt;
&lt;p&gt;Pensar a nivel host diluye el diagnóstico.
En cambio poner el foco en en services, scopes y slices permite relacionar directamente los síntomas percibidos —lentitud, tiempos de respuesta, degradación de rendimiento— con un grupo de procesos concreto.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/specific-psi.webp"&gt;&lt;img src="https://sergiobelkin.com/images/specific-psi.thumbnail.webp" alt="PSI per cgroup"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Es decir, uno puede decir que &lt;strong&gt;el host muestra la presión acumulada&lt;/strong&gt;, pero &lt;strong&gt;los cgroups permiten entender qué se queda atascado y frente qué recurso&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="power-tip-3-abordar-el-problema-de-manera-localizada"&gt;Power Tip #3: Abordar el problema de manera localizada&lt;/h3&gt;
&lt;p&gt;Cuando un servicio o aplicación empieza a tener tiempos muertos o a interferir con el resto, tenemos varias maneras de abordar el problema. Y no estamos hablando de las típicas acciones: reiniciarlo, moverlo o rediseñarlo.&lt;/p&gt;
&lt;p&gt;Podemos tomar medidas más estructurales, por ejemplo, crear un slice de systemd, establecer límites y luego confinar esos servicios o procesos en esos slices.&lt;/p&gt;
&lt;p&gt;Sin embargo, antes de intervenir de manera prematura, es conveniente tener en cuenta que Linux, en general ya tiene una agrupación de slices, scopes y servicios bastante razonable. En este punto entonces, ya sabemos que &lt;strong&gt;ese servicio problemático ya corre dentro de un perímetro definido&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;En lugar de crear un nuevo slice, que tiene un carácter más permanente, podemos adoptar una solución más sencilla y gradualista. En systemd, &lt;strong&gt;los parámetros que gobiernan cómo compite por recursos no están fijos&lt;/strong&gt; en scopes o servicios.&lt;/p&gt;
&lt;p&gt;Un vistazo rápido alcanza para verlo (los siguientes son ejemplos para entender la idea):&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;show&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;ControlGroup,CPUWeight,MemoryMax,IOWeight&lt;span class="w"&gt; &lt;/span&gt;procesos-ruidosos.scope
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y tomar cartas en el asunto:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;set-property&lt;span class="w"&gt; &lt;/span&gt;procesos-ruidosos.scope&lt;span class="w"&gt; &lt;/span&gt;…
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ese tipo de intervención es local, reversible y no convierte un incidente puntual en un cambio estructural.&lt;/p&gt;
&lt;p&gt;Intervenir sobre una unidad existente permite corregir interferencias concretas &lt;strong&gt;sin rediseñar el sistema ni propagar el problema&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="fuentes-y-mas-recursos"&gt;Fuentes y más recursos&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://sergiobelkin.com/posts/que-son-los-cgroups-y-para-que-sirven/"&gt;Qué son los cgroups y para qué sirven&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;Gaël Duval, creador de Mandrake, Murena y e/OS reflexiona sobre el impacto de la AI en el software open source: &lt;a href="https://gaelduval.com/why-ai-wont-kill-open-source/#more-1725"&gt;Why AI won’t “Kill Open Source”&lt;/a&gt;&lt;/p&gt;</description><category>monitoreo</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i9/</guid><pubDate>Sun, 04 Jan 2026 18:30:54 GMT</pubDate></item><item><title>Plan Táctico y Estratégico de la Memoria en Linux</title><link>https://sergiobelkin.com/posts/plan-tactico-y-estrategico-de-la-memoria-en-linux/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/sk-CNBRg1K9QvQ-unsplash.jpg"&gt;&lt;/figure&gt; &lt;p&gt;La mitología en torno a la memoria en Linux ha producido una serie de relatos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;En un extremo: Linux puede funcionar con muy poca memoria RAM.&lt;/li&gt;
&lt;li&gt;Del otro lado: Linux consume mucha memoria.&lt;/li&gt;
&lt;li&gt;Y que una partición SWAP debe tener entre 1 a 2 veces la memoria RAM.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Como vemos algunas historias son más recientes, otros más antiguas, pueden ser parcialmente ciertas y hasta contradictorias entre sí.&lt;/p&gt;
&lt;p&gt;Este artículo tiene como propósitos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Explicar de manera sencilla el funcionamiento de la memoria en Linux, desmitificando también algunos conceptos.&lt;/li&gt;
&lt;li&gt;Enumerar y describir tácticas para que el uso de la memoria proporcione la mejor usabilidad y experiencia del usuario.&lt;/li&gt;
&lt;li&gt;Ofrecer alternativas para que cada uno elija la mejor opción de acuerdo a sus necesidades.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="definiciones"&gt;Definiciones&lt;/h3&gt;
&lt;p&gt;Vamos a repasar algunos conceptos básicos que de manera más o menos frecuente usamos, usaremos metáforas en el camino. Ninguna metáfora es perfecta, sin embargo ellas nos ayudan a entender la realidad.&lt;/p&gt;
&lt;h4 id="memoria-virtual"&gt;Memoria Virtual&lt;/h4&gt;
&lt;p&gt;La memoria virtual es el mecanismo por el cual cada proceso recibe un espacio de direcciones propio, independiente y protegido. El hardware traduce direcciones virtuales a físicas según tablas de páginas. Esto permite aislamiento, sobreasignación, mapeos de archivos y demanda dinámica de páginas, más allá de la cantidad de RAM disponible. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linux trata de usar la mayor cantidad de memoria posible, para poder ejecutar las aplicaciones y acceder a los archivos de la manera más rápida posible. De manera que si la memoria libre es baja no es necesariamente un indicativo de un problema.&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id="page"&gt;Page&lt;/h4&gt;
&lt;p&gt;Una página es la unidad mínima de memoria, de tamaño fijo (típicamente 4 KB), que el kernel y el hardware de gestión de memoria del procesador utilizan para organizar el espacio de direcciones y realizar el mapeo entre direcciones virtuales y físicas.&lt;/p&gt;
&lt;h4 id="page-table"&gt;Page table&lt;/h4&gt;
&lt;p&gt;Es una estructura de datos jerárquica administrada por el kernel y usada por el hardware para traducir direcciones virtuales a direcciones físicas, con información de permisos y estado de cada página.&lt;/p&gt;
&lt;h4 id="page-fault"&gt;Page Fault&lt;/h4&gt;
&lt;p&gt;Un &lt;strong&gt;page fault&lt;/strong&gt; ocurre cuando un proceso accede a una dirección válida de su espacio de memoria pero la página correspondiente no está preparada para ese acceso. Puede deberse a que la página aún no fue cargada, a que debe asignarse, o a que debe traerse desde disco. Si la página no está en RAM, el kernel debe cargarla, lo que puede ser lento; si ya estaba en RAM, el costo es menor.&lt;/p&gt;
&lt;h4 id="page-cache"&gt;Page cache&lt;/h4&gt;
&lt;p&gt;Es la caché de páginas de archivos gestionada por el kernel, usada para acelerar lecturas y escrituras almacenando en RAM los datos y metadatos de archivos y directorios, reduciendo accesos al disco.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/cache.png"&gt;&lt;img src="https://sergiobelkin.com/images/cache.thumbnail.png" alt="Page cache"&gt;&lt;/a&gt;  &lt;/p&gt;
&lt;h4 id="tipos-de-memoria"&gt;Tipos de memoria&lt;/h4&gt;
&lt;h5 id="file-memory"&gt;File Memory&lt;/h5&gt;
&lt;p&gt;Es la memoria relacionada con el &lt;strong&gt;Page Cache&lt;/strong&gt;.&lt;/p&gt;
&lt;h5 id="anonymous-memory"&gt;Anonymous Memory&lt;/h5&gt;
&lt;p&gt;Es la memoria que un proceso usa y que no está respaldada por un archivo: heap (asignada dinámicamente), stack (llamadas a funciones y almacenamiento de variables locales), COW (parte de la memoria cuando se crea un proceso hijo) y mapeos con MAP_ANONYMOUS. Su único respaldo posible es la swap.
La memoria anónima se crea y utiliza en RAM. Si el kernel necesita expulsarla de RAM, su único destino posible es la swap, porque no tiene un archivo desde el cual reconstruirse. Pero su existencia normal no depende de la swap.&lt;/p&gt;
&lt;h4 id="memory-pressure"&gt;Memory Pressure&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Memory pressure&lt;/strong&gt; es estado en el que las páginas libres caen por debajo de umbrales críticos, obligando al kernel a iniciar mecanismos de liberación de memoria.&lt;/p&gt;
&lt;p&gt;En términos prácticos cuando la presión es alta pueden surgir ciertos síntomas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sitios web / servidores HTTP:&lt;/strong&gt;
  La latencia aumenta porque los workers deben esperar a que el kernel libere páginas. Además, puede haber más CPU gastada en recuperar memoria, lo que degrada aún más los tiempos de respuesta.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sistemas de escritorio:&lt;/strong&gt;
  El sistema pierde fluidez porque el scheduler empieza a verse afectado por stalls debidos a las operaciones para liberar memoria y, si hay swap, el sistema puede entrar en &lt;em&gt;swap thrashing&lt;/em&gt;. Esto produce lag del mouse, ventanas que tardan en responder, escritorios congelados por segundos, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Acceso remoto (SSH, RDP, VNC):&lt;/strong&gt;
  Al haber presión, las operaciones de usuario-espacio tardan más en ejecutarse, y los daemons pueden quedar brevemente estancados esperando memoria. Esto causa retrasos notables en la interacción remota.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;¿Y qué sucede si la presión de memoria puede llegar a ser tan alta que el kernel ya no logra conseguir memoria ni siquiera después de intentar liberarla?&lt;/p&gt;
&lt;h4 id="thrashing"&gt;Thrashing&lt;/h4&gt;
&lt;p&gt;El &lt;strong&gt;thrashing&lt;/strong&gt; ocurre cuando la memoria RAM no alcanza para mantener las páginas que los procesos usan todo el tiempo. El kernel empieza a sacar páginas de memoria para hacer lugar a otras nuevas, pero enseguida vuelve a necesitarlas. Esto genera un bucle de fallos de página y de recarga constante desde el disco.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Con swap:&lt;/strong&gt; las páginas anónimas van y vienen entre RAM y swap, lo que dispara el uso de disco y vuelve el sistema extremadamente lento.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sin swap:&lt;/strong&gt; las páginas anónimas no tienen adónde ir y el kernel termina activando el &lt;strong&gt;OOM killer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incluso sin swap:&lt;/strong&gt; puede haber thrashing si las páginas vienen de archivos (page cache), ya que el kernel debe recargarlas una y otra vez.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="oom-out-of-memory"&gt;OOM (Out-Of-Memory) 💀 🔥&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;Out-Of-Memory&lt;/strong&gt; es una situación en la cual el kernel agotó todos los mecanismos para liberar memoria:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Liberar páginas del caché.&lt;/li&gt;
&lt;li&gt;Sacar páginas anónimas de swap.&lt;/li&gt;
&lt;li&gt;Compactar memoria.&lt;/li&gt;
&lt;li&gt;Liberar memoria mediante &lt;code&gt;kswapd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Aplicación de políticas de cgroups (muy común al usar contenedores).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="oomkiller"&gt;OOMKiller&lt;/h4&gt;
&lt;p&gt;El &lt;strong&gt;OOM-killer&lt;/strong&gt; es el mecanismo que usa el kernel cuando ya no puede asignar más memoria, incluso después de intentar liberar todas las páginas que es posible descartar o mover fuera de la RAM.
En esa situación crítica, el kernel calcula un puntaje para cada proceso (&lt;code&gt;oom_score&lt;/code&gt;) y finaliza al que resulte más conveniente para recuperar memoria rápidamente y permitir que el sistema siga funcionando.
Este comportamiento puede influenciarse ajustando &lt;code&gt;oom_score_adj&lt;/code&gt;, que hace que un proceso sea más o menos propenso a ser elegido.&lt;/p&gt;
&lt;h4 id="oom_score"&gt;oom_score&lt;/h4&gt;
&lt;p&gt;Como ya se mencionó a cada proceso se le asigna un puntaje de acuerdo a distintos factores, cuanto más alto es, más susceptible es a ser terminado por OOMKiller. &lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/oom_score-from-proc.webp"&gt;&lt;img src="https://sergiobelkin.com/images/oom_score-from-proc.thumbnail.webp" alt="OOM Scores por proceso en /proc" title="Clic para agrandar"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Y también, como dijimos mediante oom_score_adj podemos influir en el score de un proceso:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/oom_score-adjfrom-proc.webp"&gt;&lt;img src="https://sergiobelkin.com/images/oom_score-adjfrom-proc.thumbnail.webp" alt="Incidencia en oom_score mediante oom_score_adj"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;En versiones más recientes de las distribuciones existe el comando &lt;strong&gt;&lt;em&gt;choom&lt;/em&gt;&lt;/strong&gt; que permite ver y/o ajustar dicho valor.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/choom.png"&gt;&lt;img src="https://sergiobelkin.com/images/choom.thumbnail.png" alt="choom"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h4 id="swap"&gt;Swap&lt;/h4&gt;
&lt;p&gt;Los usuarios ocasionales de Linux y aun muchos sysadmins tienen una idea negativa sobre "la swap". Simplificaciones extremas y conceptos anticuados la han convertido en le gran villana de la historia del sistema operativo.&lt;/p&gt;
&lt;p&gt;Si comparamos a la memoria con un escritorio, sin swap podría lucir así:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/ashim-d-silva-Kw_zQBAChws-unsplash.jpg"&gt;&lt;img src="https://sergiobelkin.com/images/ashim-d-silva-Kw_zQBAChws-unsplash.jpg" alt="Prescindir de swap no es una opción sana."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@randomlies?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Ashim D’Silva&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/mess?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Así que primero vamos a decir lo que &lt;strong&gt;no&lt;/strong&gt; es:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No&lt;/strong&gt; es la &lt;strong&gt;memoria virtual&lt;/strong&gt; sino que &lt;strong&gt;forma parte&lt;/strong&gt; de la &lt;strong&gt;técnica&lt;/strong&gt; que realiza el sistema operativo para administrar la memoria.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No&lt;/strong&gt; es un espacio de reserva ni un último recurso. &lt;strong&gt;Es&lt;/strong&gt; un espacio complementario sirve para liberar RAM.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No&lt;/strong&gt; funciona como último recurso, pero el sistema operativo puede mover hacia la swap las páginas de memoria no usadas recientemente.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No&lt;/strong&gt; es algo que el sistema operativo pueda alegremente prescindir aun cuando la cantidad de memoria RAM física sea grande. Quienes parecen haber inventado la pólvora, nos cuentan que es posible técnicamente que Linux funcione sin swap. Si bien es cierto, al carecer de swap, el kernel no tiene manera de mover páginas de memoria anónimas hacia el área de swap y liberar así RAM para procesos que la necesitan urgentemente.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nuestro escritorio con swap:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/alexandru-acea-Zg9R__O-8fM-unsplash.jpg"&gt;&lt;img src="https://sergiobelkin.com/images/alexandru-acea-Zg9R__O-8fM-unsplash.thumbnail.jpg" alt="Analogía de Swap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@alexacea?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Alexandru Acea&lt;/a&gt; (edited by me) on &lt;a href="https://unsplash.com/s/photos/desktop-drawer?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;¿Los cajones de un escritorio los usamos cuando lo tenemos abarrotado de cosas? No, los usamos para guardar cosas que no son de alta prioridad. Aunque es cierto, si luego queremos usar esa tijera o aquel destornillador en algún momento requerirá un poco más de trabajo, tendremos que abrir el cajón, buscarlo, extraerlo, etc.&lt;/p&gt;
&lt;p&gt;Ah, y la swap también sirve para hibernar, aunque honestamente no se cuanta gente mantiene esa práctica.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="tuning"&gt;Tuning&lt;/h3&gt;
&lt;p&gt;Ahora veremos diferentes tácticas que podemos usar para optimizar el uso de la memoria.&lt;/p&gt;
&lt;h4 id="cgroupv2"&gt;cgroupv2&lt;/h4&gt;
&lt;p&gt;cgroup es un mecanismo para organizar los procesos de manera jerárquica y distribuir los recursos del sistema a lo largo  de la jerarquía en una manera controlada y configurada.&lt;/p&gt;
&lt;p&gt;Un cgroup se compone de un núcleo que es responsable primariamente en organizar de manera jerárquica los procesos y controladores que comúnmente distribuyen un tipo específico de recurso del sistema a lo largo de la jerarquía.&lt;/p&gt;
&lt;p&gt;En la versión 2 de cgroup un proceso no puede pertenecer a diferentes grupos para diferentes controladores. Si el proceso se uno al grupo alfa, todos los controladores para alfa tomarán control de ese proceso.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/ps-cgroup..jpg.png"&gt;&lt;img src="https://sergiobelkin.com/images/ps-cgroup.thumbnail.png" alt="ps mostrando cgroup"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Supongamos que los procesos de un cgroup (y todos los grupos hijos) usan poca memoria, podríamos decirle al kernel que libere memoria de otros cgroups. Esto es precisamente lo que hace el parámetro memory.low.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/memory_low.png"&gt;&lt;img src="https://sergiobelkin.com/images/memory_low.thumbnail.png" alt="el parámetro memory.low"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Otro parámetro interesante para monitorear es &lt;strong&gt;memory.pressure&lt;/strong&gt;, la primera línea tiene el tiempo físico de una o más tareas demoradas debido a la falta de memoria. La segunda sería lo mismo pero para todas las tareas del grupo, full es lo mismo pero para todas las tareas del grupo, Entonces si miramos el archivo &lt;code&gt;/sys/fs/cgroup/user.slice/memory.pressure&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;some avg10=0.00 avg60=0.13 avg300=0.12 total=1690238
full avg10=0.00 avg60=0.10 avg300=0.09 total=1394199
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Significa que, dentro del grupo de control user.slice, en los últimos 10 segundos no hubo tareas afectadas por presión de memoria. Sin embargo, en el último minuto las tareas estuvieron bloqueadas un 0,13% del tiempo y un 0,12% en los últimos cinco minutos. El valor total indica que estas situaciones acumulan aproximadamente 1,7 segundos de espera.
La segunda línea muestra las mismas métricas, pero aplicadas a los casos en que todas las tareas del grupo estuvieron simultáneamente afectadas por presión de memoria (full en lugar de some).&lt;/p&gt;
&lt;p&gt;Es decir:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;some&lt;/code&gt; → indica si un retraso afectó al menos una tarea.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;full&lt;/code&gt; → indica si el retraso afectó a todo el cgroup simultáneamente.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="zram"&gt;zram&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;zram&lt;/strong&gt; es por así decirlo, una manera cool de usar swap gracias a un módulo del kernel. 
&lt;br&gt;
&lt;a class="image-reference" href="https://sergiobelkin.com/images/chuttersnap-4LnSe9KwewA-unsplash.jpg"&gt;&lt;img src="https://sergiobelkin.com/images/chuttersnap-4LnSe9KwewA-unsplash.thumbnail.jpg" alt="zram, swap pero cool"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@chuttersnap?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;chuttersnap&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/cool-drawer-desktop?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;En lugar de gastar espacio en un disco (sea rígido o sólido) usamos dispositivos de bloque en la propia RAM. Los bloques swapeados se guardan comprimidos. Esto discos virtuales son rápidos y ahorran memoria.&lt;/p&gt;
&lt;p&gt;Una de las pocas desventajas que tiene esta metodología es la incapacidad para poder hibernar el sistema operativo, al no estar presente la partición en un almacenamiento de tipo persistente.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/zram.png"&gt;&lt;img src="https://sergiobelkin.com/images/zram.png" alt="zram"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h4 id="sistemas-de-archivos"&gt;Sistemas de archivos&lt;/h4&gt;
&lt;p&gt;El journal de ext4 puede ser lento, xfs puede ser una mejor alternativa o mejor aun btrfs.&lt;/p&gt;
&lt;h4 id="earlyoom"&gt;EarlyOOM&lt;/h4&gt;
&lt;p&gt;El oom-killer del kernel solamente se dispara en situaciones extremas y le puede llevar mucho tiempo hasta que puede enviar SIGKILL a los procesos que sean necesarios para poder liberar memoria. Durante ese tiempo probablemente el usuario no pueda interactuar con el sistema operativo.&lt;/p&gt;
&lt;p&gt;EarlyOOM trabaja en espacio de usuario y por lo tanto se puede anticipar y ser mucho más rápido.&lt;/p&gt;
&lt;p&gt;El comportamiento predeterminado en Fedora es que si hay menos del 10% de RAM y/o SWAP libre, earlyoom envía una señal de terminación a todos los procesos con oom_score más alto. Si la RAM como SWAP libre bajan por debajo del 5%, earlyroom enviará una señal para matar todos los procesos con oom_score más elevado.&lt;/p&gt;
&lt;p&gt;La idea es recuperar la usabilidad (especialmente en un entorno de escritorio) lo antes posible.&lt;/p&gt;
&lt;p&gt;El problema es que EarlyOOM no soporta al momento la medición de la &lt;strong&gt;memory pressure&lt;/strong&gt; como indicativo para tomar decisiones.&lt;/p&gt;
&lt;h4 id="nohang"&gt;nohang&lt;/h4&gt;
&lt;p&gt;Este servicio es mucho más configurable y aporta una mejor solución que EarlyOOM.&lt;/p&gt;
&lt;p&gt;Algunas funcionalidades son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Se puede elegir la acción que realizará en una situación OOM.&lt;/li&gt;
&lt;li&gt;Ofrece varios criterios para elegir los procesos a finalizar.&lt;/li&gt;
&lt;li&gt;Soporta zram&lt;/li&gt;
&lt;li&gt;Puede usar &lt;strong&gt;memory pressure&lt;/strong&gt; para tomar una acción.&lt;/li&gt;
&lt;li&gt;El archivo de configuración es medianamente sencillo&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sin embargo, este proyecto en la actualidad tiene poca actividad comparado por ejemplo con EarlyOOM&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/nohangvseoom.webp"&gt;&lt;img src="https://sergiobelkin.com/images/nohangvseoom.thumbnail.webp" alt="Repos: nohang vs EarlyOOM en Github"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h4 id="zswap"&gt;zswap&lt;/h4&gt;
&lt;p&gt;Con zswap no reemplazamos el espacio swap en el disco sino que usamos un caché comprimido en la RAM. Este método ahorra I/O, obteniendo entonces mejor rendimiento y alargando la vida útil de discos flash o sólidos. La única desventaja es usar algo de tiempo del procesador para realizar la compresión.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pineapple-supply-co-SRKxB1B_sn4-unsplash.jpg"&gt;&lt;img src="https://sergiobelkin.com/images/pineapple-supply-co-SRKxB1B_sn4-unsplash.thumbnail.jpg" alt="zswap"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@pineapple?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Pineapple Supply Co.&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/tray-desktop?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Mediante el caché se logra una diferenciación entre páginas más usadas (zswap) y menos usadas (swap).&lt;/p&gt;
&lt;h4 id="systemd-oomd"&gt;systemd-oomd&lt;/h4&gt;
&lt;p&gt;El servicio systemd-oomd es un proyecto en el que comenzó en Facebook para integrarlo con systemd. En un principio estaba pensado para manejo de memoria a gran escala, y bastante más complejo de configurar. Sin embargo ha sido adoptado desde Fedora 34 reemplazando a EarlyOOM. En las distribuciones que usan versiones recientes de systemd, está disponible, aunque no todas lo habilitan de manera predeterminada.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/systemd-oomd.webp"&gt;&lt;img src="https://sergiobelkin.com/images/systemd-oomd.thumbnail.webp" alt="systemd-oomd"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="resumen"&gt;Resumen&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Swap no es la villana de la película&lt;/li&gt;
&lt;li&gt;Si existe la opción de migrar a otros sistema de archivos aunque con características un tanto experimental, elegir btrfs. Una opción más moderada es xfs.&lt;/li&gt;
&lt;li&gt;El tuning de cgroupv2 puede traer grandes beneficios, no obstante existen proyectos y distribuciones que no lo usan.&lt;/li&gt;
&lt;li&gt;EarlyOOM es una solución rápida y aplicable a una amplia gama de sistemas Linux, aunque no siempre es la más exacta ni más elegante.&lt;/li&gt;
&lt;li&gt;El servicio nohang (o no hang-desktop) es una opción más madura aunque algo más compleja que EarlyOOM, pero que sin embargo ha caído en cierta inactividad.&lt;/li&gt;
&lt;li&gt;El servicio &lt;strong&gt;systemd-oomd&lt;/strong&gt; inicialmente incorporado por Facebook es seguramente la opción más adecuada para escenarios más complejos y de manejo de memoria a gran escala. También es utilizado actualmente en sistemas de escritorio.&lt;/li&gt;
&lt;li&gt;Sin embargo, muchas distribuciones o &lt;em&gt;sabores&lt;/em&gt; de distribuciones prefieren usar el mecanismo clásico de OOMKiller.&lt;/li&gt;
&lt;li&gt;A veces se sugiere el ajuste de parámetros del kernel mediante &lt;code&gt;sysctl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Si se desea ahorrar espacio en disco se puede reemplazar la swap por zram, sacrificando la opción de hibernar el sistema.&lt;/li&gt;
&lt;li&gt;La opción zswap es más sofisticada, aunque dependemos del uso de swap en disco.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;Photo by &lt;a href="https://unsplash.com/@rollelflex_graphy726?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;sk&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/chess?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id="fuentes-consultadas"&gt;Fuentes consultadas&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.suse.com/support/kb/doc/?id=000017834"&gt;Is a swap partition required for SLES? | Support | SUSE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Virtual_memory#Thrashing"&gt;Virtual memory - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Page_(computer_memory)"&gt;Page (computer memory) - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux-mm.org/VirtualMemory?action=fullsearch&amp;amp;context=180&amp;amp;value=glossary"&gt;VirtualMemory - linux-mm.org Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kernelnewbies.org/KernelGlossary"&gt;KernelGlossary - Linux Kernel Newbies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lwn.net/Articles/411845/"&gt;Ghosts of Unix Past: a historical search for design patterns [LWN.net]&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.vishalchovatiya.com/how-does-virtual-memory-work/#How_Does_Virtual_Memory_Work"&gt;How does virtual memory work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Virtual_memory#Thrashing"&gt;Virtual memory - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Paging#Page_stealing"&gt;Paging - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux-mm.org/Memory_pressure"&gt;Memory_pressure - linux-mm.org Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kernel.org/doc/html/latest/admin-guide/mm/concepts.html?highlight=write%20back%20cache#virtual-memory-primer"&gt;Concepts overview — The Linux Kernel documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linux.com/news/all-about-linux-swap-space/"&gt;All about Linux swap space - Linux.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://unix.stackexchange.com/questions/417855/why-does-linux-need-swap-space-in-a-vm"&gt;Why does Linux need swap space in a VM? - Unix &amp;amp; Linux Stack Exchange&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chrisdown.name/2018/01/02/in-defence-of-swap.html"&gt;In defence of swap: common misconceptions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/nttlabs/cgroup-v2-596d035be4d7"&gt;The current adoption status of cgroup v2 in containers | by Akihiro Suda | nttlabs | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://facebookmicrosites.github.io/cgroup2/docs/memory-controller.html"&gt;Memory Controller · cgroup2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git/tree/Documentation/admin-guide/cgroup-v2.rst"&gt;cgroup-v2.rst « admin-guide « Documentation - kernel/git/tj/cgroup.git - cgroup export tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git/tree/Documentation/admin-guide/cgroup-v2.rst"&gt;cgroup-v2.rst « admin-guide « Documentation - kernel/git/tj/cgroup.git - cgroup export tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.archlinux.org/index.php/Cgroups#Switching_to_cgroups_v2"&gt;cgroups - ArchWiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kernel.org/doc/html/latest/admin-guide/blockdev/zram.html"&gt;zram: Compressed RAM-based block devices — The Linux Kernel documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fedoraproject.org/wiki/Changes/SwapOnZRAM#Summary"&gt;Changes/SwapOnZRAM - Fedora Project Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fedoraproject.org/wiki/Changes/EnableEarlyoom#Summary"&gt;Changes/EnableEarlyoom - Fedora Project Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://man7.org/linux/man-pages/man5/proc.5.html"&gt;proc(5) - Linux manual page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/hakavlad/nohang"&gt;hakavlad/nohang: A sophisticated low memory handler for Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Zswap"&gt;zswap - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.phoronix.com/scan.php?page=news_item&amp;amp;px=Systemd-OOMD-April-WIP"&gt;Systemd-OOMD Continues Coming Together For Better Linux Out-Of-Memory Handling - Phoronix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=beefUhRH5lU"&gt;SREcon19 Asia/Pacific - Linux Memory Management at Scale: Under the Hood - YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.man7.org/linux/man-pages/man2/mmap.2.html"&gt;mmap(2) — Linux manual page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kernel.org/doc/html/v6.13/core-api/mm-api.html"&gt;Memory Management APIs¶&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fedoraproject.org/wiki/Changes/EnableSystemdOomd"&gt;Changes/EnableSystemdOomd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><category>Memoria</category><category>RAM</category><guid>https://sergiobelkin.com/posts/plan-tactico-y-estrategico-de-la-memoria-en-linux/</guid><pubDate>Mon, 01 Dec 2025 05:00:32 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I8</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i8/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;Resumen&lt;/strong&gt;: En esta entrega, un ejemplo del poder que tienen la subshells de bash, como solucionar problemas de SELinux con podman, y el uso de la herramienta yq para procesar archivos yaml.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Nota: En los ejemplos de comandos el prompt del usuario no privilegiado es "$", mientras que el del superusuario es "#"&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="power-tip-1-crear-entornos-de-bash-efimeros-usando-subshells"&gt;Power Tip #1: Crear entornos de bash efímeros usando subshells&lt;/h3&gt;
&lt;p&gt;Una subshell es una copia del proceso de la shell actual. Una manera de crear una subshell es usando &lt;code&gt;()&lt;/code&gt; y sirve: para personalizar el entorno de bash de manera reversible. Por ejemplo, podemos cambiar de directorio y la variable de entorno C (POSIX) para que muestre los mensajes de salida y de error en inglés:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LANG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
es_AR.UTF-8
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;
/home/sergio
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ahora creamos una &lt;strong&gt;subshell&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"La variable LANG cambia a  &lt;/span&gt;&lt;span class="nv"&gt;$LANG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/algun_dir&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/tmp&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"el directorio actual es &lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;myscript.sh&lt;span class="o"&gt;)&lt;/span&gt;
La&lt;span class="w"&gt; &lt;/span&gt;variable&lt;span class="w"&gt; &lt;/span&gt;LANG&lt;span class="w"&gt; &lt;/span&gt;cambia&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt;  &lt;/span&gt;C
-bash:&lt;span class="w"&gt; &lt;/span&gt;cd:&lt;span class="w"&gt; &lt;/span&gt;/algun_dir:&lt;span class="w"&gt; &lt;/span&gt;No&lt;span class="w"&gt; &lt;/span&gt;such&lt;span class="w"&gt; &lt;/span&gt;file&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;directory
el&lt;span class="w"&gt; &lt;/span&gt;directorio&lt;span class="w"&gt; &lt;/span&gt;actual&lt;span class="w"&gt; &lt;/span&gt;es&lt;span class="w"&gt; &lt;/span&gt;/tmp
-bash:&lt;span class="w"&gt; &lt;/span&gt;myscript.sh:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;not&lt;span class="w"&gt; &lt;/span&gt;found
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Al terminar la subshell, volvemos a la shell madre y tanto el directorio de trabajo como la variable LANG, vuelven a sus valores predeterminados:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;
/home/sergio
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LANG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
es_AR.UTF-8
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="power-tip-2-identificar-y-solucionar-problemas-de-selinux-al-usar-volumenes"&gt;Power Tip #2: Identificar y solucionar problemas de SELinux al usar volúmenes.&lt;/h3&gt;
&lt;p&gt;Supongamos que necesitamos probar una configuración en un contenedor:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;podman&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt;  &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;mynginx&lt;span class="w"&gt;  &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/sandbox/nginx.conf:/etc/nginx/nginx.conf&lt;span class="w"&gt; &lt;/span&gt;--pull&lt;span class="o"&gt;=&lt;/span&gt;never&lt;span class="w"&gt; &lt;/span&gt;docker.io/library/nginx@sha256:553f64aecdc31b5bf944521731cd70e35da4faed96b2b7548a3d8e2598c52a42
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ahora bien: ¿Qué sucede si el contenedor en realidad, falla al arrancar como lo muestran los logs?:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;podman&lt;span class="w"&gt; &lt;/span&gt;logs&lt;span class="w"&gt; &lt;/span&gt;mynginx&lt;span class="w"&gt; &lt;/span&gt;
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;not&lt;span class="w"&gt; &lt;/span&gt;empty,&lt;span class="w"&gt; &lt;/span&gt;will&lt;span class="w"&gt; &lt;/span&gt;attempt&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;perform&lt;span class="w"&gt; &lt;/span&gt;configuration
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Looking&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;scripts&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
&lt;span class="m"&gt;10&lt;/span&gt;-listen-on-ipv6-by-default.sh:&lt;span class="w"&gt; &lt;/span&gt;info:&lt;span class="w"&gt; &lt;/span&gt;Getting&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;checksum&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/conf.d/default.conf
&lt;span class="m"&gt;10&lt;/span&gt;-listen-on-ipv6-by-default.sh:&lt;span class="w"&gt; &lt;/span&gt;info:&lt;span class="w"&gt; &lt;/span&gt;Enabled&lt;span class="w"&gt; &lt;/span&gt;listen&lt;span class="w"&gt; &lt;/span&gt;on&lt;span class="w"&gt; &lt;/span&gt;IPv6&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/conf.d/default.conf
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Sourcing&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Configuration&lt;span class="w"&gt; &lt;/span&gt;complete&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ready&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;start&lt;span class="w"&gt; &lt;/span&gt;up
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;:09:21&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;emerg&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: open() "/etc/nginx/nginx.conf" failed (13: Permission denied)&lt;/span&gt;
nginx:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;emerg&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;open&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/etc/nginx/nginx.conf"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;failed&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="m"&gt;13&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;Permission&lt;span class="w"&gt; &lt;/span&gt;denied&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Si estás tentado a desactivar SELinux, te recomiendo enfáticamente que leas &lt;a href="https://sergiobelkin.com/posts/selinux-nah-deshabilitalo/"&gt;¿SELinux? Nah, dejalo en Disabled&lt;/a&gt;. Lo que ocurre es que no hay ninguna regla que permita que el contenedor acceda al contexto del archivo nginx.conf del host.&lt;/p&gt;
&lt;p&gt;Contexto del archivo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;-Z&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/sandbox/nginx.conf
unconfined_u:object_r:user_home_t:s0&lt;span class="w"&gt; &lt;/span&gt;/home/sergio/sandbox/nginx.conf
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Este problema se soluciona fácilmente:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="sb"&gt;```&lt;/span&gt;bash
podman&lt;span class="w"&gt; &lt;/span&gt;stop&lt;span class="w"&gt; &lt;/span&gt;mynginx
podman&lt;span class="w"&gt; &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;mynginx
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y ahora el contenedor arrancará sin inconvenientes:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;ps
CONTAINER&lt;span class="w"&gt; &lt;/span&gt;ID&lt;span class="w"&gt;  &lt;/span&gt;IMAGE&lt;span class="w"&gt;                                                                                            &lt;/span&gt;COMMAND&lt;span class="w"&gt;               &lt;/span&gt;CREATED&lt;span class="w"&gt;         &lt;/span&gt;STATUS&lt;span class="w"&gt;         &lt;/span&gt;PORTS&lt;span class="w"&gt;       &lt;/span&gt;NAMES
a29c08eda1b1&lt;span class="w"&gt;  &lt;/span&gt;docker.io/library/nginx@sha256:553f64aecdc31b5bf944521731cd70e35da4faed96b2b7548a3d8e2598c52a42&lt;span class="w"&gt;  &lt;/span&gt;nginx&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;daemon&lt;span class="w"&gt; &lt;/span&gt;o...&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;seconds&lt;span class="w"&gt; &lt;/span&gt;ago&lt;span class="w"&gt;  &lt;/span&gt;Up&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;seconds&lt;span class="w"&gt;              &lt;/span&gt;mynginx
podman&lt;span class="w"&gt; &lt;/span&gt;logs&lt;span class="w"&gt; &lt;/span&gt;mynginx&lt;span class="w"&gt; &lt;/span&gt;
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/&lt;span class="w"&gt; &lt;/span&gt;is&lt;span class="w"&gt; &lt;/span&gt;not&lt;span class="w"&gt; &lt;/span&gt;empty,&lt;span class="w"&gt; &lt;/span&gt;will&lt;span class="w"&gt; &lt;/span&gt;attempt&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;perform&lt;span class="w"&gt; &lt;/span&gt;configuration
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Looking&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;shell&lt;span class="w"&gt; &lt;/span&gt;scripts&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
&lt;span class="m"&gt;10&lt;/span&gt;-listen-on-ipv6-by-default.sh:&lt;span class="w"&gt; &lt;/span&gt;info:&lt;span class="w"&gt; &lt;/span&gt;Getting&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;checksum&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/conf.d/default.conf
&lt;span class="m"&gt;10&lt;/span&gt;-listen-on-ipv6-by-default.sh:&lt;span class="w"&gt; &lt;/span&gt;info:&lt;span class="w"&gt; &lt;/span&gt;Enabled&lt;span class="w"&gt; &lt;/span&gt;listen&lt;span class="w"&gt; &lt;/span&gt;on&lt;span class="w"&gt; &lt;/span&gt;IPv6&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/nginx/conf.d/default.conf
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Sourcing&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Launching&lt;span class="w"&gt; &lt;/span&gt;/docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh:&lt;span class="w"&gt; &lt;/span&gt;Configuration&lt;span class="w"&gt; &lt;/span&gt;complete&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ready&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;start&lt;span class="w"&gt; &lt;/span&gt;up
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: using the "epoll" event method&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: nginx/1.29.3&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10y&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: built by gcc 14.2.0 (Debian 14.2.0-19) &lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: OS: Linux 4.18.0-553.84.1.el8_10.x86_64&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: getrlimit(RLIMIT_NOFILE): 262144:262144&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: start worker processes&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: start worker process 28&lt;/span&gt;
&lt;span class="m"&gt;2025&lt;/span&gt;/11/24&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;21&lt;/span&gt;:16:10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;notice&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="c1"&gt;#1: start worker process 29&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ahora bien, la opción &lt;code&gt;:Z&lt;/code&gt; no es mágica, para tener una aproximación a lo que hace veamos el contexto del archivo $HOME/sandbox/nginx.conf:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$&lt;span class="w"&gt; &lt;/span&gt;ls&lt;span class="w"&gt; &lt;/span&gt;-Z&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;/sandbox/nginx.conf
system_u:object_r:container_file_t:s0:c369,c839&lt;span class="w"&gt; &lt;/span&gt;/home/sergio/sandbox/nginx.conf
&lt;/pre&gt;&lt;/div&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Campo&lt;/th&gt;
&lt;th&gt;Antes&lt;/th&gt;
&lt;th&gt;Después&lt;/th&gt;
&lt;th&gt;Comentario&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Usuario (SELinux)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;unconfined_u&lt;/td&gt;
&lt;td&gt;system_u&lt;/td&gt;
&lt;td&gt;Pasa de ser un usuario sin restricciones a un usuario gestionado por el sistema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rol (SELinux)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;object_r&lt;/td&gt;
&lt;td&gt;object_r&lt;/td&gt;
&lt;td&gt;Se mantiene sin cambios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Asignación basada en tipos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;user_home_t&lt;/td&gt;
&lt;td&gt;container_file_t&lt;/td&gt;
&lt;td&gt;Cambia a un tipo de asignación en la cual los contenedores pueden escribir&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rango (SELinux)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;s0&lt;/td&gt;
&lt;td&gt;s0:c369,c839&lt;/td&gt;
&lt;td&gt;Este cambio implica que solamente podrá utilizarlo de manera exclusiva un único contenedor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="power-tip-3-filtrar-un-archivo-de-template-en-formato-yaml-de-zabbix-sin-instalar-absolutamente-nada"&gt;Power Tip #3: Filtrar un archivo de template en formato yaml de Zabbix sin instalar absolutamente nada&lt;/h3&gt;
&lt;p&gt;Solamente necesitamos podman, en el siguiente ejemplo estamos filtrando todos los triggers estáticos con nivel de severidad &lt;strong&gt;HIGH&lt;/strong&gt; o &lt;strong&gt;DISASTER&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;--rm&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PWD&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/workdir:Z&lt;span class="w"&gt; &lt;/span&gt;mikefarah/yq&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s1"&gt;'.zabbix_export.templates[].items[].triggers[] | select(.priority == "HIGH" or .priority == "DISASTER")| {"Trigger": .name}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;template_db_mssql_agent2.yaml
Trigger:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'MSSQL: Percentage of the buffer cache efficiency is low'&lt;/span&gt;
Trigger:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'MSSQL: Page life expectancy is low'&lt;/span&gt;
Trigger:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'MSSQL: Percentage of work tables available from the work table cache is low'&lt;/span&gt;
Trigger:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'MSSQL: Service is unavailable'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="fuentes-y-mas-recursos"&gt;Fuentes y más recursos&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://danwalsh.livejournal.com/81269.html"&gt;Container Labeling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://danwalsh.livejournal.com/76016.html"&gt;Be careful relabeling volumes with Container run times. Sometimes things can go very wrong?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;El enlace de esta edición apunta a una entrevista a Linux Torvalds que gira en torno a la evolución del hardware, la IA y su impacto en el Linux y el desarrollo del kernel: &lt;a href="https://www.youtube.com/watch?v=NjGHrDnPxwI"&gt;Linus Torvalds — Talks about AI Hype, GPU Power, and Linux’s Future &lt;/a&gt;. En la actualidad cuestiones como la programación guiada por la intuición con la ayuda de chatbots debates importantes, no solamente en Linux sino en el ámbito IT en general.&lt;/p&gt;</description><category>bash</category><category>containers</category><category>yaml</category><category>Zabbix</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i8/</guid><pubDate>Sun, 23 Nov 2025 22:09:59 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I7</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i7/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;Resumen&lt;/strong&gt;: Tips para bash, KDE Plasma y el uso del shell para cambiar entre ambientes de desarrollo. Además, en el Power Link, un artículo de Aaron P. MacSween, en el que discute el uso de &lt;em&gt;AI scraping&lt;/em&gt; de sitios web usados de manera no consensuada para entrenar &lt;em&gt;Modelos Extensos de Lenguaje (LLMs)&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id="power-tip-1-agrupacion-de-comandos-en-bash"&gt;Power Tip #1: Agrupación de comandos en bash&lt;/h3&gt;
&lt;p&gt;El shell bash permite agrupar comandos, una funcionalidad tan sencilla como potente, por ejemplo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;dnf&lt;span class="w"&gt; &lt;/span&gt;-y&lt;span class="w"&gt; &lt;/span&gt;upgrade&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;restart&lt;span class="w"&gt; &lt;/span&gt;httpd&lt;span class="w"&gt; &lt;/span&gt;mariadb&lt;span class="w"&gt; &lt;/span&gt;php-fpm&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The final status is unsuccessful 🙁"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;De esta manera si algunos de los dos comandos falla, mostrará un mensaje de error unificado.&lt;/p&gt;
&lt;h3 id="power-tip-2-uso-de-cuadros-de-dialogos-nativos-de-kde-plasma-en-firefox"&gt;Power Tip #2: Uso de cuadros de diálogos nativos de KDE Plasma en Firefox&lt;/h3&gt;
&lt;p&gt;Para hacerlo hay que abrir la url &lt;code&gt;about:config&lt;/code&gt; y luego setear la preferencia &lt;code&gt;widget.use-xdg-desktop-portal.file-picker&lt;/code&gt; en &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt7-set-pref-ff.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt7-set-pref-ff.thumbnail.webp" alt="Set preferences on Firefox"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Esto se basa en el uso de XDG Portals que es un elemento de la arquitectura de entornos gráficos. Ellos proporcionan sandboxing, funcionalidad en entornos Wayland y lo que nos interesa en este caso: coherencia en la interfaz del usuario.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Antes 🤐&lt;/th&gt;
&lt;th&gt;Después 😎️&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt7-ugly-dialog-box-firefox.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt7-ugly-dialog-box-firefox.thumbnail.webp" alt="Set preferences on Firefox"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt7-nice-dialog-box-firefox.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt7-nice-dialog-box-firefox.thumbnail.webp" alt="Before and After of setting file picker"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Ah... usar la variable de entorno &lt;code&gt;MOZ_USE_XDG_PORTAL&lt;/code&gt; no es la manera recomendada, más allá de lo que diga cierto chatbot...&lt;/p&gt;
&lt;h3 id="power-tip-3-flask-linux-entornos-seguros-usando-solo-la-shell"&gt;Power Tip #3: [Flask + Linux]: Entornos Seguros usando solo la Shell&lt;/h3&gt;
&lt;h4 id="problema-comun"&gt;Problema Común&lt;/h4&gt;
&lt;p&gt;Ejecutar una app Flask con &lt;code&gt;DEBUG=True&lt;/code&gt; en producción expone trazas de errores, rutas internas y detalles del &lt;em&gt;stack&lt;/em&gt; que pueden ser explotados. Un &lt;strong&gt;sysadmin o devops con experiencia&lt;/strong&gt; sabe que una práctica profesional es &lt;strong&gt;externalizar la configuración&lt;/strong&gt; y usar el sistema operativo como interruptor de entorno.&lt;/p&gt;
&lt;h4 id="solucion-basada-en-linux-flask"&gt;Solución Basada en Linux + Flask&lt;/h4&gt;
&lt;p&gt;Usá la variable de entorno de Linux &lt;code&gt;FLASK_ENV&lt;/code&gt; para alternar entre una configuración segura de Producción (&lt;code&gt;config_prod.py&lt;/code&gt;) y una configuración orientada a Desarrollo (&lt;code&gt;config_dev.py&lt;/code&gt;).&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Archivo&lt;/th&gt;
&lt;th&gt;Ajuste Crítico&lt;/th&gt;
&lt;th&gt;Enfoque Operacional&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config_dev.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DEBUG = True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enfoque en depuración y agilidad.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;config_prod.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DEBUG = False&lt;/code&gt;&lt;br&gt;&lt;code&gt;SECRET_KEY = os.environ.get('PROD_KEY')&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prioridad a la &lt;strong&gt;Seguridad&lt;/strong&gt; y la &lt;strong&gt;Gestión de Secretos&lt;/strong&gt; mediante la &lt;em&gt;shell&lt;/em&gt; de Linux.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="fragmento-de-apppy"&gt;Fragmento de app.py&lt;/h4&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;flask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;
&lt;span class="c1"&gt;# Se importan las clases para un código robusto:&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;config_dev&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DevelopmentConfig&lt;/span&gt; 
&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;config_prod&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ProductionConfig&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vm"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'FLASK_ENV'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'production'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Entorno PROD: Carga DEBUG=False&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ProductionConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Entorno DEV: Carga DEBUG=True por defecto&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DevelopmentConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id="control-desde-la-terminal"&gt;Control desde la Terminal&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;Entorno Deseado&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Comando Linux&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Resultado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Producción&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;export FLASK_ENV=production; python app.py&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;* Debug mode: off&lt;/code&gt; (Modo seguro activado por el &lt;em&gt;shell&lt;/em&gt; de Linux).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;strong&gt;Desarrollo&lt;/strong&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;unset FLASK_ENV; python app.py&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;* Debug mode: on&lt;/code&gt; (La variable se borra, volviendo al modo de depuración).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;✅ Conclusión:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Este patrón convierte tu &lt;em&gt;shell&lt;/em&gt; de Linux en un &lt;em&gt;switch&lt;/em&gt; seguro de entorno para tu app Flask.&lt;/p&gt;
&lt;h3 id="preguntas-de-repaso"&gt;Preguntas de repaso&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Seguridad y DevOps (Power Tip #3):&lt;/strong&gt; ¿Cuál es el riesgo principal de ejecutar una aplicación Flask con &lt;code&gt;DEBUG=True&lt;/code&gt; en producción, y cómo permite la variable de entorno de Linux &lt;strong&gt;&lt;code&gt;FLASK_ENV&lt;/code&gt;&lt;/strong&gt; que el administrador (&lt;code&gt;sysadmin o devops con experiencia&lt;/code&gt;) cambie de manera segura a la configuración de producción (&lt;code&gt;config_prod.py&lt;/code&gt;) usando solo un comando en la &lt;em&gt;shell&lt;/em&gt;?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Eficiencia en Bash (Power Tip #1):&lt;/strong&gt; En el ejemplo de agrupación de comandos, ¿cuál es el propósito de encerrar las sentencias de actualización (&lt;code&gt;dnf -y upgrade&lt;/code&gt;) y de reinicio de servicios (&lt;code&gt;systemctl restart ...&lt;/code&gt;) entre llaves &lt;code&gt;{}&lt;/code&gt;, y qué rol juega el operador lógico &lt;strong&gt;&lt;code&gt;||&lt;/code&gt;&lt;/strong&gt; en caso de que alguna de estas operaciones falle?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Experiencia de Usuario (Power Tip #2):&lt;/strong&gt; Si un usuario de KDE Plasma desea que Firefox utilice los cuadros de diálogo nativos del escritorio en lugar de los predeterminados del navegador, ¿qué URL debe abrir y a qué valor debe establecer la preferencia &lt;strong&gt;&lt;code&gt;widget.use-xdg-desktop-portal.file-picker&lt;/code&gt;&lt;/strong&gt;?&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://cryptography.dog/blog/AI-scrapers-request-commented-scripts/"&gt;AI scrapers request commented scripts&lt;/a&gt;. ¿Hasta qué punto una actividad es considerada benigina cuando se entrenan LLMs? Y muchas cuestiones para pensar...&lt;/p&gt;</description><category>APIs</category><category>bash</category><category>KDE Plasma</category><category>python</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i7/</guid><pubDate>Tue, 04 Nov 2025 22:10:17 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I6</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i6/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;Resumen:&lt;/strong&gt; Tips para KDE Plasma, manejo de directorios temporales e información detallada sobre podman. Además, un link a un post en el cual un líder de ingenería recomienda pasar de Docker a Podman.  &lt;/p&gt;
&lt;h3 id="power-tip-1-reiniciar-kde-plasma-sin-cerrar-sesion"&gt;Power Tip #1 Reiniciar KDE Plasma sin cerrar sesión&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;kquitapp6&lt;span class="w"&gt; &lt;/span&gt;plasmashell&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;plasmashell&lt;span class="w"&gt; &lt;/span&gt;--replace&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;/tmp/plasma.log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;disown&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-h
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="power-tip-2-crea-un-sandbox-con-limpieza-automatica-usando-tmpfilesd"&gt;Power Tip #2 Crea un sandbox con limpieza automática usando tmpfiles.d&lt;/h3&gt;
&lt;p&gt;Podemos tener un directorio al cual usamos como sandbox, por ejemplo para:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Descarga de archivos&lt;/li&gt;
&lt;li&gt;Volcar Logs y dumps temporarios&lt;/li&gt;
&lt;li&gt;Scripts, código... y cualquier cosa que queremos probar.... por un tiempo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pero la idea es que no queremos que esos archivos se almacenen de manera indefinida... entonces:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;cat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt; EOF &amp;gt;  ~/.config/user-tmpfiles.d/user-sandbox.conf &lt;/span&gt;
&lt;span class="s"&gt;&amp;gt; d %h/sandbox - - - 7d&lt;/span&gt;
&lt;span class="s"&gt;&amp;gt; d %h/sandbox/ephemeral - - - 10m&lt;/span&gt;
&lt;span class="s"&gt;&amp;gt; EOF&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Una idea tentadora es usar un directorio como &lt;code&gt;/tmp&lt;/code&gt;. Pero no es buena práctica usar ese directorio como sandbox. Luego de crear ese archivo, hay que ejecutar: &lt;code&gt;systemd-tmpfiles --create --user&lt;/code&gt; que creará los directorios en las rutas especificadas. El servicio &lt;code&gt;systemd-tmpfiles-clean&lt;/code&gt; eliminará periódicamente los archivos más viejos de 7 días del directorio ~/sandbox. El contenido de &lt;code&gt;~/sandbox/ephermeral&lt;/code&gt; en cambio, no se borrará automáticamente excepto que creemos una unit de tipo timer. Sin embargo se puede hacer manualmente mediante &lt;code&gt;systemd-tmpfiles --clean --user&lt;/code&gt;. Como siempre entender por qué hacés lo que hacés es fundamental, los manpages son siempre aliados a tener en cuenta aun en pleno hype de la AI.&lt;/p&gt;
&lt;p&gt;A propósito... el comando en el PowerTip #1 podría haber usado el directorio del sandbox en lugar de /tmp....&lt;/p&gt;
&lt;h3 id="power-tip-3-revisar-espacios-y-objetos-de-manera-detallada-en-podman"&gt;Power Tip #3 Revisar espacios y objetos de manera detallada en Podman&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;system&lt;span class="w"&gt; &lt;/span&gt;df&lt;span class="w"&gt; &lt;/span&gt;-v
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;De esta manera obtenemos información muy útil sobre las imágenes, contenedores y volúmenes que tenemos.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt6-podman-system-df.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt6-podman-system-df.thumbnail.webp" alt="Espacio ocupado por podman"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h4 id="power-link"&gt;Power Link&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.odbms.org/blog/2025/10/beyond-the-ai-hype-guido-van-rossum-on-pythons-philosophy-simplicity-and-the-future-of-programming/"&gt;Entrevista a Guido van Rossum, creador de Python, en la cual trata entre temas sobre AI&lt;/a&gt;&lt;/p&gt;</description><category>containers</category><category>KDE Plasma</category><category>systemd</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i6/</guid><pubDate>Mon, 13 Oct 2025 21:13:07 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I5</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i5/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;&lt;strong&gt;Resumen:&lt;/strong&gt; Tips para containers, uso de digests y análisis de seguridad de imágenes y obtener información de imágenes remotas. Además, un link a un post en el cual un líder de ingenería recomienda pasar de Docker a Podman.  &lt;/p&gt;
&lt;h3 id="power-tip-1-etiquetar-las-imagenes-con-digest-en-produccion"&gt;Power Tip #1 Etiquetar las imágenes con digest en producción&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;❌ Mala práctica, apuntar a un tag:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;pass_git&lt;span class="w"&gt; &lt;/span&gt;localhost/passteiner-ubi9:1
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Esta es una mala práctica porque:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Es mutable, puede apuntar a otro build&lt;/li&gt;
&lt;li&gt;También es un error confiar ciegamente usar &lt;em&gt;latest&lt;/em&gt;, hoy puede apuntar a una versión, mañana a otra&lt;/li&gt;
&lt;li&gt;Dificulta el debugging al no saber exactamente qué versión usás&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;✅ Buena práctica:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;--name&lt;span class="w"&gt; &lt;/span&gt;pass-git&lt;span class="w"&gt; &lt;/span&gt;--pull&lt;span class="o"&gt;=&lt;/span&gt;never&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;localhost/passteiner-ubi9@sha256:3ca1e63acb24d88fde5e86eb1f476ba69eb740cd43590c37f3a964b5a19f001
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Ventajas:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Totalmente reproducible y auditable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Evitás actualizaciones sorpresa.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ideal para ambientes de producción, CI/CD, y entornos donde la confiabilidad importa.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="power-tip-2-examinar-vulnerabilidades-en-imagenes-de-contenedores"&gt;Power Tip #2 Examinar vulnerabilidades en imágenes de contenedores&lt;/h3&gt;
&lt;p&gt;La abstración con que nos proporcionan los contenedores, tal vez nos den una falsa sensación de seguridad, sin embargo, con trivy se pueden escanear en una imagen vulnerabilades por ejemplo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;trivy&lt;span class="w"&gt; &lt;/span&gt;image&lt;span class="w"&gt; &lt;/span&gt;docker.io/bitnami/wordpress
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Debajo podemos ver un resumen:&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt5-trivy.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt5-trivy.thumbnail.webp" alt="Resumen del reporte realizado por trivy"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="power-tip-3-examinar-imagenes-de-contenedores-sin-necesidad-pullearlas"&gt;Power Tip #3 Examinar imágenes de contenedores sin necesidad "pullearlas"&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;skopeo&lt;span class="w"&gt; &lt;/span&gt;inspect&lt;span class="w"&gt; &lt;/span&gt;docker://docker.io/ollama/ollama&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{Digest: .Digest, Labels: .Labels, UltimaCapa: .Layers[-1]}'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"Digest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:a5409cb903d30f9cd67e9f430dd336ddc9274e16fd78f75b675c42065991b4fd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"Labels"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"org.opencontainers.image.ref.name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ubuntu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;"org.opencontainers.image.version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"24.04"&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"UltimaCapa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:45fafbfc0e267e3b61858ae5cb28ff739d901d85e1b60ee62db5dad64ae7c0d5"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id="de-esta-manera-obtenemos"&gt;De esta manera obtenemos:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;El &lt;strong&gt;Digest&lt;/strong&gt; de la imagen (identificador único inmutable).&lt;/li&gt;
&lt;li&gt;En qué &lt;strong&gt;distro base y versión&lt;/strong&gt; se construyó la imagen (&lt;code&gt;ubuntu:24.04&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;El &lt;strong&gt;Digest de la última capa&lt;/strong&gt;, que representa el &lt;strong&gt;último cambio&lt;/strong&gt; al sistema de archivos durante el proceso de build.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;El digest de la última capa representa el último cambio al sistema de archivos en el proceso de construcción de la imagen.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="power-link"&gt;Power Link&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://codesmash.dev/why-i-ditched-docker-for-podman-and-you-should-too"&gt;Why I Ditched Docker for Podman And You Should Too&lt;/a&gt;&lt;/p&gt;</description><category>containers</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i5/</guid><pubDate>Sat, 13 Sep 2025 19:38:48 GMT</pubDate></item><item><title>Gestión de Contraseñas Usando Contenedores Podman (Update 2025)</title><link>https://sergiobelkin.com/posts/gestion-de-contrasenas-usando-contenedores-podman-update-2025/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/podman-pass-2025.png"&gt;&lt;/figure&gt; &lt;p&gt;En 2023, &lt;a href="https://sergiobelkin.com/posts/gestion-de-contrasenas-usando-contenedores-podman/"&gt;publiqué un post&lt;/a&gt; sobre cómo usar &lt;strong&gt;&lt;code&gt;pass&lt;/code&gt;&lt;/strong&gt; con un contenedor Git administrado por Podman. Esa guía fue muy útil como demo inicial, pero desde entonces cambiaron algunas cosas: nuevas versiones de Podman, la aparición de &lt;strong&gt;Quadlet&lt;/strong&gt;, la deprecación de &lt;code&gt;podman generate systemd&lt;/code&gt;, y la conveniencia de usar imágenes más estables.&lt;/p&gt;
&lt;p&gt;Este post es una &lt;strong&gt;actualización 2025&lt;/strong&gt; del artículo original, incorporando:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Imagen base &lt;strong&gt;UBI9 minimal&lt;/strong&gt; (más liviana y con soporte extendido). Esta imagen, desarrollada por Red Hat, es de tamaño relativamente pequeño, usa una versión reduccida de dnf, llamada &lt;em&gt;microdnf&lt;/em&gt; con soporte de módulos y usa software de repositorios - también - de Red Hat.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rootless limpio&lt;/strong&gt; con &lt;code&gt;UserNS=keep-id&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Quadlet&lt;/strong&gt; para integrar con &lt;code&gt;systemd --user&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Volúmenes persistentes&lt;/strong&gt; para no perder datos ni claves al actualizar la imagen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Endurecimiento SSH&lt;/strong&gt; (solo claves públicas, nada de contraseñas).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="1-construccion-de-la-imagen"&gt;1. Construcción de la imagen&lt;/h3&gt;
&lt;p&gt;Dockerfile (&lt;code&gt;Dockerfile&lt;/code&gt;):&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;registry.access.redhat.com/ubi9/ubi-minimal&lt;/span&gt;

&lt;span class="k"&gt;RUN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;microdnf&lt;span class="w"&gt; &lt;/span&gt;-y&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;openssh-server&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;shadow-utils&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;microdnf&lt;span class="w"&gt; &lt;/span&gt;clean&lt;span class="w"&gt; &lt;/span&gt;all&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;useradd&lt;span class="w"&gt; &lt;/span&gt;-ms&lt;span class="w"&gt; &lt;/span&gt;/bin/bash&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;chsh&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;/usr/bin/git-shell&lt;span class="w"&gt; &lt;/span&gt;git

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;2222&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/usr/sbin/sshd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-D"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-e"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Construcción:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;build&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;localhost/passteiner-ubi9:1&lt;span class="w"&gt; &lt;/span&gt;.
&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3 id="2-crear-volumenes-persistentes"&gt;2. Crear volúmenes persistentes&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;volume&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;git-home
podman&lt;span class="w"&gt; &lt;/span&gt;volume&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;ssh-etc

&lt;span class="nv"&gt;VHOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;podman&lt;span class="w"&gt; &lt;/span&gt;volume&lt;span class="w"&gt; &lt;/span&gt;inspect&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{{.Mountpoint}}'&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git-home&lt;span class="k"&gt;)&lt;/span&gt;
mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VHOME&lt;/span&gt;&lt;span class="s2"&gt;/.ssh"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VHOME&lt;/span&gt;&lt;span class="s2"&gt;/.password-store"&lt;/span&gt;
cp&lt;span class="w"&gt; &lt;/span&gt;~/.ssh/id_ed25519.pub&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VHOME&lt;/span&gt;&lt;span class="s2"&gt;/.ssh/authorized_keys"&lt;/span&gt;
chmod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VHOME&lt;/span&gt;&lt;span class="s2"&gt;/.ssh"&lt;/span&gt;
chmod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VHOME&lt;/span&gt;&lt;span class="s2"&gt;/.ssh/authorized_keys"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Repositorio bare:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;podman&lt;span class="w"&gt; &lt;/span&gt;unshare&lt;span class="w"&gt; &lt;/span&gt;chown&lt;span class="w"&gt; &lt;/span&gt;-R&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt;:1000&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VHOME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
podman&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;--rm&lt;span class="w"&gt; &lt;/span&gt;-v&lt;span class="w"&gt; &lt;/span&gt;git-home:/home/git&lt;span class="w"&gt; &lt;/span&gt;localhost/passteiner-ubi9:1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;init&lt;span class="w"&gt; &lt;/span&gt;--bare&lt;span class="w"&gt; &lt;/span&gt;/home/git/.password-store
&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3 id="3-quadlet-systemd-integration"&gt;3. Quadlet (systemd integration)&lt;/h3&gt;
&lt;p&gt;Archivo &lt;code&gt;~/.config/containers/systemd/pass_git.container&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pass git over SSH (podman quadlet)&lt;/span&gt;
&lt;span class="na"&gt;Wants&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network-online.target&lt;/span&gt;
&lt;span class="na"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network-online.target&lt;/span&gt;

&lt;span class="k"&gt;[Container]&lt;/span&gt;
&lt;span class="na"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;containers-storage:localhost/passteiner-ubi9:1&lt;/span&gt;
&lt;span class="na"&gt;Pull&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;never&lt;/span&gt;

&lt;span class="na"&gt;ContainerName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pass_git&lt;/span&gt;
&lt;span class="na"&gt;Network&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pasta&lt;/span&gt;
&lt;span class="na"&gt;PublishPort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;60003:2222&lt;/span&gt;

&lt;span class="na"&gt;Volume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;git-home:/home/git:Z,U&lt;/span&gt;
&lt;span class="na"&gt;Volume&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;ssh-etc:/etc/ssh:Z&lt;/span&gt;

&lt;span class="na"&gt;UserNS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;keep-id&lt;/span&gt;
&lt;span class="na"&gt;LogDriver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;journald&lt;/span&gt;
&lt;span class="na"&gt;Exec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/sbin/sshd -D -e -p 2222 -o PidFile=/tmp/sshd.pid&lt;/span&gt;

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;on-failure&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default.target&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Activación:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;daemon-reload
systemctl&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--now&lt;span class="w"&gt; &lt;/span&gt;pass_git.service
&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3 id="4-probar-conexion-ssh"&gt;4. Probar conexión SSH&lt;/h3&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;60003&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;git@&amp;lt;IP_DEL_HOST&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PreferredAuthentications&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;publickey&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PasswordAuthentication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s1"&gt;'git --version &amp;amp;&amp;amp; echo OK'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Debe autenticar con tu clave pública y responder &lt;code&gt;git version ...&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="5-probar-pass-con-git"&gt;5. Probar pass con git&lt;/h3&gt;
&lt;p&gt;Inicializar &lt;code&gt;pass&lt;/code&gt; en tu host y configurar el remoto:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/.local/share/pass
pass&lt;span class="w"&gt; &lt;/span&gt;init&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tu_clave_gpg"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PASSWORD_STORE_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
git&lt;span class="w"&gt; &lt;/span&gt;remote&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;ssh://git@&amp;lt;IP_DEL_HOST&amp;gt;:60003/home/git/.password-store
git&lt;span class="w"&gt; &lt;/span&gt;push&lt;span class="w"&gt; &lt;/span&gt;origin&lt;span class="w"&gt; &lt;/span&gt;master
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y luego:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;pass&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;push
pass&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;pull
&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h3 id="diferencias-clave-respecto-al-articulo-original"&gt;Diferencias clave respecto al artículo original&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Imagen&lt;/strong&gt;: antes Fedora, ahora UBI9 minimal (más estable, soporte hasta 2032).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Systemd&lt;/strong&gt;: antes &lt;code&gt;podman generate systemd&lt;/code&gt;, ahora &lt;strong&gt;Quadlet&lt;/strong&gt; (futuro estándar, más limpio).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rootless&lt;/strong&gt;: antes root dentro del contenedor, ahora &lt;code&gt;UserNS=keep-id&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Volúmenes&lt;/strong&gt;: ahora explícitos (&lt;code&gt;git-home&lt;/code&gt;, &lt;code&gt;ssh-etc&lt;/code&gt;), evitando pérdidas de datos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Seguridad SSH&lt;/strong&gt;: solo claves, sin password, &lt;code&gt;PidFile&lt;/code&gt; movido a &lt;code&gt;/tmp&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="conclusion"&gt;Conclusión&lt;/h3&gt;
&lt;p&gt;Este enfoque actualizado:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Evita perder el repositorio y las claves al recrear el contenedor.&lt;/li&gt;
&lt;li&gt;Asegura compatibilidad a futuro con Podman + systemd.&lt;/li&gt;
&lt;li&gt;Se apoya en una base más segura (UBI9 minimal).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;👉 Si ya usás el setup original, podés migrar en pocas horas y quedarte tranquilo de que tu &lt;strong&gt;gestor de contraseñas &lt;code&gt;pass&lt;/code&gt;&lt;/strong&gt; seguirá funcionando a largo plazo.&lt;/p&gt;</description><category>containers</category><category>pass</category><category>passwords</category><category>podman</category><guid>https://sergiobelkin.com/posts/gestion-de-contrasenas-usando-contenedores-podman-update-2025/</guid><pubDate>Mon, 25 Aug 2025 22:27:46 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I4</title><link>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i4/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;Resumen: Tips para &lt;strong&gt;curl&lt;/strong&gt;, &lt;strong&gt;ollama&lt;/strong&gt; y &lt;strong&gt;KDE Plasma&lt;/strong&gt;. Y un link acerca de cómo las organizaciones están usando el open source y el upskilling para responder a las demandas laborales impulsadas por IA&lt;/p&gt;
&lt;h3 id="power-tip-1"&gt;Power Tip #1&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Obtener un json con información de diagnóstico a partir de curl&lt;/strong&gt;. Por ejemplo: una solicitud que devuelva el &lt;em&gt;código de respuesta http&lt;/em&gt;, &lt;em&gt;la versión del protocolo http`, &lt;/em&gt;la dirección ip&lt;em&gt;, &lt;/em&gt;el tiempo de transferencia hasta el primer byte recibido&lt;em&gt; y el &lt;/em&gt;tiempo total de la operación completa*:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-Ls&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;-w&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"code":%{response_code},"http":"%{http_version}","ip":"%{remote_ip}","ttfb":%{time_starttransfer},"total":%{time_total}}\n'&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;https://fast.com&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;jq
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt1-curl-json.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt1-curl-json.thumbnail.webp" alt="Ejemplo de curl obteniendo json con información de diagnóstico"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="power-tip-2"&gt;Power Tip #2&lt;/h3&gt;
&lt;p&gt;En &lt;a href="https://sergiobelkin.com/posts/3-power-tips-plus-1-power-link-i3/"&gt;el PT 2 anterior&lt;/a&gt; mostramos como usar un LLM offline. Aquí tenemos un &lt;strong&gt;script para bajar e instalar ollama&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#! /usr/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/tmp&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
curl&lt;span class="w"&gt; &lt;/span&gt;-LO&lt;span class="w"&gt; &lt;/span&gt;https://ollama.com/download/ollama-linux-amd64.tgz
sudo&lt;span class="w"&gt; &lt;/span&gt;tar&lt;span class="w"&gt; &lt;/span&gt;-C&lt;span class="w"&gt; &lt;/span&gt;/usr/local&lt;span class="w"&gt; &lt;/span&gt;-xzf&lt;span class="w"&gt; &lt;/span&gt;ollama-linux-amd64.tgz
sudo&lt;span class="w"&gt; &lt;/span&gt;useradd&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;/bin/false&lt;span class="w"&gt; &lt;/span&gt;-U&lt;span class="w"&gt; &lt;/span&gt;-m&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;/usr/local/share/ollama&lt;span class="w"&gt; &lt;/span&gt;ollama
sudo&lt;span class="w"&gt; &lt;/span&gt;usermod&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;-G&lt;span class="w"&gt; &lt;/span&gt;ollama&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;whoami&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
sudo&lt;span class="w"&gt; &lt;/span&gt;tee&lt;span class="w"&gt;  &lt;/span&gt;/etc/systemd/system/ollama.service&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt; 'EOF'&lt;/span&gt;
&lt;span class="s"&gt;[Unit]&lt;/span&gt;
&lt;span class="s"&gt;Description=Ollama Service&lt;/span&gt;
&lt;span class="s"&gt;After=network-online.target&lt;/span&gt;

&lt;span class="s"&gt;[Service]&lt;/span&gt;
&lt;span class="s"&gt;ExecStart=/usr/local/bin/ollama serve&lt;/span&gt;
&lt;span class="s"&gt;User=ollama&lt;/span&gt;
&lt;span class="s"&gt;Group=ollama&lt;/span&gt;
&lt;span class="s"&gt;Restart=always&lt;/span&gt;
&lt;span class="s"&gt;RestartSec=3&lt;/span&gt;
&lt;span class="s"&gt;Environment="PATH=$PATH&lt;/span&gt;

&lt;span class="s"&gt;[Install]&lt;/span&gt;
&lt;span class="s"&gt;WantedBy=multi-user.target&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;

sudo&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;daemon-reload
sudo&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--now&lt;span class="w"&gt; &lt;/span&gt;ollama
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y ya está listo &lt;strong&gt;ollama&lt;/strong&gt; para usar. 😉 &lt;/p&gt;
&lt;h3 id="power-tip-3"&gt;Power Tip #3&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Configurar klipper en Plasma para que al copiar una url llame a una acción&lt;/strong&gt;. A diferencia de lo que ocurre en otros entornos o sistemas operativos, el &lt;strong&gt;Portapapeles&lt;/strong&gt; de Plasma no sirve solamente para cortar/copiar y pegar. Sino que puede realizar tareas que hacen más sencillas las tareas tanto para usuarios finales como para usuarios administradores y/o desarrolladores.
Los fundamentos de este &lt;strong&gt;Power Tip&lt;/strong&gt; son:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Una &lt;strong&gt;expresión regular&lt;/strong&gt;, por ejemplo: &lt;code&gt;^(https?://[^ \t\r\n"'&amp;lt;&amp;gt;]+)$&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;acción comando&lt;/strong&gt;, por ejemplo: &lt;code&gt;konsole --new-tab -e bash -lc 'curl -I -L -- "%1"; exec "${SHELL:-/bin/bash}" -i'&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dentro de la &lt;strong&gt;configuración del Portapapeles (&lt;em&gt;klipper&lt;/em&gt;)&lt;/strong&gt;, se pueden realizar esos y otros ajustes.&lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt3-klipper-acttion-config.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt3-klipper-acttion-config.thumbnail.webp" alt="Configurar una acción en Klipper"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Luego al copiar una URL, podemos usar un menú emergente que dispare la acción &lt;strong&gt;(en este de acuerdo al ejemplo arriba mencionado el comando curl en konsole)&lt;/strong&gt;.  💪 &lt;/p&gt;
&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/pt3-klipper-acttion-example.webp"&gt;&lt;img src="https://sergiobelkin.com/images/pt3-klipper-acttion-example.thumbnail.webp" alt="Configurar una acción en Klipper"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://training.linuxfoundation.org/blog/just-released-2025-state-of-tech-talent-report/"&gt;2025 State of Tech Talent Report&lt;/a&gt;&lt;/p&gt;</description><category>AI</category><category>curl</category><category>LLM</category><category>plasma</category><guid>https://sergiobelkin.com/posts/3-power-tips-1-power-link-i4/</guid><pubDate>Mon, 11 Aug 2025 22:20:56 GMT</pubDate></item><item><title>3 Power Tips + 1 Power Link I3</title><link>https://sergiobelkin.com/posts/3-power-tips-plus-1-power-link-i3/</link><dc:creator>sebelk</dc:creator><description>&lt;figure&gt;&lt;img src="https://sergiobelkin.com/images/PowerTipsPlus.png"&gt;&lt;/figure&gt; &lt;p&gt;En esta edición, tips para &lt;strong&gt;bash scripting&lt;/strong&gt;, gestión de paquetes con &lt;strong&gt;dnf&lt;/strong&gt;, y &lt;strong&gt;LLM en tu máquina&lt;/strong&gt;.  😉 
Y un link sobre como se refieren los medios de comunicación a la IA.&lt;/p&gt;
&lt;h3 id="power-tip-1"&gt;Power Tip #1&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Self-logging script con exec&lt;/strong&gt; (script con logging incorporado)&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;LOG_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/logs"&lt;/span&gt;
mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_DIR&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;basename&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="w"&gt; &lt;/span&gt;+%Y%m%d-%H%M%S&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="nv"&gt;$$&lt;/span&gt;&lt;span class="s2"&gt;.log"&lt;/span&gt;
&lt;span class="nb"&gt;exec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;tee&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
ping&lt;span class="w"&gt; &lt;/span&gt;-c10&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;.9.9.9
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;La línea &lt;code&gt;exec &amp;gt; &amp;gt;(tee -a "$LOG") 2&amp;gt;&amp;amp;1&lt;/code&gt; sirve para que &lt;strong&gt;toda&lt;/strong&gt; la salida del script también vaya el archivo determinado por la variable &lt;code&gt;$LOG&lt;/code&gt;.
&lt;strong&gt;Comentario&lt;/strong&gt;: En general &lt;code&gt;2&amp;gt;&amp;amp;1&lt;/code&gt; es reemplazado por &lt;code&gt;&amp;amp;&amp;gt;&lt;/code&gt;,  en versiones de bash bastante recientes. ¿Y por qué no usarlo? Porque ese atajo solamente sirve para redireccionar a archivos regulares. Por lo tanto, hay que usar la manera clásica de redireccionamiento de &lt;strong&gt;stdin&lt;/strong&gt; y &lt;strong&gt;stderr&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id="power-tip-2"&gt;Power Tip #2&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Reemplazar un paquete por otro con dnf&lt;/strong&gt;. Por ejemplo, reemplazar pipewire-pulseaudio, por pulseaudio, en caso de problemas de compatibilidad.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;dnf&lt;span class="w"&gt; &lt;/span&gt;swap&lt;span class="w"&gt; &lt;/span&gt;pipewire-pulseaudio&lt;span class="w"&gt; &lt;/span&gt;pulseaudio&lt;span class="w"&gt; &lt;/span&gt;--allowerasing
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="power-tip-3"&gt;Power Tip #3&lt;/h3&gt;
&lt;p&gt;Usar ollama, para ejecutar y gestionar modelos de AI especializados en lenguaje  en tu propia máquina, por ejemplo para explicar el contenido de un archivo:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;ollama&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;gemma3&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Explicar sintéticamente, lo que hace este archivo de reglas de polkit  &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;/usr/share/polkit-1/rules.d/org.freedesktop.Flatpak.rules&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a class="image-reference" href="https://sergiobelkin.com/images/ollama.webp"&gt;&lt;img src="https://sergiobelkin.com/images/ollama.thumbnail.webp" alt="Ollama, LLM en tu propia máquina"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3 id="power-link"&gt;Power Link&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.readtpa.com/p/stop-pretending-chatbots-have-feelings"&gt;Stop Pretending Chatbots Have Feelings: Media's Dangerous AI Anthropomorphism Problem&lt;/a&gt;&lt;/p&gt;</description><category>AI</category><category>bash</category><category>dnf</category><category>LLM</category><guid>https://sergiobelkin.com/posts/3-power-tips-plus-1-power-link-i3/</guid><pubDate>Tue, 29 Jul 2025 22:27:32 GMT</pubDate></item></channel></rss>