<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>arthofer.sh</title>
    <link>http://arthofer.sh/</link>
    <description>Recent content on arthofer.sh</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 17 Jan 2025 19:09:00 +0200</lastBuildDate><atom:link href="http://arthofer.sh/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Easy Is Not Simple</title>
      <link>http://arthofer.sh/posts/2025-01-17-easy-is-no-simple/</link>
      <pubDate>Fri, 17 Jan 2025 19:09:00 +0200</pubDate>
      
      <guid>http://arthofer.sh/posts/2025-01-17-easy-is-no-simple/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m faced with a lot of what is hip and bleeding-edge in IT in my professional work
every day. And for some time now, i had this weird, subtle feeling that something is &amp;ldquo;off&amp;rdquo;.
Things are supposed to be easy to work with and get a lot of shit done. But it doesn&amp;rsquo;t feel
like it. All those supposed easy interfaces to get stuff done are putting a ton of mental
load on you, even for tasks which should be very simple. And when something goes sideways
there are suddenly a lot of flaming hoops to jump through to actually get to the point of
debugging something.&lt;/p&gt;
&lt;p&gt;And recently i realized my problem with all of this: none of those tools are simple anymore.&lt;/p&gt;
&lt;p&gt;The tech stack which is required to run a stupid &amp;ldquo;hello world&amp;rdquo; on a given Kubernetes cluster
is just gigantic. The amount of moving parts involved here are is staggering. And Kubernetes
is just an example. It is the same nearly everywhere. On the way to &amp;ldquo;ease of use&amp;rdquo;, things
have become unbelievably complicated under the hood. Another classic example is systemd
on my beloved Linux. While i do understand some of the initial motives, it has grown into
a gigantic pile of interwoven moving parts which are hard to really understand well. Sure,
some things might be easier to do with it, but it definitly isn&amp;rsquo;t as simple as oldschool
rc-scripts. Those have their problems, but they&amp;rsquo;re easier to understand.&lt;/p&gt;
&lt;p&gt;There is (supposedly) easy to use. And there is easy to understand. I mean really
understand how a given thing works. This is only possible if something is relatively
simple.&lt;/p&gt;
&lt;p&gt;Simplicity is hard to achieve. It is way easier to just throw stuff together until it
kinda works in some way. But what is lost with that approach is actually understanding
what the fuck is happening. Things become unmaintenable very fast. And this is not only
a problem in IT. It is everywhere in this modern, &amp;ldquo;civilized&amp;rdquo; world we live in.&lt;/p&gt;
&lt;p&gt;Can it be nice to stream music over the internet on your phone while it&amp;rsquo;s connected
to your cars stereo via Bluetooth? Sure. Until you drive briefly through a narrow valley.
Or the streaming app crashes/malfunctions for whatever reason. Or Bluetooth is acting
up.
Putting some kind of physical media (tape, CD, Minidisc&amp;hellip;) into a dedicated device
has always worked more reliably for me. And i don&amp;rsquo;t have to fucking re-pair the thing
or wait a minute until it decides to maybe finally connect. Put the media in, it
gets played.
It&amp;rsquo;s simpler.&lt;/p&gt;
&lt;p&gt;Or modern roadbikes. They tend to come with fully electronic shifting nowadays,
most even wireless. It shifts very precise and very fast, which is great. Until
you forget to charge the battery.
One of the great things about bikes in general is, that they&amp;rsquo;re very simple machines.
I honestly don&amp;rsquo;t understand why it is necessary to introduce complexity here.
Cable-based shifting might need a tiny bit of maintenance from time to time. But
it is very simple and probably everybody can do it themself.&lt;/p&gt;
&lt;p&gt;This topic is bothering me for a while now and i&amp;rsquo;ll continue to spend time to think and research
about this in general.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Thanks for Ruining the Internet</title>
      <link>http://arthofer.sh/posts/2024-07-13-thanks-for-ruining-the-internet/</link>
      <pubDate>Sat, 13 Jul 2024 19:25:58 +0200</pubDate>
      
      <guid>http://arthofer.sh/posts/2024-07-13-thanks-for-ruining-the-internet/</guid>
      <description>&lt;p&gt;I admit I&amp;rsquo;m guilty.
I had a Facebook account once. But i deleted that one years ago.
I had an Instagram account once. also deleted that one years ago.
I had a Twitter account once, deleted it once the crazy, spoiled idiot took over.
I had a Reddit account once, deleted it when they went &lt;a href=&#34;https://en.wikipedia.org/wiki/2023_Reddit_API_controversy&#34;&gt;full-moron&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;the-shit-shows&#34;&gt;The Shit shows&lt;/h1&gt;
&lt;h2 id=&#34;facebook&#34;&gt;Facebook&lt;/h2&gt;
&lt;p&gt;I joined it after some &amp;ldquo;social pressure&amp;rdquo; after resisting for a while. It was kinda fun in the
beginning, but commercialization made it worse and worse rather fast. At some point i stopped
attending and didn&amp;rsquo;t even silently check on it anymore. A bit after that i deleted the account.
Nothing of value was lost.&lt;/p&gt;
&lt;h2 id=&#34;instagram&#34;&gt;Instagram&lt;/h2&gt;
&lt;p&gt;Joined out of curiosity and because I&amp;rsquo;m into photography and wanted to share some pictures.
Also was a bit of fun in the beginning, but at some point i noticed that i started to think
idiotic thoughts like &amp;ldquo;if i post this, it could get some likes&amp;rdquo;. Which disgusted me.
I&amp;rsquo;m not some influencer marketing slave zombie.
A while after that i deleted my account and nothing of value was lost here as well.&lt;/p&gt;
&lt;h2 id=&#34;twitter&#34;&gt;Twitter&lt;/h2&gt;
&lt;p&gt;Had my first account on there rather in the beginning. It was fun. Lots of weird people from
all over the world. Was nice to just blast out some random thoughts and sometimes getting a
response on it from somebody. But i somehow got bored with it after a while and deleted the
account.
A few years ago i created an account there again. I think i wanted to follow some specific
people and also stay up to date and &amp;ldquo;in the game&amp;rdquo; with what this IT business madness is.
Actually connected with a small handful of local people there, which lead to attending a
few very relaxed meetups with fellow nerdy people. Also gave some talks there.
Rest in peace &amp;ldquo;Infrastructure as a Meetup&amp;rdquo;-meetup, you were a good one (more on that maybe in
another post).
Overall it was sometimes fun, but not as much as in ye olde days. Already thought a while about
getting rid of the account and thanks to The Idiot taking over, the decision was very easy in the
end.&lt;/p&gt;
&lt;h2 id=&#34;reddit&#34;&gt;Reddit&lt;/h2&gt;
&lt;p&gt;Created my account there quite some while ago. When the &amp;ldquo;old&amp;rdquo; layout was still the only one.
It was really fun for a long while. Having all those niche communities in one place made it
very easy to discover new things.
But in the end the turbo capitalists once more took over and shat into everyone&amp;rsquo;s soup.
When they decided to basically block alternatives clients the fun was gone for me. I let the
account alive for a little longer, but once they announced to feed all the Reddit content into
some Artificial Imbecile i deleted it instantly.
A little bit of value was lost for me, but nothing serious.&lt;/p&gt;
&lt;h1 id=&#34;back-to-the-basics&#34;&gt;Back to the basics&lt;/h1&gt;
&lt;p&gt;All of this threw me back into the corners of the internet where i actually feel comfy.
Mastodon is a so much nicer place to be than Twitter every was.
Lemmy, while still rather small and missing some of the communities i liked on Reddit, is also
so much better.
Being on a platform that has not been created with the main goal of earning money with it really
makes a gigantic difference. The instances are all just run by some random people for the fun
of it. They sometimes ask for a little donation to keep the lights on, but that is obviously
more than OK. I&amp;rsquo;m thankful that somebody is running the instances I&amp;rsquo;m on. Keeping stuff updated
and online can be challenging, so it is really OK to ask to at least share the bill.
It is very nice to be back in the weirder internet. Where people exchange knowledge because
they&amp;rsquo;re interested in a topic. Where people actively mix computer stuff with occultism. Where
i don&amp;rsquo;t have the feeling every second person is trying to sell me something.&lt;/p&gt;
&lt;p&gt;So i guess i have to say &amp;ldquo;Thank you!&amp;rdquo; to all the nasty, idiotic, greedy tech bros for ruining
the commercial social media platforms. This drove me back into the waters where i belong.
Also probably a &amp;ldquo;Thank you!&amp;rdquo; for actively fucking up the rest of the internet. It keeps doing
things like we did 20 years ago interesting and actually makes it necessary.&lt;/p&gt;
&lt;p&gt;I really like the basic idea of the internet, but we must drive out the money.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Nested Maps in Go</title>
      <link>http://arthofer.sh/posts/2022-04-22-go-nested-maps/</link>
      <pubDate>Fri, 22 Apr 2022 20:00:15 +0200</pubDate>
      
      <guid>http://arthofer.sh/posts/2022-04-22-go-nested-maps/</guid>
      <description>&lt;p&gt;I recently had to use a bunch of nested maps in Go and struggled way too long to get them &amp;ldquo;working&amp;rdquo;.
And obviously there wasn&amp;rsquo;t a lot of good information to be found via $popular_search_engine. So i thought
this might make a good blog post.&lt;/p&gt;
&lt;p&gt;What gave me the proper nudge in the correct direction of thinking correctly was a Google Groups posting
from 2012: &lt;a href=&#34;https://groups.google.com/g/golang-nuts/c/PoRkoN84KKU/m/7330L9NulHQJ&#34;&gt;https://groups.google.com/g/golang-nuts/c/PoRkoN84KKU/m/7330L9NulHQJ&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;You need to actually initialize every inner map seperatly if you want to use it!
For more details you should read the rest ;-)&lt;/p&gt;
&lt;h2 id=&#34;a-simple-example-and-the-attempt-of-an-explaination&#34;&gt;A simple example and the attempt of an explaination&lt;/h2&gt;
&lt;p&gt;Lets create a simple example to demonstrate the issue at hand:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ go mod init nested_maps
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go: creating new go.mod: module nested_maps
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ touch nested_maps.go
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now open &lt;code&gt;nested_maps.go&lt;/code&gt; in your favorite editor and paste in the following piece of code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;encoding/json&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;people&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;Name&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;Age&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;groups&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;Groups&lt;/span&gt; []&lt;span style=&#34;color:#a6e22e&#34;&gt;people&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt; = []byte(&lt;span style=&#34;color:#e6db74&#34;&gt;`{&amp;#34;Groups&amp;#34;:[
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		{&amp;#34;Group&amp;#34;: &amp;#34;first&amp;#34;, &amp;#34;Name&amp;#34;: &amp;#34;Stanislaus&amp;#34;, &amp;#34;Age&amp;#34;: &amp;#34;23&amp;#34;},
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		{&amp;#34;Group&amp;#34;: &amp;#34;second&amp;#34;, &amp;#34;Name&amp;#34;: &amp;#34;Mechthild&amp;#34;, &amp;#34;Age&amp;#34;: &amp;#34;13&amp;#34;},
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		{&amp;#34;Group&amp;#34;: &amp;#34;third&amp;#34;,    &amp;#34;Name&amp;#34;: &amp;#34;Gunhilde&amp;#34;, &amp;#34;Age&amp;#34;: &amp;#34;42&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	]}`&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peopleA&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;groups&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;json&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Unmarshal&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;peopleA&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Fatal&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// here we assume at first that we create our nested map
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; make(&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peopleA&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Groups&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;][&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Name&lt;/span&gt;] = &lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Age&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What we try to do here:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; make(&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peopleA&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Groups&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;][&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Name&lt;/span&gt;] = &lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Age&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;is to put a JSON array, where each array element contains three key-value pairs that
define a group name, the persons name and their age, into a nested map. The intention
for this might be that we think processing the data via a nested map is nice. Or whatever.&lt;/p&gt;
&lt;p&gt;While this compiles perfectly fine, running the created binary will result in this runtime error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./nested_maps
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;panic: assignment to entry in nil map
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;goroutine &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;running&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;main.main&lt;span style=&#34;color:#f92672&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	/home/flart/temp/nested_maps/nested_maps.go:34 +0x1e8
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My n00bish reaction at first was &amp;ldquo;WTF? I created the map with &lt;code&gt;make()&lt;/code&gt;. It&amp;rsquo;s not nil!&amp;rdquo;
But obviously i was terribly wrong.&lt;/p&gt;
&lt;p&gt;What happens here is that Go creates the outer map but nothing else.
And this makes perfect sense since it can&amp;rsquo;t possibly know how many inner maps we might
want later on. It&amp;rsquo;s our job to take care of that.&lt;/p&gt;
&lt;p&gt;A solution for that is extending our &lt;code&gt;for&lt;/code&gt; loop like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// here&amp;#39;s our nested map
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; make(&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peopleA&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Groups&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;// here we check if the inner map exists
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;ok&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; !&lt;span style=&#34;color:#a6e22e&#34;&gt;ok&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#75715e&#34;&gt;// if the inner map doesn&amp;#39;t exist, we create it with make()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;] = make(&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;// now we can safely fill up the nested map
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;][&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Name&lt;/span&gt;] = &lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Age&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The comments hopefully speak for themselves, but anyways:
What we added is a simple check if the inner map to which we want write data already exists.
This is done with a simple map lookup, which in Go returns not only the potential value
but also a boolean value on which we can do a simple check with &lt;code&gt;if&lt;/code&gt;. So if we get a &lt;code&gt;false&lt;/code&gt;
back, we just create the inner map with a &lt;code&gt;make()&lt;/code&gt; and all is good.&lt;/p&gt;
&lt;p&gt;Here is the full example which executes without a runtime error:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;encoding/json&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;people&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;Name&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;Age&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;groups&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;Groups&lt;/span&gt; []&lt;span style=&#34;color:#a6e22e&#34;&gt;people&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt; = []byte(&lt;span style=&#34;color:#e6db74&#34;&gt;`{&amp;#34;Groups&amp;#34;:[
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		{&amp;#34;Group&amp;#34;: &amp;#34;first&amp;#34;, &amp;#34;Name&amp;#34;: &amp;#34;Stanislaus&amp;#34;, &amp;#34;Age&amp;#34;: &amp;#34;23&amp;#34;},
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		{&amp;#34;Group&amp;#34;: &amp;#34;second&amp;#34;, &amp;#34;Name&amp;#34;: &amp;#34;Mechthild&amp;#34;, &amp;#34;Age&amp;#34;: &amp;#34;13&amp;#34;},
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;		{&amp;#34;Group&amp;#34;: &amp;#34;third&amp;#34;,    &amp;#34;Name&amp;#34;: &amp;#34;Gunhilde&amp;#34;, &amp;#34;Age&amp;#34;: &amp;#34;42&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;	]}`&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peopleA&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;groups&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;json&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Unmarshal&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;a&lt;/span&gt;, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;peopleA&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;!=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;log&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Fatal&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// here&amp;#39;s our nested map
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; make(&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;range&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;peopleA&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Groups&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;// here we check if the inner map exists
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;ok&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; !&lt;span style=&#34;color:#a6e22e&#34;&gt;ok&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;			&lt;span style=&#34;color:#75715e&#34;&gt;// if the inner map doesn&amp;#39;t exist, we create it with make()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;			&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;] = make(&lt;span style=&#34;color:#66d9ef&#34;&gt;map&lt;/span&gt;[&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;]&lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;// now we can safely fill up the nested map
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;jsonData&lt;/span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Group&lt;/span&gt;][&lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Name&lt;/span&gt;] = &lt;span style=&#34;color:#a6e22e&#34;&gt;v&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Age&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hope this helps somebody else at some point in the future :-)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>TIL Memory Fragmentation</title>
      <link>http://arthofer.sh/posts/2020-08-22-til-memory-fragmentation/</link>
      <pubDate>Sat, 22 Aug 2020 21:10:37 +0200</pubDate>
      
      <guid>http://arthofer.sh/posts/2020-08-22-til-memory-fragmentation/</guid>
      <description>&lt;p&gt;I was recently sent down a very nice rabbit hole of low-level operating system knowledge,
which i would like to share here.&lt;/p&gt;
&lt;h1 id=&#34;what-the-hell-is-happening&#34;&gt;What the hell is happening?&lt;/h1&gt;
&lt;p&gt;We&amp;rsquo;re using &lt;a href=&#34;https://concourse-ci.org&#34;&gt;Concourse&lt;/a&gt; as the main driver for pretty much all of our
deployment automations in our team at my job.
During some time frame in the end of 2019 and the beginning of 2020, we sometimes encountered
rather strange errors in pipeline jobs, which then caused those jobs to fail. The pattern was
always looking something like&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;iptables: vmalloc: allocation failure, allocated 0 of XXXX bytes
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where the number at XXX was always different. But it was never something gigantic and the worker
node where the job was running, definitely had enough memory available in total at this point in
time, to serve that allocation request from iptables. And usually, the next run of that job went
through just fine.
So this was all very confusing and strange in the beginning.&lt;/p&gt;
&lt;h1 id=&#34;lets-ask-the-internet&#34;&gt;Lets ask the internet&lt;/h1&gt;
&lt;p&gt;As it is common nowadays, we just put the error message from above into $search_engine and
discovered, that we&amp;rsquo;re not the only ones with that problem. Somebody already opened and issue
on the GitHub project of Concourse: &lt;a href=&#34;https://github.com/concourse/concourse/issues/3127&#34;&gt;https://github.com/concourse/concourse/issues/3127&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As @circosta pointed out at &lt;a href=&#34;https://github.com/concourse/concourse/issues/3127#issuecomment-484895481&#34;&gt;https://github.com/concourse/concourse/issues/3127#issuecomment-484895481&lt;/a&gt;, this all seems to be caused by a bug in iptables:
&lt;a href=&#34;https://bugzilla.kernel.org/show_bug.cgi?id=200651&#34;&gt;https://bugzilla.kernel.org/show_bug.cgi?id=200651&lt;/a&gt;
Basically, there was (at least for some time) a very restrictive flag set, when requesting memory
via kmalloc (search for GFD_NORETRY on &lt;a href=&#34;https://www.kernel.org/doc/htmldocs/kernel-api/API-kmalloc.html)&#34;&gt;https://www.kernel.org/doc/htmldocs/kernel-api/API-kmalloc.html)&lt;/a&gt;, which caused iptables to fail hard instantly. This was then fixed, as i understood it,
by changing the flag to a bit less restrictive one.&lt;/p&gt;
&lt;p&gt;OK, so memory was short and iptables decided to fail because it couldn&amp;rsquo;t get the amount it
wanted.
But wait&amp;hellip; our monitoring did not show that the worker node was &lt;em&gt;this&lt;/em&gt; much under memory
pressure, that it couldn&amp;rsquo;t satisfy the request in question.
Well, at this point in time, there was no good explanation for me. But we accepted that it&amp;rsquo;s
basically a kernel bug, that was fixed in a later version. So we made sure our workers where
running on a recent enough kernel version and where happy that those cryptic iptables errors
disappeared. And i shoved all of this on some area in the backside of my brain.&lt;/p&gt;
&lt;h1 id=&#34;aaaand-down-the-rabbit-hole&#34;&gt;&amp;hellip;aaaand down the rabbit hole&lt;/h1&gt;
&lt;p&gt;Back then, i subscribed to the GitHub issue. Because i was majorly annoyed by the problem and i
also have a weakness for such low-level issues :-)
And recently i got an e-mail that somebody posted a new comment there:
&lt;a href=&#34;https://github.com/concourse/concourse/issues/3127#issuecomment-663520233&#34;&gt;https://github.com/concourse/concourse/issues/3127#issuecomment-663520233&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As @blairboy362 stated, this all seems to be a memory fragmentation problem. There was potentially
enough total memory available on the host, but no big enough continuous chunk.&lt;/p&gt;
&lt;p&gt;The mentioning of &lt;code&gt;/proc/buddyinfo&lt;/code&gt; was the first step of this fall into the rabbit hole.
Because i didn&amp;rsquo;t know it existed up until that moment.
If you run &lt;code&gt;cat&lt;/code&gt; on it, you&amp;rsquo;ll get a result that will look somehow like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cat /proc/buddyinfo
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Node 0, zone      DMA      &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Node 0, zone    DMA32      &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;7&lt;/span&gt;     &lt;span style=&#34;color:#ae81ff&#34;&gt;13&lt;/span&gt;     &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;9&lt;/span&gt;     &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;      &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;    &lt;span style=&#34;color:#ae81ff&#34;&gt;419&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Node 0, zone   Normal   &lt;span style=&#34;color:#ae81ff&#34;&gt;1795&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;19012&lt;/span&gt;  &lt;span style=&#34;color:#ae81ff&#34;&gt;11279&lt;/span&gt;   &lt;span style=&#34;color:#ae81ff&#34;&gt;6581&lt;/span&gt;   &lt;span style=&#34;color:#ae81ff&#34;&gt;5116&lt;/span&gt;   &lt;span style=&#34;color:#ae81ff&#34;&gt;2335&lt;/span&gt;   &lt;span style=&#34;color:#ae81ff&#34;&gt;1008&lt;/span&gt;    &lt;span style=&#34;color:#ae81ff&#34;&gt;416&lt;/span&gt;    &lt;span style=&#34;color:#ae81ff&#34;&gt;136&lt;/span&gt;     &lt;span style=&#34;color:#ae81ff&#34;&gt;62&lt;/span&gt;   &lt;span style=&#34;color:#ae81ff&#34;&gt;5294&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip;OK, what the fuck am i looking at?
I did a quick search for &lt;code&gt;/proc/buddyinfo&lt;/code&gt; in the interwebs, and stumbled upon this very nice explanation:
&lt;a href=&#34;https://www.uninformativ.de/blog/postings/2017-12-23/0/POSTING-en.html&#34;&gt;https://www.uninformativ.de/blog/postings/2017-12-23/0/POSTING-en.html&lt;/a&gt;
tl;dr:
&lt;code&gt;/proc/buddyinfo&lt;/code&gt; gives you information how fragmented your memory is.
The Linux kernel allocates memory in chunks of 4KB, called pages.
Each column shows how many units of pages of different sizes are available. The leftmost column being
basic 4KB pages, the next column being 4^2KB pages&amp;hellip;.and so on. Meaning the last column shows the
largest available continuous chunks of memory the kernel can allocate.
Low or even none available blocks of memory on the right side are bad, indicating very fragmented RAM,
which lead to failing larger allocation requests. Like with &lt;code&gt;iptables&lt;/code&gt; in Concourse in the example above.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s pretty logical that memory can get fragmented, but i honestly never gave it a thought before. And
i didn&amp;rsquo;t know i could check something in &lt;code&gt;/proc&lt;/code&gt; for information about the state of fragmentation.
Definitly makes sense to keep an eye on weird issues, because you most likely learn something new :-)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>WTF is a Container?</title>
      <link>http://arthofer.sh/posts/2020-07-07-wtf-is-a-container/</link>
      <pubDate>Tue, 07 Jul 2020 19:22:36 +0200</pubDate>
      
      <guid>http://arthofer.sh/posts/2020-07-07-wtf-is-a-container/</guid>
      <description>&lt;p&gt;Nowadays (and for quite some while now) everything seems to be somehow related to &amp;ldquo;containers&amp;rdquo;.
Astonishingly, not a lot of people really know what a container actually is.&lt;/p&gt;
&lt;p&gt;And it&amp;rsquo;s quite hard to find good technical information about this on the internet. Because if you search
for it, you&amp;rsquo;ll find a shitload of crappy medium.com postings from some neighborhood startups, which
are all talking about Docker and Kubernetes. But nobody explaining the underlying tech layer that
makes all of this possible.
Funnily, some of the most valuable information is in some man pages which you most likely have on
your Linux machine.&lt;/p&gt;
&lt;h2 id=&#34;wrong&#34;&gt;Wrong&lt;/h2&gt;
&lt;p&gt;Most people seem to think that Docker images are containers, but this is wrong.
A Docker image is just a compressed layered file system and some meta data, which can be used to
spawn a container with.&lt;/p&gt;
&lt;p&gt;Also, Kubernetes pods are not containers. They consist of at least one container, but there can be
multiple bundled together in a pod. I&amp;rsquo;ll try to write something about that in the future.&lt;/p&gt;
&lt;p&gt;And containers are not &amp;ldquo;some kind of virtualization&amp;rdquo;, it&amp;rsquo;s process- and resource isolation.&lt;/p&gt;
&lt;h2 id=&#34;so-what-does-this-mean&#34;&gt;So what does this mean?&lt;/h2&gt;
&lt;p&gt;What everybody is calling a container, is actually just using a bunch of Linux kernel features
to isolate a process (or more) from the rest of the system. Usually it also gets some resources
like networking, disks and CPU shares assigned.&lt;/p&gt;
&lt;p&gt;The two kernel features that enable this are &lt;em&gt;namespaces&lt;/em&gt; and &lt;em&gt;cgroups&lt;/em&gt;.
Where namespaces define what a process can &amp;ldquo;see&amp;rdquo; and cgroups (short for &amp;ldquo;control groups&amp;rdquo;) define
what a process is allowed to utilize.&lt;/p&gt;
&lt;p&gt;There are currently namespaces for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cgroups&lt;/li&gt;
&lt;li&gt;IPC&lt;/li&gt;
&lt;li&gt;network&lt;/li&gt;
&lt;li&gt;mounts&lt;/li&gt;
&lt;li&gt;PID&lt;/li&gt;
&lt;li&gt;time&lt;/li&gt;
&lt;li&gt;users&lt;/li&gt;
&lt;li&gt;UTS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And cgroups for basically any resource a process would want to use.&lt;/p&gt;
&lt;h2 id=&#34;i-want-more-information&#34;&gt;I want more information!&lt;/h2&gt;
&lt;p&gt;Some people were already very nice and wrote a lot of information in man pages. So i will not copy
that content onto my site to look smart.
Good starting points are &lt;code&gt;man namespaces&lt;/code&gt; and &lt;code&gt;man cgroups&lt;/code&gt;. In there you&amp;rsquo;ll find pointers to more
detailed information of the specific namespaces and cgroups.&lt;/p&gt;
&lt;p&gt;Yes, i did just tell you to RTFM ;-)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Make Email Great Again</title>
      <link>http://arthofer.sh/posts/2020-04-05-make-email-great-again/</link>
      <pubDate>Sun, 05 Apr 2020 20:19:56 +0200</pubDate>
      
      <guid>http://arthofer.sh/posts/2020-04-05-make-email-great-again/</guid>
      <description>&lt;h2 id=&#34;the-situation&#34;&gt;The situation&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s the beginning of April 2020 and &lt;a href=&#34;https://en.wikipedia.org/wiki/Coronavirus_disease_2019&#34;&gt;&amp;ldquo;COVID-19&amp;rdquo;&lt;/a&gt;
happened.
Nearly the whole world is in lock-down mode currently. Some more, some less. And most people are
very worried.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m stupidly lucky to work at a company that reacted quite early and strict and went into full
mandatory &amp;ldquo;work from home&amp;rdquo;-mode. And since it&amp;rsquo;s a very modern IT company, all of the work luckily
can be done remotely. Because the internet exists and our whole infrastructure (at least the parts
i know of) is available from every place in the world (with proper VPN of course).&lt;/p&gt;
&lt;p&gt;Quite recently i got promoted to a team-lead position, which doesn&amp;rsquo;t mean &amp;ldquo;management&amp;rdquo; in our company,
just that you&amp;rsquo;re the person that should take care about various organizational and operational topics.
That means for example planning sprints and that I&amp;rsquo;m the main contact point for people outside of our
team that need something from us.&lt;/p&gt;
&lt;h2 id=&#34;instant-messaging-is-a-problem-not-a-solution-at-least-at-work&#34;&gt;Instant messaging is a problem, not a solution (at least at work)&lt;/h2&gt;
&lt;p&gt;So now I&amp;rsquo;m sitting at my cozy office at home and first was naively thinking &amp;ldquo;Well, at least I&amp;rsquo;ll get
some actual development work done now. Because there will be less interruptions&amp;rdquo;
&amp;hellip;.Holy shit did i underestimate the interruptive power of instant messaging. In our case: Slack.
And also &lt;a href=&#34;https://en.wikipedia.org/wiki/Zoom_Video_Communications&#34;&gt;Zoom&lt;/a&gt; meetings. Holy crap.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m about 3 weeks into government prescribed self-isolation and it feels like all i do during
my working hours is constantly chatting and video-conferencing.
Don&amp;rsquo;t get me wrong, those two can be quite valuable tools to keep up the social contact with my
colleagues. But in my opinion, chatting is terrible for handling our &amp;ldquo;daily business&amp;rdquo;. You are
confronted with a constant stream of tiny chunks of information. And not only from one source
(person), but from multiple. At the same time. Usually about different topics.
That&amp;rsquo;s like trying to watch 15 movies at the same time. Afterwards you&amp;rsquo;ve watched 15 movies,
but you can&amp;rsquo;t barely remember any details.
Of course this is a bit different with chatting. You might have the chance to stick with one
conversation at a time, at least for a short time frame. But you&amp;rsquo;ll still jump around between
conversations constantly. And it&amp;rsquo;s all for the greater good! You want to be a helpful colleague,
you want to be responsive, you want to react quickly to whatever comes along&amp;hellip;etc.
And in the end, after your day of &amp;ldquo;work&amp;rdquo; is over, it will feel like you accomplished nothing. Sure,
you answered lots of questions, helped others getting over some obstacle in their task, where
a nice and overly helpful co-worker. But damn, I&amp;rsquo;m (more or less) a developer. I want to build
something. Automate some annoying task, produce a piece of software for our customers, patch
a bug&amp;hellip;.etc. But it&amp;rsquo;s impossible, because there&amp;rsquo;s always this nagging feeling that I&amp;rsquo;ve to answer
somebody on Slack. Because that&amp;rsquo;s the expectation that comes with tools like that: instant feedback.
But this is not how software development work. We deal with complex problems on complex systems
and need to prioritize which of those problems we deal with in what order. That can&amp;rsquo;t be done
with this kind of fragmented communication. It&amp;rsquo;s like I&amp;rsquo;m a server which gets bombarded with
a constant flood of UDP packets on all ports.
I need a firewall, a packet filter, a way to keep my communication-ports free and available.
And also a way to reduce my own system-load to have resources free to get some actual work done.&lt;/p&gt;
&lt;h2 id=&#34;e-mail-to-the-rescue&#34;&gt;E-Mail to the rescue?&lt;/h2&gt;
&lt;p&gt;This got me thinking. A lot.
Back when i started working in IT,there was no instant messaging for &amp;ldquo;the masses&amp;rdquo; at work
Sure, there was IRC, but it was only used by us nerds/geeks to keep in touch. And maybe sometimes
to ask a quick technical question. But then you mostly got a pointer where to look for a
solution to your problem (quite often the infamous RTFM). From what i experienced, most of the more
serious technical discussions in the internet happened in mailing lists and the Usenet.&lt;/p&gt;
&lt;p&gt;Maybe because an asynchronous medium is the better tool for the job?
It&amp;rsquo;s just the modern version of writing a letter.
When you write a letter, you (hopefully!) take your time to phrase the words for your objective
properly. Because you want to make sure to get the whole idea to the other side of communication
without going back and forth needlessly. You could say the limitations can be the main
advantage here.&lt;/p&gt;
&lt;p&gt;With instant messaging the conversation very often starts with a simple &amp;ldquo;hello&amp;rdquo;. Then nothing
happens until you finally answer to find out what the person on the other side actually wants.
This at least problematic enough that there is now a website which advocates against this
exact behavior: &lt;a href=&#34;https://nohello.com&#34;&gt;nohello.com&lt;/a&gt;. I can only emphasize that even this
small behavioral phenomenon can be quite a recurring problem during a typical day. And this is
only the start of one single communication stream. Then you have to, quite often, pull it
out of peoples noses what they actually want or need. Because they haven&amp;rsquo;t yet sat back for
5 minutes to think about it. They started a chat.&lt;/p&gt;
&lt;p&gt;I do believe that this won&amp;rsquo;t happen as much with an asynchronous medium like e-mail.
Nobody sends a mail with just &amp;ldquo;hello&amp;rdquo; in it (at least not in a professional environment).
People tend to at least shortly think about what they want to tell or ask you.
So this is the first part that&amp;rsquo;s better.&lt;/p&gt;
&lt;p&gt;The second and at least evenly important part is: You can sift through your inbox in a way
more structured manner. At the worst you do something like &amp;ldquo;from top to bottom&amp;rdquo; or &amp;ldquo;start with
the oldest and work your way to the most recent&amp;rdquo;. But with every not completely crappy
mail client you can apply some basic filtering. And the less crappy ones also have proper
displaying of mail threads (no, the &amp;ldquo;threads&amp;rdquo; in Slack are not good enough), which helps
understanding the flow of information quite a bit.&lt;/p&gt;
&lt;h2 id=&#34;you-ranted-a-lot-but-what-now&#34;&gt;You ranted a lot, but what now?&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll try to move my communication more back to e-mails.
That will definitely take some time since i got very used to Slack at this point of time.
Ironically i was even annoyed by mails lately. Because it felt like it costs so much more
time compared to just chatting. But as i rambled intensively above, the quality of information
transported is potentially better with e-mails (at least that&amp;rsquo;s what i currently believe).&lt;/p&gt;
&lt;p&gt;This will probably also take some understanding from my colleagues, since most things
are communicated via Slack currently. I&amp;rsquo;m looking forward to some lengthy discussions
here ;-)&lt;/p&gt;
&lt;p&gt;I guess this will be some kind of experiment of going &amp;ldquo;back to the roots&amp;rdquo;. Maybe I&amp;rsquo;ll
be posting some update to that later one. Assuming my co-workers haven&amp;rsquo;t chased my away
with pitchforks and torches.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Vim with fancy code completion</title>
      <link>http://arthofer.sh/posts/2019-11-20-vim-code-completion/</link>
      <pubDate>Wed, 20 Nov 2019 21:26:00 +0100</pubDate>
      
      <guid>http://arthofer.sh/posts/2019-11-20-vim-code-completion/</guid>
      <description>&lt;p&gt;I finally was annoyed enough to set up proper code-completion in Vim.
This is mostly a highly condensed and simplified version of a great blog post from
somebody else:
&lt;a href=&#34;https://octetz.com/posts/vim-as-go-ide&#34;&gt;https://octetz.com/posts/vim-as-go-ide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The main difference is that i&amp;rsquo;m not using Neovim. The reason being that i really like
gvim and all the GUI options for Neovim are either bloated Electron abominations or just
looking awkward.&lt;/p&gt;
&lt;h1 id=&#34;quick-setup&#34;&gt;Quick setup&lt;/h1&gt;
&lt;p&gt;Anyway, to replicate my setup you need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vim in at least version 8.0&lt;/li&gt;
&lt;li&gt;The excellent vim-plug installed: &lt;a href=&#34;https://github.com/junegunn/vim-plug&#34;&gt;https://github.com/junegunn/vim-plug&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Go installed and properly configured (if you care about the Go integration)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Put this in your &lt;code&gt;.vimrc&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;#34; vim-plug config
call plug#begin(&amp;#39;~/.vim/plugged&amp;#39;)
Plug &amp;#39;fatih/vim-go&amp;#39;, { &amp;#39;do&amp;#39;: &amp;#39;:GoInstallBinaries&amp;#39;, &amp;#39;for&amp;#39;: &amp;#39;go&amp;#39; }
Plug &amp;#39;tpope/vim-surround&amp;#39;
Plug &amp;#39;scrooloose/nerdtree&amp;#39;, { &amp;#39;on&amp;#39;:  &amp;#39;NERDTreeToggle&amp;#39; }
Plug &amp;#39;neoclide/coc.nvim&amp;#39;, {&amp;#39;branch&amp;#39;: &amp;#39;release&amp;#39;}
Plug &amp;#39;sheerun/vim-polyglot&amp;#39;
Plug &amp;#39;PProvost/vim-ps1&amp;#39;
call plug#end()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then either open Vim and run &lt;code&gt;:PlugInstall&lt;/code&gt;, or run it via your shell with
&lt;code&gt;vim +PlugInstall&lt;/code&gt;. The result will be the same. You&amp;rsquo;ll get some progress indicators
and in the end a confirmation that all the wanted plugins are installed.&lt;/p&gt;
&lt;p&gt;Explaination of the plugins from above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;vim-go: Go development plugin (&lt;a href=&#34;https://github.com/fatih/vim-go&#34;&gt;https://github.com/fatih/vim-go&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;vim-surround: nice helper for changing quotes, braces&amp;hellip;etc (&lt;a href=&#34;https://github.com/tpope/vim-surround&#34;&gt;https://github.com/tpope/vim-surround&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;nerdtree: file browser thingy (&lt;a href=&#34;https://github.com/scrooloose/nerdtree&#34;&gt;https://github.com/scrooloose/nerdtree&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;CoC: code completion engine black magic (&lt;a href=&#34;https://github.com/neoclide/coc.nvim&#34;&gt;https://github.com/neoclide/coc.nvim&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;vim-polyglot: language pack collection (&lt;a href=&#34;https://github.com/sheerun/vim-polyglot&#34;&gt;https://github.com/sheerun/vim-polyglot&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;vim-ps1: powershell plugin (yes, some of us have professionally deal with that) (&lt;a href=&#34;https://github.com/PProvost/vim-ps1&#34;&gt;https://github.com/PProvost/vim-ps1&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;install-language-servers&#34;&gt;Install language servers&lt;/h1&gt;
&lt;p&gt;&lt;code&gt;coc.nvim&lt;/code&gt; enables you to use the very nice concept of language servers (&lt;a href=&#34;https://en.wikipedia.org/wiki/Language_Server_Protocol)&#34;&gt;https://en.wikipedia.org/wiki/Language_Server_Protocol)&lt;/a&gt;.
So to use that, you need to install some of them. On Arch you&amp;rsquo;d do something like&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ pacman -S bash-language-server python-language-server
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;go-langserver&lt;/code&gt; can be installed with&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ go get -u github.com/sourcegraph/go-langserver
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h1 id=&#34;configure-language-servers&#34;&gt;Configure language servers&lt;/h1&gt;
&lt;p&gt;To actually configure &lt;code&gt;coc.nvim&lt;/code&gt; to make use of some language servers run &lt;code&gt;:CocConfig&lt;/code&gt; in your Vim.
Then configure it like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;powershell.integratedConsole.showOnStartup&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;diagnostic.virtualText&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;languageserver&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;golang&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;go-langserver&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;filetypes&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;go&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;initializationOptions&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;gocodeCompletionEnabled&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;diagnosticsEnabled&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;lintTool&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;golint&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;languageserver&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;bash&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bash-language-server&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;start&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;filetypes&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sh&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;ignoredRootPaths&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;~&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;languageserver&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;terraform&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;terraform-lsp&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;filetypes&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;terraform&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;initializationOptions&amp;#34;&lt;/span&gt;: {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then you want to make sure some &lt;code&gt;coc.nvim&lt;/code&gt; extensions are installed if missing.
You do that with adding this to your &lt;code&gt;.vimrc&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;#34; automatically install coc extensions if they&amp;#39;re missing
let g:coc_global_extensions=[ &amp;#39;coc-powershell&amp;#39;, &amp;#39;coc-python&amp;#39; , &amp;#39;coc-yaml&amp;#39;]
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;overall-cocnvim-config&#34;&gt;Overall coc.nvim config&lt;/h1&gt;
&lt;p&gt;Finally, you want to properly configure &lt;code&gt;coc.nvim&lt;/code&gt;.
Just put this into your &lt;code&gt;.vimrc&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;#34; -------------------------------------------------------------------------------------------------
&amp;#34; coc.nvim default settings
&amp;#34; -------------------------------------------------------------------------------------------------

&amp;#34; if hidden is not set, TextEdit might fail.
set hidden
&amp;#34; Better display for messages
set cmdheight=2
&amp;#34; Smaller updatetime for CursorHold &amp;amp; CursorHoldI
set updatetime=300
&amp;#34; don&amp;#39;t give |ins-completion-menu| messages.
set shortmess+=c
&amp;#34; always show signcolumns
set signcolumn=yes

&amp;#34; Use tab for trigger completion with characters ahead and navigate.
&amp;#34; Use command &amp;#39;:verbose imap &amp;lt;tab&amp;gt;&amp;#39; to make sure tab is not mapped by other plugin.
inoremap &amp;lt;silent&amp;gt;&amp;lt;expr&amp;gt; &amp;lt;TAB&amp;gt;
      \ pumvisible() ? &amp;#34;\&amp;lt;C-n&amp;gt;&amp;#34; :
      \ &amp;lt;SID&amp;gt;check_back_space() ? &amp;#34;\&amp;lt;TAB&amp;gt;&amp;#34; :
      \ coc#refresh()
inoremap &amp;lt;expr&amp;gt;&amp;lt;S-TAB&amp;gt; pumvisible() ? &amp;#34;\&amp;lt;C-p&amp;gt;&amp;#34; : &amp;#34;\&amp;lt;C-h&amp;gt;&amp;#34;

function! s:check_back_space() abort
  let col = col(&amp;#39;.&amp;#39;) - 1
  return !col || getline(&amp;#39;.&amp;#39;)[col - 1]  =~# &amp;#39;\s&amp;#39;
endfunction

&amp;#34; Use &amp;lt;c-space&amp;gt; to trigger completion.
inoremap &amp;lt;silent&amp;gt;&amp;lt;expr&amp;gt; &amp;lt;c-space&amp;gt; coc#refresh()

&amp;#34; Use `[c` and `]c` to navigate diagnostics
nmap &amp;lt;silent&amp;gt; [c &amp;lt;Plug&amp;gt;(coc-diagnostic-prev)
nmap &amp;lt;silent&amp;gt; ]c &amp;lt;Plug&amp;gt;(coc-diagnostic-next)

&amp;#34; Remap keys for gotos
nmap &amp;lt;silent&amp;gt; gd &amp;lt;Plug&amp;gt;(coc-definition)
nmap &amp;lt;silent&amp;gt; gy &amp;lt;Plug&amp;gt;(coc-type-definition)
nmap &amp;lt;silent&amp;gt; gi &amp;lt;Plug&amp;gt;(coc-implementation)
nmap &amp;lt;silent&amp;gt; gr &amp;lt;Plug&amp;gt;(coc-references)

&amp;#34; Use U to show documentation in preview window
nnoremap &amp;lt;silent&amp;gt; U :call &amp;lt;SID&amp;gt;show_documentation()&amp;lt;CR&amp;gt;

&amp;#34; Remap for rename current word
nmap &amp;lt;leader&amp;gt;rn &amp;lt;Plug&amp;gt;(coc-rename)

&amp;#34; Remap for format selected region
vmap &amp;lt;leader&amp;gt;f  &amp;lt;Plug&amp;gt;(coc-format-selected)
nmap &amp;lt;leader&amp;gt;f  &amp;lt;Plug&amp;gt;(coc-format-selected)
&amp;#34; Show all diagnostics
nnoremap &amp;lt;silent&amp;gt; &amp;lt;space&amp;gt;a  :&amp;lt;C-u&amp;gt;CocList diagnostics&amp;lt;cr&amp;gt;
&amp;#34; Manage extensions
nnoremap &amp;lt;silent&amp;gt; &amp;lt;space&amp;gt;e  :&amp;lt;C-u&amp;gt;CocList extensions&amp;lt;cr&amp;gt;
&amp;#34; Show commands
nnoremap &amp;lt;silent&amp;gt; &amp;lt;space&amp;gt;c  :&amp;lt;C-u&amp;gt;CocList commands&amp;lt;cr&amp;gt;
&amp;#34; Find symbol of current document
nnoremap &amp;lt;silent&amp;gt; &amp;lt;space&amp;gt;o  :&amp;lt;C-u&amp;gt;CocList outline&amp;lt;cr&amp;gt;
&amp;#34; Search workspace symbols
nnoremap &amp;lt;silent&amp;gt; &amp;lt;space&amp;gt;s  :&amp;lt;C-u&amp;gt;CocList -I symbols&amp;lt;cr&amp;gt;
&amp;#34; Do default action for next item.
nnoremap &amp;lt;silent&amp;gt; &amp;lt;space&amp;gt;j  :&amp;lt;C-u&amp;gt;CocNext&amp;lt;CR&amp;gt;
&amp;#34; Do default action for previous item.
nnoremap &amp;lt;silent&amp;gt; &amp;lt;space&amp;gt;k  :&amp;lt;C-u&amp;gt;CocPrev&amp;lt;CR&amp;gt;
&amp;#34; Resume latest coc list
nnoremap &amp;lt;silent&amp;gt; &amp;lt;space&amp;gt;p  :&amp;lt;C-u&amp;gt;CocListResume&amp;lt;CR&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This seemed to work fine for me. Have fun and enjoy your Vim on steroids :-)&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Set up environment-modules</title>
      <link>http://arthofer.sh/posts/2019-01-05-env-modules/</link>
      <pubDate>Sat, 05 Jan 2019 20:00:00 +0200</pubDate>
      
      <guid>http://arthofer.sh/posts/2019-01-05-env-modules/</guid>
      <description>&lt;p&gt;These instructions are valid for a current Arch Linux installation, since that&amp;rsquo;s
what i&amp;rsquo;m using. Some details might differ on other distributions.&lt;/p&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;p&gt;Install env-modules package from AUR:&lt;/p&gt;
&lt;p&gt;(I use trizen to manage AUR packages, but that&amp;rsquo;s just personal preference)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;trizen -S env-modules
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There&amp;rsquo;s also env-modules-tcl, but i had some problems with that, so i stayed
with env-modules.&lt;/p&gt;
&lt;h2 id=&#34;setup&#34;&gt;Setup&lt;/h2&gt;
&lt;p&gt;Create $HOME/.modulefiles:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mkdir $HOME/modulefiles
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add this snippet to your .bashrc:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;#add own modules to modulepath&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; -d $HOME/.modulefiles &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    module use $HOME/.modulefiles
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Reload .bash&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;source .bashrc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;example-module-file&#34;&gt;Example module file&lt;/h2&gt;
&lt;p&gt;Create &amp;lsquo;hello&amp;rsquo; module file:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;touch $HOME/.modulefiles/hello
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Open $HOME/.modulefiles/hello with your editor and insert this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#%Module1.0######################################################################&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;##&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;## helllo modulefile&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;##&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;proc ModulesHelp &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    puts stderr &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;\t&amp;#39;hello world&amp;#39; for demo purposes&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;module-whatis   &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;sets HELLO to &amp;#39;hello world&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You should see the new module file now when you run &amp;ldquo;module avail&amp;rdquo;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ module avail
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;------------------------------------- /home/flart/.modulefiles --------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;hello
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Other directories in your module path might also show up here)&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
