Skip to main content

The Bootstrapping Problem

·989 words·5 mins
Unrefined Kepler Halley
Author
Jonas A. Hultén
Opinionated engineer who rambles semi-coherently about DevOps, type systems, math, music, keyboard layouts, security, and misc.

Thinking up a project is easy. Starting it is hard. Starting it correctly is way hard.

Case in point: I am writing this post on a local Hugo installation, because I currently don’t have anywhere to host it. Or, well… I do, but it hasn’t been configured yet. And this is just the (current) bottom layer of a very big Russian nesting doll of projects.

But why a blog?
#

Given the heap of projects, why am I prioritizing a blog?

Good question. For starters, as anyone who has ever met me can attest to, I am absolute trash at prioritization. Can’t project-manage myself worth even half a damn.

The real reason, though, is that it’s getting to the point where I can’t keep it all in my head. My trusty notebook helps, but it’s not a good fix. I vented to a friend about this, who’s response was “you should set up a blog!” with the added subtext “so I can follow your descent into madness!”.

So this blog exists somewhere between a stream of consciousness and an actual dev-log of my myriad projects. The unrefined tag is for the former. The latter… is to be determined.

The Project Matryoshka
#

There are… two or three top-level projects from which all others stem. One is Halley, my backup manager. It’s unfinished, and has been unfinished for the better part of four years. More on that later.

Jonas A. Hultén / Halley

Offsite backup manager

0
0

The other one is Kepler, my attempt to manage all my systems using some sort of unified process and configuration. This started as some sort of run-Ansible-but-locally shenanigans and has slowly evolved into “just run NixOS on everything”. Which begs the question: Am I any good at NixOS?

No, no I am not. Still, I have been using it — with some limited success — on my laptop now for about six months (don’t ask about the desktop, that’s a separate story for another time).

Which brings me to the blog, kind of. While I have written some rudimentary Tofu in Kepler to let me set up remote servers and even handle the DNS for me, most sane cloud hosts don’t offer NixOS as an option. Could I just install nginx on a bog-standard Ubuntu server, publish my blog, and call it a day? I could, but I don’t want to. The point of the Kepler project is that I don’t have to do one-off manual installations. Everything which can be automated should be automated. Everything which can be specified should be specified. Unknowns must be eliminated. A key component of that is using NixOS, but how on earth do I bootstrap it?

The point
#

I have, despite my best attempts, not figured out a decent way of bootstrapping a NixOS machine. In fact, doing so is a key function of Kepler, but I’m trapped in a Catch-22.

I’d set up a local VM on my laptop — which feels like I’m torturing the poor machine — to play around with installing a NixOS system. However, by default, the NixOS ISO doesn’t have ssh enabled. Or, rather, it does, but the default nix account doesn’t have a password or a key, so you can’t connect to it.

This lead me down a rabbit hole of trying to figure out how to inject an SSH authorized_keys file into the ISO, which in turn lead to me researching how SquashFS works, before eventually getting distracted and trundling off to work on something else — did I mention I’m garbage at prioritization? The hope here was to put together a script that can take the latest NixOS ISO, unpack it somewhere, inject the authorized_keys file, and re-pack it. Needless to say, I haven’t gotten that far. But without SSH access to the system, I can’t use Ansible (or some other mechanism) to inject Nix config and actually configure a new system.

This problem reared its ugly head again the other day when I decided that it was blog time. For quite some time I have been sitting on a cloud server that I have done absolutely nothing with, because while I have written the Tofu to create it, I ran out of patience when it came to the Ansible part. Ultimately, I’d like for all of my systems to run NixOS or, barring that, Nix, but working out how to get Nix up and running on an Ubuntu system felt like too big of a headache at the time.

Anyhow, the other day I realized that Hetzner, in their greatness, actually lets you mount the NixOS installation ISO to your cloud server and boot from it, effectively allowing you to install NixOS in the cloud. So far so good, but… how do I bootstrap it? The answer seems to be that I have to connect to the server’s cloud console to do initial installation — because, again, there’s no SSH — which pains me.

My hope is that I will be able to install a tiny NixOS installation — maybe even with flakes enabled — plug in my SSH key, then take a snapshot of that system so that I can create future servers from that snapshot. It’s not an elegant solution, since I still have to manually do that initial installation, but it may solve one layer of this unholy tower of projects and tasks.

So, why haven’t you?
#

Say it with me: poor prioritization skills!

Crafting chain mail has been more fun and rewarding, and doesn’t require me having to mentally unravel the definitely-not-acyclic graph of projects I have floating around in my head. I also have another programming task for the benefit of my choir — also more on that later. And, as one might expect, I also have a day job.

So, for the time being, this blog lives on my hard drive. Until I solve the bootstrapping problem.