(Go) Docker Context

2022-01-08 12:10

I've lately been writing some coding projects in Go for no particular reason. I had a brief encounter with rust but it didn't really click with me since the language seems to require you to have completely planned out your program before you even start. Ideas just don't fall out of my head complete like Athena from the head of Zeus.

This time the project was one of necessity (as usual); I've been moving away from docker-machine at home and at work since it seems to have become unfasionable and moving to Docker Desktop. Docker-machine has the superior feature of saving the docker host in an environment variable meaning you can have a different host for each terminal, something I often exploited at work keeping one Windows Terminal pointed at the local docker machine and one to the staging / production server, using a small bat script that changed the terminal prompt to include a red indicator which host I was connected to to avoid accidentally stopping or restarting containers on the production servers for instance.

Docker desktop does away with that since it has a global context and while you can pass the -c <context> flag, you have to remember to type that... It's also extra cumbersome in that you have to type docker context show just to see context is currently active and docker context use <context> to switch!

So this last and this (long) epiphany weekend I set about writing something.

I wanted a program that could be always on the screen somewhere and hold the name of the context as well as a color indicator so it would be obviously glanceable which context currently was active.

At first I thought an always-on-top window would be good but along the way I found wsl-ssh-pageant, a fantastic piece of glue software that bridges pageant (the putty ssh agent that I've previously linked up with keepassxc at work; whenever I unlock the password database, it loads the ssh keys into pageant) with both the WSL OpenSSH and windows built-in OpenSSH. Very handy.

wsl-ssh-pageant used the windows system tray for showing that it was running and I thought I could use that instead as the Go module (systray) that handles it seemed really nice and simple.

I knew from converting to docker context that it stored the current context in a file ($HOME/.docker/config.json) and started there with file monitoring observing the changes of the file and when it was written to, load the JSON data inside and output the context name.

This got turned into a goroutine with an output channel that the main loop could just sit waiting for data on and then update the systray icon.

But just having a tooltip on a systray icon wasn't really useful to me so I changed the code to dynamically create a colored icon (just a square since the golang draw module isn't terribly featureful, I'll probably fix that) that took its color from the context name by adding up all the letters (unicode runes in golang) in the name and using a simple modulo instruction over the number of colors to pick one. Pretty bad still, this is prone to collsions and I would really like to be able to configure the colors manually. This would however need either more command arguments or a configuration file of our own. Something to think about.

There was a couple of go modules for generating ico files, but they all were expecting to work on files (presumably favico generators, and I'd have to mess around with bufio writers) and it seemed like ICO was a simple enough format that I could just write my own that outputs []bytes so along the way I wrote my own ICO format module, which was quite fun and also instructive in that I now know why Go had such awful modules for ico... :-)

My module is very basic still, but it has the potential for covering the entire ICO spec (As found on everyone's favourite source of knowledge on the internet; Wikipedia).

A fun project anyway, I'm not entirely over Go's many idiosyncracies yet, but it seems like a pretty ok high-level compiled language that isn't rust.

A language for getting things done.

Oh, and here's the program: godockercontext

Staffan