<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blog on Wael Nasreddine</title><link>https://risala.pages.dev/posts/</link><description>Recent content in Blog on Wael Nasreddine</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 14 Nov 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://risala.pages.dev/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>Configure Tailscale DNS on Qubes OS</title><link>https://risala.pages.dev/posts/configure-tailscale-dns-on-qubes-os/</link><pubDate>Thu, 14 Nov 2024 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/configure-tailscale-dns-on-qubes-os/</guid><description>&lt;p&gt;This post goes over configuring Tailscale DNS to support DNS resolution from other AppVMs using the Tailscale VM.&lt;/p&gt;&#10;&lt;p&gt;This guide assumes you already have Tailscale configured in a TemplateVM and a sys-tailscale AppVM is running Tailscaled for other AppVMs to use. If you don't have Tailscale already configured, then please head over to &lt;a href="https://forum.qubes-os.org/u/taradiddles" class="external-link" target="_blank" rel="noopener"&gt;taradiddles&lt;/a&gt;' &lt;a href="https://forum.qubes-os.org/t/19004" class="external-link" target="_blank" rel="noopener"&gt;excellent guide&lt;/a&gt; over on the Qubes forum.&lt;/p&gt;&#10;&lt;p&gt;We need to do the following on the &lt;strong&gt;TemplateVM&lt;/strong&gt; to get it all configured:&lt;/p&gt;</description></item><item><title>Why I Use NixOS</title><link>https://risala.pages.dev/posts/why-i-use-nixos/</link><pubDate>Sun, 24 Mar 2019 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/why-i-use-nixos/</guid><description>&lt;p&gt;This post highlights my reasoning behind switching to NixOS.&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;This was originally posted as a&lt;/em&gt; &lt;a href="https://www.reddit.com/r/archlinux/comments/b2jkrp/anyone_tried_nixos_what_are_your_thoughts/eixbwu6" class="external-link" target="_blank" rel="noopener"&gt;&lt;em&gt;Reddit comment&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="linuxunix-history"&gt;&#10; Linux/Unix History&#10; &lt;a class="heading-link" href="#linuxunix-history"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Please head over to read all about my &lt;a href="https://risala.pages.dev/about/linux-unix-history/" &gt;Linux/Unix History&lt;/a&gt;. In a Gist: I have about 20 years experience in using and managing Linux and Unix machines ranging from various Linux distributions, as well as *BSD and by extension Darwin (a.k.a Mac).&lt;/p&gt;&#10;&lt;h2 id="why-did-i-switch-to-nixos"&gt;&#10; Why did I switch to NixOS?&#10; &lt;a class="heading-link" href="#why-did-i-switch-to-nixos"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Last year -- 2018 -- I was still working as a co-founder of a small Ad-related startup. I used to have crazy long days (averaging about 12-16 hours), and I used to do about ten different things (in parallel). The reliability of my machine to say the least is of utmost importance as my day (and thus my productivity) depends on it. One day early May of last year, I wanted to install a new Vim plugin (can't remember the exact plugin) and I inadvertently ran &lt;code&gt;:PlugUpdate&lt;/code&gt; which updated all of my Vim plugins to the latest version and this has broken my entire &lt;a href="https://github.com/fatih/vim-go" class="external-link" target="_blank" rel="noopener"&gt;Go&lt;/a&gt; setup. Not only I could no longer get auto-completion as I was typing, but I was also greeted with a multi-line error every time I open a Go file, attempted to edit something or save it. I had to disable most of my plugins just to get by. By the end of that day, I was very much late on my tasks and extremely frustrated, I decided to take the weekend off and look for a solution!&lt;/p&gt;</description></item><item><title>Announcing the new Golang infrastructure: buildGoModule</title><link>https://risala.pages.dev/posts/announcing-the-new-golang-infrastructure-buildgomodule/</link><pubDate>Sun, 17 Mar 2019 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/announcing-the-new-golang-infrastructure-buildgomodule/</guid><description>&lt;div class="notice info"&gt;&#10; &lt;div class="notice-title"&gt;&#10; &lt;i class="fa-solid fa-exclamation-circle" aria-hidden="true"&gt;&lt;/i&gt;Important&#10; &lt;/div&gt;&#10; &lt;div class="notice-content"&gt;&lt;p&gt;This guide was written on March 17&lt;sup&gt;th&lt;/sup&gt; 2019 and thus is &lt;strong&gt;out of date&lt;/strong&gt;! Please refer to &lt;a href="https://nixos.org/manual/nixpkgs/stable/#sec-language-go" class="external-link" target="_blank" rel="noopener"&gt;Go section in the nixpkgs manual&lt;/a&gt; for a more up-to-date instructions!&lt;/p&gt;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;I &lt;a href="https://github.com/NixOS/nixpkgs/pull/57080" class="external-link" target="_blank" rel="noopener"&gt;recently introduced&lt;/a&gt; a new function in Nixpkgs named &lt;code&gt;buildGoModule&lt;/code&gt;. The new function allows you to package Go application (or modules) with ease, provided the modules have added support for &lt;a href="https://github.com/golang/go/wiki/Modules" class="external-link" target="_blank" rel="noopener"&gt;Go modules&lt;/a&gt; upstream.&lt;/p&gt;&#10;&lt;p&gt;Go, starting at version 1.11, has shipped with an internal solution for vendoring dependencies named: &lt;a href="https://github.com/golang/go/wiki/Modules" class="external-link" target="_blank" rel="noopener"&gt;Go Modules&lt;/a&gt;. This feature provides a pseudo-lockfile-based implementation for vendoring dependencies, with one guarentee: Reproducible build. This means that all the dependencies are guarenteed to be the same.&lt;/p&gt;</description></item><item><title>💀 How I Accidentally DDoSed My Own Kubernetes Cluster</title><link>https://risala.pages.dev/posts/how-i-accidentally-ddosed-my-k8s-cluster/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/how-i-accidentally-ddosed-my-k8s-cluster/</guid><description>&lt;h2 id="introduction"&gt;&#10; Introduction&#10; &lt;a class="heading-link" href="#introduction"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;For the past few weeks, my production Kubernetes cluster has been fighting a ghost. Every few days (or sometimes hours), the entire Control Plane would commit suicide. Critical components like the scheduler and controller manager would crash simultaneously, claiming they had &amp;quot;lost leadership.&amp;quot;&lt;/p&gt;&#10;&lt;p&gt;Usually, this happens when the network fails. But my network was fine. The nodes were up. The CPUs were idling.&lt;/p&gt;</description></item><item><title>🔒Locking Down Mastodon: Cilium Network Policies &amp; Audit Mode</title><link>https://risala.pages.dev/posts/mastodon-locking-down-with-net-policies/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/mastodon-locking-down-with-net-policies/</guid><description>&lt;h3 id="the-goal-defense-in-depth"&gt;&#10; The Goal: Defense in Depth&#10; &lt;a class="heading-link" href="#the-goal-defense-in-depth"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;Running &lt;a href="https://mastodon.nasreddine.com" class="external-link" target="_blank" rel="noopener"&gt;Mastodon&lt;/a&gt; on my bare metal cluster exposes it to the wider internet for federation. If the Mastodon container were ever compromised (RCE, supply chain attack, etc.), I need to ensure the attacker cannot use it as a jumpbox to scan my internal home lab network or access sensitive data stores (Postgres/Redis) indiscriminately.&lt;/p&gt;&#10;&lt;p&gt;The objective was to implement a &lt;strong&gt;Zero Trust&lt;/strong&gt; model using Cilium Network Policies (CNP):&lt;/p&gt;</description></item><item><title>🚨Alerting on Kyverno Policy Validation Failures with Loki</title><link>https://risala.pages.dev/posts/alert-kyverno-policy-validation-fail/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/alert-kyverno-policy-validation-fail/</guid><description>&lt;h3 id="context"&gt;&#10; Context&#10; &lt;a class="heading-link" href="#context"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;We needed to create an alert for Kyverno policy violations across our clusters. The goal was to catch when a resource fails validation (e.g., &lt;code&gt;policy=&amp;quot;require-requests-limits&amp;quot;&lt;/code&gt;) and surface relevant metadata like the resource name, kind, and target namespace directly in the alert.&lt;/p&gt;&#10;&lt;h3 id="the-data"&gt;&#10; The Data&#10; &lt;a class="heading-link" href="#the-data"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;Kyverno logs validation failures to &lt;code&gt;stderr&lt;/code&gt; in JSON format. Below is a trimmed example of the relevant fields we extract:&lt;/p&gt;</description></item><item><title>Arista - Add SSH key to a user</title><link>https://risala.pages.dev/posts/arista-add-ssh-key-to-a-user/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/arista-add-ssh-key-to-a-user/</guid><description>&lt;h1 id="arista---add-ssh-key-to-a-user"&gt;&#10; Arista - Add SSH key to a user&#10; &lt;a class="heading-link" href="#arista---add-ssh-key-to-a-user"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to add an SSH key to my user&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Starting with a fresh shell logged in as admin.&lt;/p&gt;&#10;&lt;h3 id="template"&gt;&#10; Template&#10; &lt;a class="heading-link" href="#template"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;pre&gt;&lt;code&gt;localhost&amp;gt;enable&#10;localhost#config&#10;localhost(config)#username &amp;lt;user&amp;gt; sshkey &amp;lt;contents of the public key&amp;gt;&#10;localhost(config)#write memory&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h3 id="example"&gt;&#10; Example&#10; &lt;a class="heading-link" href="#example"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;pre&gt;&lt;code&gt;localhost&amp;gt;enable&#10;localhost#config&#10;localhost(config)#username &amp;lt;user&amp;gt; sshkey ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDXxkkRoNAtqR6/CnhqzPA3uEOP4FrClAz5M0jQZDo8KEkk+X4hBglGdZi/lb4TF5BNqjQiOYKCSH1hWoSpCuhOrRPx7Xcok5r8sgumKAIIUa7BJKM81HW/XnU6y24bjGtUbOHLyM6xrd/e5VllfXMq6QNz+wymWH19xr7xrLUUfbULkem6Au3i0ueVUir7z1di/FvmVIXA+ZLy4+IhhoWScP6w+O0RWFKT2FY9FkXtlcgSDZ/NbzSz0iDruzykFfh2t7Ew99iC9XjHxL2nSEhcKruByBzfYVzc6DGh8M2Bv+ZYvqCZnnlCjoq5+u0/DVGk9COBIkaUM/bbUc7d4C6UVQyky2r27B8nfdfWCVZCvJWEpFlwojicYuSqjKHjr4WDEMuFALJn32pJ2p+vdmszTHPdu11W+F9MSGb18XdIBicVSpoNuyNggEXaBfjDwAh+a+ff65ATw86KC15Dg3FjVHmlOC3fBKn0KPdYvTLC7P0CjYQe7jm+NCXxkb6zvt/3bfc3BGY0dYZzXalNdSV4oqtk+c7QqcM1MfH+mXfaBUJUYJQONfgzXwBEZlaMIuhg/GAIURTtKFx1qcMrv+o/K40Bwtnd9Rg4VK4yq/YRosxcZ9x/bNHfZRIORmWpsaRkqnXTqnwi3UL5FD7DIYOIG/Bt344/mL85HkEIQZOTdw== Arista SSH Key&#10;localhost(config)#write memory&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-create-a-new-user/" &gt;Arista - Create a new user&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Arista - Check Fan Speed</title><link>https://risala.pages.dev/posts/arista-check-fan-speed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/arista-check-fan-speed/</guid><description>&lt;h1 id="arista---check-fan-speed"&gt;&#10; Arista - Check Fan Speed&#10; &lt;a class="heading-link" href="#arista---check-fan-speed"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to check the current speed for the fans.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;You can check the fan speed by running the command &lt;code&gt;show environment cooling&lt;/code&gt;&lt;/p&gt;&#10;&lt;h3 id="example"&gt;&#10; Example&#10; &lt;a class="heading-link" href="#example"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;pre&gt;&lt;code&gt;localhost&amp;gt;show environment cooling&#10;System cooling status is: Ok&#10;Ambient temperature: 14C&#10;Fan speed override mode enabled at 30%&#10;Airflow: front-to-back&#10;Fan Status Configured Speed Actual Speed&#10;---------------- --------------- ---------------- ----------------&#10;1/1 Ok 30% 30%&#10;2/1 Ok 30% 30%&#10;3/1 Ok 30% 30%&#10;4/1 Ok 30% 30%&#10;PowerSupply1/1 Ok 30% 40%&#10;PowerSupply2/1 Ok 30% 40%&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-control-fan-speed/" &gt;Arista - Control Fan Speed&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-custom-fan-speed-controller/" &gt;Arista - Custom Fan Speed Controller&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Arista - Configure Terminal</title><link>https://risala.pages.dev/posts/arista-configure-terminal/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/arista-configure-terminal/</guid><description>&lt;h1 id="arista---configure-terminal"&gt;&#10; Arista - Configure Terminal&#10; &lt;a class="heading-link" href="#arista---configure-terminal"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need to configure an Arista device&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;To configure an Arista, you must open a configure terminal which requires a user with privilege 15. Start the shell following the steps below:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;code&gt;enable&lt;/code&gt; to enable privileged escalation.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;config&lt;/code&gt; to start the configuration terminal.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-custom-fan-speed-controller/" &gt;Arista - Custom Fan Speed Controller&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Arista - Control Fan Speed</title><link>https://risala.pages.dev/posts/arista-control-fan-speed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/arista-control-fan-speed/</guid><description>&lt;h1 id="arista---control-fan-speed"&gt;&#10; Arista - Control Fan Speed&#10; &lt;a class="heading-link" href="#arista---control-fan-speed"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to set a custom fan speed for the fans.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Ensure you are logged in as admin (or privileged user).&lt;/p&gt;&#10;&lt;p&gt;Change the fan speed can be done with the command &lt;code&gt;environment fan-speed override xx&lt;/code&gt; where xx can be anywhere between 30 and 100. This command must be ran from within a configure block.&lt;/p&gt;</description></item><item><title>Arista - Create a new user</title><link>https://risala.pages.dev/posts/arista-create-a-new-user/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/arista-create-a-new-user/</guid><description>&lt;h1 id="arista---create-a-new-user"&gt;&#10; Arista - Create a new user&#10; &lt;a class="heading-link" href="#arista---create-a-new-user"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need to add a new user to Arista&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Starting with a fresh shell logged in as admin.&lt;/p&gt;&#10;&lt;h3 id="template"&gt;&#10; Template&#10; &lt;a class="heading-link" href="#template"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;pre&gt;&lt;code&gt;localhost&amp;gt;enable&#10;localhost#config&#10;localhost(config)#username &amp;lt;user&amp;gt; privilege &amp;lt;privilege&amp;gt; role &amp;lt;role&amp;gt; [nopassword | secret &amp;lt;password&amp;gt;]&#10;localhost(config)#write memory&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h3 id="examples"&gt;&#10; Examples&#10; &lt;a class="heading-link" href="#examples"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;h4 id="example-with-a-password"&gt;&#10; Example with a password&#10; &lt;a class="heading-link" href="#example-with-a-password"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h4&gt;&#10;&lt;pre&gt;&lt;code&gt;localhost&amp;gt;enable&#10;localhost#config&#10;localhost(config)#username &amp;lt;user&amp;gt; privilege 15 role network-admin secret &amp;lt;password&amp;gt;&#10;localhost(config)#write memory&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h4 id="example-without-a-password"&gt;&#10; Example without a password&#10; &lt;a class="heading-link" href="#example-without-a-password"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h4&gt;&#10;&lt;pre&gt;&lt;code&gt;localhost&amp;gt;enable&#10;localhost#config&#10;localhost(config)#username &amp;lt;user&amp;gt; privilege 15 role network-admin nopassword&#10;localhost(config)#write memory&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-add-ssh-key-to-a-user/" &gt;Arista - Add SSH key to a user&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Arista - Custom Fan Speed Controller</title><link>https://risala.pages.dev/posts/arista-custom-fan-speed-controller/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/arista-custom-fan-speed-controller/</guid><description>&lt;h1 id="arista---custom-fan-speed-controller"&gt;&#10; Arista - Custom Fan Speed Controller&#10; &lt;a class="heading-link" href="#arista---custom-fan-speed-controller"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The automatic fan speed controller is too conservative which leads to a lot of noise coming out of my switch. For instance, in an ambient temperature of 15℃ the fan is running at 60% which is absurd.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The solution is to run a custom Python script that controls the speed of the fans based on the temperature of the system.&lt;/p&gt;</description></item><item><title>Arista - Download Firmware - DCS-7050T</title><link>https://risala.pages.dev/posts/arista-download-firmware-dcs-7050t/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/arista-download-firmware-dcs-7050t/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to download the latest firmware supported by my Arista DCS-7050T network switch that has reached &lt;a href="https://www.arista.com/en/support/advisories-notices/end-of-sale/1249-end-of-sale-of-the-arista-7050-series" class="external-link" target="_blank" rel="noopener"&gt;End-of-life on August 9th, 2019&lt;/a&gt;. I can't seem to find the firmware &lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;List of EOS firmware I found on a &lt;a href="https://cdn.as212934.net/firmware/routers/arista/EOS/" class="external-link" target="_blank" rel="noopener"&gt;random CDN&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;I pulled the Firmware that came on my device and uploaded it to archive.org: &lt;a href="https://archive.org/details/eos-4.12.7.1" class="external-link" target="_blank" rel="noopener"&gt;eos-4.12.7.1&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;I also found and confirmed that latest supported version by my hardware and uploaded to archive.org: &lt;a href="https://archive.org/details/eos-4.18.11-m" class="external-link" target="_blank" rel="noopener"&gt;eos-4.18.11-m&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-configure-terminal/" &gt;Arista - Configure Terminal&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-update-the-firmware/" &gt;Arista - Update The Firmware&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Arista - Set the admin password</title><link>https://risala.pages.dev/posts/arista-set-the-admin-password/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/arista-set-the-admin-password/</guid><description>&lt;h1 id="arista---set-the-admin-password"&gt;&#10; Arista - Set the admin password&#10; &lt;a class="heading-link" href="#arista---set-the-admin-password"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="proble"&gt;&#10; Proble&#10; &lt;a class="heading-link" href="#proble"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to configure a password for the admin user.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Starting with a fresh shell logged in as admin.&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;localhost&amp;gt;enable&#10;localhost#config&#10;localhost(config)#username admin secret &amp;lt;password&amp;gt;&#10;localhost(config)#write memory&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-update-the-firmware/" &gt;Arista - Update The Firmware&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Arista - Update The Firmware</title><link>https://risala.pages.dev/posts/arista-update-the-firmware/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/arista-update-the-firmware/</guid><description>&lt;h1 id="arista---update-the-firmware"&gt;&#10; Arista - Update The Firmware&#10; &lt;a class="heading-link" href="#arista---update-the-firmware"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;pre&gt;&lt;code&gt;localhost&amp;gt;show version&#10;Arista DCS-7050T-36-F&#10;Hardware version: 04.02&#10;Serial number: JPE14202311&#10;System MAC address: 001c.7330.53b0&#10;&#10;Software image version: 4.12.7.1&#10;Architecture: i386&#10;Internal build version: 4.12.7.1-1692483.EOS4127.1&#10;Internal build ID: aae7a01c-f862-4897-aac7-5b9f890f5f1f&#10;&#10;Uptime: 24 minutes&#10;Total memory: 4017108 kB&#10;Free memory: 152396 kB&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-set-the-admin-password/" &gt;Arista - Set the admin password&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-create-a-new-user/" &gt;Arista - Create a new user&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-add-ssh-key-to-a-user/" &gt;Arista - Add SSH key to a user&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/arista-download-firmware-dcs-7050t/" &gt;Arista - Download Firmware - DCS-7050T&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Automation</title><link>https://risala.pages.dev/posts/hass-pager-automation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/hass-pager-automation/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;OnCall: Page Wael&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Pager is triggered with a Webhook and notifies me until I ack the page&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;triggers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;webhook&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;allowed_methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;POST&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;webhook_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-13dy9GK4x2S9t7gDzwMNqClO&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;local_only&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;conditions&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;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ack_code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{ range(1000, 9999) | random }}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;acked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;signal_messages_sent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;call_frequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;notify.signal_wael&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;-&lt;/span&gt;&lt;span class="sd"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; You are being paged by {{ trigger.json.email }} because {{&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; trigger.json.reason }}. Reply with code {{ ack_code }} to ack the&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; page.&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;signal_messages_sent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{ signal_messages_sent + 1 }}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;wait_template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;-&lt;/span&gt;&lt;span class="sd"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {% set received_code =&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; states(&amp;#39;sensor.signal_message_received&amp;#39;) | trim | int(0) %}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {% set expected_code = ack_code | int(0) %}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {{ state_attr(&amp;#39;sensor.signal_message_received&amp;#39;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#39;sourceNumber&amp;#39;) == &amp;#39;+15554443333&amp;#39; and&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; received_code == expected_code and received_code != 0 }}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;continue_on_timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;00:02:00&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;template&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value_template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{ wait.completed }}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;then&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;acked&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;template&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value_template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{ signal_messages_sent == call_frequency }}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;then&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;notify.twilio_call&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;-&lt;/span&gt;&lt;span class="sd"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; You are being paged by {{&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; trigger.json.email }} because {{&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; trigger.json.reason }}.&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="m"&gt;16509333448&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;call_frequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{ [ call_frequency + 1, 5] | min }}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;signal_messages_sent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;notify.signal_wael&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;-&lt;/span&gt;&lt;span class="sd"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; You are being paged by {{&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; trigger.json.email }} because {{&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; trigger.json.reason }}. Reply with code {{&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; ack_code }} to ack the page.&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;signal_messages_sent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{ signal_messages_sent + 1 }}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;until&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;template&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;value_template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;{{ acked == true }}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;notify.signal_wael&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;{}&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;The page {{ ack_code }} was acked!&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;queued&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>CDC: Why Decompression is Worth the Complexity</title><link>https://risala.pages.dev/posts/cdc-why-decompression-worth-complexity/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/cdc-why-decompression-worth-complexity/</guid><description>&lt;p&gt;When I started building &lt;a href="https://github.com/kalbasit/ncps" class="external-link" target="_blank" rel="noopener"&gt;ncps&lt;/a&gt;, a Nix cache protocol server, the fundamental question was: &lt;strong&gt;should we chunk compressed NARs or decompress first?&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;Decompressing before chunking adds CPU cost and complexity. Compressing individual chunks adds storage overhead. It seemed wasteful. The naive approach — chunk the compressed NAR directly — is simpler and avoids the extra round-trip through decompression and recompression.&lt;/p&gt;&#10;&lt;p&gt;But I had data. Over a year of real-world use, I'd accumulated 60,910 NAR files across multiple nixpkgs revisions and platforms. Before committing to the complex path, I wanted empirical evidence.&lt;/p&gt;</description></item><item><title>Cilium Network Policies</title><link>https://risala.pages.dev/posts/mastodon-cilium-network-policies/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/mastodon-cilium-network-policies/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cilium.io/v2&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon-egress-federation&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;egress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;toCIDRSet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;cidr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0.0.0.0&lt;/span&gt;&lt;span class="l"&gt;/0&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="m"&gt;192.168.0.0&lt;/span&gt;&lt;span class="l"&gt;/16&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="m"&gt;100.64.0.0&lt;/span&gt;&lt;span class="l"&gt;/10&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="m"&gt;10.244.0.0&lt;/span&gt;&lt;span class="l"&gt;/16&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="m"&gt;10.96.0.0&lt;/span&gt;&lt;span class="l"&gt;/12&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpointSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cilium.io/v2&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon-infra-core&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;egress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;toEndpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;io.kubernetes.pod.namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kube-system&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s-app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kube-dns&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;toPorts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;53&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;UDP&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;dns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchPattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;toEndpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;io.kubernetes.pod.namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pg-vchord-cluster&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;toPorts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;5432&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;toEndpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;k8s:io.kubernetes.pod.namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;v1.min.io/tenant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;production&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;toPorts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;9000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;toFQDNs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon.redis.prod.nasreddine.com&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;toPorts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;6379&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpointSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cilium.io/v2&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;CiliumNetworkPolicy&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon-ingress-cloudflare&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpointSelector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mastodon&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ingress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;fromEndpoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;matchLabels&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;app.kubernetes.io/name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cloudflare-tunnel&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;io.kubernetes.pod.namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;cloudflare-tunnel&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;toPorts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;4000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;8080&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;TCP&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Cloudflare Tunnel - Troubleshooting - Cannot determine default origin certificate path</title><link>https://risala.pages.dev/posts/cloudflare-tunnel-debug-cert-path-not-found/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/cloudflare-tunnel-debug-cert-path-not-found/</guid><description>&lt;h1 id="cloudflare-tunnel---troubleshooting---cannot-determine-default-origin-certificate-path"&gt;&#10; Cloudflare Tunnel - Troubleshooting - Cannot determine default origin certificate path&#10; &lt;a class="heading-link" href="#cloudflare-tunnel---troubleshooting---cannot-determine-default-origin-certificate-path"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I installed a Cloudflare Tunnel on my Kubernetes cluster using the Helm Chart and I used the token given by the Cloudflare Zero Trust tunnel creation. When the tunnel starts up, it crashes with the following error:&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;2025-06-09T05:39:13Z ERR Cannot determine default origin certificate path. No file cert.pem in [~/.cloudflared ~/.cloudflare-warp ~/cloudflare-warp /etc/cloudflared /usr/local/etc/cloudflared]. You need to specify the origin certificate path by specifying the origincert option in the configuration file, or set TUNNEL_ORIGIN_CERT environment variable originCertPath=&#10;&#10;error parsing tunnel ID: Error locating origin cert: client didn't specify origincert path&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h3 id="analysis"&gt;&#10; Analysis&#10; &lt;a class="heading-link" href="#analysis"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;I found online related to the above error mostly discussions about deployment on R-pi or other OSes but nothing on Kubernetes. I started to compare the tunnel configuration I was given with the one running on my cluster and although both are JSON based, the JSON keys are different&lt;/p&gt;</description></item><item><title>Cloudflare Tunnel for Kubernetes</title><link>https://risala.pages.dev/posts/cloudflare-tunnel-for-k8s/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/cloudflare-tunnel-for-k8s/</guid><description>&lt;h1 id="cloudflare-tunnel-for-kubernetes"&gt;&#10; Cloudflare Tunnel for Kubernetes&#10; &lt;a class="heading-link" href="#cloudflare-tunnel-for-kubernetes"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Hosting services on Kubernetes is amazing but running Kubernetes inside a home network can be quite risky as it's incredibly difficult to ensure the environment is secure, monitored for intruders and backed up --- It just lacks the backing of a company/team behind it. With that in mind, how is it possible to open websites to the internet without opening ports on the router?&lt;/p&gt;</description></item><item><title>Content-Defined Chunking (CDC) Results for NAR Storage</title><link>https://risala.pages.dev/posts/ncps-results-nar-storage/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/ncps-results-nar-storage/</guid><description>&lt;p&gt;I’ve been benchmarking Content-Defined Chunking (CDC) to optimize storage for our NAR files. The goal was to maximize deduplication by decompressing the source NARs before chunking, then re-compressing the unique chunks for final storage.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The Pipeline:&lt;/strong&gt; &lt;code&gt;Compressed NAR&lt;/code&gt; → &lt;code&gt;Decompress&lt;/code&gt; → &lt;code&gt;CDC Chunking&lt;/code&gt; → &lt;code&gt;Re-compress Chunks&lt;/code&gt; → &lt;code&gt;Store&lt;/code&gt;&lt;/p&gt;&#10;&lt;h3 id="summary-statistics"&gt;&#10; Summary Statistics&#10; &lt;a class="heading-link" href="#summary-statistics"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Metric&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Value&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Total Files (NARs)&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;60,784&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Original Compressed Size&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;161.06 GB&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Post-Deduplication Size&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;125.46 GB&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Net Space Saved&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;35.60 GB (22.1%)&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Unique Chunks Stored&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;3,934,658&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;Deduplication Hit Rate&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;strong&gt;47.72%&lt;/strong&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;hr&gt;&#10;&lt;h3 id="database-insights"&gt;&#10; Database Insights&#10; &lt;a class="heading-link" href="#database-insights"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;The following queries highlight the storage efficiency and the chunk distribution across the dataset.&lt;/p&gt;</description></item><item><title>Disaster Recovery: Talos etcd Corruption &amp; Kyverno CNI Deadlock</title><link>https://risala.pages.dev/posts/disaster-recovery-etcd-corruption-kyverno-cni-deadlock/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/disaster-recovery-etcd-corruption-kyverno-cni-deadlock/</guid><description>&lt;h2 id="incident-summary-talos-control-plane--cni-deadlock"&gt;&#10; Incident Summary: Talos Control Plane &amp;amp; CNI Deadlock&#10; &lt;a class="heading-link" href="#incident-summary-talos-control-plane--cni-deadlock"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;h2 id="overview"&gt;&#10; Overview&#10; &lt;a class="heading-link" href="#overview"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;During a physical disk migration for the TrueNAS VM (running on the Proxmox bare-metal host), severe I/O latency spikes caused a cascading failure across the Kubernetes production cluster. The incident unfolded in two distinct, critical phases: a complete loss of the Talos etcd control plane, followed by a severe CNI routing deadlock caused by admission webhooks.&lt;/p&gt;</description></item><item><title>enable_audit.sh</title><link>https://risala.pages.dev/posts/mastodon-cilium-enable-audit-script/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/mastodon-cilium-enable-audit-script/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#!/usr/bin/env bash&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;set&lt;/span&gt; -euo pipefail&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;NAMESPACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;mastodon&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;SELECTOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;app.kubernetes.io/name=mastodon&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;🔍 Finding Mastodon pods and enabling Cilium Policy Audit Mode...&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. Loop through pod names directly&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; POD_NAME in &lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pods -n &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$NAMESPACE&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -l &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$SELECTOR&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.items[*].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 2. Get the NODE NAME from the Pod itself (Reliable)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;NODE_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pod -n &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$NAMESPACE&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$POD_NAME&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.spec.nodeName}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 3. Get the ENDPOINT ID from the CiliumEndpoint (Same name as pod)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;EP_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;kubectl get cep -n &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$NAMESPACE&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$POD_NAME&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.status.id}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;---------------------------------------------------&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;target: &lt;/span&gt;&lt;span class="nv"&gt;$POD_NAME&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; node: &lt;/span&gt;&lt;span class="nv"&gt;$NODE_NAME&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; id: &lt;/span&gt;&lt;span class="nv"&gt;$EP_ID&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 4. Find the Cilium Agent Pod running on that specific node&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;CILIUM_POD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;kubectl get pod -n kube-system -l k8s-app&lt;span class="o"&gt;=&lt;/span&gt;cilium --field-selector spec.nodeName&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$NODE_NAME&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -o &lt;span class="nv"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{.items[0].metadata.name}&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; -z &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$CILIUM_POD&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;❌ ERROR: Could not find Cilium agent on node &amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;$NODE_NAME&lt;/span&gt;&lt;span class="s2"&gt;&amp;#39;. Skipping...&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;fi&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 5. Exec into the agent and toggle Audit Mode&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; exec: Enabling PolicyAuditMode on &lt;/span&gt;&lt;span class="nv"&gt;$CILIUM_POD&lt;/span&gt;&lt;span class="s2"&gt;...&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; kubectl &lt;span class="nb"&gt;exec&lt;/span&gt; -n kube-system &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$CILIUM_POD&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; -c cilium-agent -- cilium-dbg endpoint config &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$EP_ID&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="nv"&gt;PolicyAuditMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Enabled&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34; ✅ Done.&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;---------------------------------------------------&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;🎉 Audit Mode enabled. You can now apply the NetworkPolicy without dropping traffic.&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>FortiGate - Export certificate with private key</title><link>https://risala.pages.dev/posts/fortigate-export-cert-with-private-key/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/fortigate-export-cert-with-private-key/</guid><description>&lt;h1 id="fortigate---export-certificate-with-private-key"&gt;&#10; FortiGate - Export certificate with private key&#10; &lt;a class="heading-link" href="#fortigate---export-certificate-with-private-key"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I recently purchased a wildcard certificate based on a CSR generated by FortiGate and uploaded the certificate to it. It is named &lt;code&gt;wildcard-domain-tld&lt;/code&gt;. We are moving away from FortiGate and I didn't want to have to pay for it again so I needed the private key.&lt;/p&gt;</description></item><item><title>Home Assistant remove all rtl_433 devices</title><link>https://risala.pages.dev/posts/hass-remove-all-rtl_433-devices/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/hass-remove-all-rtl_433-devices/</guid><description>&lt;h1 id="home-assistant-remove-all-rtl_433-devices"&gt;&#10; Home Assistant remove all rtl_433 devices&#10; &lt;a class="heading-link" href="#home-assistant-remove-all-rtl_433-devices"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;p&gt;Home assistant does not have a way to mass delete devices; I want to delete all rtl_433 devices (there are many of them).&lt;/p&gt;&#10;&lt;h1 id="code"&gt;&#10; Code&#10; &lt;a class="heading-link" href="#code"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;deleteDevices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;manufacturer_to_delete&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;home-assistant&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;hass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;config/device_registry/list&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callWS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;device&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;manufacturer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;manufacturer_to_delete&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;hass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callWS&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config/device_registry/remove_config_entry&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;device_id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;device&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;config_entry_id&amp;#34;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;device&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;config_entries&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`Deleted device &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`Deleted &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt; devices`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;})&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;deleteDevices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;rtl_433&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id="resources"&gt;&#10; Resources&#10; &lt;a class="heading-link" href="#resources"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://community.home-assistant.io/t/some-entities-not-visible-in-rfxcom-rfxtrx/353134/4?u=kalbasit" class="external-link" target="_blank" rel="noopener"&gt;https://community.home-assistant.io/t/some-entities-not-visible-in-rfxcom-rfxtrx/353134/4?u=kalbasit&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Install ArchLinux from within NixOS</title><link>https://risala.pages.dev/posts/install-archlinux-from-nixos-system/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/install-archlinux-from-nixos-system/</guid><description>&lt;h2 id="introduction"&gt;&#10; Introduction&#10; &lt;a class="heading-link" href="#introduction"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="notice note"&gt;&#10; &lt;div class="notice-title"&gt;&#10; &lt;i class="fa-solid fa-sticky-note" aria-hidden="true"&gt;&lt;/i&gt;Note&#10; &lt;/div&gt;&#10; &lt;div class="notice-content"&gt;&lt;p&gt;This is more of a journal entry (of a self-challenge) than a guide. I call my device &lt;strong&gt;Hercules&lt;/strong&gt; and my ZFS pool is named &lt;strong&gt;olympus&lt;/strong&gt;. If you decide to follow this guide, make sure to reference the sources at the bottom.&lt;/p&gt;&lt;/div&gt;&#10;&lt;/div&gt;&lt;div class="notice error"&gt;&#10; &lt;div class="notice-title"&gt;&#10; &lt;i class="fa-solid fa-times-circle" aria-hidden="true"&gt;&lt;/i&gt;Caution&#10; &lt;/div&gt;&#10; &lt;div class="notice-content"&gt;&lt;p&gt;&lt;strong&gt;Backup your ZFS pool.&lt;/strong&gt; I am not responsible if you end up losing your data. Please proceed with caution.&lt;/p&gt;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Install Debian or Ubuntu from within NixOS</title><link>https://risala.pages.dev/posts/install-debian-or-ubuntu-from-nixos/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/install-debian-or-ubuntu-from-nixos/</guid><description>&lt;h2 id="introduction"&gt;&#10; Introduction&#10; &lt;a class="heading-link" href="#introduction"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;div class="notice note"&gt;&#10; &lt;div class="notice-title"&gt;&#10; &lt;i class="fa-solid fa-sticky-note" aria-hidden="true"&gt;&lt;/i&gt;Note&#10; &lt;/div&gt;&#10; &lt;div class="notice-content"&gt;&lt;p&gt;This is more of a journal entry (of a self-challenge) than a guide. I call my device &lt;strong&gt;Hercules&lt;/strong&gt; and my ZFS pool is named &lt;strong&gt;olympus&lt;/strong&gt;. If you decide to follow this guide, make sure to reference the sources at the bottom.&lt;/p&gt;&lt;/div&gt;&#10;&lt;/div&gt;&lt;div class="notice error"&gt;&#10; &lt;div class="notice-title"&gt;&#10; &lt;i class="fa-solid fa-times-circle" aria-hidden="true"&gt;&lt;/i&gt;Caution&#10; &lt;/div&gt;&#10; &lt;div class="notice-content"&gt;&lt;p&gt;&lt;strong&gt;Backup your ZFS pool.&lt;/strong&gt; I am not responsible if you end up losing your data. Please proceed with caution.&lt;/p&gt;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Kubernetes - List Abnormally Terminated Pods Across All Namespaces</title><link>https://risala.pages.dev/posts/k8s-list-pod-exiting-abnormally/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/k8s-list-pod-exiting-abnormally/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to get a list of all pods that have terminated abnormally along with their restart reason and count.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Run the following command:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods --all-namespaces -o custom-columns&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;NAME:.metadata.name,REASON:.status.containerStatuses[0].lastState.terminated.reason,RESTARTS:.status.containerStatuses[0].restartCount&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; grep -v &lt;span class="s1"&gt;&amp;#39;&amp;lt;none&amp;gt;\|Running\|Completed&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Migrate home-assistant from SQLite to PostgreSQL</title><link>https://risala.pages.dev/posts/hass-migrate-recorder-to-pg/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/hass-migrate-recorder-to-pg/</guid><description>&lt;h1 id="migrate-home-assistant-from-sqlite-to-postgresql"&gt;&#10; Migrate home-assistant from SQLite to PostgreSQL&#10; &lt;a class="heading-link" href="#migrate-home-assistant-from-sqlite-to-postgresql"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to migrate home-assistant from SQLite to PostgreSQL.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The migration involves the following steps:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Create a PostgreSQL database following &lt;a href="https://risala.pages.dev/posts/pg-create-utf-8-db/" &gt;PostgreSQL - Create UTF-8 Database&lt;/a&gt; and &lt;a href="https://risala.pages.dev/posts/pg-create-role-for-a-db/" &gt;PostgreSQL - Create Role for a Database&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;Configure home-assistant to use PostgreSQL.&lt;/li&gt;&#10;&lt;li&gt;Boot home-assistant to allow it to create the tables on PostgreSQL.&lt;/li&gt;&#10;&lt;li&gt;Dump the database (schema-only) and re-create the database and load the schema into it.&lt;/li&gt;&#10;&lt;li&gt;Workaround issue where sqlite store boolean as integer and postgres stores it as boolean.&lt;/li&gt;&#10;&lt;li&gt;Have pgloader migrate the database.&lt;/li&gt;&#10;&lt;li&gt;Undo the workaround.&lt;/li&gt;&#10;&lt;li&gt;Reset sequences so new records is correct.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="configure-home-assistant-to-connect-to-postgresql"&gt;&#10; Configure home-assistant to connect to PostgreSQL&#10; &lt;a class="heading-link" href="#configure-home-assistant-to-connect-to-postgresql"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;Follow &lt;a href="https://www.home-assistant.io/integrations/recorder/" class="external-link" target="_blank" rel="noopener"&gt;this document&lt;/a&gt; to configure the recorder to connect to PostgreSQL.&lt;/p&gt;</description></item><item><title>NixOS - ZFS - No space left on device</title><link>https://risala.pages.dev/posts/nixos-zfs-no-space-left-on-device/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/nixos-zfs-no-space-left-on-device/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;My system ran out of space, and I am unable to run &lt;code&gt;sudo nix-collect-garbage -d&lt;/code&gt;.&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;❯ sudo nix-collect-garbage -d&#10;removing old generations of profile /nix/var/nix/profiles/per-user/root/channels&#10;error: opening lock file '/nix/var/nix/profiles/per-user/root/channels.lock': No space left on device&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Remove your &lt;code&gt;~/.cache/nix&lt;/code&gt; and you should be able to collect the garbage and untangle your system.&lt;/p&gt;</description></item><item><title>Post-Mortem: Recovering a Corrupted Talos etcd Cluster</title><link>https://risala.pages.dev/posts/post-mortem-recovering-corrupted-talos-etcd-cluster/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/post-mortem-recovering-corrupted-talos-etcd-cluster/</guid><description>&lt;h2 id="the-incident"&gt;&#10; The Incident&#10; &lt;a class="heading-link" href="#the-incident"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;During a recent physical disk migration for a TrueNAS VM running on Proxmox, the resulting I/O latency spikes and storage disruption caused a massive ungraceful state change. This led to a complete loss of consensus in the 3-node Talos Linux control plane.&lt;/p&gt;&#10;&lt;p&gt;The Kubernetes API became completely unreachable, and the Virtual IP (VIP) dropped. Checking the control plane nodes revealed a relentless stream of errors:&lt;/p&gt;</description></item><item><title>Post-Mortem: The Admission Webhook CNI Deadlock</title><link>https://risala.pages.dev/posts/post-mortem-admission-webhook-cni-deadlock/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/post-mortem-admission-webhook-cni-deadlock/</guid><description>&lt;h2 id="the-incident"&gt;&#10; The Incident&#10; &lt;a class="heading-link" href="#the-incident"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Following a successful bare-metal restore of a Talos etcd cluster, the control plane was healthy, but the entire pod network remained offline. Cilium (running in strict kube-proxy replacement mode) was completely failing to route traffic.&lt;/p&gt;&#10;&lt;p&gt;Critical infrastructure pods like &lt;code&gt;talos-ccm&lt;/code&gt;, &lt;code&gt;coredns&lt;/code&gt;, and &lt;code&gt;hubble-relay&lt;/code&gt; were constantly crashing. Inspecting their logs revealed they were being firewalled by the host network when trying to reach the Kubernetes API or CoreDNS:&lt;/p&gt;</description></item><item><title>PostgreSQL - Create Role for a Database</title><link>https://risala.pages.dev/posts/pg-create-role-for-a-db/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/pg-create-role-for-a-db/</guid><description>&lt;h1 id="postgresql---create-role-for-a-database"&gt;&#10; PostgreSQL - Create Role for a Database&#10; &lt;a class="heading-link" href="#postgresql---create-role-for-a-database"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to create a role that has all permissions on a database (owner of such database) so the application can do whatever it needs within the db.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;First &lt;a href="https://risala.pages.dev/posts/pg-create-utf-8-db/" &gt;PostgreSQL - Create UTF-8 Database&lt;/a&gt;.&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;CREATE ROLE &amp;quot;role_name&amp;quot; WITH LOGIN PASSWORD '&amp;lt;password&amp;gt;';&#10;ALTER DATABASE &amp;quot;db_name&amp;quot; OWNER TO &amp;quot;role_name&amp;quot;;&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/pg-create-utf-8-db/" &gt;PostgreSQL - Create UTF-8 Database&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>PostgreSQL - Create UTF-8 Database</title><link>https://risala.pages.dev/posts/pg-create-utf-8-db/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/pg-create-utf-8-db/</guid><description>&lt;h1 id="postgresql---create-utf-8-database"&gt;&#10; PostgreSQL - Create UTF-8 Database&#10; &lt;a class="heading-link" href="#postgresql---create-utf-8-database"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to create a new database ensuring encoding is set to UTF-8.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;pre&gt;&lt;code&gt;CREATE DATABASE &amp;quot;db_name&amp;quot; WITH ENCODING = 'UTF8';&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/pg-create-role-for-a-db/" &gt;PostgreSQL - Create Role for a Database&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>PostgreSQL - psql using URI</title><link>https://risala.pages.dev/posts/pg-psql-with-uri/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/pg-psql-with-uri/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I have a PostgreSQL URI for one of my applications, a URI such as &lt;code&gt;postgres://username:password@hostname:port/database-name&lt;/code&gt; and I need to connect to the database from the command-line&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I used to break the URI into its parts and pass them to &lt;code&gt;psql&lt;/code&gt; in the usual way (&lt;code&gt;PGPASSWORD&lt;/code&gt; for the password, &lt;code&gt;-h &amp;lt;host&amp;gt;&lt;/code&gt; for the host, &lt;code&gt;-U &amp;lt;user&amp;gt;&lt;/code&gt; for the user etc..&lt;/p&gt;</description></item><item><title>PostgreSQL - Read-Only PSQL Session</title><link>https://risala.pages.dev/posts/pg-readonly-psql-session/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/pg-readonly-psql-session/</guid><description>&lt;h1 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;p&gt;I want to connect to a database ensuring that I cannot perform any write operations&lt;/p&gt;&#10;&lt;h1 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Connect to a PostgreSQL server with psql or your graphical interface. This guide &lt;strong&gt;has only been tested with psql&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Connect to the database you'd like to explore with &lt;code&gt;\c dbname&lt;/code&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Run the following command:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SESSION&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;CHARACTERISTICS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TRANSACTION&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;READ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;ONLY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h1 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://stackoverflow.com/a/71023224%5D%28https://stackoverflow.com/a/71023224%29" class="external-link" target="_blank" rel="noopener"&gt;https://stackoverflow.com/a/71023224&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.postgresql.org/docs/15/sql-set-transaction.html%5D%28https://www.postgresql.org/docs/15/sql-set-transaction.html%29" class="external-link" target="_blank" rel="noopener"&gt;https://www.postgresql.org/docs/15/sql-set-transaction.html&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Proxmox VM - Ensure SCSI0 in Boot Order for Talos OS</title><link>https://risala.pages.dev/posts/proxmox-scsi0-boot-order/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmox-scsi0-boot-order/</guid><description>&lt;h1 id="proxmox-vm---ensure-scsi0-in-boot-order-for-talos-os"&gt;&#10; Proxmox VM - Ensure SCSI0 in Boot Order for Talos OS&#10; &lt;a class="heading-link" href="#proxmox-vm---ensure-scsi0-in-boot-order-for-talos-os"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="symptom"&gt;&#10; Symptom&#10; &lt;a class="heading-link" href="#symptom"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;After installing Talos Linux to a Proxmox VM's SCSI disk (e.g., &lt;code&gt;scsi0&lt;/code&gt;) and removing the installation ISO, the VM may fail to boot, potentially getting stuck in a PXE/no boot loop.&lt;/p&gt;&#10;&lt;h2 id="cause"&gt;&#10; Cause&#10; &lt;a class="heading-link" href="#cause"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The Proxmox VM's boot order might not have the SCSI disk (e.g., &lt;code&gt;scsi0&lt;/code&gt;) enabled or prioritized. This can happen if disks were deleted and re-added during experimentation.&lt;/p&gt;</description></item><item><title>ProxmoxVE - Add Certificate via ACME</title><link>https://risala.pages.dev/posts/proxmox-add-cret-via-acme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmox-add-cret-via-acme/</guid><description>&lt;h1 id="proxmoxve---add-certificate-via-acme"&gt;&#10; ProxmoxVE - Add Certificate via ACME&#10; &lt;a class="heading-link" href="#proxmoxve---add-certificate-via-acme"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need to get a valid TLS certificate for my ProxmoxVE so browser don't complain.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The server certificate can be configured to use ACME to install a certificate. Follow &lt;a href="https://pve.proxmox.com/pve-docs/pve-admin-guide.html#sysadmin_certs_acme_dns_challenge" class="external-link" target="_blank" rel="noopener"&gt;this documentation&lt;/a&gt; to configure it.&lt;/p&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#root/NgSzJ5aYNkZr" &gt;ProxmoxVE - Build Log&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>ProxmoxVE - Boot without starting any VM</title><link>https://risala.pages.dev/posts/proxmox-boot-without-guest-vms/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmox-boot-without-guest-vms/</guid><description>&lt;h1 id="proxmoxve---boot-without-starting-any-vm"&gt;&#10; ProxmoxVE - Boot without starting any VM&#10; &lt;a class="heading-link" href="#proxmoxve---boot-without-starting-any-vm"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to boot ProxmoxVE without booting any guest in order to perform a maintenance task.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;During boot interrupt systemd (proxmox-boot) so it does not boot&lt;/li&gt;&#10;&lt;li&gt;Press &lt;code&gt;e&lt;/code&gt; to edit the command line&lt;/li&gt;&#10;&lt;li&gt;Type in the following at the very end of the line: &lt;code&gt;systemd.mask=pve-guests.service&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Hit Enter to boot without starting any guests.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/supermicro-install-proxmox/" &gt;SuperMicro - Install ProxmoxVE&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#root/NgSzJ5aYNkZr" &gt;ProxmoxVE - Build Log&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>ProxmoxVE - Shutdown timeout</title><link>https://risala.pages.dev/posts/proxmox-shutdown-timeout/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmox-shutdown-timeout/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;In order to give important VM time to shutdown properly, I need to define shutdown timeout for each important VM.&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;The default timeout is 180s&lt;/strong&gt;&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The timeouts are defined per VM and not per Group. Since TrueNAS takes a while to shut down and is crucial for it to take its time shutting down, I will increase its timeout to 300 seconds. The default timeout is good enough for the rest of the VMs.&lt;/p&gt;</description></item><item><title>ProxmoxVE - Start and Shutdown order</title><link>https://risala.pages.dev/posts/proxmox-start-and-shutdown-order/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmox-start-and-shutdown-order/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need to define the Start and Shutdown order for all of my VMs in order to ensure dependencies between vms.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The order defined below per group and not per VM although each VM in the group needs to input the same order number.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Group 5&lt;/strong&gt;: Basic Infrastructure&#10;&lt;ul&gt;&#10;&lt;li&gt;Basic DNS&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Group 10&lt;/strong&gt;: Infrastructure&#10;&lt;ul&gt;&#10;&lt;li&gt;TrueNAS&lt;/li&gt;&#10;&lt;li&gt;Tailscale&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Group 15&lt;/strong&gt;: Enhanced Infrastructure&#10;&lt;ul&gt;&#10;&lt;li&gt;Full Featured DNS (it depends on NFS to mount local zone files.)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Group 20&lt;/strong&gt;: Databases and caches&#10;&lt;ul&gt;&#10;&lt;li&gt;Postgres&lt;/li&gt;&#10;&lt;li&gt;Redis&lt;/li&gt;&#10;&lt;li&gt;Etc..&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Group 30&lt;/strong&gt;: Kubernetes Control Plane&#10;&lt;ul&gt;&#10;&lt;li&gt;All clusters&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Group 40&lt;/strong&gt;: Kubernetes Worker&#10;&lt;ul&gt;&#10;&lt;li&gt;All clusters&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/proxmox-startup-delay/" &gt;ProxmoxVE - Startup delay&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/proxmox-shutdown-timeout/" &gt;ProxmoxVE - Shutdown timeout&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>ProxmoxVE - Startup delay</title><link>https://risala.pages.dev/posts/proxmox-startup-delay/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmox-startup-delay/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;In order to guarantee dependent VMs boot before they are needed, I need to define a delay to wait before booting the top VMs&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The delays are defined per VM and not per Group.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Basic DNS&lt;/strong&gt;: 60s&#10;&lt;ul&gt;&#10;&lt;li&gt;Allow basic DNS to load correctly and become available as other VMs depends on it.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;TrueNAS&lt;/strong&gt;: 60s&#10;&lt;ul&gt;&#10;&lt;li&gt;TrueNAS boots pretty quickly (unlike shutdown), so give it enough time to boot before other VMs.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/proxmox-start-and-shutdown-order/" &gt;ProxmoxVE - Start and Shutdown order&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/proxmox-shutdown-timeout/" &gt;ProxmoxVE - Shutdown timeout&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>ProxmoxVE - TrueNAS VM - Disable Memory Ballooning</title><link>https://risala.pages.dev/posts/proxmoxve-truenas-disable-memory-ballooning/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmoxve-truenas-disable-memory-ballooning/</guid><description>&lt;h1 id="proxmoxve---truenas-vm---disable-memory-ballooning"&gt;&#10; ProxmoxVE - TrueNAS VM - Disable Memory Ballooning&#10; &lt;a class="heading-link" href="#proxmoxve---truenas-vm---disable-memory-ballooning"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;p&gt;&lt;strong&gt;ProxmoxVE's memory ballooning&lt;/strong&gt; feature allows a virtual machine's operating system to dynamically adjust its reported memory usage. This enables the hypervisor (ProxmoxVE) to reclaim memory from the VM if it's not actively being used by the guest OS, and allocate it to other VMs or the host.&lt;/p&gt;&#10;&lt;p&gt;However, for &lt;strong&gt;TrueNAS virtual machines, memory ballooning should be disabled.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>ProxmoxVE - Turn off laptop screen</title><link>https://risala.pages.dev/posts/proxmox-turn-off-laptop-screen/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmox-turn-off-laptop-screen/</guid><description>&lt;h1 id="proxmoxve---turn-off-laptop-screen"&gt;&#10; ProxmoxVE - Turn off laptop screen&#10; &lt;a class="heading-link" href="#proxmoxve---turn-off-laptop-screen"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I have a couple of ProxmoxVE servers running on old laptops and I noticed that the screen never turns off.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The solution is to leverage the consoleblank kernel command line flag:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Edit &lt;code&gt;/etc/kernel/cmdline&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Append &lt;code&gt;consoleblank=60&lt;/code&gt; to the end of the line&lt;/li&gt;&#10;&lt;li&gt;Run &lt;code&gt;proxmox-boot-tool refresh&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Reboot&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#root/NgSzJ5aYNkZr" &gt;ProxmoxVE - Build Log&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#root/QhAdfbJICkpd" &gt;ProxmoxVE - Prevent sleep on lid close&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>ProxmoxVE - VM - Talos Linux - New Kubernetes Cluster</title><link>https://risala.pages.dev/posts/proxmox-talos-new-k8s-cluster/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmox-talos-new-k8s-cluster/</guid><description>&lt;h1 id="proxmoxve---vm---talos-linux---new-kubernetes-cluster"&gt;&#10; ProxmoxVE - VM - Talos Linux - New Kubernetes Cluster&#10; &lt;a class="heading-link" href="#proxmoxve---vm---talos-linux---new-kubernetes-cluster"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;p&gt;Talos runs great on ProxmoxVE. Make sure to add the system extension &lt;code&gt;siderolabs/qemu-guest-agent&lt;/code&gt; when producing the &lt;a href="https://risala.pages.dev/posts/talos-factory-iso-with-extensions/" &gt;Talos - Generate ISO and Installer with Custom Extensions via Image Factory&lt;/a&gt;. This enhances VM manageability from Proxmox (e.g., proper shutdowns, IP reporting in Proxmox UI).&lt;/p&gt;&#10;&lt;p&gt;The required steps for a new Kubernetes Cluster are:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Generate an ISO and Download it on ProxmoxVE.&lt;/li&gt;&#10;&lt;li&gt;Setup the Control Plane of Kubernetes.&lt;/li&gt;&#10;&lt;li&gt;Create one Talos VM for each Talos Control Plane node.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Kubernetes recommends an odd number of nodes. Typically one node for development and three nodes for production for high availability.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt; &lt;/li&gt;&#10;&lt;li&gt; &lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="generate-an-iso-and-download-it-on-proxmoxve"&gt;&#10; Generate an ISO and Download it on ProxmoxVE&#10; &lt;a class="heading-link" href="#generate-an-iso-and-download-it-on-proxmoxve"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Generate an ISO by following &lt;a href="https://risala.pages.dev/posts/talos-factory-iso-with-extensions/" &gt;Talos - Generate ISO and Installer with Custom Extensions via Image Factory&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Pin the Talos version in your image factory command for reproducible builds.&lt;/li&gt;&#10;&lt;li&gt;Download the ISO on ProxmoxVE&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="create-talos-vms"&gt;&#10; Create Talos VM(s)&#10; &lt;a class="heading-link" href="#create-talos-vms"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Create a new VM, and be sure to follow the &lt;a href="#root/tzME4XCbt2Kh" &gt;Talos Linux - System Requirements&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;Use advanced configuration and disable memory ballooning, that will not be useful with Kubernetes and could in fact be harmful.&lt;/li&gt;&#10;&lt;li&gt;Choose OVMF over SeaBIOS as it loads a nicer console font by default. See &lt;a href="#root/UybHqtYYxrbZ" &gt;Proxmox VM - UEFI vs SeaBIOS Consideration&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;CPU Type:&lt;/strong&gt; Set CPU type to &lt;code&gt;host&lt;/code&gt; in Proxmox VM options for best performance, unless live migration to different CPU hosts is a strict requirement.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Network Adapter:&lt;/strong&gt; Use &lt;code&gt;virtio&lt;/code&gt; (paravirtualized) for the network device model for best performance.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Resource Allocation:&lt;/strong&gt; Plan CPU cores and RAM for each VM based on expected load. For control planes: typically 2+ cores, 4GB+ RAM. Workers depend on workload.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;(Optional) VM Template:&lt;/strong&gt; After setting up and testing one worker VM (before applying Talos config), consider converting it to a Proxmox template for faster worker node deployment. You'd still need to boot with the ISO and apply the Talos config.&lt;/li&gt;&#10;&lt;li&gt;Gather the NIC Mac Address from the VM Hardware page, this is needed to setup a static IP on the router.&lt;/li&gt;&#10;&lt;li&gt;Add the node to the router with fixed IP following &lt;a href="#root/QTeojEQdVxUM" &gt;UniFi - Add DHCP Reservation for MAC&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;Start the VM&lt;/li&gt;&#10;&lt;li&gt;Follow the heading below for configuring the cluster.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="configure-the-cluster"&gt;&#10; Configure the cluster&#10; &lt;a class="heading-link" href="#configure-the-cluster"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Write the &lt;code&gt;controlplane-patch.yaml&lt;/code&gt; and &lt;code&gt;worker-patch.yaml&lt;/code&gt; &lt;strong&gt;with the contents below&lt;/strong&gt;.&lt;/li&gt;&#10;&lt;li&gt;Generate the secrets with &lt;code&gt;talosctl gen secrets -o secrets.yaml&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; Store &lt;code&gt;secrets.yaml&lt;/code&gt; securely. It contains sensitive PKI data. Consider encrypting it at rest (e.g., using GPG, HashiCorp Vault, or similar). Back it up to a secure location.&lt;/li&gt;&#10;&lt;li&gt;Generate the configuration with the command &lt;code&gt;talosctl gen config --with-secrets secrets.yaml --config-patch-control-plane @controlplane-patch.yaml --config-patch-worker @worker-patch.yaml &amp;lt;cluster name&amp;gt; https://&amp;lt;IP_of_first_node&amp;gt;:6443 --output-dir . --install-image &amp;lt;url-to-installer-image-from-factory&amp;gt;&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt; &#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;&amp;lt;IP_of_first_node&amp;gt;&lt;/code&gt; in the URL for &lt;code&gt;talosctl gen config&lt;/code&gt; is used as the initial endpoint for the generated &lt;code&gt;talosconfig&lt;/code&gt; and as one of the default cert SANs. Your &lt;code&gt;controlplane-patch.yaml&lt;/code&gt; correctly overrides/supplements &lt;code&gt;apiServer.certSANs&lt;/code&gt; and defines &lt;code&gt;controlPlane.endpoint&lt;/code&gt; to your VIP (&lt;code&gt;&amp;lt;VIP&amp;gt;&lt;/code&gt;), which is good practice.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;The command generates &lt;code&gt;controlplane.yaml&lt;/code&gt;, &lt;code&gt;worker.yaml&lt;/code&gt;, and &lt;code&gt;talosconfig&lt;/code&gt;. The &lt;code&gt;.yaml&lt;/code&gt; files are the machine configs for your nodes.&lt;/li&gt;&#10;&lt;li&gt;For each control plane node, apply the config with the command and wait for the node to become ready &lt;code&gt;talosctl apply-config --insecure --file controlplane.yaml --nodes &amp;lt;IP&amp;gt;&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;First node should start saying &amp;quot;waiting for talosctl bootstrap&amp;quot;&lt;/li&gt;&#10;&lt;li&gt;Other nodes are ready as soon you see the number of machines increment on the first node.&lt;/li&gt;&#10;&lt;li&gt;Worker plane nodes can be applied all at once with the command &lt;code&gt;talosctl apply-config --insecure --file worker.yaml --nodes &amp;lt;IP&amp;gt; --nodes &amp;lt;IP&amp;gt;&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Configure &lt;code&gt;talosconfig&lt;/code&gt; with the IP of the &lt;strong&gt;first node. Do not add other nodes yet&lt;/strong&gt; (see &lt;a href="https://risala.pages.dev/posts/talos-bootstrap-x509-unknown-authority/" &gt;Talos - Bootstrap - x509 Unknown Authority&lt;/a&gt;)&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;talosctl config endpoint &amp;lt;IP_of_one_control_plane_node&amp;gt;&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;talosctl config node &amp;lt;IP_of_one_control_plane_node&amp;gt;&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Either copy &lt;code&gt;talosconfig&lt;/code&gt; to &lt;code&gt;~/.talos/config&lt;/code&gt; or export &lt;code&gt;TALOSCONFIG&lt;/code&gt; environment variable to point to its location.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; The &lt;code&gt;talosconfig&lt;/code&gt; file contains client certificates that grant administrative access to your cluster. Protect it accordingly.&lt;/li&gt;&#10;&lt;li&gt;Bootstrap the cluster with &lt;code&gt;talosctl bootstrap&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Wait for &lt;code&gt;talosctl health -n &amp;lt;IP&amp;gt;&lt;/code&gt; for each IP to report healthy.&lt;/li&gt;&#10;&lt;li&gt;Generate the proper kube config with the command &lt;code&gt;talosctl kubeconfig&lt;/code&gt;. This command merges with &lt;code&gt;~/.kube/config&lt;/code&gt; if one is found and automatically sets the context to the cluster so it's ready to use.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Important:&lt;/strong&gt; After bootstrap and verifying health, update your &lt;code&gt;talosconfig&lt;/code&gt; to include all control plane node endpoints for high availability when using &lt;code&gt;talosctl&lt;/code&gt;: &lt;code&gt;talosctl config endpoint &amp;lt;CP1_IP&amp;gt;,&amp;lt;CP2_IP&amp;gt;,&amp;lt;CP3_IP&amp;gt; --nodes &amp;lt;CP1_IP&amp;gt;,&amp;lt;CP2_IP&amp;gt;,&amp;lt;CP3_IP&amp;gt;&lt;/code&gt; (Or edit the &lt;code&gt;talosconfig&lt;/code&gt; YAML file directly to update &lt;code&gt;contexts.&amp;lt;your-cluster&amp;gt;.endpoints&lt;/code&gt; and &lt;code&gt;contexts.&amp;lt;your-cluster&amp;gt;.nodes&lt;/code&gt;). This ensures &lt;code&gt;talosctl&lt;/code&gt; can reach the Talos API even if one control plane node is down.&lt;/li&gt;&#10;&lt;li&gt;Run &lt;code&gt;kubectl get node -o wide&lt;/code&gt; to confirm things are working fine.&lt;/li&gt;&#10;&lt;li&gt;Ensure no node is tainted as &lt;code&gt;uninitialized&lt;/code&gt;, use the following command: &lt;code&gt;kubectl get nodes -o custom-columns=NODE:.metadata.name,TAINTS:.spec.taints&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#root/eYDTIsTbfIxy" &gt;Talos Linux - Cloud Controller Manager (or CCM)&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;&lt;code&gt;controlplane-patch.yaml&lt;/code&gt;&lt;/p&gt;</description></item><item><title>ProxmoxVE - VM Performance Tuning</title><link>https://risala.pages.dev/posts/proxmoxve-vm-performance-tuning/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/proxmoxve-vm-performance-tuning/</guid><description>&lt;h1 id="proxmoxve---vm-performance-tuning"&gt;&#10; ProxmoxVE - VM Performance Tuning&#10; &lt;a class="heading-link" href="#proxmoxve---vm-performance-tuning"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;p&gt;Proxmox VE, being based on KVM/QEMU, offers numerous avenues for tuning Virtual Machine (VM) performance. Optimal settings often depend on the specific workload of the VM (e.g., I/O intensive, CPU intensive, network intensive). This note covers general best practices and specific configurations.&lt;/p&gt;&#10;&lt;h2 id="1-cpu-configuration"&gt;&#10; 1. CPU Configuration&#10; &lt;a class="heading-link" href="#1-cpu-configuration"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;CPU Type:&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;host&lt;/code&gt;: This is generally recommended for best performance. It passes through the host CPU's features and model directly to the VM, avoiding emulation overhead and ensuring access to all instruction sets (e.g., AVX, AES-NI).&lt;/li&gt;&#10;&lt;li&gt;Avoid older emulated CPU types unless required for specific compatibility (e.g., live migration to a host with a different CPU).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Cores &amp;amp; Sockets:&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;Start with what the VM workload reasonably needs. Over-allocating CPU cores can sometimes lead to scheduler contention on the host, potentially degrading performance for all VMs.&lt;/li&gt;&#10;&lt;li&gt;For most VMs, configuring sockets=1 and adjusting the number of cores is straightforward. NUMA considerations might influence socket/core layout for very large VMs on multi-socket hosts.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;NUMA Pinning:&lt;/strong&gt; For VMs with significant RAM and CPU allocated on NUMA-aware host hardware, enabling the &amp;quot;NUMA&amp;quot; option in Proxmox and ensuring the VM's vCPUs and memory are pinned to the same NUMA node can improve memory access latency and performance. This is an advanced setting.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="2-memory-configuration"&gt;&#10; 2. Memory Configuration&#10; &lt;a class="heading-link" href="#2-memory-configuration"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Static Allocation:&lt;/strong&gt; For performance-sensitive VMs, especially those running databases or memory-intensive applications (like TrueNAS with ZFS), assign static memory.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Disable Ballooning:&lt;/strong&gt; As detailed in &lt;a href="https://risala.pages.dev/posts/proxmoxve-truenas-disable-memory-ballooning/" &gt;ProxmoxVE - TrueNAS VM - Disable Memory Ballooning&lt;/a&gt;, memory ballooning can be detrimental for workloads that manage their own memory carefully (e.g., ZFS ARC, database buffer pools). Uncheck the &amp;quot;Ballooning Device&amp;quot; for such VMs.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Hugepages:&lt;/strong&gt; For certain applications (e.g., databases, Java applications), transparent hugepages (THP) or explicitly configured hugepages can improve memory performance by reducing TLB misses. This is configured at the host level and sometimes within the guest OS.&lt;/li&gt;&#10;&lt;li&gt;Proxmox allows enabling hugepages for VMs (e.g., &amp;quot;KSM and Hugepages&amp;quot; settings).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="3-storage-performance"&gt;&#10; 3. Storage Performance&#10; &lt;a class="heading-link" href="#3-storage-performance"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Disk Image Format:&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;raw&lt;/code&gt;: Generally offers the best performance as it has minimal overhead.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;qcow2&lt;/code&gt;: Offers features like snapshots and thin provisioning but can have a slight performance overhead compared to &lt;code&gt;raw&lt;/code&gt;. If using &lt;code&gt;qcow2&lt;/code&gt;, preallocation can improve performance.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Storage Type on Host:&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;Local SSDs (NVMe or SATA) will provide the best I/O performance for VM disks.&lt;/li&gt;&#10;&lt;li&gt;Ceph or ZFS (if Proxmox is installed on ZFS) can provide robust and performant shared storage, but their performance depends heavily on their own configuration (e.g., number of OSDs, SSD journaling, network).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;VirtIO Drivers:&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;VirtIO SCSI / VirtIO Block (&lt;code&gt;virtio-blk&lt;/code&gt;):&lt;/strong&gt; Both are paravirtualized drivers offering good performance.&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;VirtIO SCSI&lt;/code&gt; (often with &lt;code&gt;VirtIO SCSI single&lt;/code&gt; controller type) is generally recommended for flexibility and features like TRIM/UNMAP support.&lt;/li&gt;&#10;&lt;li&gt;Enable &lt;code&gt;IO Thread&lt;/code&gt; for VirtIO SCSI disks. This dedicates a separate I/O thread per disk, which can significantly improve I/O throughput and reduce latency, especially for multi-core VMs and fast storage.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;Ensure VirtIO drivers are installed in the guest OS (most modern Linux distros include them; Windows requires separate driver installation).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Cache Mode:&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;none&lt;/code&gt; (or &lt;code&gt;writethrough&lt;/code&gt; for certain data integrity needs): Often recommended for VMs with applications that manage their own caching (e.g., databases) or when data integrity is paramount. This bypasses the host page cache.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;writeback&lt;/code&gt;: Can offer higher performance by using the host page cache, but carries a risk of data loss if the host crashes before data is flushed to disk (unless using features like Ceph's RBD caching with appropriate safety measures).&lt;/li&gt;&#10;&lt;li&gt;Carefully consider the implications of cache modes based on the workload and storage backend.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Discard/TRIM:&lt;/strong&gt; Enable the &amp;quot;Discard&amp;quot; option for virtual disks on SSD-backed storage (and ensure the guest OS also issues TRIM commands). This helps SSDs maintain performance by allowing them to reclaim unused blocks.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="4-network-performance"&gt;&#10; 4. Network Performance&#10; &lt;a class="heading-link" href="#4-network-performance"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;VirtIO NIC:&lt;/strong&gt; The &lt;code&gt;VirtIO (paravirtualized)&lt;/code&gt; network device type offers the best performance for most VMs. Ensure guest OS drivers are installed.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Multiqueue VirtIO:&lt;/strong&gt; Enable the &amp;quot;Multiqueue&amp;quot; option for VirtIO NICs (and ensure the guest OS supports it, e.g., Linux kernel 3.8+). This allows network packet processing to be distributed across multiple vCPUs, significantly improving network throughput for multi-core VMs. Set the number of queues appropriately (e.g., to match the number of vCPUs, up to a reasonable limit).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;vHostNet (Host-side processing):&lt;/strong&gt; While not a direct Proxmox setting, understanding that VirtIO networking can leverage vHostNet in the host kernel can offload some network processing from QEMU, improving efficiency.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;SR-IOV / PCI Passthrough:&lt;/strong&gt; For extreme network performance needs, passing through a physical NIC or a Virtual Function (VF) via SR-IOV to the VM can provide near bare-metal network performance by bypassing the hypervisor's network stack.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="5-guest-os-optimizations"&gt;&#10; 5. Guest OS Optimizations&#10; &lt;a class="heading-link" href="#5-guest-os-optimizations"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Install Guest Utilities/Drivers:&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;qemu-guest-agent&lt;/code&gt;: Essential for proper communication with the hypervisor (e.g., for clean shutdowns, IP address reporting, freezing filesystem for snapshots).&lt;/li&gt;&#10;&lt;li&gt;Latest VirtIO drivers for Windows.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Kernel Tuning (Linux Guests):&lt;/strong&gt; Adjust kernel parameters within the guest (e.g., I/O schedulers, network buffer sizes, swappiness) based on the workload.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Disable Unused Services:&lt;/strong&gt; Minimize resource consumption within the guest.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="6-general-proxmox-host-considerations"&gt;&#10; 6. General Proxmox Host Considerations&#10; &lt;a class="heading-link" href="#6-general-proxmox-host-considerations"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Host Kernel:&lt;/strong&gt; Keep Proxmox VE updated to benefit from the latest KVM/QEMU features, bug fixes, and performance improvements.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Host Resource Monitoring:&lt;/strong&gt; Regularly monitor host CPU, memory, disk I/O, and network utilization to identify bottlenecks.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Limit KSM (Kernel Samepage Merging):&lt;/strong&gt; While KSM can save memory by deduplicating identical memory pages between VMs, it consumes CPU resources. If CPU is a bottleneck or for latency-sensitive VMs, consider disabling KSM or tuning its parameters. It's often disabled by default in recent Proxmox versions or can be toggled per VM.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/proxmoxve-truenas-disable-memory-ballooning/" &gt;ProxmoxVE - TrueNAS VM - Disable Memory Ballooning&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/truenas-vm-sizing-and-configuration-best-practices/" &gt;TrueNAS - VM Sizing and Configuration Best Practices&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Redis - Add ACL Users</title><link>https://risala.pages.dev/posts/redis-add-acl-users/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/redis-add-acl-users/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I want to configure a Redis database and enabled authentication as well as add users with auth that can login from anywhere on my nextwork.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Login to the Redis box/container.&lt;/li&gt;&#10;&lt;li&gt;Open a Redis CLI with &lt;code&gt;redis-cli&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Run &lt;code&gt;ACL LIST&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;If you get &lt;code&gt;(error) NOAUTH Authentication required.&lt;/code&gt; then you need to authentication first with the following command: &lt;code&gt;AUTH default &amp;lt;password&amp;gt;&lt;/code&gt; and if you got it should respond with &lt;code&gt;OK&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Add a new user with &lt;code&gt;ACL SETUSER nextcloud +@all ~* allchannels on &amp;gt;MYPASSWORD&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Save with &lt;code&gt;ACL SAVE&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/redis-noperm-on-channel/" &gt;Redis - Troubleshooting NOPERM this user has no permissions to access one of the channels&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Redis - Troubleshooting NOPERM this user has no permissions to access one of the channels</title><link>https://risala.pages.dev/posts/redis-noperm-on-channel/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/redis-noperm-on-channel/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I configured ArgoCD to use an external Redis server with authentication, and I'm getting the following error on the UI: &lt;code&gt;Unable to load data: error getting cached app managed resources: cache: key is missing&lt;/code&gt;. In the logs of ArgoCD I also found this log entry:&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;Failed to cache app resources: error setting app resource tree: NOPERM this user has no permissions to access one of the channels used as arguments&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Add &lt;code&gt;allchannels&lt;/code&gt; to the users.list&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Before&lt;/p&gt;</description></item><item><title>Simple Oncall Pager with Home Assistant</title><link>https://risala.pages.dev/posts/hass-oncall-pager/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/hass-oncall-pager/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need a simple pager that allows my clients to page me. The pager should first try to notify me by a Signal message, and if there is no answer, it should call me.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;h3 id="high-level-workflow"&gt;&#10; High Level Workflow&#10; &lt;a class="heading-link" href="#high-level-workflow"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Frontend:&lt;/strong&gt; A Cloudflare application deployed at &lt;a href="https://page-wael.nasreddine.com" class="external-link" target="_blank" rel="noopener"&gt;https://page-wael.nasreddine.com&lt;/a&gt;, guarded by Google authentication.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Ingress:&lt;/strong&gt; The Cloudflare application leads to a deployment on my Kubernetes cluster via a Cloudflare Tunnel.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;User Interaction:&lt;/strong&gt; The deployment serves a simple HTML page that collects the &lt;code&gt;reason&lt;/code&gt; for the page.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Trigger:&lt;/strong&gt; Once the user submits the form, the backend sends a POST request to a Home Assistant webhook.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Notification:&lt;/strong&gt; The webhook triggers a Home Assistant automation that sends me a message on Signal containing:&#10;&lt;ul&gt;&#10;&lt;li&gt;The email of the person triggering the page (extracted from the &lt;code&gt;cf-access-authenticated-user-email&lt;/code&gt; header).&lt;/li&gt;&#10;&lt;li&gt;The reason provided.&lt;/li&gt;&#10;&lt;li&gt;A 4-digit ACK code.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 id="escalation-policy"&gt;&#10; Escalation Policy&#10; &lt;a class="heading-link" href="#escalation-policy"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;If I reply with the ACK code, the automation stops. As long as I do not ACK, the loop continues:&lt;/p&gt;</description></item><item><title>SuperMicro - BMC - Boot from USB</title><link>https://risala.pages.dev/posts/supermicro-bmc-boot-from-usb/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/supermicro-bmc-boot-from-usb/</guid><description>&lt;h1 id="supermicro---bmc---boot-from-usb"&gt;&#10; SuperMicro - BMC - Boot from USB&#10; &lt;a class="heading-link" href="#supermicro---bmc---boot-from-usb"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need to boot from USB in order to start installing ProxmoxVE. The server has no HDMI (could have serial console and/or VGA; I have not checked yet).&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Login to IPMI on the management interface, and select Remote Control &amp;gt; iKVM/HTML5.&lt;/p&gt;</description></item><item><title>SuperMicro - Install ProxmoxVE</title><link>https://risala.pages.dev/posts/supermicro-install-proxmox/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/supermicro-install-proxmox/</guid><description>&lt;h1 id="supermicro---install-proxmoxve"&gt;&#10; SuperMicro - Install ProxmoxVE&#10; &lt;a class="heading-link" href="#supermicro---install-proxmoxve"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need to install ProxmoxVE on the server.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/supermicro-bmc-boot-from-usb/" &gt;SuperMicro - BMC - Boot from USB&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;Perform a normal ProxmoxVE installation using the two SSD in RAID1 (mirror)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img src="supermicro-install-proxmox_Screenshot-2025-05-25-at-16.09.00.png" alt="Screenshot 2025-05-25 at 16.09.00.png"&gt;&lt;/p&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#root/faEXa14ZnKKN" &gt;Setting up SuperMicro SuperStorage 6048R-E1CR36H&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/supermicro-bmc-boot-from-usb/" &gt;SuperMicro - BMC - Boot from USB&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Synology - Allow SSH for non-admin users</title><link>https://risala.pages.dev/posts/synology-allow-ssh-for-non-admin-users/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/synology-allow-ssh-for-non-admin-users/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need to grant regular users SSH access to my Synology NAS, specifically for a &lt;a href="https://www.borgbackup.org/" class="external-link" target="_blank" rel="noopener"&gt;Borg&lt;/a&gt; account used to back up my TrueNAS.&lt;/p&gt;&#10;&lt;p&gt;By default, DSM restricts SSH access to users in the &lt;strong&gt;administrators&lt;/strong&gt; group, as noted at the bottom of &lt;a href="https://kb.synology.com/en-af/DSM/tutorial/How_to_login_to_DSM_with_root_permission_via_SSH_Telnet" class="external-link" target="_blank" rel="noopener"&gt;this page&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The workaround is to modify &lt;code&gt;/etc/passwd&lt;/code&gt; and change the target user's shell from &lt;code&gt;/sbin/nologin&lt;/code&gt; to a valid shell like &lt;code&gt;/bin/sh&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Talos - Bootstrap - x509 Unknown Authority</title><link>https://risala.pages.dev/posts/talos-bootstrap-x509-unknown-authority/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/talos-bootstrap-x509-unknown-authority/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;When bootstrapping a Talos Linux cluster, &lt;code&gt;talosctl bootstrap&lt;/code&gt; may fail with an error:&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;rpc error: code = Unavailable desc = last connection error: connection error: desc = &amp;quot;transport: authentication handshake failed: tls: failed to verify certificate: x509: certificate signed by unknown authority&amp;quot;&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;This occurred during an installation on Proxmox.&lt;/p&gt;&#10;&lt;h2 id="solution--workaround"&gt;&#10; Solution / Workaround&#10; &lt;a class="heading-link" href="#solution--workaround"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The issue was resolved by performing the following steps:&lt;/p&gt;</description></item><item><title>Talos - Generate ISO and Installer with Custom Extensions via Image Factory</title><link>https://risala.pages.dev/posts/talos-factory-iso-with-extensions/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/talos-factory-iso-with-extensions/</guid><description>&lt;p&gt;Talos Linux provides an &lt;a href="https://factory.talos.dev/" class="external-link" target="_blank" rel="noopener"&gt;Image Factory&lt;/a&gt; to generate customized installation images. For a bare-metal or Proxmox installation, a &amp;quot;metal&amp;quot; platform image can be generated.&lt;/p&gt;&#10;&lt;h2 id="process-example-using-web-interface-v1102"&gt;&#10; Process Example using web interface (v1.10.2):&#10; &lt;a class="heading-link" href="#process-example-using-web-interface-v1102"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Go to the &lt;a href="https://factory.talos.dev/" class="external-link" target="_blank" rel="noopener"&gt;Talos Linux Image Factory&lt;/a&gt;.&lt;/li&gt;&#10;&lt;li&gt;Select architecture (e.g., &lt;code&gt;amd64&lt;/code&gt;), platform (&lt;code&gt;metal&lt;/code&gt;), desired Talos version (e.g., &lt;code&gt;1.10.2&lt;/code&gt;).&lt;/li&gt;&#10;&lt;li&gt;Specify desired system extensions. For example, to include &lt;code&gt;nfsd&lt;/code&gt;, &lt;code&gt;qemu-guest-agent&lt;/code&gt;, and &lt;code&gt;tailscale&lt;/code&gt;:&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt; &lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;customization:&#10; systemExtensions:&#10; officialExtensions:&#10; - siderolabs/nfsd&#10; - siderolabs/qemu-guest-agent&#10; - siderolabs/tailscale&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;The factory will generate a unique schematic ID and an installation URL for the ISO. Example URL: &lt;code&gt;factory.talos.dev/metal-installer/630b5c0ccc1955f97a7c6f097fd5eae789d10a425fed8431985e22bf7a831af2:v1.10.2&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;This ISO can then be downloaded and used to install Talos on Proxmox VMs or physical hardware.&lt;/p&gt;</description></item><item><title>TrueNAS - Add Certificate via ACME</title><link>https://risala.pages.dev/posts/truenas-add-cert-via-acme/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/truenas-add-cert-via-acme/</guid><description>&lt;h1 id="truenas---add-certificate-via-acme"&gt;&#10; TrueNAS - Add Certificate via ACME&#10; &lt;a class="heading-link" href="#truenas---add-certificate-via-acme"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need TrueNAS to have a valid certificate for use by democratic-csi (for iSCSI and NFS) and for use on the UI.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="https://www.truenas.com/docs/scale/scaletutorials/credentials/certificates/settingupletsencryptcertificates/" class="external-link" target="_blank" rel="noopener"&gt;Official Documentation&lt;/a&gt;&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Go to &lt;a href="https://dash.cloudflare.com/profile/api-tokens" class="external-link" target="_blank" rel="noopener"&gt;Cloudflare &amp;gt; My Profile &amp;gt; API Tokens&lt;/a&gt; and create a new Edit zone DNS Token.&lt;/li&gt;&#10;&lt;li&gt;Go to Credentials &amp;gt; Certificates &lt;img src="truenas-add-cert-via-acme_Screenshot-2025-05-29-at-14.56.45.png" alt="Screenshot 2025-05-29 at 14.56.45.png"&gt;&lt;/li&gt;&#10;&lt;li&gt;Click Add next to ACME DNS-Authenticators, fill in the API Token generated on step 1 and save. &lt;img src="truenas-add-cert-via-acme_Screenshot-2025-05-29-at-14.57.55.png" alt="Screenshot 2025-05-29 at 14.57.55.png"&gt;&lt;/li&gt;&#10;&lt;li&gt;Add a new Certificate Signing Request (CSR)&lt;/li&gt;&#10;&lt;li&gt;Click the wrench icon next to the new CSR to create the new certificate with ACME.&lt;/li&gt;&#10;&lt;li&gt;Set the GUI SSL Certificate by going to &lt;strong&gt;System &amp;gt; General Settings&lt;/strong&gt; and click &lt;strong&gt;Settings&lt;/strong&gt; in the GUI widget.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="#root/mtH688R3M098" &gt;ProxmoxVE - VM - TrueNAS Scale&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.truenas.com/docs/scale/scaletutorials/credentials/certificates/settingupletsencryptcertificates/" class="external-link" target="_blank" rel="noopener"&gt;TrueNAS ACME Certificate&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>TrueNAS - VM Sizing and Configuration Best Practices</title><link>https://risala.pages.dev/posts/truenas-vm-sizing-and-configuration-best-practices/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/truenas-vm-sizing-and-configuration-best-practices/</guid><description>&lt;h1 id="truenas---vm-sizing-and-configuration-best-practices"&gt;&#10; TrueNAS - VM Sizing and Configuration Best Practices&#10; &lt;a class="heading-link" href="#truenas---vm-sizing-and-configuration-best-practices"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;p&gt;Running TrueNAS (CORE or SCALE) as a virtual machine (VM) in a hypervisor like ProxmoxVE requires careful sizing and configuration to ensure stability, performance, and data integrity. This note outlines key best practices.&lt;/p&gt;&#10;&lt;h2 id="1-memory-ram-allocation"&gt;&#10; 1. Memory (RAM) Allocation&#10; &lt;a class="heading-link" href="#1-memory-ram-allocation"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Minimum:&lt;/strong&gt; TrueNAS CORE officially states 8GB of RAM as a minimum. TrueNAS SCALE also benefits from at least 8GB.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ZFS ARC:&lt;/strong&gt; The most critical consumer of RAM is the ZFS Adaptive Replacement Cache (ARC). A common rule of thumb is &lt;strong&gt;1GB of RAM per 1TB of raw storage capacity&lt;/strong&gt; for optimal ARC performance, though this can vary based on workload. More RAM for ARC generally means better read performance.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Services:&lt;/strong&gt; Account for RAM needed by TrueNAS services (SMB, NFS, iSCSI, Jails, Plugins, Apps, etc.).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Static Allocation:&lt;/strong&gt; &lt;strong&gt;Crucially, assign a static amount of RAM to the TrueNAS VM.&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Disable Memory Ballooning:&lt;/strong&gt; As detailed in &lt;a href="https://risala.pages.dev/posts/proxmoxve-truenas-disable-memory-ballooning/" &gt;ProxmoxVE - TrueNAS VM - Disable Memory Ballooning&lt;/a&gt;, this feature is detrimental to ZFS ARC performance and stability.&lt;/li&gt;&#10;&lt;li&gt;Avoid dynamic memory or memory overcommitment for the TrueNAS VM.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ECC RAM:&lt;/strong&gt; While this applies to the host hardware, if TrueNAS is critical, the host system should ideally use ECC RAM to protect ZFS data integrity from memory errors.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="2-cpu-allocation"&gt;&#10; 2. CPU Allocation&#10; &lt;a class="heading-link" href="#2-cpu-allocation"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Cores:&lt;/strong&gt; A minimum of 2 CPU cores is generally recommended. More cores can be beneficial if running many services, plugins/apps, or handling high network throughput, especially with encryption (e.g., SMB encryption, VPNs).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;CPU Type:&lt;/strong&gt; Modern CPUs with AES-NI support are beneficial if using ZFS encryption or other cryptographic workloads.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Host Passthrough (Optional but Recommended):&lt;/strong&gt; If your hypervisor supports it (like ProxmoxVE's &lt;code&gt;host&lt;/code&gt; CPU type), passing through the host CPU model can provide better performance and access to all CPU features.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Avoid Over-Allocation:&lt;/strong&gt; While ZFS itself isn't always CPU-bound for basic NAS tasks, services running on TrueNAS can be. Monitor CPU usage and avoid excessive over-allocation that could lead to contention on the host.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="3-storage-configuration"&gt;&#10; 3. Storage Configuration&#10; &lt;a class="heading-link" href="#3-storage-configuration"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Disk Passthrough (HBA Passthrough):&lt;/strong&gt; &lt;strong&gt;This is the highly recommended method.&lt;/strong&gt; Pass an entire HBA (Host Bus Adapter) directly to the TrueNAS VM.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Benefits:&lt;/strong&gt; TrueNAS gets direct, unimpeded access to the raw disks. This allows ZFS to manage SMART data, disk health, and perform its functions optimally. It's the most reliable and performant method.&lt;/li&gt;&#10;&lt;li&gt;Requires VT-d/AMD-Vi enabled on the host.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Individual Disk Passthrough (RDM, Virtual Disks):&lt;/strong&gt; If HBA passthrough isn't feasible, passing individual disks as raw device mappings (RDMs) or as virtual disks (e.g., VMDK, qcow2) is an alternative.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Raw Disks (e.g.&lt;/strong&gt; &lt;strong&gt;&lt;code&gt;virtio-scsi&lt;/code&gt;&lt;/strong&gt; &lt;strong&gt;with&lt;/strong&gt; &lt;strong&gt;&lt;code&gt;scsiblock=true&lt;/code&gt;&lt;/strong&gt; &lt;strong&gt;in Proxmox):&lt;/strong&gt; Generally preferred over file-backed virtual disks for performance.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;File-backed Virtual Disks:&lt;/strong&gt; Can work, but may introduce a slight performance overhead and abstract SMART data. If used, ensure they are preallocated/thick-provisioned for better performance and to avoid issues with thin provisioning on the ZFS layer.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Boot Drive:&lt;/strong&gt; The TrueNAS boot drive can be a small virtual disk (e.g., 16-32GB SSD-backed virtual disk is fine). It does not need to be part of the main storage pool HBA passthrough.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ZFS Pool Design:&lt;/strong&gt; Standard ZFS pool design principles (RAIDZ levels, mirroring, vdevs) apply within the VM, regardless of how disks are presented.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="4-network-configuration"&gt;&#10; 4. Network Configuration&#10; &lt;a class="heading-link" href="#4-network-configuration"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Virtual NIC:&lt;/strong&gt; Use a performant virtual network interface, such as &lt;code&gt;virtio&lt;/code&gt; (common in KVM/Proxmox).&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Dedicated Physical NIC (Optional):&lt;/strong&gt; For high-performance needs, consider passing through a dedicated physical NIC to the TrueNAS VM, or using SR-IOV if available.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Jumbo Frames:&lt;/strong&gt; If your physical network supports it and you need maximum throughput for large file transfers, configure jumbo frames (MTU 9000) consistently across the TrueNAS VM, hypervisor, physical switches, and clients.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="5-hypervisor-specific-settings-example-proxmoxve"&gt;&#10; 5. Hypervisor-Specific Settings (Example: ProxmoxVE)&#10; &lt;a class="heading-link" href="#5-hypervisor-specific-settings-example-proxmoxve"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;BIOS:&lt;/strong&gt; OVMF (UEFI) is generally recommended for modern OSes like TrueNAS.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Machine Type:&lt;/strong&gt; &lt;code&gt;q35&lt;/code&gt; is a common modern choice.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;SCSI Controller:&lt;/strong&gt; For virtual disks or passthrough disks not on a dedicated HBA, &lt;code&gt;VirtIO SCSI single&lt;/code&gt; (with &lt;code&gt;iothread=1&lt;/code&gt; enabled on the disk) can offer good performance.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;QEMU Guest Agent:&lt;/strong&gt; Install and enable the QEMU guest agent in the TrueNAS VM for better integration with the hypervisor (e.g., clean shutdowns, IP address reporting).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="6-backup-and-snapshots"&gt;&#10; 6. Backup and Snapshots&#10; &lt;a class="heading-link" href="#6-backup-and-snapshots"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Hypervisor Snapshots vs. ZFS Snapshots:&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ZFS Snapshots:&lt;/strong&gt; Use ZFS's native snapshot capabilities within TrueNAS for your data pools. These are efficient and application-consistent for ZFS.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Hypervisor Snapshots:&lt;/strong&gt; Be cautious with hypervisor-level snapshots of a running TrueNAS VM, especially if it's actively performing I/O. While often safe, there's a small risk of issues if the snapshot doesn't perfectly capture in-flight I/O. If used, ensure the QEMU guest agent is running to help quiesce the filesystem. For the data pools themselves, ZFS snapshots are superior.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Backups:&lt;/strong&gt; Plan a robust backup strategy for your TrueNAS data, independent of hypervisor snapshots (e.g., ZFS replication to another TrueNAS instance or a cloud provider).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/proxmoxve-truenas-disable-memory-ballooning/" &gt;ProxmoxVE - TrueNAS VM - Disable Memory Ballooning&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/zfs-adaptive-replacement-cache-explained/" &gt;ZFS - Adaptive Replacement Cache (ARC) Explained&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/proxmoxve-vm-performance-tuning/" &gt;ProxmoxVE - VM Performance Tuning&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>UniFi - Adopt a disconnected device</title><link>https://risala.pages.dev/posts/unifi-adopt-disconnected-device/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/unifi-adopt-disconnected-device/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;A device is shown offline even though it was adopted in the past. This has happened to me when I changed the IP of the UniFi Network Controller.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;SSH into the USG device and run the following command&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;set-inform http://192.168.50.11:8080/inform&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h3 id="adoption-failed-and-the-device-is-still-disconnected"&gt;&#10; Adoption failed, and the device is still disconnected&#10; &lt;a class="heading-link" href="#adoption-failed-and-the-device-is-still-disconnected"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h3&gt;&#10;&lt;p&gt;You should try to &lt;a href="https://risala.pages.dev/posts/unifi-reset-device/" &gt;UniFi - Reset Device&lt;/a&gt;, and then re-adopt the device from the UI.&lt;/p&gt;</description></item><item><title>UniFi - Device Adoption</title><link>https://risala.pages.dev/posts/unifi-device-adoption/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/unifi-device-adoption/</guid><description>&lt;h2 id="introduction"&gt;&#10; Introduction&#10; &lt;a class="heading-link" href="#introduction"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Adoption is the process of connecting a device to the UniFi application that will manage it. All UniFi Access Points (APs), cameras, phones, and other devices (excluding consoles) are designed to make the adoption process as simple as possible.&lt;/p&gt;&#10;&lt;h2 id="how-to-adopt-a-device"&gt;&#10; How to Adopt a Device&#10; &lt;a class="heading-link" href="#how-to-adopt-a-device"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;If you have not yet done so, &lt;a href="https://help.ui.com/hc/en-us/articles/4416276882327" class="external-link" target="_blank" rel="noopener"&gt;set up UniFi&lt;/a&gt;. We recommend a &lt;a href="https://ui.com/consoles" class="external-link" target="_blank" rel="noopener"&gt;UniFi Cloud Gateway&lt;/a&gt; for the simplest, most streamlined experience.&lt;/li&gt;&#10;&lt;li&gt;Connect the UniFi device to a PoE power source on the same network as the UniFi Console. &lt;/li&gt;&#10;&lt;li&gt;Sign in to the &lt;a href="http://unifi.ui.com/" class="external-link" target="_blank" rel="noopener"&gt;UniFi Site Manager&lt;/a&gt; in a web browser, or use the UniFi Mobile App (&lt;a href="https://apps.apple.com/us/app/unifi-network/id1057750338" class="external-link" target="_blank" rel="noopener"&gt;iOS&lt;/a&gt; / &lt;a href="https://play.google.com/store/apps/details?id=com.ubnt.easyunifi&amp;amp;hl=en_US&amp;amp;gl=US" class="external-link" target="_blank" rel="noopener"&gt;Android&lt;/a&gt;) to adopt the device.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="adoption-troubleshooting"&gt;&#10; Adoption Troubleshooting&#10; &lt;a class="heading-link" href="#adoption-troubleshooting"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;If you are having trouble adopting a UniFi device, follow the relevant steps below.&lt;/p&gt;</description></item><item><title>UniFI - Get Current Value of set-inform</title><link>https://risala.pages.dev/posts/unifi-get-current-values-of-set-inform/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/unifi-get-current-values-of-set-inform/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need to get the current value of set-inform on my USG.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;SSH Into USG and run the command&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;info&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;p&gt;and look for the line &lt;code&gt;Status&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;Example&lt;/p&gt;&#10;&lt;pre&gt;&lt;code&gt;admin@ubnt:~$ info&#10;&#10;Model: UniFi-Gateway-4&#10;Version: 4.4.57.5578372&#10;MAC Address: 74:83:c2:1f:10:4d&#10;IP Address: 73.220.150.111&#10;Hostname: ubnt&#10;Uptime: 179455 seconds&#10;&#10;Status: Unknown[11] (http://192.168.50.11:8080/inform)&#10;&lt;/code&gt;&lt;/pre&gt;&#10;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/unifi-adopt-disconnected-device/" &gt;UniFi - Adopt a disconnected device&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/unifi-reset-device/" &gt;UniFi - Reset Device&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>UniFi - Remote Adoption (Layer 3)</title><link>https://risala.pages.dev/posts/unifi-remote-adoption-layer-3/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/unifi-remote-adoption-layer-3/</guid><description>&lt;h2 id="introduction"&gt;&#10; Introduction&#10; &lt;a class="heading-link" href="#introduction"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Layer 3 adoption is the process of adopting a UniFi device to a remote or cloud-hosted UniFi Network Application. This is only recommended for advanced users, or those adopting devices when using Official UniFi Hosting.&lt;/p&gt;&#10;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; Refer to&lt;/em&gt; &lt;a href="https://risala.pages.dev/posts/unifi-device-adoption/" &gt;UniFi - Device Adoption&lt;/a&gt; &lt;em&gt;if you are unsure whether you require remote adoption.&lt;/em&gt;&lt;/p&gt;&#10;&lt;h2 id="requirements"&gt;&#10; Requirements&#10; &lt;a class="heading-link" href="#requirements"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The UniFi device and the UniFi Network Application must have unrestricted connectivity over TCP Port 8080.&lt;/p&gt;</description></item><item><title>UniFi - Reset Device</title><link>https://risala.pages.dev/posts/unifi-reset-device/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/unifi-reset-device/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I need to reset a UniFi device, maybe it's failing adoption or it became unresponsive.&lt;/p&gt;&#10;&lt;h2 id="solution"&gt;&#10; Solution&#10; &lt;a class="heading-link" href="#solution"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;SSH into the UniFi Device and type in &lt;code&gt;set-default&lt;/code&gt;&lt;/p&gt;&#10;&lt;div class="notice info"&gt;&#10; &lt;div class="notice-title"&gt;&#10; &lt;i class="fa-solid fa-exclamation-circle" aria-hidden="true"&gt;&lt;/i&gt;Important&#10; &lt;/div&gt;&#10; &lt;div class="notice-content"&gt;&lt;p&gt;Running &lt;code&gt;set-default&lt;/code&gt; &lt;strong&gt;immediately reset the device&lt;/strong&gt; and restarts it. It &lt;strong&gt;does not ask for confirmation&lt;/strong&gt;.&lt;/p&gt;&lt;/div&gt;&#10;&lt;/div&gt;&lt;h2 id="related"&gt;&#10; Related&#10; &lt;a class="heading-link" href="#related"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://risala.pages.dev/posts/unifi-adopt-disconnected-device/" &gt;UniFi - Adopt a disconnected device&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="#root/88by0rAa9rWp" &gt;Everything UniFi&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>UniFi - Troubleshooting - Failed to save network</title><link>https://risala.pages.dev/posts/unifi-failed-to-save-network/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/unifi-failed-to-save-network/</guid><description>&lt;h2 id="problem"&gt;&#10; Problem&#10; &lt;a class="heading-link" href="#problem"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;I was trying to make a change to one of the Networks from the UniFi Controller, and I was unable to save the settings due to the following error:&lt;/p&gt;&#10;&lt;p&gt;&lt;img src="unifi-failed-to-save-network_Screenshot-2025-05-25-at-00.03.59.png" alt="Screenshot 2025-05-25 at 00.03.59.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;I managed to grabbed the response from the Developer Tools, Network tab:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;meta&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;rc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;api.err.InvalidPayload&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;data&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;validationError&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;field&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;wan_gateway&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;pattern&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;rc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;api.err.InvalidValue&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It seems the issue is in the &lt;code&gt;wan_gateway&lt;/code&gt; is not valid, and sure enough looking at the payload request (trimmed to relevant part), it's empty:&lt;/p&gt;</description></item><item><title>ZFS - Adaptive Replacement Cache (ARC) Explained</title><link>https://risala.pages.dev/posts/zfs-adaptive-replacement-cache-explained/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/zfs-adaptive-replacement-cache-explained/</guid><description>&lt;h1 id="zfs---adaptive-replacement-cache-arc-explained"&gt;&#10; ZFS - Adaptive Replacement Cache (ARC) Explained&#10; &lt;a class="heading-link" href="#zfs---adaptive-replacement-cache-arc-explained"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h1&gt;&#10;&lt;p&gt;The &lt;strong&gt;Adaptive Replacement Cache (ARC)&lt;/strong&gt; is a core component of the ZFS filesystem and is critical to its performance. It's an advanced caching mechanism that resides in the system's RAM and is designed to store frequently and recently accessed data from the ZFS storage pool.&lt;/p&gt;&#10;&lt;h2 id="purpose-of-arc"&gt;&#10; Purpose of ARC&#10; &lt;a class="heading-link" href="#purpose-of-arc"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;The primary purpose of the ARC is to &lt;strong&gt;reduce disk I/O operations&lt;/strong&gt; by serving read requests directly from RAM whenever possible. Accessing data from RAM is orders of magnitude faster than accessing it from disk (even SSDs), leading to significant improvements in read performance for workloads that benefit from caching.&lt;/p&gt;</description></item><item><title>🧠 Analysis: Etcd Consensus in a Hybrid Optane/SATA Cluster</title><link>https://risala.pages.dev/posts/analysis-etcd-consensus-in-hybrid-storage-speed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://risala.pages.dev/posts/analysis-etcd-consensus-in-hybrid-storage-speed/</guid><description>&lt;p&gt;Architecture:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;Node 1 (CP1):&lt;/strong&gt; Intel Optane (Ultra-Low Latency ~10µs)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;Node 2 (CP2):&lt;/strong&gt; Intel Optane (Ultra-Low Latency ~10µs)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;Node 3 (CP3):&lt;/strong&gt; SATA SSD &lt;code&gt;rpool&lt;/code&gt; (Variable Latency 10ms - 500ms+)&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="1-the-physics-of-consensus-speed"&gt;&#10; 1. The Physics of Consensus (Speed)&#10; &lt;a class="heading-link" href="#1-the-physics-of-consensus-speed"&gt;&#10; &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"&gt;&lt;/i&gt;&#10; &lt;span class="sr-only"&gt;Link to heading&lt;/span&gt;&#10; &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;p&gt;Etcd uses the Raft Consensus Algorithm. For a cluster of size $N=3$, the Quorum (votes required to commit data) is calculated as:&lt;/p&gt;&#10;&lt;p&gt;\(\text{Quorum} = \lfloor \frac{3}{2} \rfloor + 1 = 2\)&lt;/p&gt;</description></item></channel></rss>